64 lines
1.6 KiB
Go
64 lines
1.6 KiB
Go
|
|
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)
|
|||
|
|
}
|
|||
|
|
}
|