Commit eee21ef5 authored by JiebinHu's avatar JiebinHu

feat:事务操作账号明细

明早细细调,用游戏服务
parent d9e63096
......@@ -6,8 +6,11 @@ import (
"git.hilo.cn/hilo-common/internal/enum/diamond_e"
"git.hilo.cn/hilo-common/internal/enum/msg_e"
"git.hilo.cn/hilo-common/internal/model/diamond_m"
"git.hilo.cn/hilo-common/myerr"
"git.hilo.cn/hilo-common/resource/mysql"
"git.hilo.cn/hilo-common/txop/msg"
"github.com/sirupsen/logrus"
"gorm.io/gorm"
)
// 下发钻石
......@@ -51,3 +54,113 @@ func SendDiamondPink(model *domain.Model, userId mysql.ID, opt diamond_e.Operate
}
return nil
}
// 事务操作账号明细
// 注意:外层不能再加事务了
// 注意:DiamondOperateSet限流的不能用
// 账号冻结/账号余额:属于业务逻辑,不在事务做
// 函数步骤
// 1. 非事务前置判断: 获取账号信息,加减,封号等
// 事务
// 2. diamondAccount表原子操作, 判断更新条数
// 3. 更新明细表
// param extraTxFunc: 外部函数,可能会影响到事务回滚的函数
func TxAddReduceDiamondAccount(model *domain.Model, userId mysql.ID, operateType diamond_e.OperateType, diamondNum mysql.Num, originId mysql.ID, operateIds mysql.Str, extraTxFunc ...func() error) error {
var diamondOperateSet diamond_m.DiamondOperateSet
var err error
if err = model.DB().Where(&diamond_m.DiamondOperateSet{
Type: operateType,
Status: mysql.USER,
DiamondType: diamond_e.DiamondYellow,
}).First(&diamondOperateSet).Error; err != nil {
return err
}
// logs
model.Log = model.Log.WithFields(logrus.Fields{
"func": "TxAddReduceDiamondAccount",
"uid": userId,
"ot": operateType,
"num": diamondNum,
"oid": originId,
"oids": operateIds,
"ar": diamondOperateSet.AddReduce,
})
var diamondAccount = new(diamond_m.DiamondAccount)
if err := model.DB().Model(diamond_m.DiamondAccount{}).Where("user_id = ?", userId).First(diamondAccount).Error; err != nil {
model.Log.Errorf("TxAddReduceDiamondAccount fail :%v", err)
return err
}
if diamondOperateSet.AddReduce == mysql.REDUCE && diamondAccount.DiamondNum < diamondNum {
return fmt.Errorf("bizerr.DiamondAccountNotEnough")
}
if diamondAccount.Status == diamond_e.Frozen && diamondOperateSet.AddReduce == mysql.REDUCE {
return fmt.Errorf("bizerr.DiamondAccountFrozen")
}
return model.Transaction(func(model *domain.Model) error {
// 更新diamondAccount表
var db *gorm.DB
if diamondOperateSet.AddReduce == mysql.ADD {
//增加
db = model.DB().Model(diamond_m.DiamondAccount{}).UpdateColumn("diamond_num", gorm.Expr("diamond_num + ?", diamondNum))
} else if diamondOperateSet.AddReduce == mysql.REDUCE {
//减少,保证不能扣成负数
db = model.DB().Model(diamond_m.DiamondAccount{}).Where("diamond_num >= ?", diamondNum).UpdateColumn("diamond_num", gorm.Expr("diamond_num - ?", diamondNum))
} else {
return myerr.NewSysErrorF("addReduce 枚举错误 value:", diamondOperateSet.AddReduce)
}
// 错误判断
if db == nil {
model.Log.Errorf("db nil")
return myerr.NewSysError("db nil")
}
if err := db.Error; err != nil {
model.Log.Errorf("db err:%v", err)
return myerr.WrapErr(err)
}
if db.RowsAffected == 0 {
model.Log.Errorf("gorm condition update.RowsAffected = 0")
return myerr.NewWaring("gorm condition update.RowsAffected = 0")
}
// 写后读(写后缓存都会丢失,多读一次不影响)
newAccount := new(diamond_m.DiamondAccount)
if err := model.DB().Model(diamond_m.DiamondAccount{}).Where("id = ?", diamondAccount.ID).First(newAccount).Error; err != nil {
model.Log.Errorf("newAccount err:%v", err)
return err
}
if newAccount.DiamondNum < 0 {
model.Log.Errorf("newAccount 0")
return myerr.NewSysError("newAccount 0")
}
// 更新明细
befNum := mysql.Num(0)
if diamondOperateSet.AddReduce == mysql.ADD {
befNum = newAccount.DiamondNum - diamondNum
}
if diamondOperateSet.AddReduce == mysql.REDUCE {
befNum = newAccount.DiamondNum + diamondNum
}
if err := model.DB().Table(diamond_m.DiamondAccountDetail{}.TableName()).Create(&diamond_m.DiamondAccountDetail{
UserId: userId,
DiamondAccountId: newAccount.ID,
OperateId: diamondOperateSet.ID,
OperateType: operateType,
OriginId: originId,
AddReduce: diamondOperateSet.AddReduce,
Num: diamondNum,
Remark: diamondOperateSet.Name,
BefNum: befNum,
AftNum: newAccount.DiamondNum,
}).Error; err != nil {
model.Log.Errorf("add detail fail:%v", err)
return err
}
for i, f := range extraTxFunc {
if err := f(); err != nil {
model.Log.Errorf("extraFunc i:%v fail:%v", i, err)
return err
}
}
return nil
})
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment