You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
154 lines
3.8 KiB
Go
154 lines
3.8 KiB
Go
package coin_manager
|
|
|
|
import (
|
|
"context"
|
|
"github.com/zeromicro/go-zero/core/logx"
|
|
"gorm.io/gorm"
|
|
pbMq "live-service/app/pb/mq"
|
|
pbVars "live-service/app/pb/vars"
|
|
"live-service/app/user_center/model"
|
|
"live-service/app/user_center/rpc/internal/mq"
|
|
"live-service/app/user_center/rpc/pb"
|
|
"live-service/common/nerr"
|
|
)
|
|
|
|
type (
|
|
Manager struct {
|
|
userCoinModel model.UserCoinModel
|
|
userMq *mq.UserMq
|
|
|
|
logx.Logger
|
|
}
|
|
ChangeCoinReq struct {
|
|
BattleId int64 // 战局ID
|
|
UserId int64 // 用户ID
|
|
Change int64 // 变化量(负数为减扣)
|
|
}
|
|
ChangeCoinResp struct {
|
|
BattleId int64 // 战局ID
|
|
UserId int64 // 用户ID
|
|
Change int64 // 变化量(负数为减扣)
|
|
Current int64 // 当前量
|
|
}
|
|
)
|
|
|
|
func NewCoinManager(mod model.UserCoinModel, userMq *mq.UserMq) *Manager {
|
|
return &Manager{
|
|
userCoinModel: mod,
|
|
userMq: userMq,
|
|
Logger: logx.WithContext(context.Background()),
|
|
}
|
|
}
|
|
|
|
func (m *Manager) GetUserCoin(ctx context.Context, userId int64) (int64, error) {
|
|
resp, err := m.userCoinModel.FindOne(ctx, nil, userId)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
return resp.Coin, err
|
|
}
|
|
|
|
func (m *Manager) TransferCoin(ctx context.Context, req *pb.TransferUserCoinReq) (*pb.TransferUserCoinResp, error) {
|
|
if req.Transfer < 0 {
|
|
req.Transfer = -req.Transfer
|
|
}
|
|
resp := &pb.TransferUserCoinResp{
|
|
UserId: req.UserId,
|
|
TargetUserId: req.TargetUserId,
|
|
}
|
|
if err := m.userCoinModel.TransactCtx(ctx, nil, func(tx *gorm.DB) error {
|
|
if req.UserId == 0 {
|
|
return nerr.NewError(nerr.RequestParamError, "源用户ID为空")
|
|
}
|
|
if req.TargetUserId == 0 {
|
|
return nerr.NewError(nerr.RequestParamError, "目标用户ID为空")
|
|
}
|
|
coin, err := m.userCoinModel.ChangeCoin(ctx, tx, req.UserId, -req.Transfer, false)
|
|
if err != nil {
|
|
return nerr.NewWithErr(err)
|
|
}
|
|
targetCoin, err := m.userCoinModel.ChangeCoin(ctx, tx, req.TargetUserId, req.Transfer, false)
|
|
if err != nil {
|
|
return nerr.NewWithErr(err)
|
|
}
|
|
resp.UserCoin = coin
|
|
resp.TargetUserCoin = targetCoin
|
|
|
|
// 通知
|
|
go func() {
|
|
m.userMq.NotifyUserCoinChanged(&pbMq.MqUserCoinChanged{
|
|
UserId: req.UserId,
|
|
Change: -req.Transfer,
|
|
Current: coin,
|
|
Reason: pbVars.UserCoinChangedReason_Transfer,
|
|
})
|
|
m.userMq.NotifyUserCoinChanged(&pbMq.MqUserCoinChanged{
|
|
UserId: req.TargetUserId,
|
|
Change: req.Transfer,
|
|
Current: targetCoin,
|
|
Reason: pbVars.UserCoinChangedReason_Transfer,
|
|
})
|
|
}()
|
|
|
|
return nil
|
|
}); err != nil {
|
|
return nil, err
|
|
}
|
|
return resp, nil
|
|
}
|
|
|
|
func (m *Manager) ChangeCoin(ctx context.Context, tx *gorm.DB, req *ChangeCoinReq, reason pbVars.UserCoinChangedReason) (*ChangeCoinResp, error) {
|
|
coin, err := m.userCoinModel.ChangeCoin(ctx, tx, req.UserId, req.Change, false)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// 通知
|
|
go m.userMq.NotifyUserCoinChanged(&pbMq.MqUserCoinChanged{
|
|
UserId: req.UserId,
|
|
Change: req.Change,
|
|
Current: coin,
|
|
Reason: reason,
|
|
})
|
|
|
|
return &ChangeCoinResp{
|
|
UserId: req.UserId,
|
|
Change: req.Change,
|
|
Current: coin,
|
|
}, nil
|
|
}
|
|
|
|
func (m *Manager) ChangeCoinBatch(ctx context.Context, req []ChangeCoinReq, reason pbVars.UserCoinChangedReason) (map[int64]ChangeCoinResp, error) {
|
|
resp := make(map[int64]ChangeCoinResp)
|
|
if err := m.userCoinModel.TransactCtx(ctx, nil, func(tx *gorm.DB) error {
|
|
for _, item := range req {
|
|
coin, err := m.userCoinModel.ChangeCoin(ctx, tx, item.UserId, item.Change, false)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
resp[item.UserId] = ChangeCoinResp{
|
|
BattleId: item.BattleId,
|
|
UserId: item.UserId,
|
|
Change: item.Change,
|
|
Current: coin,
|
|
}
|
|
}
|
|
return nil
|
|
}); err != nil {
|
|
return resp, err
|
|
}
|
|
|
|
go func() {
|
|
for _, coinResp := range resp {
|
|
m.userMq.NotifyUserCoinChanged(&pbMq.MqUserCoinChanged{
|
|
UserId: coinResp.UserId,
|
|
Change: coinResp.Change,
|
|
Current: coinResp.Current,
|
|
Reason: reason,
|
|
})
|
|
}
|
|
}()
|
|
|
|
return resp, nil
|
|
}
|