diff --git a/backend/internal/service/billing_service.go b/backend/internal/service/billing_service.go index d256102c..458788fd 100644 --- a/backend/internal/service/billing_service.go +++ b/backend/internal/service/billing_service.go @@ -542,6 +542,11 @@ func (s *BillingService) calculatePerRequestCost(resolved *ResolvedPricing, inpu unitPrice = input.Resolver.GetRequestTierPriceByContext(resolved, totalContext) } + // 回退到默认按次价格 + if unitPrice == 0 { + unitPrice = resolved.DefaultPerRequestPrice + } + totalCost := unitPrice * float64(count) actualCost := totalCost * input.RateMultiplier diff --git a/backend/internal/service/model_pricing_resolver.go b/backend/internal/service/model_pricing_resolver.go index 67f2684c..55387809 100644 --- a/backend/internal/service/model_pricing_resolver.go +++ b/backend/internal/service/model_pricing_resolver.go @@ -19,6 +19,9 @@ type ResolvedPricing struct { // 按次/图片模式:分层定价 RequestTiers []PricingInterval + // 按次/图片模式:默认价格(未命中层级时使用) + DefaultPerRequestPrice float64 + // 来源标识 Source string // "channel", "litellm", "fallback" @@ -136,6 +139,9 @@ func (r *ModelPricingResolver) applyTokenOverrides(chPricing *ChannelModelPricin // applyRequestTierOverrides 应用按次/图片模式的渠道覆盖 func (r *ModelPricingResolver) applyRequestTierOverrides(chPricing *ChannelModelPricing, resolved *ResolvedPricing) { resolved.RequestTiers = chPricing.Intervals + if chPricing.PerRequestPrice != nil { + resolved.DefaultPerRequestPrice = *chPricing.PerRequestPrice + } } // GetIntervalPricing 根据 context token 数获取区间定价。