Преглед изворни кода

fix: channel pricing not working correctly

This PR fixes three issues:
1. Token bound_channel_id not updating: Add bound field to Update() method
2. Channel pricing quota_type detection: Use QuotaTypeByCall constant instead of magic number 1
3. Log display for ratio-based pricing: Set ModelPrice=-1 for ratio-based pricing

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
feat/alipay-payment
fengsilin пре 1 месец
родитељ
комит
15a99da48e
5 измењених фајлова са 46 додато и 4 уклоњено
  1. +3
    -0
      .gitignore
  2. +3
    -0
      controller/relay.go
  3. +2
    -2
      model/channel_pricing.go
  4. +1
    -1
      model/token.go
  5. +37
    -1
      relay/helper/price.go

+ 3
- 0
.gitignore Прегледај датотеку

@@ -32,3 +32,6 @@ data/
.gomodcache/ .gomodcache/
.gocache-temp .gocache-temp
.gopath .gopath

# 测试脚本目录
test-scripts/

+ 3
- 0
controller/relay.go Прегледај датотеку

@@ -191,6 +191,9 @@ func Relay(c *gin.Context, relayFormat types.RelayFormat) {
break break
} }


// 在渠道选择后更新价格数据以使用渠道定价
helper.UpdatePriceDataForChannelPricing(c, relayInfo, channel.Id)

addUsedChannel(c, channel.Id) addUsedChannel(c, channel.Id)
bodyStorage, bodyErr := common.GetBodyStorage(c) bodyStorage, bodyErr := common.GetBodyStorage(c)
if bodyErr != nil { if bodyErr != nil {


+ 2
- 2
model/channel_pricing.go Прегледај датотеку

@@ -150,7 +150,7 @@ func GetEffectivePricing(modelName string, channelId int) (modelRatio, completio
if time.Since(channelPricingCacheTime) < channelPricingCacheTTL { if time.Since(channelPricingCacheTime) < channelPricingCacheTTL {
if cp, ok := channelPricingCache[cacheKey]; ok { if cp, ok := channelPricingCache[cacheKey]; ok {
channelPricingCacheLock.RUnlock() channelPricingCacheLock.RUnlock()
return cp.ModelRatio, cp.CompletionRatio, cp.ModelPrice, true, true
return cp.ModelRatio, cp.CompletionRatio, cp.ModelPrice, cp.QuotaType == QuotaTypeByCall, true
} }
} }
channelPricingCacheLock.RUnlock() channelPricingCacheLock.RUnlock()
@@ -173,7 +173,7 @@ func GetEffectivePricing(modelName string, channelId int) (modelRatio, completio
channelPricingCache[cacheKey] = &cp channelPricingCache[cacheKey] = &cp
channelPricingCacheLock.Unlock() channelPricingCacheLock.Unlock()


return cp.ModelRatio, cp.CompletionRatio, cp.ModelPrice, true, true
return cp.ModelRatio, cp.CompletionRatio, cp.ModelPrice, cp.QuotaType == QuotaTypeByCall, true
} }


// RefreshChannelPricingCache 刷新渠道定价缓存 // RefreshChannelPricingCache 刷新渠道定价缓存


+ 1
- 1
model/token.go Прегледај датотеку

@@ -284,7 +284,7 @@ func (token *Token) Update() (err error) {
} }
}() }()
err = DB.Model(token).Select("name", "status", "expired_time", "remain_quota", "unlimited_quota", err = DB.Model(token).Select("name", "status", "expired_time", "remain_quota", "unlimited_quota",
"model_limits_enabled", "model_limits", "allow_ips", "group", "cross_group_retry").Updates(token).Error
"model_limits_enabled", "model_limits", "allow_ips", "group", "cross_group_retry", "bound_channel_id").Updates(token).Error
return err return err
} }




+ 37
- 1
relay/helper/price.go Прегледај датотеку

@@ -54,7 +54,7 @@ func ModelPriceHelper(c *gin.Context, info *relaycommon.RelayInfo, promptTokens
var channelPricingFound bool var channelPricingFound bool


// 尝试获取渠道定价(优先于全局定价) // 尝试获取渠道定价(优先于全局定价)
if info.ChannelMeta != nil && info.ChannelId > 0 {
if info != nil && info.ChannelMeta != nil && info.ChannelId > 0 {
cpRatio, cpCompletionRatio, cpPrice, cpUsePrice, found := model.GetEffectivePricing(info.OriginModelName, info.ChannelId) cpRatio, cpCompletionRatio, cpPrice, cpUsePrice, found := model.GetEffectivePricing(info.OriginModelName, info.ChannelId)
if found { if found {
modelRatio = cpRatio modelRatio = cpRatio
@@ -207,3 +207,39 @@ func ContainPriceOrRatio(modelName string) bool {
} }
return false return false
} }

// UpdatePriceDataForChannelPricing 在渠道选择后更新 PriceData 以使用渠道定价
// ModelPriceHelper 在渠道选择之前被调用,此时 ChannelMeta 为 nil,导致渠道定价无法使用。
// 需要在渠道选择后调用此函数更新价格数据,用于后续的日志记录和计费计算。
func UpdatePriceDataForChannelPricing(c *gin.Context, info *relaycommon.RelayInfo, channelId int) {
if info == nil || channelId <= 0 {
return
}

cpRatio, cpCompletionRatio, cpPrice, cpUsePrice, found := model.GetEffectivePricing(info.OriginModelName, channelId)
if !found {
return
}

// 更新 PriceData 中的定价相关字段
info.PriceData.ModelRatio = cpRatio
info.PriceData.CompletionRatio = cpCompletionRatio
info.PriceData.UsePrice = cpUsePrice
// 按次计费模式下使用渠道价格,按量计费模式下设置 ModelPrice = -1 让前端识别计费模式
if cpUsePrice {
info.PriceData.ModelPrice = cpPrice
} else {
info.PriceData.ModelPrice = -1
}

// 重新计算预扣费额度(用于后续可能的引用)
if cpUsePrice {
info.PriceData.QuotaToPreConsume = int(cpPrice * common.QuotaPerUnit * info.PriceData.GroupRatioInfo.GroupRatio)
} else {
estimateTokens := info.GetEstimatePromptTokens()
if estimateTokens > 0 {
ratio := cpRatio * info.PriceData.GroupRatioInfo.GroupRatio
info.PriceData.QuotaToPreConsume = int(float64(estimateTokens) * ratio)
}
}
}

Loading…
Откажи
Сачувај