From 4211409f5259538538b708d6a88e88406bd7fb13 Mon Sep 17 00:00:00 2001 From: 111 <1509332485@qq.com> Date: Thu, 7 May 2026 22:02:20 +0800 Subject: [PATCH] =?UTF-8?q?stc-5/7-22.01=E8=A7=A3=E5=86=B3=E6=96=87?= =?UTF-8?q?=E6=9C=AC=E7=AD=89=E6=A8=A1=E5=9E=8B=E4=BA=8C=E6=AC=A1=E5=BA=94?= =?UTF-8?q?=E7=94=A8=E4=BC=81=E4=B8=9A=E6=8A=98=E6=89=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- service/billing.go | 33 ++++++++++++++++++++++++++++++--- service/billing_session.go | 12 +++++++++++- service/quota.go | 2 +- service/text_quota.go | 2 +- 4 files changed, 43 insertions(+), 6 deletions(-) diff --git a/service/billing.go b/service/billing.go index b823ec88cc5f..37626b576023 100644 --- a/service/billing.go +++ b/service/billing.go @@ -76,8 +76,25 @@ func PreConsumeBilling(c *gin.Context, preConsumedQuota int, relayInfo *relaycom // SettleBilling 执行计费结算。如果 RelayInfo 上有 BillingSession 则通过 session 结算, // 否则回退到旧的 PostConsumeQuota 路径(兼容按次计费等场景)。 func SettleBilling(ctx *gin.Context, relayInfo *relaycommon.RelayInfo, actualQuota int) error { + return settleBilling(ctx, relayInfo, actualQuota, false) +} + +// SettleBillingDiscounted settles a quota value that has already had enterprise +// discount applied by the quota calculator. +func SettleBillingDiscounted(ctx *gin.Context, relayInfo *relaycommon.RelayInfo, actualQuota int) error { + return settleBilling(ctx, relayInfo, actualQuota, true) +} + +type discountedSettler interface { + SettleDiscounted(actualQuota int) error +} + +func settleBilling(ctx *gin.Context, relayInfo *relaycommon.RelayInfo, actualQuota int, alreadyDiscounted bool) error { if relayInfo.Billing != nil { - normalizedActual := NormalizeRecordedQuota(ctx, relayInfo, actualQuota) + normalizedActual := actualQuota + if !alreadyDiscounted { + normalizedActual = NormalizeRecordedQuota(ctx, relayInfo, actualQuota) + } preConsumed := relayInfo.Billing.GetPreConsumedQuota() delta := normalizedActual - preConsumed @@ -99,8 +116,18 @@ func SettleBilling(ctx *gin.Context, relayInfo *relaycommon.RelayInfo, actualQuo )) } - if err := relayInfo.Billing.Settle(actualQuota); err != nil { - return err + if alreadyDiscounted { + settler, ok := relayInfo.Billing.(discountedSettler) + if !ok { + return fmt.Errorf("billing session does not support discounted settlement") + } + if err := settler.SettleDiscounted(actualQuota); err != nil { + return err + } + } else { + if err := relayInfo.Billing.Settle(actualQuota); err != nil { + return err + } } // 发送额度通知(订阅计费使用订阅剩余额度) diff --git a/service/billing_session.go b/service/billing_session.go index 4a5119299d22..94878470838f 100644 --- a/service/billing_session.go +++ b/service/billing_session.go @@ -38,12 +38,22 @@ type BillingSession struct { // 资金来源和令牌额度分两步提交:若资金来源已提交但令牌调整失败, // 会标记 fundingSettled 防止 Refund 对已提交的资金来源执行退款。 func (s *BillingSession) Settle(actualQuota int) error { + return s.settle(actualQuota, false) +} + +// SettleDiscounted settles a quota value that already has the enterprise +// discount applied by the caller. +func (s *BillingSession) SettleDiscounted(actualQuota int) error { + return s.settle(actualQuota, true) +} + +func (s *BillingSession) settle(actualQuota int, alreadyDiscounted bool) error { s.mu.Lock() defer s.mu.Unlock() if s.settled { return nil } - if s.discountRate < 1.0 { + if !alreadyDiscounted && s.discountRate < 1.0 { discountedActual := int(float64(actualQuota) * s.discountRate) if discountedActual < 1 && actualQuota > 0 { discountedActual = 1 diff --git a/service/quota.go b/service/quota.go index 7a2b528a970e..a8bedefa6089 100644 --- a/service/quota.go +++ b/service/quota.go @@ -334,7 +334,7 @@ func PostAudioConsumeQuota(ctx *gin.Context, relayInfo *relaycommon.RelayInfo, u model.UpdateChannelUsedQuota(relayInfo.ChannelId, quota) } - if err := SettleBilling(ctx, relayInfo, quota); err != nil { + if err := SettleBillingDiscounted(ctx, relayInfo, quota); err != nil { logger.LogError(ctx, "error settling billing: "+err.Error()) } diff --git a/service/text_quota.go b/service/text_quota.go index a36697c58231..d090ad717ccb 100644 --- a/service/text_quota.go +++ b/service/text_quota.go @@ -344,7 +344,7 @@ func PostTextConsumeQuota(ctx *gin.Context, relayInfo *relaycommon.RelayInfo, us model.UpdateChannelUsedQuota(relayInfo.ChannelId, summary.Quota) } - if err := SettleBilling(ctx, relayInfo, summary.Quota); err != nil { + if err := SettleBillingDiscounted(ctx, relayInfo, summary.Quota); err != nil { logger.LogError(ctx, "error settling billing: "+err.Error()) }