feat(api): GET /v1/user/balance 查询用户余额

users 表新增 credits_used(累计消耗积分):扣费累加、失败退款回减(refundIfNeeded / 维护清扫改走 RefundCredits),充值/CDK/签到发放不计入。接口返回 {object,balance,used,total},Bearer API Key 鉴权,与其他 v1 接口同一 CORS 与错误格式。站内接口文档与 README 补充端点说明。
This commit is contained in:
GlossSeaDress
2026-08-10 14:59:48 +08:00
parent 2c47344ed9
commit f94a7ace5f
9 changed files with 79 additions and 6 deletions
+16 -1
View File
@@ -391,6 +391,21 @@ func (s *V1Service) ListModels(ctx context.Context) ([]map[string]any, error) {
return out, nil
}
// UserBalance — GET /v1/user/balance 的数据。重新读一次用户行保证实时
// principal 里那份是鉴权时读的,可能已经过期)。
func (s *V1Service) UserBalance(ctx context.Context, principal *APIPrincipal) (map[string]any, error) {
user := principal.User
if fresh, err := s.users.GetByID(ctx, user.ID); err == nil && fresh != nil {
user = fresh
}
return map[string]any{
"object": "user.balance",
"balance": user.Credits,
"used": user.CreditsUsed,
"total": user.Credits + user.CreditsUsed,
}, nil
}
func (s *V1Service) PrepareImageRequest(ctx context.Context, principal *APIPrincipal, in V1ImageRequest) (map[string]any, error) {
return s.prepareImageExecution(ctx, principal, in, "v1", true)
}
@@ -3279,7 +3294,7 @@ func (s *V1Service) refundIfNeeded(ctx context.Context, principal *APIPrincipal,
if !claimed {
return nil
}
updated, err := s.users.AdjustCredits(ctx, principal.User.ID, price)
updated, err := s.users.RefundCredits(ctx, principal.User.ID, price)
if err == nil {
principal.User = updated
}