package players import ( "context" "joybuywork/internal/app" "joybuywork/internal/consts" "joybuywork/internal/consts/ckey" "joybuywork/internal/repository/cache" "joybuywork/internal/repository/dao" "joybuywork/internal/repository/dbcheck" "joybuywork/internal/repository/model" "joybuywork/internal/repository/mtype" "joybuywork/internal/repository/withdefault" "joybuywork/internal/service/provider" "joybuywork/internal/service/provider/award" "joybuywork/internal/utils" "math/rand" "time" "gits.branchcn.com/backend/microcode/plugins/lucky" ) const ( unoClaimStatusOk = iota unoClaimStatusDoing // 正在收集中 unoClaimStatusDone // 已经收集完成了 ) const ( unoCollectStatusOk = iota unoCollectStatusLack // 抽奖次数不足 unoCollectStatusPropLack // 道具不足 unoCollectStatusPropFail // 道具不存在 ) // Uno Uno卡牌交互逻辑 type Uno struct { Player player *model.FissionUno conf *model.FissionCampaignUno fissionPlayerSetInitOnceKey string fissionUserUnoClaimOnceKey string fissionUserUnoCollectOnceKey string collectMap map[string]*model.FissionUnoCollect collectUp map[string]bool } func NewUno(ctx context.Context, user *model.FissionUser, opts ...Option) (player *Uno, err error) { player = &Uno{} err = player.Init(ctx, user, consts.IdUno, opts...) if err != nil { return } err = player.initPlayer() if err != nil { return } return } func (s *Uno) Claim(colorMark string) (status int32, info provider.RewardAutoLang, record *model.FissionRewardRecord, err error) { s.Tran() defer func() { s.TranCommit(err) s.AfterDo(err) }() lock := app.NewRedisLock(s.Ctx, s.fissionUserUnoClaimOnceKey) defer lock.Release() if !lock.SoftLock() { status = unoClaimStatusDoing return } player := s.GetPlayer() m := s.GetDao().FissionUnoCollect collect, err := m.WithContext(s.Ctx).Where(m.UnoID.Eq(player.ID), m.Mark.Eq(colorMark)).Take() if err = dbcheck.DbError(err); err != nil { err = s.BE().MysqlError(err) return } if collect == nil || collect.PreIntactNum <= 0 { status = unoClaimStatusDone return } groupM := s.GetDao().FissionCampaignUnoGroup group, err := groupM.WithContext(s.Ctx).Where(groupM.CampaignID.Eq(player.CampaignID), groupM.Mark.Eq(colorMark)).Take() if err = dbcheck.DbError(err); err != nil { err = s.BE().MysqlError(err) return } rewardM := s.GetDao().FissionCampaignReward reward, err := rewardM.WithContext(s.Ctx).Where(rewardM.ID.Eq(group.RewardID)).Take() if err = dbcheck.DbError(err); err != nil { err = s.BE().MysqlError(err) return } record, info, async, err := award.NewAwardReward(s.Ctx, s.GetDao(), s.cpn.ProjectID, s.user).One(reward, false) if err != nil { return } s.AddOkDone(func() { for _, fn := range async { fn() } }) _, err = m.WithContext(s.Ctx).Where(m.ID.Eq(collect.ID)).UpdateColumnSimple( m.IntactNum.Add(1), m.PreIntactNum.Sub(1), ) if err != nil { err = s.BE().MysqlError(err) return } err = s._addLog(withdefault.FissionUnoLog(&model.FissionUnoLog{ UserID: player.UserID, CampaignID: player.CampaignID, UnoID: player.ID, Type: mtype.FissionUnoLogTypeClaim, Source: mtype.FissionUnoLogSourceClaim, }, mtype.UnoLogVal{ RewardId: record.RewardID, RecordId: record.ID, })) if err != nil { return } // 收集卡牌埋点 s.appTrack().CollectUnoCard(time.Now().Unix(), colorMark) return unoClaimStatusOk, info, record, nil } type UnoCollectCard struct { Mark string CardNo int32 } func (s *Uno) _randMark(groups []*model.FissionCampaignUnoGroup) string { var odds []string for _, v := range groups { odds = append(odds, v.Odds) } shares, _ := utils.NormalizeDecimalStrings(odds) var marks []lucky.Reward for i, v := range groups { marks = append(marks, lucky.Reward{ Share: shares[i], Mark: v.Mark, }) } // 抽奖 lcy, _ := lucky.NewDiscrete(s.Ctx, marks).Lottery() return lcy.String() } func (s *Uno) _randCard(group *model.FissionCampaignUnoGroup) (card *UnoCollectCard, err error) { collectMap, err := s._userCollect() if err != nil { return } collect := collectMap[group.Mark] cardInfo := collect.GetCardInfo() var hasCardMap = make(map[int]struct{}) for i, cardNum := range cardInfo { if cardNum > 0 { hasCardMap[i+1] = struct{}{} } } var unoCardMap = map[int]struct{}{1: {}, 2: {}, 3: {}, 4: {}, 5: {}, 6: {}, 7: {}, 8: {}, 9: {}} switch group.OpenRule { case mtype.No: for k := range hasCardMap { delete(unoCardMap, k) } case mtype.Yes: rule := group.GetLimitRule() num := int(rule.InitNum + rule.AddNum*(collect.SignNum/rule.SignDay)) if num >= 9 { for k := range hasCardMap { delete(unoCardMap, k) } } else { var reset = make(map[int]struct{}) for k := range hasCardMap { reset[k] = struct{}{} } hcmL := len(hasCardMap) if hcmL > num { idx := hcmL - num for i := 0; i < 9; i++ { if _, ok := hasCardMap[i+1]; ok { delete(reset, i+1) idx-- if idx <= 0 { break } } } } else if hcmL < num { idx := num - hcmL for k := range unoCardMap { if _, ok := reset[k]; !ok { reset[k] = struct{}{} idx-- if idx <= 0 { break } } } } unoCardMap = reset } } var hasL = len(hasCardMap) var cardNo, preIntactNum int32 for no := range unoCardMap { cardNo = int32(no) idx := no - 1 intactL := hasL + 1 if intactL < 9 { cardInfo[idx]++ break } rewardM := s.GetDao().FissionCampaignReward reward, _ := rewardM.WithContext(s.Ctx).Where(rewardM.ID.Eq(group.RewardID)).Take() if reward == nil { continue } issVr := award.NewAwardIssVerify(s.Ctx, s.user, reward) ok1, _ := issVr.DeductStock().IsOK() if !ok1 { continue } preIntactNum++ for i := range cardInfo { if i != idx { cardInfo[i]-- } } break } if cardNo == 0 { for no := range hasCardMap { cardNo = int32(no) } } collect.SetCardInfo(cardInfo) collect.PreIntactNum += preIntactNum if preIntactNum > 0 && group.OpenRule == mtype.Yes && group.GetLimitRule().ResetType == mtype.FissionCampaignUnoGroupResetTypeReward { collect.SignNum = 0 } s.collectUp[group.Mark] = true card = &UnoCollectCard{ Mark: group.Mark, CardNo: cardNo, } return } func (s *Uno) Collect() (status int32, cards *UnoCollectCard, err error) { player := s.GetPlayer() m := s.GetDao().FissionCampaignUnoGroup groups, err := m.WithContext(s.Ctx).Where(m.CampaignID.Eq(player.CampaignID)).Find() if err != nil { err = s.BE().CacheError(err) return } groupMap := make(map[string]*model.FissionCampaignUnoGroup) for _, v := range groups { groupMap[v.Mark] = v } mark := s._randMark(groups) if s.IsView() { return unoCollectStatusOk, &UnoCollectCard{ Mark: mark, CardNo: rand.Int31n(8) + 1, }, nil } if player.Chance <= 0 { status = unoCollectStatusLack return } randCard, err := s._randCard(groupMap[mark]) if err != nil { return } playerM := s.GetDao().FissionUno _, err = playerM.WithContext(s.Ctx).Where(playerM.ID.Eq(player.ID)).UpdateSimple(playerM.Chance.Sub(1)) if err != nil { err = s.BE().CacheError(err) return } err = s._upCollect() if err != nil { return } log := withdefault.FissionUnoLog(&model.FissionUnoLog{ UserID: player.UserID, CampaignID: player.CampaignID, UnoID: player.ID, Type: mtype.FissionUnoLogTypeDecr, Source: mtype.FissionLogSourceLottery, }, mtype.UnoLogVal{ Chance: 1, Cards: []*mtype.UnoLogValCard{ { CardNo: randCard.CardNo, Mark: mark, }, }, }) err = s._addLog(log) if err != nil { return } return unoCollectStatusOk, randCard, nil } func (s *Uno) UseProp(propMark, colorMark string) (status int32, cards []*UnoCollectCard, err error) { switch propMark { case mtype.FissionCampaignUnoPropMarkThree: return s._useThree() case mtype.FissionCampaignUnoPropMarkFive: return s._useFive() case mtype.FissionCampaignUnoPropMarkFix: return s._useFix(colorMark) } return unoCollectStatusPropFail, nil, nil } func (s *Uno) _useFix(colorMark string) (status int32, cards []*UnoCollectCard, err error) { player := s.GetPlayer() m := s.GetDao().FissionCampaignUnoGroup groups, err := m.WithContext(s.Ctx).Where(m.CampaignID.Eq(player.CampaignID)).Find() if err != nil { err = s.BE().CacheError(err) return } groupMap := make(map[string]*model.FissionCampaignUnoGroup) for _, v := range groups { groupMap[v.Mark] = v } if s.IsView() { return unoCollectStatusOk, []*UnoCollectCard{ { Mark: colorMark, CardNo: rand.Int31n(8) + 1, }, }, nil } if player.FixNum <= 0 { status = unoCollectStatusPropLack return } randCard, err := s._randCard(groupMap[colorMark]) if err != nil { return } playerM := s.GetDao().FissionUno _, err = playerM.WithContext(s.Ctx).Where(playerM.ID.Eq(player.ID)).UpdateSimple(playerM.FixNum.Sub(1)) if err != nil { err = s.BE().CacheError(err) return } err = s._upCollect() if err != nil { return } log := withdefault.FissionUnoLog(&model.FissionUnoLog{ UserID: player.UserID, CampaignID: player.CampaignID, UnoID: player.ID, Type: mtype.FissionUnoLogTypePropUse, Source: mtype.FissionUnoLogSourceFixUse, }, mtype.UnoLogVal{ Chance: 1, PropMark: mtype.FissionCampaignTaskPropMarkUnoFix, Cards: []*mtype.UnoLogValCard{ { CardNo: randCard.CardNo, Mark: randCard.Mark, }, }, }) err = s._addLog(log) if err != nil { return } cards = append(cards, randCard) // 使用道具埋点 s.appTrack().UseProp(time.Now().Unix(), consts.PropNameUnoFix) return } func (s *Uno) _useFive() (status int32, cards []*UnoCollectCard, err error) { player := s.GetPlayer() m := s.GetDao().FissionCampaignUnoGroup groups, err := m.WithContext(s.Ctx).Where(m.CampaignID.Eq(player.CampaignID)).Find() if err != nil { err = s.BE().CacheError(err) return } groupMap := make(map[string]*model.FissionCampaignUnoGroup) for _, v := range groups { groupMap[v.Mark] = v } if s.IsView() { cards = append(cards, &UnoCollectCard{}) for i := 0; i < 5; i++ { cards = append(cards, &UnoCollectCard{ Mark: s._randMark(groups), CardNo: rand.Int31n(8) + 1, }) } return unoCollectStatusOk, cards, nil } if player.FiveNum <= 0 { status = unoCollectStatusPropLack return } for i := 0; i < 5; i++ { mark := s._randMark(groups) var randCard *UnoCollectCard randCard, err = s._randCard(groupMap[mark]) if err != nil { return } cards = append(cards, randCard) } playerM := s.GetDao().FissionUno _, err = playerM.WithContext(s.Ctx).Where(playerM.ID.Eq(player.ID)).UpdateSimple(playerM.FiveNum.Sub(1)) if err != nil { err = s.BE().CacheError(err) return } err = s._upCollect() if err != nil { return } var logCards []*mtype.UnoLogValCard for _, v := range cards { logCards = append(logCards, &mtype.UnoLogValCard{ CardNo: v.CardNo, Mark: v.Mark, }) } log := withdefault.FissionUnoLog(&model.FissionUnoLog{ UserID: player.UserID, CampaignID: player.CampaignID, UnoID: player.ID, Type: mtype.FissionUnoLogTypePropUse, Source: mtype.FissionUnoLogSourceFiveUse, }, mtype.UnoLogVal{ Chance: 1, PropMark: mtype.FissionCampaignTaskPropMarkUnoFive, Cards: logCards, }) err = s._addLog(log) if err != nil { return } s.appTrack().UseProp(time.Now().Unix(), consts.PropNameUnoFive) return } func (s *Uno) _useThree() (status int32, cards []*UnoCollectCard, err error) { player := s.GetPlayer() m := s.GetDao().FissionCampaignUnoGroup groups, err := m.WithContext(s.Ctx).Where(m.CampaignID.Eq(player.CampaignID)).Find() if err != nil { err = s.BE().MysqlError(err) return } groupMap := make(map[string]*model.FissionCampaignUnoGroup) for _, v := range groups { groupMap[v.Mark] = v } if s.IsView() { cards = append(cards, &UnoCollectCard{}) for i := 0; i < 3; i++ { cards = append(cards, &UnoCollectCard{ Mark: s._randMark(groups), CardNo: rand.Int31n(8) + 1, }) } return unoCollectStatusOk, cards, nil } if player.ThreeNum <= 0 { status = unoCollectStatusPropLack return } for i := 0; i < 3; i++ { mark := s._randMark(groups) var randCard *UnoCollectCard randCard, err = s._randCard(groupMap[mark]) if err != nil { return } cards = append(cards, randCard) } playerM := s.GetDao().FissionUno _, err = playerM.WithContext(s.Ctx).Where(playerM.ID.Eq(player.ID)).UpdateSimple(playerM.ThreeNum.Sub(1)) if err != nil { err = s.BE().CacheError(err) return } err = s._upCollect() if err != nil { return } var logCards []*mtype.UnoLogValCard for _, v := range cards { logCards = append(logCards, &mtype.UnoLogValCard{ CardNo: v.CardNo, Mark: v.Mark, }) } log := withdefault.FissionUnoLog(&model.FissionUnoLog{ UserID: player.UserID, CampaignID: player.CampaignID, UnoID: player.ID, Type: mtype.FissionUnoLogTypePropUse, Source: mtype.FissionUnoLogSourceThreeUse, }, mtype.UnoLogVal{ Chance: 1, PropMark: mtype.FissionCampaignTaskPropMarkUnoThree, Cards: logCards, }) err = s._addLog(log) if err != nil { return } s.appTrack().UseProp(time.Now().Unix(), consts.PropNameUnoThree) return } type UnoCards struct { CardNo int32 `json:"card_no"` CardNum int32 `json:"card_num"` } func (s *Uno) Cards() (data map[string][]*UnoCards, err error) { collectMap, err := s._userCollect() if err != nil { return } data = map[string][]*UnoCards{ mtype.FissionCampaignUnoGroupRed: {}, mtype.FissionCampaignUnoGroupBlue: {}, mtype.FissionCampaignUnoGroupYellow: {}, mtype.FissionCampaignUnoGroupGreen: {}, } for k := range data { collect := collectMap[k] nums := collect.GetCardInfo() data[k] = make([]*UnoCards, 9) for i := 0; i < 9; i++ { one := &UnoCards{ CardNo: int32(i) + 1, CardNum: nums[i] + collect.PreIntactNum, } data[k][i] = one } } return } // Sign 签到 func (s *Uno) Sign() (err error) { player := s.GetPlayer() signOk, lastSign := s._lastSign(player.LastSign) if !signOk { return } playerM := s.GetDao().FissionUno _, err = playerM.WithContext(s.Ctx).Where(playerM.ID.Eq(player.ID)).UpdateSimple(playerM.LastSign.Value(lastSign)) if err != nil { return s.BE().MysqlError(err) } m := s.GetDao().FissionUnoCollect _, err = m.WithContext(s.Ctx).Where(m.UnoID.Eq(player.ID)).UpdateSimple(m.SignNum.Add(1)) if err != nil { return s.BE().MysqlError(err) } return } // ReceiveReward 手动领取奖励 func (s *Uno) ReceiveReward(taskRewards ...*model.FissionUserTaskReward) (chance int32, reward *award.RewardRes, err error) { err = s._receiveReward(taskRewards, func(tasks []*model.FissionCampaignTask, records []*award.RewardRes) error { chance, err = s.taskFinish(tasks, false) if err != nil { return err } if len(records) == 0 { return nil } reward = records[0] return nil }) if err != nil { return } return } // FinishTask 完成任务 func (s *Uno) FinishTask(tasks ...*model.FissionCampaignTask) (err error) { _, err = s.taskFinish(tasks, true) if err != nil { return } return } // 完成任务 func (s *Uno) taskFinish(tasks []*model.FissionCampaignTask, checkManual bool) (chance int32, err error) { player := s.GetPlayer() var lotteryChance, threeNum, fiveNum, fixNum int32 var logs []*model.FissionUnoLog for _, task := range tasks { if checkManual && task.AwardMode == mtype.FissionCampaignTaskAwardModeManual { continue } val := mtype.UnoLogVal{ TaskId: task.ID, Chance: task.Chance, } var logType int8 switch task.PropMark { case mtype.FissionCampaignTaskPropMarkChance: chance += task.Chance lotteryChance += task.Chance logType = mtype.FissionUnoLogTypeAdd case mtype.FissionCampaignTaskPropMarkUnoFive: chance += task.Chance fiveNum += task.Chance logType = mtype.FissionUnoLogTypeProp case mtype.FissionCampaignTaskPropMarkUnoThree: chance += task.Chance threeNum += task.Chance logType = mtype.FissionUnoLogTypeProp case mtype.FissionCampaignTaskPropMarkUnoFix: chance += task.Chance fixNum += task.Chance logType = mtype.FissionUnoLogTypeProp } log := withdefault.FissionUnoLog(&model.FissionUnoLog{ UserID: player.UserID, CampaignID: player.CampaignID, UnoID: player.ID, Type: logType, }, val) switch task.TaskType { case mtype.FissionCampaignTaskTypeRegister: log.Source = mtype.FissionLogSourceRegister case mtype.FissionCampaignTaskTypeInstall: log.Source = mtype.FissionLogSourceInstall case mtype.FissionCampaignTaskTypeCondAll: log.Source = utils.Ternary[string](task.AwardMode == mtype.FissionCampaignTaskAwardModeManual, mtype.FissionLogSourceManualCondAll, mtype.FissionLogSourceCondAll) case mtype.FissionCampaignTaskTypeCondOne: log.Source = utils.Ternary[string](task.AwardMode == mtype.FissionCampaignTaskAwardModeManual, mtype.FissionLogSourceManualCondOne, mtype.FissionLogSourceCondOne) } logs = append(logs, log) } if lotteryChance > 0 || threeNum > 0 || fiveNum > 0 || fixNum > 0 { m := s.GetDao().FissionUno _, err = m.WithContext(s.Ctx).Where(m.ID.Eq(player.ID)).UpdateSimple( m.Chance.Add(lotteryChance), m.ThreeNum.Add(threeNum), m.FiveNum.Add(fiveNum), m.FixNum.Add(fixNum), ) if err != nil { return } if lotteryChance > 0 { s.addChanceNotify(int64(lotteryChance)) } } err = s._addLog(logs...) if err != nil { return } s.trackGetProp(threeNum, fiveNum, fixNum) return } func (s *Uno) trackGetProp(threeNum, fiveNum, fixNum int32) { props := []struct { name string num int32 }{ {name: consts.PropNameUnoThree, num: threeNum}, {name: consts.PropNameUnoFive, num: fiveNum}, {name: consts.PropNameUnoFix, num: fixNum}, } now := time.Now().Unix() for _, prop := range props { if prop.num > 0 { s.appTrack().GetProp(now, prop.name, prop.num) } } } // SetInit 获得初始次数 func (s *Uno) SetInit() (err error) { player, conf := s.GetPlayer(), s.GetConf() if player.SetInit == mtype.Yes || conf.InitChance == 0 { return } key := s.fissionPlayerSetInitOnceKey if !app.NewRedisLock(s.Ctx, key).SoftLock() { return } m := s.GetDao().FissionUno _, err = m.WithContext(s.Ctx).Where(m.ID.Eq(player.ID)).UpdateSimple(m.SetInit.Value(mtype.Yes), m.Chance.Add(conf.InitChance)) if err != nil { err = s.BE().MysqlError(err) return } log := withdefault.FissionUnoLog(&model.FissionUnoLog{ UserID: player.UserID, CampaignID: player.CampaignID, UnoID: player.ID, Type: mtype.FissionUnoLogTypeAdd, Source: mtype.FissionLogSourceInit, }, mtype.UnoLogVal{ Chance: conf.InitChance, }) err = s._addLog(log) if err != nil { return } s.player.Chance += conf.InitChance return } // GetConf 获取玩法配置 func (s *Uno) GetConf() *model.FissionCampaignUno { if s.conf == nil { s.conf, _ = cache.NewCampaignUno(s.Ctx).FindByCampaignId(s.user.CampaignID) } return s.conf } // GetPlayer 获取玩家基础数据 func (s *Uno) GetPlayer() *model.FissionUno { return s.player } // 玩家 func (s *Uno) initPlayer() (err error) { player, err := s._dbFirst() if err != nil { return } defer func() { if err != nil { return } s.player = player s.fissionPlayerSetInitOnceKey = ckey.FissionPlayerSetInitOnce(player.UserID) s.fissionUserUnoClaimOnceKey = ckey.FissionUserUnoClaimOnce(player.UserID) s.fissionUserUnoCollectOnceKey = ckey.FissionUserUnoCollectOnce(player.UserID) s.collectMap = make(map[string]*model.FissionUnoCollect, 4) s.collectUp = make(map[string]bool, 4) }() if player != nil { return } player, err = s.firstOrCreate() if err != nil { return } return } // 创建玩家基础数据 func (s *Uno) firstOrCreate() (player *model.FissionUno, err error) { lc := app.NewFollower(s.Ctx, ckey.FissionUserCreatePlayerOnce(s.user.ID)).Lock() defer lc.Release() if lc.Error() != nil { err = lc.Error() return } player, err = s._dbFirst() if err != nil { return } if player != nil { return } return s.createPlayer() } // 数据库查询 func (s *Uno) _dbFirst() (*model.FissionUno, error) { playerM := dao.FissionUno player, err := playerM.WithContext(s.Ctx).Where(playerM.UserID.Eq(s.user.ID)).Take() if err = dbcheck.DbError(err); err != nil { return nil, s.BE().MysqlError(err) } return player, nil } // 创建一个玩家 func (s *Uno) createPlayer() (player *model.FissionUno, err error) { playerM := dao.FissionUno player = withdefault.FissionUno(&model.FissionUno{ CampaignID: s.user.CampaignID, UserID: s.user.ID, }) err = playerM.WithContext(s.Ctx).Create(player) if err != nil { err = s.BE().MysqlError(err) return } return } func (s *Uno) _addLog(logs ...*model.FissionUnoLog) (err error) { err = s.GetDao().FissionUnoLog.WithContext(s.Ctx).Create(logs...) if err != nil { err = s.BE().MysqlError(err) return } return } func (s *Uno) _userCollect() (data map[string]*model.FissionUnoCollect, err error) { if len(s.collectMap) > 0 { return s.collectMap, nil } player := s.GetPlayer() m := s.GetDao().FissionUnoCollect list, err := m.WithContext(s.Ctx).Where(m.UnoID.Eq(player.ID)).Find() if err != nil { err = s.BE().MysqlError(err) return } if len(list) == 0 { key := s.fissionUserUnoCollectOnceKey lc := app.NewFollower(s.Ctx, key).Lock() defer lc.Release() if lc.Error() != nil { err = lc.Error() return } list, err = m.WithContext(s.Ctx).Where(m.UnoID.Eq(player.ID)).Find() if err != nil { err = s.BE().MysqlError(err) return } if len(list) == 0 { cardInfo := make([]int32, 9) list = append( list, withdefault.FissionUnoCollect(&model.FissionUnoCollect{ UserID: player.UserID, CampaignID: player.CampaignID, UnoID: player.ID, Mark: mtype.FissionCampaignUnoGroupRed, }, cardInfo), withdefault.FissionUnoCollect(&model.FissionUnoCollect{ UserID: player.UserID, CampaignID: player.CampaignID, UnoID: player.ID, Mark: mtype.FissionCampaignUnoGroupBlue, }, cardInfo), withdefault.FissionUnoCollect(&model.FissionUnoCollect{ UserID: player.UserID, CampaignID: player.CampaignID, UnoID: player.ID, Mark: mtype.FissionCampaignUnoGroupYellow, }, cardInfo), withdefault.FissionUnoCollect(&model.FissionUnoCollect{ UserID: player.UserID, CampaignID: player.CampaignID, UnoID: player.ID, Mark: mtype.FissionCampaignUnoGroupGreen, }, cardInfo), ) if err = m.WithContext(s.Ctx).Create(list...); err != nil { err = s.BE().MysqlError(err) return } } } for _, v := range list { s.collectMap[v.Mark] = v } return s.collectMap, nil } // 增加抽奖次数通知 func (s *Uno) addChanceNotify(chance int64) { provider.NewFissionClue(s.Ctx, s.user.ID).AddChance(chance) } func (s *Uno) _upCollect() (err error) { for _, collect := range s.collectMap { if up, ok := s.collectUp[collect.Mark]; ok && up { err = s.GetDao().FissionUnoCollect.WithContext(s.Ctx).Save(collect) if err != nil { err = s.BE().MysqlError(err) return } } } return }