97 lines
2.9 KiB
Go
97 lines
2.9 KiB
Go
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
|
||
}
|