thread-master/apps/backend/internal/module/radar/usecase/billing.go

64 lines
1.6 KiB
Go
Raw Normal View History

2026-08-03 05:52:02 +00:00
package usecase
import (
"context"
"github.com/zeromicro/go-zero/core/logx"
)
/*
charge 是一次計點呼叫的預留與結算沿用既有四個 meter不新增第五個RG-04
用法`defer charge.Settle(ctx, &err)` 綁在具名 error 回傳上這樣任何失敗路徑都退點
不會出現AI 失敗了但點數扣掉
*/
type charge struct {
svc *Service
uid int64
meter string
mode string
label string
source string
settled bool
}
func (s *Service) bill(ctx context.Context, uid int64, meter, label, source string) (*charge, error) {
if s == nil || s.Usage == nil {
return &charge{settled: true}, nil
}
mode, err := s.Usage.PrepareCall(ctx, uid, meter)
if err != nil {
return nil, err
}
return &charge{svc: s, uid: uid, meter: meter, mode: mode, label: label, source: source}, nil
}
func (c *charge) Settle(ctx context.Context, errp *error) {
if errp != nil && *errp != nil {
c.Release(ctx)
return
}
c.Commit(ctx)
}
// Commit 寫入用量事件。使用者已經拿到結果,所以這裡失敗只記錄不轉成錯誤。
func (c *charge) Commit(ctx context.Context) {
if c == nil || c.settled {
return
}
c.settled = true
if _, err := c.svc.Usage.RecordCall(ctx, c.uid, c.meter, c.mode, c.label, c.source); err != nil {
logx.Errorf("usage record uid=%d meter=%s source=%s: %v", c.uid, c.meter, c.source, err)
}
}
func (c *charge) Release(ctx context.Context) {
if c == nil || c.settled {
return
}
c.settled = true
if err := c.svc.Usage.ReleaseCall(ctx, c.uid, c.meter, c.mode); err != nil {
logx.Errorf("usage release uid=%d meter=%s source=%s: %v", c.uid, c.meter, c.source, err)
}
}