Files
qian 67514a44a3 feat(billing):新增MiniMax特殊计费功能
此功能可以作为示例,后续需要特殊计费模式可参考此功能实现自行二开
2026-09-13 22:14:21 +08:00

59 lines
3.7 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package common
import (
"context"
"time"
"github.com/shopspring/decimal"
)
// TaskBillingProvider 异步任务计费接口
// 异步任务计费基于时长/分辨率等比率,非 token 数。
// ratios 键约定见 TaskAdaptor.EstimateBilling(float64 乘数 + spec.* 规格事实值)
type TaskBillingProvider interface {
// EstimateTaskCost 估算任务费用。
// taskBody 为归一化后的任务体(转换后通用格式):定价配置了参数倍率(param_multipliers)时,
// 实现方在函数内求值并把命中倍率就地注入 ratios(param_multiplier / param_matched 键,
// 随任务持久化保证预扣/结算/重算三口径同源);nil body = 不求值。
EstimateTaskCost(ctx context.Context, tenantID int64, modelName string, ratios map[string]any, taskBody []byte) (decimal.Decimal, error)
// PreDeductTask 预扣任务费用
PreDeductTask(ctx context.Context, tenantID int64, requestID string, estimatedCost decimal.Decimal, modelName string) (decimal.Decimal, error)
// CheckRateLimit QPS 限流检查
CheckRateLimit(ctx context.Context, tenantID, userID, apiKeyID int64, keyQPS int) (allowed bool, limitLevel string, limit int, remaining int, resetAt int64)
// AcquireApiKeyConcurrent 获取 API Key 级并发许可
AcquireApiKeyConcurrent(ctx context.Context, apiKeyID int64, limit int) bool
// ReleaseApiKeyConcurrent 释放 API Key 级并发许可
ReleaseApiKeyConcurrent(ctx context.Context, apiKeyID int64)
// CheckApiKeyQuota 检查 API Key 额度是否足够
CheckApiKeyQuota(ctx context.Context, apiKeyID int64, preDeductAmount decimal.Decimal) error
// SettleTaskSuccess 任务成功结算(含计费快照)。billAt 为任务受理时刻(时段定价按该时刻评估,
// 异步任务结算滞后数分钟~小时,按结算时刻会丢失受理时的时段价)
SettleTaskSuccess(ctx context.Context, tenantID, userID, apiKeyID, channelID int64, modelName, requestID string, actualCost, preDeductAmount decimal.Decimal, totalTokens, completionTokens int, ratios map[string]any, taskID string, billAt time.Time) (*SettlementResult, error)
// SettleTaskFailed 任务失败退还预扣
SettleTaskFailed(ctx context.Context, tenantID int64, requestID string, preDeductAmount decimal.Decimal) error
// IncrApiKeyQuotaUsed 结算后累加 API Key 已用额度
IncrApiKeyQuotaUsed(ctx context.Context, apiKeyID int64, amount decimal.Decimal)
// AdjustTaskBilling 调整预扣金额(提交后上游确认了新参数)
AdjustTaskBilling(ctx context.Context, tenantID int64, requestID string, preDeductAmount, newEstimatedCost decimal.Decimal) (decimal.Decimal, error)
// RecalculateByTokens 根据上游返回的 total_tokens 重算费用(billAt 为任务受理时刻,时段定价用)
// totalTokens: 上游返回的 token 计费单位
// ratios: 提交时保存的计费上下文(如 video_input 折扣)
RecalculateByTokens(ctx context.Context, tenantID int64, modelName string, totalTokens int, ratios map[string]any, billAt time.Time) (decimal.Decimal, error)
// RecalculateByMaterials 按上游 usage 的素材计量重算任务费用(素材计费方案的结算依据)。
// 仅模型配置了素材计费方案(pricing JSONB scheme)时适用:ok=true 返回按方案结算口径
// 重算的最终费用;未配置方案、取价失败或 usage 为 nil 时 ok=false,调用方保持既有结算来源
// (预扣金额 / token 重算)。billAt 为任务受理时刻(时段定价用),ratios 为提交时持久化的计费上下文
RecalculateByMaterials(ctx context.Context, tenantID int64, modelName string, ratios map[string]any, usage *TaskMaterialUsage, billAt time.Time) (cost decimal.Decimal, ok bool, err error)
}