feat: SaaS P2 计量·增量1 —— 用量按租户落持久明细 + 积分/成本折算
链路打通 tenant → 计费事实源: - 契约:Task.Meta 加 MetaTenantID;UsageEvent 加 TenantID。 - 提交:网关 task.Meta[MetaTenantID]=tenantID(c);dispatcher emitUsage 带租户。 - 明细表 sundynix_usage_event(追加式,task_id 唯一→幂等防重投重复计费): tenant/owner/model/tokens + credits_micro + cost_micros。 - 折算:credits=total_tok/TOKENS_PER_CREDIT×credit_weight(token 基准,设 1 即 token 直计); cost 按 Pricing 折算;Pricing 加 credit_weight 列(每模型积分权重,缺省 1)。 模型名空则回退激活 chat 模型(近似,忽略 failover 备用模型,已在设计标注)。 - 网关 SubscribeUsage 折算落明细(保留 Redis 日计数作快速配额校验)。 live 验证:提交任务→一行 usage_event,tenant 匹配用户租户、 credits=89tok/1000×2×1e6=178000 微积分、cost=45/1000×1+44/1000×2=133000 微元 CNY, 折算数学与幂等键均正确。 设计见 SAAS_P2_DESIGN.md。增量2(credit_ledger 余额软扣 + rollup)待做。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -104,9 +104,14 @@ func main() {
|
||||
return
|
||||
}
|
||||
day := time.UnixMilli(ev.TS).Format("20060102")
|
||||
// 快速配额校验:Redis 按用户按天累计(48h TTL,供提交前门控)。
|
||||
if _, err := cache.AddUsage(context.Background(), ev.UserID, day, ev.TotalTok); err != nil {
|
||||
log.Printf("[gateway] 累计用量 user=%s 失败: %v", ev.UserID, err)
|
||||
}
|
||||
// 计费事实源:折算 credits + cost 幂等落持久明细(按 task_id 去重)。
|
||||
if err := db.SaveUsageEvent(context.Background(), ev); err != nil {
|
||||
log.Printf("[gateway] 落库用量明细 task=%s 失败: %v", ev.TaskID, err)
|
||||
}
|
||||
}); err != nil {
|
||||
log.Printf("[gateway] subscribe usage: %v", err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user