Files
rootandClaude Opus 4.7 79ac89b458 Initial commit
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-11-07 10:47:18 +08:00

97 lines
2.9 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 payment
import (
"context"
"fmt"
"videoweb/pub/common/log"
"videoweb/pub/common/srvdef"
"videoweb/pub/common/utils"
"videoweb/pub/models/cointransmod"
"videoweb/pub/models/usermod"
"videoweb/pub/mongos"
"go.mongodb.org/mongo-driver/bson"
)
// WriteCoinTransOpt 写流水所需参数
type WriteCoinTransOpt struct {
UserId int64
UserName string // 可为空,自动查询
FlowDir cointransmod.FlowDir // FlowIn / FlowOut
TranType cointransmod.TranType // 交易类型
Amount int64 // 本次交易金币数(正整数)
OrderNo string // 关联订单号(可为空)
RelatedId int64 // 关联内容ID(可为空)
Remark string // 备注
}
// WriteCoinTrans 写一条金币流水记录
// balanceBefore 和 balanceAfter 从用户当前余额自动推算:
// - 若传入 balanceAfter(>= 0),直接使用;
// - 否则查库获取用户当前余额作为 balanceAfter,再反推 balanceBefore。
func WriteCoinTrans(ctx context.Context, opt WriteCoinTransOpt, balanceAfter int64) *srvdef.SrvErr {
userName := opt.UserName
if userName == "" {
if u, _ := usermod.FindOneUser(ctx, bson.M{usermod.FN.User.Id: opt.UserId}); u != nil {
userName = u.NickName
}
}
var balanceBefore int64
if opt.FlowDir == cointransmod.FlowIn {
balanceBefore = balanceAfter - opt.Amount
} else {
balanceBefore = balanceAfter + opt.Amount
}
if balanceBefore < 0 {
balanceBefore = 0
}
remark := opt.Remark
if remark == "" {
remark = opt.TranType.Desc()
}
doc := &cointransmod.CoinTrans{
Id: mongos.Lid.CoinTrans.Get(),
UserId: opt.UserId,
UserName: userName,
FlowDir: opt.FlowDir,
TranType: opt.TranType,
Amount: opt.Amount,
BalanceBefore: balanceBefore,
BalanceAfter: balanceAfter,
OrderNo: opt.OrderNo,
RelatedId: opt.RelatedId,
Remark: remark,
CreatedAt: utils.Now(),
}
if serr := cointransmod.InsertOneCoinTrans(ctx, doc); serr != nil {
log.Error("WriteCoinTrans InsertOneCoinTrans failed",
log.Any("userId", opt.UserId), log.Any("tranType", opt.TranType), log.E(serr))
return serr
}
return nil
}
// WriteCoinTransByUser 查询用户当前余额后自动写流水(适合已更新余额后调用)
func WriteCoinTransByUser(ctx context.Context, opt WriteCoinTransOpt) *srvdef.SrvErr {
u, serr := usermod.FindOneUser(ctx, bson.M{usermod.FN.User.Id: opt.UserId})
if serr != nil || u == nil {
return srvdef.New(srvdef.ErrNoData, "用户不存在", "")
}
if opt.UserName == "" {
opt.UserName = u.NickName
}
return WriteCoinTrans(ctx, opt, u.Recharge)
}
// CoinTransRemark 生成标准备注
func CoinTransRemark(tranType cointransmod.TranType, extra string) string {
name := tranType.Desc()
if extra != "" {
return fmt.Sprintf("%s:%s", name, extra)
}
return name
}