diamond.go 5.87 KB
Newer Older
hujiebin's avatar
hujiebin committed
1 2 3
package diamond_tx

import (
chenweijian's avatar
chenweijian committed
4
	"fmt"
hujiebin's avatar
hujiebin committed
5 6
	"git.hilo.cn/hilo-common/domain"
	"git.hilo.cn/hilo-common/internal/enum/diamond_e"
chenweijian's avatar
chenweijian committed
7
	"git.hilo.cn/hilo-common/internal/enum/msg_e"
hujiebin's avatar
hujiebin committed
8
	"git.hilo.cn/hilo-common/internal/model/diamond_m"
9
	"git.hilo.cn/hilo-common/myerr"
hujiebin's avatar
hujiebin committed
10
	"git.hilo.cn/hilo-common/resource/mysql"
chenweijian's avatar
chenweijian committed
11
	"git.hilo.cn/hilo-common/txop/msg"
12 13
	"github.com/sirupsen/logrus"
	"gorm.io/gorm"
hujiebin's avatar
hujiebin committed
14 15 16
)

// 下发钻石
chenweijian's avatar
chenweijian committed
17 18
func SendDiamond(model *domain.Model, userId mysql.ID, opt diamond_e.OperateType, originId mysql.ID, diamondNum mysql.Num,
	msgType ...msg_e.MsgUserRecordType) error {
hujiebin's avatar
hujiebin committed
19 20 21 22 23 24 25 26 27 28 29
	diamondAccount, err := diamond_m.GetDiamondAccountByUserId(model, userId)
	if err != nil {
		return err
	}
	diamondSendAccountDetail, err := diamondAccount.AddDiamondAccountDetail(opt, originId, diamondNum)
	if err != nil {
		return err
	}
	if err := diamondSendAccountDetail.Persistent(); err != nil {
		return err
	}
chenweijian's avatar
chenweijian committed
30 31 32 33
	if len(msgType) > 0 {
		// 小助手提示获得钻石
		msg.SendLittleAssistantMsg(model, userId, msgType[0], fmt.Sprintf("%d", diamondNum), "", "", "", "")
	}
hujiebin's avatar
hujiebin committed
34 35
	return nil
}
hujiebin's avatar
hujiebin committed
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56

// 下发钻石
func SendDiamondPink(model *domain.Model, userId mysql.ID, opt diamond_e.OperateType, originId mysql.ID, diamondNum mysql.Num, operateIds string,
	msgType ...msg_e.MsgUserRecordType) error {
	diamondAccount, err := diamond_m.GetDiamondAccountByUserId(model, userId)
	if err != nil {
		return err
	}
	diamondSendAccountDetail, err := diamondAccount.ChangePinkDiamondAccountDetail(opt, originId, diamondNum, operateIds)
	if err != nil {
		return err
	}
	if err := diamondSendAccountDetail.Persistent(); err != nil {
		return err
	}
	if len(msgType) > 0 {
		// 小助手提示获得钻石
		msg.SendLittleAssistantMsg(model, userId, msgType[0], fmt.Sprintf("%d", diamondNum), "", "", "", "")
	}
	return nil
}
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98

// 事务操作账号明细
// 注意:外层不能再加事务了
// 注意: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")
	}
99 100
	return model.Transaction(func(model *domain.Model) error {

101 102 103 104
		// 更新diamondAccount表
		var db *gorm.DB
		if diamondOperateSet.AddReduce == mysql.ADD {
			//增加
hujiebin's avatar
hujiebin committed
105
			db = model.DB().Model(diamond_m.DiamondAccount{}).Where("id = ?", diamondAccount.ID).UpdateColumn("diamond_num", gorm.Expr("diamond_num + ?", diamondNum))
106 107
		} else if diamondOperateSet.AddReduce == mysql.REDUCE {
			//减少,保证不能扣成负数
hujiebin's avatar
hujiebin committed
108
			db = model.DB().Model(diamond_m.DiamondAccount{}).Where("id = ?", diamondAccount.ID).Where("diamond_num >= ?", diamondNum).UpdateColumn("diamond_num", gorm.Expr("diamond_num - ?", diamondNum))
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
		} 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")
		}
		// 写后读(写后缓存都会丢失,多读一次不影响)
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
		//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
		//}
143 144
		if err := model.DB().Table(diamond_m.DiamondAccountDetail{}.TableName()).Create(&diamond_m.DiamondAccountDetail{
			UserId:           userId,
145
			DiamondAccountId: diamondAccount.ID,
146 147 148 149 150 151
			OperateId:        diamondOperateSet.ID,
			OperateType:      operateType,
			OriginId:         originId,
			AddReduce:        diamondOperateSet.AddReduce,
			Num:              diamondNum,
			Remark:           diamondOperateSet.Name,
152 153
			BefNum:           0,
			AftNum:           0,
154 155 156 157
		}).Error; err != nil {
			model.Log.Errorf("add detail fail:%v", err)
			return err
		}
158 159 160 161 162 163 164 165 166
		for i, f := range extraTxFunc {
			if err := f(); err != nil {
				model.Log.Errorf("extraFunc i:%v fail:%v", i, err)
				return err
			}
		}
		return nil
	})
}