Commit f3ab3fe5 authored by erio's avatar erio
Browse files

fix: billing mode display follows cost calculation result

Instead of hardcoding BillingMode="image" when ImageCount>0,
let cost.BillingMode (set by CalculateCostUnified/CalculateImageCost)
take priority. This ensures channel token pricing shows "token" mode.
parent b8c56ff9
...@@ -890,8 +890,9 @@ func (s *BillingService) CalculateImageCost(model string, imageSize string, imag ...@@ -890,8 +890,9 @@ func (s *BillingService) CalculateImageCost(model string, imageSize string, imag
actualCost := totalCost * rateMultiplier actualCost := totalCost * rateMultiplier
return &CostBreakdown{ return &CostBreakdown{
TotalCost: totalCost, TotalCost: totalCost,
ActualCost: actualCost, ActualCost: actualCost,
BillingMode: string(BillingModeImage),
} }
} }
......
...@@ -7762,17 +7762,17 @@ func (s *GatewayService) RecordUsage(ctx context.Context, input *RecordUsageInpu ...@@ -7762,17 +7762,17 @@ func (s *GatewayService) RecordUsage(ctx context.Context, input *RecordUsageInpu
} else if result.MediaType == "prompt" { } else if result.MediaType == "prompt" {
cost = &CostBreakdown{} cost = &CostBreakdown{}
} else if result.ImageCount > 0 { } else if result.ImageCount > 0 {
// 图片生成计费:渠道 token 定价优先,否则走按次计费(兼容旧版本) // 图片生成计费:渠道级别定价优先,否则走按次计费(兼容旧版本)
useImageTokenBilling := false hasChannelPricing := false
if s.resolver != nil && apiKey.Group != nil { if s.resolver != nil && apiKey.Group != nil {
gid := apiKey.Group.ID gid := apiKey.Group.ID
resolved := s.resolver.Resolve(ctx, PricingInput{Model: billingModel, GroupID: &gid}) resolved := s.resolver.Resolve(ctx, PricingInput{Model: billingModel, GroupID: &gid})
if resolved.Source == "channel" && resolved.Mode == BillingModeToken { if resolved.Source == "channel" {
useImageTokenBilling = true hasChannelPricing = true
} }
} }
if useImageTokenBilling { if hasChannelPricing {
// 渠道配置了 token 定价 → 用 token 计费(image_output_tokens 独立计价) // 渠道定价优先 → 由 CalculateCostUnified 按 resolved.Mode 分发计费
tokens := UsageTokens{ tokens := UsageTokens{
InputTokens: result.Usage.InputTokens, InputTokens: result.Usage.InputTokens,
OutputTokens: result.Usage.OutputTokens, OutputTokens: result.Usage.OutputTokens,
...@@ -7901,12 +7901,12 @@ func (s *GatewayService) RecordUsage(ctx context.Context, input *RecordUsageInpu ...@@ -7901,12 +7901,12 @@ func (s *GatewayService) RecordUsage(ctx context.Context, input *RecordUsageInpu
// 设置计费模式 // 设置计费模式
if result.MediaType != "image" && result.MediaType != "video" && result.MediaType != "prompt" { if result.MediaType != "image" && result.MediaType != "video" && result.MediaType != "prompt" {
if result.ImageCount > 0 { if cost != nil && cost.BillingMode != "" {
billingMode := "image"
usageLog.BillingMode = &billingMode
} else if cost != nil && cost.BillingMode != "" {
billingMode := cost.BillingMode billingMode := cost.BillingMode
usageLog.BillingMode = &billingMode usageLog.BillingMode = &billingMode
} else if result.ImageCount > 0 {
billingMode := "image"
usageLog.BillingMode = &billingMode
} else { } else {
billingMode := "token" billingMode := "token"
usageLog.BillingMode = &billingMode usageLog.BillingMode = &billingMode
...@@ -8033,16 +8033,16 @@ func (s *GatewayService) RecordUsageWithLongContext(ctx context.Context, input * ...@@ -8033,16 +8033,16 @@ func (s *GatewayService) RecordUsageWithLongContext(ctx context.Context, input *
// 根据请求类型选择计费方式 // 根据请求类型选择计费方式
if result.ImageCount > 0 { if result.ImageCount > 0 {
// 图片生成计费:渠道 token 定价优先,否则走按次计费(兼容旧版本) // 图片生成计费:渠道级别定价优先,否则走按次计费(兼容旧版本)
useImageTokenBilling := false hasChannelPricing := false
if s.resolver != nil && apiKey.Group != nil { if s.resolver != nil && apiKey.Group != nil {
gid := apiKey.Group.ID gid := apiKey.Group.ID
resolved := s.resolver.Resolve(ctx, PricingInput{Model: billingModel, GroupID: &gid}) resolved := s.resolver.Resolve(ctx, PricingInput{Model: billingModel, GroupID: &gid})
if resolved.Source == "channel" && resolved.Mode == BillingModeToken { if resolved.Source == "channel" {
useImageTokenBilling = true hasChannelPricing = true
} }
} }
if useImageTokenBilling { if hasChannelPricing {
tokens := UsageTokens{ tokens := UsageTokens{
InputTokens: result.Usage.InputTokens, InputTokens: result.Usage.InputTokens,
OutputTokens: result.Usage.OutputTokens, OutputTokens: result.Usage.OutputTokens,
...@@ -8175,12 +8175,12 @@ func (s *GatewayService) RecordUsageWithLongContext(ctx context.Context, input * ...@@ -8175,12 +8175,12 @@ func (s *GatewayService) RecordUsageWithLongContext(ctx context.Context, input *
} }
// 设置计费模式 // 设置计费模式
if result.ImageCount > 0 { if cost != nil && cost.BillingMode != "" {
billingMode := "image"
usageLog.BillingMode = &billingMode
} else if cost != nil && cost.BillingMode != "" {
billingMode := cost.BillingMode billingMode := cost.BillingMode
usageLog.BillingMode = &billingMode usageLog.BillingMode = &billingMode
} else if result.ImageCount > 0 {
billingMode := "image"
usageLog.BillingMode = &billingMode
} else { } else {
billingMode := "token" billingMode := "token"
usageLog.BillingMode = &billingMode usageLog.BillingMode = &billingMode
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment