wip: 新版优化,开发中。
parent
f32e82fe1c
commit
7c8343bc17
@ -1,51 +0,0 @@
|
|||||||
package model
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"git.noahlan.cn/northlan/ntools-go/gorm-zero/gormx"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
)
|
|
||||||
|
|
||||||
var _ UserGiftPackModel = (*customUserGiftPackModel)(nil)
|
|
||||||
|
|
||||||
type (
|
|
||||||
// UserGiftPackModel is an interface to be customized, add more methods here,
|
|
||||||
// and implement the added methods in customUserGiftPackModel.
|
|
||||||
UserGiftPackModel interface {
|
|
||||||
userGiftPackModel
|
|
||||||
// FindOneByUserPack 获取用户领取的礼包
|
|
||||||
FindOneByUserPack(ctx context.Context, tx *gorm.DB, userId int64, packType string) (*UserGiftPack, error)
|
|
||||||
// AddDrawCount 新增领取次数
|
|
||||||
AddDrawCount(ctx context.Context, tx *gorm.DB, userId int64, packType string) error
|
|
||||||
}
|
|
||||||
|
|
||||||
PackContent struct {
|
|
||||||
Integral int64 `json:"integral"` // 奖励积分数量
|
|
||||||
Title []string `json:"title,optional"` // 称号列表
|
|
||||||
}
|
|
||||||
|
|
||||||
customUserGiftPackModel struct {
|
|
||||||
*defaultUserGiftPackModel
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
// NewUserGiftPackModel returns a model for the database table.
|
|
||||||
func NewUserGiftPackModel(conn *gorm.DB) UserGiftPackModel {
|
|
||||||
return &customUserGiftPackModel{
|
|
||||||
defaultUserGiftPackModel: newUserGiftPackModel(conn),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *customUserGiftPackModel) FindOneByUserPack(ctx context.Context, tx *gorm.DB, userId int64, packType string) (*UserGiftPack, error) {
|
|
||||||
var resp UserGiftPack
|
|
||||||
err := withTx(ctx, m.conn, tx).Model(&UserGiftPack{}).
|
|
||||||
Where("user_id = ? AND pack_type = ?", userId, packType).Take(&resp).Error
|
|
||||||
switch err {
|
|
||||||
case nil:
|
|
||||||
return &resp, nil
|
|
||||||
case gormx.ErrNotFound:
|
|
||||||
return nil, ErrNotFound
|
|
||||||
default:
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,91 +0,0 @@
|
|||||||
// Code generated by goctl. DO NOT EDIT!
|
|
||||||
|
|
||||||
package model
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"git.noahlan.cn/northlan/ntools-go/gorm-zero/gormc"
|
|
||||||
"gorm.io/plugin/optimisticlock"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/core/stores/builder"
|
|
||||||
"github.com/zeromicro/go-zero/core/stringx"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
userGiftPackFieldNames = builder.RawFieldNames(&UserGiftPack{})
|
|
||||||
userGiftPackRows = strings.Join(userGiftPackFieldNames, ",")
|
|
||||||
userGiftPackRowsExpectAutoSet = strings.Join(stringx.Remove(userGiftPackFieldNames, "`create_time`", "`update_time`"), ",")
|
|
||||||
userGiftPackRowsWithPlaceHolder = strings.Join(stringx.Remove(userGiftPackFieldNames, "`id`", "`create_time`", "`update_time`"), "=?,") + "=?"
|
|
||||||
)
|
|
||||||
|
|
||||||
type (
|
|
||||||
userGiftPackModel interface {
|
|
||||||
Insert(ctx context.Context, data *UserGiftPack) error
|
|
||||||
FindOne(ctx context.Context, id int64) (*UserGiftPack, error)
|
|
||||||
Update(ctx context.Context, data *UserGiftPack) error
|
|
||||||
Delete(ctx context.Context, id int64) error
|
|
||||||
}
|
|
||||||
|
|
||||||
defaultUserGiftPackModel struct {
|
|
||||||
conn *gorm.DB
|
|
||||||
table string
|
|
||||||
}
|
|
||||||
|
|
||||||
UserGiftPack struct {
|
|
||||||
Id int64 `gorm:"column:id;primaryKey"` // 主键
|
|
||||||
UserId int64 `gorm:"column:user_id"` // 用户ID
|
|
||||||
PackType string `gorm:"column:pack_type"` // 礼包类型
|
|
||||||
PackContent string `gorm:"column:pack_content"` // 礼包内容(冗余)
|
|
||||||
DrawCount int64 `gorm:"column:draw_count"` // 已领取数目
|
|
||||||
DrawTime time.Time `gorm:"column:draw_time;default:null"` // 领取时间
|
|
||||||
Version optimisticlock.Version `gorm:"column:version"` // 乐观锁,版本号
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
func newUserGiftPackModel(conn *gorm.DB) *defaultUserGiftPackModel {
|
|
||||||
return &defaultUserGiftPackModel{
|
|
||||||
conn: conn,
|
|
||||||
table: "`user_gift_pack`",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *defaultUserGiftPackModel) Insert(ctx context.Context, data *UserGiftPack) error {
|
|
||||||
err := m.conn.WithContext(ctx).Create(&data).Error
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *defaultUserGiftPackModel) FindOne(ctx context.Context, id int64) (*UserGiftPack, error) {
|
|
||||||
var resp UserGiftPack
|
|
||||||
err := m.conn.WithContext(ctx).Model(&UserGiftPack{}).Where("`id` = ?", id).Take(&resp).Error
|
|
||||||
switch err {
|
|
||||||
case nil:
|
|
||||||
return &resp, nil
|
|
||||||
case gormc.ErrNotFound:
|
|
||||||
return nil, ErrNotFound
|
|
||||||
default:
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *defaultUserGiftPackModel) Update(ctx context.Context, data *UserGiftPack) error {
|
|
||||||
err := m.conn.WithContext(ctx).Save(data).Error
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *defaultUserGiftPackModel) Delete(ctx context.Context, id int64) error {
|
|
||||||
err := m.conn.WithContext(ctx).Delete(&UserGiftPack{}, id).Error
|
|
||||||
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *defaultUserGiftPackModel) tableName() string {
|
|
||||||
return m.table
|
|
||||||
}
|
|
||||||
|
|
||||||
func (UserGiftPack) TableName() string {
|
|
||||||
model := newUserGiftPackModel(nil)
|
|
||||||
return model.tableName()
|
|
||||||
}
|
|
@ -0,0 +1,132 @@
|
|||||||
|
package integral_manager
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
"live-service/app/user_center/model"
|
||||||
|
"live-service/app/user_center/rpc/internal/common/reward_pool"
|
||||||
|
"live-service/app/user_center/rpc/pb"
|
||||||
|
"live-service/common/nerr"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
Manager struct {
|
||||||
|
cfg Config // 配置
|
||||||
|
userIntegralModel model.UserIntegralModel
|
||||||
|
rewardPoolManager *reward_pool.PoolManager
|
||||||
|
|
||||||
|
logx.Logger
|
||||||
|
}
|
||||||
|
Config struct {
|
||||||
|
GiftRatio float64
|
||||||
|
}
|
||||||
|
ChangeIntegralReq struct {
|
||||||
|
BattleId int64 // 战局ID
|
||||||
|
UserId int64 // 用户ID
|
||||||
|
Change int64 // 变化量(负数为减扣)
|
||||||
|
Type pb.IntegralType // 积分类型
|
||||||
|
}
|
||||||
|
ChangeIntegralResp struct {
|
||||||
|
BattleId int64 // 战局ID
|
||||||
|
UserId int64 // 用户ID
|
||||||
|
Change int64 // 变化量(负数为减扣)
|
||||||
|
Integral int64 // 剩余积分
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewIntegralManager(userIntegralModel model.UserIntegralModel, rewardPoolManager *reward_pool.PoolManager) *Manager {
|
||||||
|
return &Manager{
|
||||||
|
userIntegralModel: userIntegralModel,
|
||||||
|
rewardPoolManager: rewardPoolManager,
|
||||||
|
Logger: logx.WithContext(context.Background()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Manager) GetUserIntegral(ctx context.Context, userId int64) (int64, error) {
|
||||||
|
resp, err := m.userIntegralModel.FindOne(ctx, nil, userId)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return resp.Integral, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Manager) TransferIntegral(ctx context.Context, req *pb.TransferUserIntegralReq) *pb.TransferUserIntegralResp {
|
||||||
|
resp := &pb.TransferUserIntegralResp{
|
||||||
|
UserId: req.UserId,
|
||||||
|
TargetUserId: req.TargetUserId,
|
||||||
|
}
|
||||||
|
if err := m.userIntegralModel.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为空")
|
||||||
|
}
|
||||||
|
integral, err := m.userIntegralModel.ChangeIntegral(ctx, tx, req.UserId, -req.Transfer)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
targetIntegral, err := m.userIntegralModel.ChangeIntegral(ctx, tx, req.TargetUserId, req.Transfer)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
resp.Code = int32(nerr.OK)
|
||||||
|
resp.Msg = "转移成功"
|
||||||
|
resp.UserIntegral = integral
|
||||||
|
resp.TargetUserIntegral = targetIntegral
|
||||||
|
return nil
|
||||||
|
}); err != nil {
|
||||||
|
if e, ok := err.(*nerr.Error); ok {
|
||||||
|
resp.Code = int32(e.Code)
|
||||||
|
resp.Msg = e.Msg
|
||||||
|
} else {
|
||||||
|
resp.Code = int32(nerr.ServerCommonError)
|
||||||
|
resp.Msg = "转移失败,未知原因"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return resp
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Manager) ChangeIntegral(ctx context.Context, req *ChangeIntegralReq, rewardPool bool) (*ChangeIntegralResp, error) {
|
||||||
|
integral, err := m.userIntegralModel.ChangeIntegral(ctx, nil, req.UserId, req.Change)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if req.BattleId != 0 && rewardPool {
|
||||||
|
m.rewardPoolManager.Pool(req.BattleId).Add(req.UserId, req.Change, req.Type)
|
||||||
|
}
|
||||||
|
return &ChangeIntegralResp{
|
||||||
|
UserId: req.UserId,
|
||||||
|
Change: req.Change,
|
||||||
|
Integral: integral,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Manager) ChangeIntegralBatch(ctx context.Context, req []ChangeIntegralReq, rewardPool bool) (map[int64]ChangeIntegralResp, error) {
|
||||||
|
resp := make(map[int64]ChangeIntegralResp)
|
||||||
|
if err := m.userIntegralModel.TransactCtx(ctx, nil, func(tx *gorm.DB) error {
|
||||||
|
for _, item := range req {
|
||||||
|
integral, err := m.userIntegralModel.ChangeIntegral(ctx, tx, item.UserId, item.Change)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
resp[item.UserId] = ChangeIntegralResp{
|
||||||
|
BattleId: item.BattleId,
|
||||||
|
UserId: item.UserId,
|
||||||
|
Change: item.Change,
|
||||||
|
Integral: integral,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}); err != nil {
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
// 奖池
|
||||||
|
for _, item := range req {
|
||||||
|
if item.BattleId != 0 && rewardPool {
|
||||||
|
m.rewardPoolManager.Pool(item.BattleId).Add(item.UserId, item.Change, item.Type)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return resp, nil
|
||||||
|
}
|
@ -0,0 +1,295 @@
|
|||||||
|
package reward_pool
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.noahlan.cn/northlan/ntools-go/kafka"
|
||||||
|
"github.com/shopspring/decimal"
|
||||||
|
pbMq "live-service/app/pb/mq"
|
||||||
|
"live-service/app/user_center/rpc/pb"
|
||||||
|
"sort"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
pool struct {
|
||||||
|
id int64 // 奖池ID(对局ID)
|
||||||
|
initReward int64 // 初始奖池
|
||||||
|
battleReward int64 // 积分奖池
|
||||||
|
giftReward int64 // 礼物奖池
|
||||||
|
otherReward int64 // 其它奖池
|
||||||
|
|
||||||
|
userBattleReward map[int64]int64 // 用户战斗积分[暴兵|造墙|技能 等等],用于计算分配比例
|
||||||
|
userGiftReward map[int64]int64 // 用户送礼积分,扩充奖池
|
||||||
|
userOtherReward map[int64]int64 // 用户其它积分[抽奖|兑换 等等],扩充奖池
|
||||||
|
|
||||||
|
manager *PoolManager // 管理器
|
||||||
|
mutex sync.RWMutex // 锁
|
||||||
|
}
|
||||||
|
PoolManager struct {
|
||||||
|
welfarePool int64 // 福利池,开服重置
|
||||||
|
pools map[int64]*pool // 奖池
|
||||||
|
|
||||||
|
initReward int64 // 初始奖池
|
||||||
|
ratio Ratio // 比例
|
||||||
|
|
||||||
|
producer *kafka.Producer // kafka
|
||||||
|
mutex sync.Mutex
|
||||||
|
}
|
||||||
|
|
||||||
|
Ratio struct {
|
||||||
|
Ratio float64 // 奖池比例
|
||||||
|
BattleRatio float64 // 战斗积分投入奖池比例
|
||||||
|
GiftRatio float64 // 礼物算作奖池比例
|
||||||
|
ReturnRatio float64 // 回收比例
|
||||||
|
WelfareRatio float64 // 从奖金扣除福利比例
|
||||||
|
}
|
||||||
|
|
||||||
|
// DrawResult 结算结果
|
||||||
|
DrawResult struct {
|
||||||
|
UserReturns map[int64]int64 // 用户回收积分,投放多少回收多少,战败方不回收
|
||||||
|
DrawRewards map[int64]int64 // 用户瓜分奖池,根据回收后的剩余奖池,逐级投放
|
||||||
|
AddonWelfare int64 // 本次结算添加的福利
|
||||||
|
}
|
||||||
|
// DrawRequest 结算请求
|
||||||
|
DrawRequest struct {
|
||||||
|
UserId int64 // 用户ID
|
||||||
|
Position int32 // 排名
|
||||||
|
Ratio float64 // 其它因素计算的比例
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewRewardPoolManager 构建奖池
|
||||||
|
func NewRewardPoolManager(initReward int64, ratio Ratio, producer *kafka.Producer) *PoolManager {
|
||||||
|
return &PoolManager{
|
||||||
|
initReward: initReward,
|
||||||
|
pools: make(map[int64]*pool),
|
||||||
|
producer: producer,
|
||||||
|
ratio: ratio,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pool 创建或获取 pool
|
||||||
|
func (p *PoolManager) Pool(battleId int64) *pool {
|
||||||
|
resp, ok := p.pools[battleId]
|
||||||
|
if !ok {
|
||||||
|
resp = newRewardPool(battleId, p.initReward, p)
|
||||||
|
p.pools[battleId] = resp
|
||||||
|
}
|
||||||
|
return resp
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw 结算
|
||||||
|
func (p *PoolManager) Draw(battleId int64, req []DrawRequest) *DrawResult {
|
||||||
|
result := p.Pool(battleId).draw(req)
|
||||||
|
p.AddWelfare(result.AddonWelfare)
|
||||||
|
// 移除奖池
|
||||||
|
p.Remain(battleId)
|
||||||
|
// 变动通知
|
||||||
|
_ = p.producer.SendMessageAsync(&pbMq.MqRewardPool{
|
||||||
|
WelfarePool: p.welfarePool,
|
||||||
|
BattleId: battleId,
|
||||||
|
InitReward: 0,
|
||||||
|
GiftReward: 0,
|
||||||
|
BattleReward: 0,
|
||||||
|
OtherReward: 0,
|
||||||
|
AllRewards: 0,
|
||||||
|
})
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remain 移除 pool
|
||||||
|
func (p *PoolManager) Remain(battleId int64) {
|
||||||
|
p.mutex.Lock()
|
||||||
|
defer p.mutex.Unlock()
|
||||||
|
|
||||||
|
if _, ok := p.pools[battleId]; ok {
|
||||||
|
delete(p.pools, battleId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PoolManager) AddWelfare(welfare int64) {
|
||||||
|
p.mutex.Lock()
|
||||||
|
defer p.mutex.Unlock()
|
||||||
|
|
||||||
|
p.welfarePool += welfare
|
||||||
|
}
|
||||||
|
|
||||||
|
func newRewardPool(battleId int64, initReward int64, manager *PoolManager) *pool {
|
||||||
|
return &pool{
|
||||||
|
id: battleId,
|
||||||
|
initReward: initReward,
|
||||||
|
userBattleReward: make(map[int64]int64),
|
||||||
|
userGiftReward: make(map[int64]int64),
|
||||||
|
userOtherReward: make(map[int64]int64),
|
||||||
|
manager: manager,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// draw 奖池结算
|
||||||
|
func (p *pool) draw(req []DrawRequest) *DrawResult {
|
||||||
|
p.mutex.Lock()
|
||||||
|
defer p.mutex.Unlock()
|
||||||
|
|
||||||
|
sort.SliceStable(req, func(i, j int) bool {
|
||||||
|
return req[i].Position < req[j].Position
|
||||||
|
})
|
||||||
|
|
||||||
|
resp := DrawResult{
|
||||||
|
UserReturns: make(map[int64]int64),
|
||||||
|
DrawRewards: make(map[int64]int64),
|
||||||
|
}
|
||||||
|
|
||||||
|
remainRewards := p.rewards()
|
||||||
|
var addonWelfare int64 // 福利池
|
||||||
|
|
||||||
|
// 获胜方战斗总投入
|
||||||
|
var winBattleRewards int64
|
||||||
|
for _, item := range req {
|
||||||
|
// 用户回收战斗积分
|
||||||
|
if reward, ok := p.userBattleReward[item.UserId]; ok {
|
||||||
|
returnsReward := decimal.NewFromInt(reward).Mul(decimal.NewFromFloat(p.manager.ratio.ReturnRatio)).Round(0).IntPart()
|
||||||
|
resp.UserReturns[item.UserId] = returnsReward // 玩家回收,比例回收
|
||||||
|
remainRewards -= reward // 奖池回收,完全回收
|
||||||
|
addonWelfare += reward - returnsReward // 玩家比例回收,奖池完全回收,多余奖金加入福利池
|
||||||
|
winBattleRewards += reward // 获胜方战斗总投入
|
||||||
|
//fmt.Printf("用户 %d 回收战斗积分 %d\n", item.UserId, reward)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//fmt.Printf("剩余奖池: %d\n", remainRewards)
|
||||||
|
//fmt.Printf("获胜方战斗总投入 %d\n", winBattleRewards)
|
||||||
|
|
||||||
|
// 福利池抽取
|
||||||
|
{
|
||||||
|
tmp := decimal.NewFromInt(remainRewards).Mul(decimal.NewFromFloat(p.manager.ratio.WelfareRatio)).Round(0).IntPart()
|
||||||
|
addonWelfare += tmp
|
||||||
|
remainRewards -= tmp
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO 奖池分的其余用途
|
||||||
|
// 用户瓜分奖池
|
||||||
|
for _, item := range req {
|
||||||
|
// 计算战斗积分分配比例
|
||||||
|
var ratio float64
|
||||||
|
if reward, ok := p.userBattleReward[item.UserId]; ok {
|
||||||
|
ratio, _ = decimal.NewFromInt(reward).Div(decimal.NewFromInt(winBattleRewards)).Round(2).Float64()
|
||||||
|
}
|
||||||
|
// 其它因素计算比例
|
||||||
|
var poolRatio float64
|
||||||
|
if item.Ratio == 0 {
|
||||||
|
poolRatio = ratio * 1.0
|
||||||
|
} else {
|
||||||
|
poolRatio = ratio * p.manager.ratio.Ratio
|
||||||
|
}
|
||||||
|
ratio, _ = decimal.NewFromFloat(poolRatio).Add(decimal.NewFromFloat(item.Ratio * (1.0 - p.manager.ratio.Ratio))).Round(2).Float64()
|
||||||
|
//fmt.Printf("用户: %d 瓜分比例 %v\n", item.UserId, ratio)
|
||||||
|
|
||||||
|
reward := decimal.NewFromInt(remainRewards).Mul(decimal.NewFromFloat(ratio)).Round(0).IntPart()
|
||||||
|
resp.DrawRewards[item.UserId] = reward
|
||||||
|
remainRewards -= reward
|
||||||
|
//fmt.Printf("用户: %d 瓜分奖金 %d\n", item.UserId, reward)
|
||||||
|
//fmt.Printf("剩余奖池: %d\n", remainRewards)
|
||||||
|
}
|
||||||
|
addonWelfare += remainRewards
|
||||||
|
//fmt.Printf("积分 %d 加入福利池\n", remainRewards)
|
||||||
|
resp.AddonWelfare = addonWelfare
|
||||||
|
return &resp
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rewards 获取当前总积分
|
||||||
|
func (p *pool) Rewards() int64 {
|
||||||
|
p.mutex.RLock()
|
||||||
|
defer p.mutex.RUnlock()
|
||||||
|
return p.rewards()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *pool) rewards() int64 {
|
||||||
|
return p.initReward + p.battleReward + p.giftReward + p.otherReward
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add 积分加入奖池
|
||||||
|
func (p *pool) Add(userId, val int64, integralType pb.IntegralType) int64 {
|
||||||
|
switch integralType {
|
||||||
|
case pb.IntegralType_Battle:
|
||||||
|
p.addBattle(userId, val)
|
||||||
|
case pb.IntegralType_Gift:
|
||||||
|
p.addGift(userId, val)
|
||||||
|
case pb.IntegralType_Other:
|
||||||
|
p.addOther(userId, val)
|
||||||
|
default:
|
||||||
|
p.addOther(userId, val)
|
||||||
|
}
|
||||||
|
result := p.Rewards()
|
||||||
|
// 变动通知
|
||||||
|
_ = p.manager.producer.SendMessageAsync(&pbMq.MqRewardPool{
|
||||||
|
WelfarePool: p.manager.initReward,
|
||||||
|
BattleId: p.id,
|
||||||
|
InitReward: p.initReward,
|
||||||
|
GiftReward: p.giftReward,
|
||||||
|
BattleReward: p.battleReward,
|
||||||
|
OtherReward: p.otherReward,
|
||||||
|
AllRewards: result,
|
||||||
|
})
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *pool) addBattle(userId, val int64) int64 {
|
||||||
|
p.mutex.Lock()
|
||||||
|
defer p.mutex.Unlock()
|
||||||
|
if val == 0 || val > 0 {
|
||||||
|
return p.battleReward
|
||||||
|
}
|
||||||
|
val = -val
|
||||||
|
|
||||||
|
val = decimal.NewFromInt(val).Mul(decimal.NewFromFloat(p.manager.ratio.BattleRatio)).Round(0).IntPart()
|
||||||
|
reward, ok := p.userBattleReward[userId]
|
||||||
|
if !ok {
|
||||||
|
reward = val
|
||||||
|
p.userBattleReward[userId] = reward
|
||||||
|
} else {
|
||||||
|
p.userBattleReward[userId] = reward + val
|
||||||
|
}
|
||||||
|
p.battleReward += val
|
||||||
|
//fmt.Printf("用户 %d 战斗积分 %d 加入奖池\n", userId, val)
|
||||||
|
return p.battleReward
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *pool) addGift(userId, val int64) int64 {
|
||||||
|
p.mutex.Lock()
|
||||||
|
defer p.mutex.Unlock()
|
||||||
|
if val == 0 || val < 0 {
|
||||||
|
return p.giftReward
|
||||||
|
}
|
||||||
|
|
||||||
|
val = decimal.NewFromInt(val).Mul(decimal.NewFromFloat(p.manager.ratio.GiftRatio)).Round(0).IntPart()
|
||||||
|
reward, ok := p.userGiftReward[userId]
|
||||||
|
if !ok {
|
||||||
|
reward = val
|
||||||
|
p.userGiftReward[userId] = reward
|
||||||
|
} else {
|
||||||
|
p.userGiftReward[userId] = reward + val
|
||||||
|
}
|
||||||
|
|
||||||
|
p.giftReward += val
|
||||||
|
//fmt.Printf("用户 %d 礼物积分 %d 加入奖池\n", userId, val)
|
||||||
|
return p.giftReward
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *pool) addOther(userId, val int64) int64 {
|
||||||
|
p.mutex.Lock()
|
||||||
|
defer p.mutex.Unlock()
|
||||||
|
if val == 0 || val > 0 {
|
||||||
|
return p.otherReward
|
||||||
|
}
|
||||||
|
val = -val
|
||||||
|
|
||||||
|
reward, ok := p.userOtherReward[userId]
|
||||||
|
if !ok {
|
||||||
|
reward = val
|
||||||
|
p.userOtherReward[userId] = reward
|
||||||
|
} else {
|
||||||
|
p.userOtherReward[userId] = reward + val
|
||||||
|
}
|
||||||
|
|
||||||
|
p.otherReward += val
|
||||||
|
//fmt.Printf("用户 %d 其它消耗积分 %d 加入奖池\n", userId, val)
|
||||||
|
return p.otherReward
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
package draw_pool
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"live-service/app/user_center/rpc/internal/svc"
|
||||||
|
"live-service/app/user_center/rpc/pb"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
|
)
|
||||||
|
|
||||||
|
type IncreaseWelfareLogic struct {
|
||||||
|
ctx context.Context
|
||||||
|
svcCtx *svc.ServiceContext
|
||||||
|
logx.Logger
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewIncreaseWelfareLogic(ctx context.Context, svcCtx *svc.ServiceContext) *IncreaseWelfareLogic {
|
||||||
|
return &IncreaseWelfareLogic{
|
||||||
|
ctx: ctx,
|
||||||
|
svcCtx: svcCtx,
|
||||||
|
Logger: logx.WithContext(ctx),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *IncreaseWelfareLogic) IncreaseWelfare(in *pb.IncreaseWelfareReq) (*pb.Empty, error) {
|
||||||
|
// todo: add your logic here and delete this line
|
||||||
|
|
||||||
|
return &pb.Empty{}, nil
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
package integral
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"live-service/app/user_center/rpc/internal/svc"
|
||||||
|
"live-service/app/user_center/rpc/pb"
|
||||||
|
"live-service/common/nerr"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
|
)
|
||||||
|
|
||||||
|
type TransferUserIntegralLogic struct {
|
||||||
|
ctx context.Context
|
||||||
|
svcCtx *svc.ServiceContext
|
||||||
|
logx.Logger
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewTransferUserIntegralLogic(ctx context.Context, svcCtx *svc.ServiceContext) *TransferUserIntegralLogic {
|
||||||
|
return &TransferUserIntegralLogic{
|
||||||
|
ctx: ctx,
|
||||||
|
svcCtx: svcCtx,
|
||||||
|
Logger: logx.WithContext(ctx),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TransferUserIntegral 转移积分
|
||||||
|
func (l *TransferUserIntegralLogic) TransferUserIntegral(in *pb.TransferUserIntegralReq) (*pb.TransferUserIntegralResp, error) {
|
||||||
|
transResp := l.svcCtx.IntegralManager.TransferIntegral(l.ctx, in)
|
||||||
|
if transResp.Code == int32(nerr.OK) {
|
||||||
|
// 获取 username
|
||||||
|
if tmp, err := l.svcCtx.UserPlatformModel.FindDisplayOneByUserId(l.ctx, transResp.UserId); err == nil {
|
||||||
|
transResp.Uname = tmp.PUname
|
||||||
|
transResp.Avatar = tmp.PAvatar
|
||||||
|
}
|
||||||
|
if tmp, err := l.svcCtx.UserPlatformModel.FindDisplayOneByUserId(l.ctx, transResp.TargetUserId); err == nil {
|
||||||
|
transResp.TargetUname = tmp.PUname
|
||||||
|
transResp.TargetAvatar = tmp.PAvatar
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return transResp, nil
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,22 @@
|
|||||||
|
package timex
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
const (
|
||||||
|
seconds = 1e11
|
||||||
|
milliseconds = 1e14
|
||||||
|
microseconds = 1e17
|
||||||
|
)
|
||||||
|
|
||||||
|
func TimestampToTime(ts int64) time.Time {
|
||||||
|
if ts < seconds {
|
||||||
|
return time.Unix(ts, 0)
|
||||||
|
}
|
||||||
|
if ts < milliseconds {
|
||||||
|
return time.Unix(ts/1000, (ts%1000)*1e6)
|
||||||
|
}
|
||||||
|
if ts < microseconds {
|
||||||
|
return time.Unix(ts/1e6, (ts%1e6)*1000)
|
||||||
|
}
|
||||||
|
return time.Unix(0, ts)
|
||||||
|
}
|
Loading…
Reference in New Issue