package campaignuser import ( "joybuywork/internal/consts" "joybuywork/internal/repository/cache" "joybuywork/internal/repository/dao" "joybuywork/internal/repository/dbcheck" "joybuywork/internal/repository/finder" "joybuywork/internal/repository/model" "joybuywork/internal/repository/mtype" "joybuywork/internal/repository/withdefault" "joybuywork/internal/service/cmm" "joybuywork/internal/service/provider" "joybuywork/internal/service/provider/players" "joybuywork/internal/utils" "joybuywork/internal/utils/logic" "joybuywork/internal/utils/timez" pb "joybuywork/proto/go_proto/w_campaign_user" "joybuywork/proto/go_proto/workerr" "strings" "time" "github.com/golang-module/carbon/v2" ) type Play struct { logic.Logic Req *pb.PlayReq Res *pb.PlayRes taskChance int32 cpnControl *provider.CampaignTZ } func (s *Play) Run() error { return logic.Run(s) } func (s *Play) Exec() (err error) { user, cpn, err := s.user() if err != nil { return } err = s.play(user, cpn) if err != nil { return } s.clue(user) return } func (s *Play) user() (user *model.FissionUser, cpn *model.FissionCampaign, err error) { cpn, err = finder.Campaign(s.Ctx, s.Req.GetCampaignId()) if err != nil { err = s.BE().CacheError(err) return } if cpn == nil || cpn.IsDel == mtype.Yes { err = workerr.NotFound("not found cpn") return } user, err = finder.FissionUser(s.Ctx, cpn.ID, s.Req.GetId()) if err != nil { err = s.BE().CacheError(err) return } if user == nil { err = workerr.NotFound("not found user") return } var parentUserId string if user.ParentID > 0 { var puser *model.FissionUser puser, err = finder.FissionUser(s.Ctx, cpn.ID, user.ParentID) if err = dbcheck.DbError(err); err != nil { err = s.BE().MysqlError(err) return } parentUserId = puser.SubUserID } s.cpnControl = provider.NewCampaignTZ(s.Ctx, cpn, user.LangMark) s.AddAfterRun(func() (err error) { s.Res.SubUserId = user.SubUserID s.Res.ParentUserId = parentUserId s.Res.DeviceId = user.DeviceID s.Res.ShareLink = user.ShareLink s.Res.FissionId = cpn.FissionID return }) return } func (s *Play) play(user *model.FissionUser, cpn *model.FissionCampaign) (err error) { switch cpn.FissionID { case consts.IdPrizeWheel: //大转盘 return s._prizeWheel(user, cpn) case consts.IdSlotMachine: //老虎机 return s._slotMachine(user, cpn) case consts.IdLuckyGrid: //九宫格 return s._luckyGrid(user, cpn) case consts.IdBlindBox: //盲盒 return s._blindBox(user, cpn) case consts.IdReferral: //老带新 return s._referral(user, cpn) case consts.IdWinTogether: //一起赢 return s._winTogether(user, cpn) case consts.IdPrizeAnswer, consts.IdQa, consts.IdQaVideo, consts.IdQaAudio: //趣味问答 return s._prizeAnswer(user, cpn) case consts.IdPrizeQuiz: //有奖竞猜 return s._prizeQuiz(user, cpn) case consts.IdSignIn: //签到 return s._signIn(user) case consts.IdDice: //大富翁 return s._dice(user, cpn) case consts.IdGrow: //农场 return s._grow(user) case consts.IdBallot: //抽签 return s._ballot(user, cpn) case consts.IdChop: //砍一刀 return s._chop(user, cpn) case consts.IdCash: //现金抽奖 return s._cash(user, cpn) case consts.IdFlip: //翻牌抽奖 return s._flip(user, cpn) case consts.IdKeep: //激励养成 return s._keep(user, cpn) case consts.IdGold: //金币任务 return s._gold(user, cpn) case consts.IdCoin: //瓜分金币 return s._coin(user, cpn) case consts.IdVs: //VS return s._vs(user, cpn) case consts.IdUno: //Uno return s._uno(user, cpn) case consts.IdGashapon: //翻牌 return s._gashapon(user, cpn) } return } func (s *Play) _referral(user *model.FissionUser, cpn *model.FissionCampaign) (err error) { player, err := cmm.NewFirstCreate(s.Ctx, s.GetDao()).FissionReferral(user) if err != nil { return } rcf, err := cache.NewCampaignReferral(s.Ctx).FindByCampaignId(user.CampaignID) if err != nil { err = s.BE().CacheError(err) return } return s._invitePlayer(user, cpn, rcf.RewardRule, player.LimitStatus, player.BindRegister, player.BindInstall, player.NextStep, player.LoopInvite) } func (s *Play) _winTogether(user *model.FissionUser, cpn *model.FissionCampaign) (err error) { player, err := cmm.NewFirstCreate(s.Ctx, s.GetDao()).FissionWin(user) if err != nil { return } fcw, err := cache.NewCampaignWin(s.Ctx).FindByCampaignId(cpn.ID) if err != nil { err = s.BE().CacheError(err) return } err = s._invitePlayer(user, cpn, fcw.RewardRule, player.LimitStatus, player.BindRegister, player.BindInstall, player.NextStep, player.LoopInvite) if err != nil { return } // 新人奖通知 recordM := s.GetDao().FissionRewardRecord.SubTable(cpn.ID) records, err := recordM.WithContext(s.Ctx).Where(recordM.UserID.Eq(player.UserID), recordM.RewardType.Eq(mtype.FissionCampaignRewardTypeNewcomer)).Find() if err != nil { err = s.BE().MysqlError(err) return } // 能不能拿新人奖 s.AddAfterRun(func() (err error) { if user.ParentID == 0 { return } switch fcw.NewcomerCond { case mtype.FissionNewcomerCondInstall: s.Res.InvitePlayer.HasNewcomerReward = user.Source == mtype.FissionUserSourceInstall && len(records) == 0 case mtype.FissionNewcomerCondHelp: s.Res.InvitePlayer.HasNewcomerReward = user.IsHelp == mtype.No && len(records) == 0 case mtype.FissionNewcomerCondInstallAndHelp: s.Res.InvitePlayer.HasNewcomerReward = user.Source == mtype.FissionUserSourceInstall && user.IsHelp == mtype.No && len(records) == 0 } return }) var ntr *model.FissionRewardRecord ntRecordId := provider.NewFissionClue(s.Ctx, user.ID).GetNewcomerReward() if ntRecordId == 0 { return } for _, v := range records { if v.ID == ntRecordId { ntr = v break } } if ntr == nil { return } prewards, err := provider.NewRewards(s.Ctx, cpn.ProjectID, ntr.BaseRewardID) if err != nil { return } s.AddAfterRun(func() (err error) { info, _ := prewards.InfoAutoLang(ntr.BaseRewardID, user.LangMark) s.Res.InvitePlayer.NoticeReward = &pb.PlayRes_NoticeReward{ HashId: ntr.HashID, Title: info.Title, RewardNum: ntr.RewardNum, ReceiveType: info.ReceiveType, KvData: nil, RewardId: ntr.RewardID, Contact: info.Contact, } if info.ReceiveType == mtype.RewardReceiveTypeClient { s.Res.InvitePlayer.NoticeReward.KvData = make([]*pb.PlayRes_KV, 0, len(info.KvData)) for _, v := range info.KvData { s.Res.InvitePlayer.NoticeReward.KvData = append(s.Res.InvitePlayer.NoticeReward.KvData, &pb.PlayRes_KV{ Key: v.Key, Value: v.Value, }) } } return }) return } func (s *Play) _invitePlayer(user *model.FissionUser, cpn *model.FissionCampaign, rewardRule, limitStatus, br, bi int8, nextStep, loopInvite int32) (err error) { conf, err := cache.NewCampaignConfig(s.Ctx).FindByCampaignId(cpn.ID) if err != nil { err = s.BE().CacheError(err) return } var hasHelpTask bool if conf.Option == mtype.FissionCampaignConfigTargetOptionFriend && user.IsHelp == mtype.No { var ticket *model.FissionCampaignTicket ticket, err = cache.NewCampaignTicket(s.Ctx).FindByMark(cpn.ID, mtype.FissionCampaignTicketCustom) if err != nil { err = s.BE().CacheError(err) return } if ticket != nil && ticket.Open == mtype.Yes { switch ticket.PreEvent { case mtype.FissionCampaignTicketPreEventRegister: hasHelpTask = br == mtype.Yes case mtype.FissionCampaignTicketPreEventInstall: hasHelpTask = bi == mtype.Yes } } } stat, err := cmm.NewFirstCreate(s.Ctx, s.GetDao()).FissionUserStat(user) if err != nil { return } cms := cmm.NewCMM(s.Ctx, s.GetDao()) appRewardList, err := cms.UserAppReward(user) if err != nil { return } rewardM, recordM := s.GetDao().FissionCampaignReward, s.GetDao().FissionRewardRecord.SubTable(cpn.ID) //常规奖励,旧非阶梯 if rewardRule == mtype.FissionReferralRewardRuleCycle { var extraReward *model.FissionCampaignReward extraReward, err = rewardM.WithContext(s.Ctx).Where( rewardM.CampaignID.Eq(cpn.ID), rewardM.RewardType.Eq(mtype.FissionCampaignRewardTypeExtra), rewardM.IsDel.Eq(mtype.No), ).Order(rewardM.Step).Take() if err = dbcheck.DbError(err); err != nil { return s.BE().MysqlError(err) } reward := appRewardList[0] type numT struct { RewardType int32 Num int64 } var nums []numT if err = recordM.WithContext(s.Ctx). Select(recordM.RewardType, recordM.RewardNum.Sum().As("num")). Where(recordM.UserID.Eq(user.ID), recordM.RewardType.In(mtype.FissionCampaignRewardTypeExtra, mtype.FissionCampaignRewardTypeApp)). Group(recordM.RewardType). Scan(&nums); err != nil { return s.BE().MysqlError(err) } var num, extraNum numT for _, v := range nums { if v.RewardType == mtype.FissionCampaignRewardTypeExtra { extraNum = v } else { num = v } } var ids = []int64{reward.RewardID} if extraReward != nil { ids = append(ids, extraReward.RewardID) } var prewards *provider.Rewards prewards, err = provider.NewRewards(s.Ctx, cpn.ProjectID, ids...) if err != nil { return } s.AddAfterRun(func() (err error) { info := prewards.AutoLang(reward.RewardID, user.LangMark) s.Res.InvitePlayer = &pb.PlayRes_InvitePalyer{ Id: user.ID, InviteNum: stat.EffectiveNum, NeedNum: int64(reward.InviteNum), LimitStatus: int32(limitStatus), Title: info.Title, RewardNum: num.Num, RewardRule: int32(rewardRule), RewardId: reward.ID, ExtraTitle: "", ExtraRewardNum: 0, HasHelpTask: hasHelpTask, } if extraReward != nil { extraInfo := prewards.AutoLang(extraReward.RewardID, user.LangMark) s.Res.InvitePlayer.ExtraRewardId = extraReward.ID s.Res.InvitePlayer.ExtraTitle = extraInfo.Title s.Res.InvitePlayer.ExtraRewardNum = extraNum.Num } return }) return } // 阶梯逻辑 // 被限制了 if limitStatus != mtype.FissionReferralLimitStatusNone { //找第一条数据来做单位,因为产品会保证每个阶梯都是同一种单位,后续有问题再处理 reward := appRewardList[0] var num struct { Num int64 } if err = recordM.WithContext(s.Ctx). Select(recordM.RewardNum.Sum().As("num")). Where(recordM.UserID.Eq(user.ID), recordM.RewardType.In(mtype.FissionCampaignRewardTypeExtra, mtype.FissionCampaignRewardTypeApp)). Scan(&num); err != nil { return s.BE().MysqlError(err) } var prewards *provider.Rewards prewards, err = provider.NewRewards(s.Ctx, cpn.ProjectID, reward.RewardID) if err != nil { return } s.AddAfterRun(func() (err error) { info := prewards.AutoLang(reward.RewardID, user.LangMark) s.Res.InvitePlayer = &pb.PlayRes_InvitePalyer{ Id: user.ID, InviteNum: stat.EffectiveNum, NeedNum: int64(reward.InviteNum), LimitStatus: int32(limitStatus), Title: info.Title, RewardNum: num.Num, RewardRule: int32(rewardRule), RewardId: reward.ID, HasHelpTask: hasHelpTask, } return }) return } var allInviteNum int32 for _, reward := range appRewardList { if reward.InviteNum > allInviteNum { allInviteNum = reward.InviteNum } } var reward *model.FissionCampaignReward for _, v := range appRewardList { if v.Step == nextStep { reward = v break } } var title string var rewardId, rewardNum, needNum int64 if reward != nil { var prewards *provider.Rewards prewards, err = provider.NewRewards(s.Ctx, cpn.ProjectID, reward.RewardID) if err != nil { return } info := prewards.AutoLang(reward.RewardID, user.LangMark) rewardId = reward.ID title = info.Title rewardNum = int64(reward.RewardNum) needNum = int64(reward.InviteNum) - (stat.EffectiveNum - int64(loopInvite*allInviteNum)) } s.AddAfterRun(func() (err error) { s.Res.InvitePlayer = &pb.PlayRes_InvitePalyer{ Id: user.ID, InviteNum: stat.EffectiveNum, NeedNum: utils.Ternary(needNum > 0, needNum, 1), LimitStatus: int32(limitStatus), Title: title, RewardNum: rewardNum, RewardRule: int32(rewardRule), RewardId: rewardId, HasHelpTask: hasHelpTask, } return }) return } func (s *Play) _prizeWheel(user *model.FissionUser, cpn *model.FissionCampaign) (err error) { wheel, err := players.NewWheel(s.Ctx, user, players.SetCpn(cpn), players.SetDao(s.GetDao())) if err != nil { return } err = wheel.SetInit() if err != nil { return } err = wheel.Sign() if err != nil { return } player := wheel.GetPlayer() return s._chancePlayer(user, player.Chance) } func (s *Play) _chancePlayer(user *model.FissionUser, chance int32) (err error) { statM := s.GetDao().FissionUserStat stat, err := statM.WithContext(s.Ctx).Where(statM.UserID.Eq(user.ID)).Take() if err = dbcheck.DbError(err); err != nil { return s.BE().MysqlError(err) } if stat == nil { stat = withdefault.FissionUserStat(&model.FissionUserStat{ UserID: user.ID, CampaignID: user.CampaignID, }) err = statM.WithContext(s.Ctx).Create(stat) if err != nil { return s.BE().MysqlError(err) } } s.AddAfterRun(func() (err error) { s.Res.ChancePlayer = &pb.PlayRes_ChancePlayer{ Id: user.ID, Chance: chance, InviteNum: stat.DirectNum, } return }) return } func (s *Play) _prizeQuiz(user *model.FissionUser, cpn *model.FissionCampaign) (err error) { quiz, err := players.NewQuiz(s.Ctx, user, players.SetCpn(cpn)) if err != nil { return } err = quiz.SetInit() if err != nil { return } player, fcq := quiz.GetPlayer(), quiz.GetConf() //奖励 var record *model.FissionRewardRecord recordM := s.GetDao().FissionRewardRecord.SubTable(cpn.ID) record, err = recordM.WithContext(s.Ctx).Where(recordM.UserID.Eq(user.ID)).Take() if err = dbcheck.DbError(err); err != nil { return s.BE().MysqlError(err) } statM := s.GetDao().FissionUserStat stat, err := statM.WithContext(s.Ctx).Where(statM.UserID.Eq(user.ID)).Take() if err = dbcheck.DbError(err); err != nil { return s.BE().MysqlError(err) } s.AddAfterRun(func() (err error) { s.Res.Quiz = &pb.PlayRes_Quiz{ Id: user.ID, Chance: player.Chance, OptionId: player.OptionID, Win: player.IsWin == mtype.Yes, Title: "", ImgUrl: "", InviteNum: stat.DirectNum, RewardHashId: "", ReceiveType: 0, IsPush: false, KvData: nil, OpenType: mtype.FissionCampaignQuizOpenTypeWait, } if fcq.OpenType == mtype.FissionCampaignQuizOpenTypeNone { //开奖了,但是不发奖励的开奖 s.Res.Quiz.OpenType = mtype.FissionCampaignQuizOpenTypeNone } if record != nil { s.Res.Quiz.OpenType = mtype.FissionCampaignQuizOpenTypeOpen s.Res.Quiz.Title = record.Title s.Res.Quiz.ImgUrl = record.ImgURL s.Res.Quiz.RewardHashId = record.HashID s.Res.Quiz.IsPush = record.Status != mtype.FissionRewardRecordStatusWait s.Res.Quiz.RewardId = record.RewardID prewards, _ := provider.NewRewards(s.Ctx, cpn.ProjectID, record.BaseRewardID) info, _ := prewards.InfoAutoLang(record.BaseRewardID, user.LangMark) s.Res.Quiz.Contact = info.Contact s.Res.Quiz.ReceiveType = info.ReceiveType kvData := info.KvData s.Res.Quiz.KvData = make([]*pb.PlayRes_KV, 0, len(kvData)) for _, v := range kvData { s.Res.Quiz.KvData = append(s.Res.Quiz.KvData, &pb.PlayRes_KV{ Key: v.Key, Value: v.Value, }) } } return }) return } func (s *Play) _slotMachine(user *model.FissionUser, cpn *model.FissionCampaign) (err error) { flip, err := players.NewSlot(s.Ctx, user, players.SetCpn(cpn), players.SetDao(s.GetDao())) if err != nil { return } err = flip.SetInit() if err != nil { return } err = flip.Sign() if err != nil { return } player := flip.GetPlayer() return s._chancePlayer(user, player.Chance) } func (s *Play) _luckyGrid(user *model.FissionUser, cpn *model.FissionCampaign) (err error) { grid, err := players.NewGrid(s.Ctx, user, players.SetCpn(cpn), players.SetDao(s.GetDao())) if err != nil { return } err = grid.SetInit() if err != nil { return } err = grid.Sign() if err != nil { return } player := grid.GetPlayer() return s._chancePlayer(user, player.Chance) } func (s *Play) _blindBox(user *model.FissionUser, cpn *model.FissionCampaign) (err error) { blind, err := players.NewBlind(s.Ctx, user, players.SetCpn(cpn), players.SetDao(s.GetDao())) if err != nil { return } err = blind.SetInit() if err != nil { return } err = blind.Sign() if err != nil { return } player := blind.GetPlayer() return s._chancePlayer(user, player.Chance) } func (s *Play) _flip(user *model.FissionUser, cpn *model.FissionCampaign) (err error) { flip, err := players.NewFlip(s.Ctx, user, players.SetCpn(cpn), players.SetDao(s.GetDao())) if err != nil { return } err = flip.SetInit() if err != nil { return } err = flip.Sign() if err != nil { return } player := flip.GetPlayer() return s._chancePlayer(user, player.Chance) } func (s *Play) _prizeAnswer(user *model.FissionUser, cpn *model.FissionCampaign) (err error) { qa, err := players.NewQa(s.Ctx, user, cpn.FissionID, players.SetCpn(cpn), players.SetDao(s.GetDao())) if err != nil { return } err = qa.SetInit() if err != nil { return } err = qa.Sign() if err != nil { return } player := qa.GetPlayer() return s._chancePlayer(user, player.Chance) } func (s *Play) _signIn(user *model.FissionUser) (err error) { sign, err := players.NewSign(s.Ctx, user) if err != nil { return } player := sign.GetPlayer() status, err := sign.GetStatus() if err != nil { return } s.AddAfterRun(func() (err error) { s.Res.Sign = &pb.PlayRes_Sign{ Id: player.ID, SignDay: player.SignDay, ContinueDay: player.SignContinue, InviteNum: status.DirectNum, CardNum: player.CardNum, MaxContinue: status.MaxContinue, TodaySign: status.TodaySign, CycleDay: status.CycleDay, } return }) return } func (s *Play) _dice(user *model.FissionUser, cpn *model.FissionCampaign) (err error) { dice, err := players.NewDice(s.Ctx, user, players.SetCpn(cpn), players.SetDao(s.GetDao())) if err != nil { return } err = dice.SetInit() if err != nil { return } err = dice.Sign() if err != nil { return } status, err := dice.Status() if err != nil { return } player := dice.GetPlayer() defer func() { s.taskChance = player.TaskChance }() rewards, err := cmm.NewCMM(s.Ctx, s.GetDao()).UserAppReward(user) if err != nil { return } var brIds []int64 for _, v := range rewards { brIds = append(brIds, v.RewardID) } preward, err := provider.NewRewards(s.Ctx, cpn.ProjectID, brIds...) if err != nil { return } s.AddAfterRun(func() (err error) { s.Res.Dice = &pb.PlayRes_Dice{ Id: player.ID, Chance: player.Chance, MapHashId: status.Run.MapHashID, PropsChance: status.PropMap[mtype.FissionDicePropMarkChance], PropsFixedRoll: status.PropMap[mtype.FissionDicePropMarkFixedRoll], Collects: make([]*pb.PlayRes_Collect, 0, len(rewards)), InviteNum: status.Stat.DirectNum, FixedRollTaskFinish: status.FixedRollTaskFinish, DmgId: status.Run.ID, } for _, reward := range rewards { info := preward.AutoLang(reward.RewardID, user.LangMark) one := &pb.PlayRes_Collect{ Id: reward.ID, Num: status.CollectMap[reward.ID], CollectNum: reward.CollectNum, RewardTitle: info.Title, ImgUrl: info.ImgUrl, IsSuper: int32(reward.IsSuper), } s.Res.Dice.Collects = append(s.Res.Dice.Collects, one) } return }) return } func (s *Play) _diceDayChance(user *model.FissionUser, dayChance int32) (err error) { if dayChance == 0 { return } // 看看需不需要骰子记录 record := withdefault.FissionDiceRecord(&model.FissionDiceRecord{ CampaignID: user.CampaignID, UserID: user.ID, Mark: mtype.FissionDiceRecordMarkSign, }) record.SetData(&mtype.DiceRecord{ Chance: dayChance, }) err = s.GetDao().FissionDiceRecord.WithContext(s.Ctx).Create(record) if err != nil { err = s.BE().MysqlError(err) } return } func (s *Play) _grow(user *model.FissionUser) (err error) { player, err := cmm.NewFirstCreate(s.Ctx, s.GetDao()).FissionGrow(user) if err != nil { return } statM := s.GetDao().FissionUserStat stat, err := statM.WithContext(s.Ctx).Where(statM.UserID.Eq(user.ID)).Take() if err = dbcheck.DbError(err); err != nil { return s.BE().MysqlError(err) } s.AddAfterRun(func() (err error) { now := carbon.Now() next := carbon.CreateFromTimestamp(player.PropsTime) s.Res.Grow = &pb.PlayRes_Grow{ Id: player.ID, GrowNum: player.GrowNum, InviteNum: stat.DirectNum, HasProps: utils.Ternary(next.IsZero(), false, next.Lt(now)), NextProps: utils.Ternary[int64](next.Lt(now), 0, now.DiffAbsInSeconds(next)), } return }) return } func (s *Play) _ballot(user *model.FissionUser, cpn *model.FissionCampaign) (err error) { ballot, err := players.NewBallot(s.Ctx, user, players.SetCpn(cpn), players.SetDao(s.GetDao())) if err != nil { return } err = ballot.SetInit() if err != nil { return } err = ballot.Sign() if err != nil { return } player := ballot.GetPlayer() return s._chancePlayer(user, player.Chance) } func (s *Play) _chop(user *model.FissionUser, cpn *model.FissionCampaign) (err error) { chop, err := players.NewChop(s.Ctx, user) if err != nil { return } player := chop.GetPlayer() if player.ChopRewardID == 0 { s.AddAfterRun(func() (err error) { s.Res.Chop = &pb.PlayRes_Chop{ Id: player.ID, } return }) return } crm := s.GetDao().FissionChopReward chopReward, err := crm.WithContext(s.Ctx).Where(crm.ID.Eq(player.ChopRewardID)).Take() if err != nil { err = s.BE().MysqlError(err) return } // 是否有可选择的奖品 canSelect, err := chop.ExistSelectReward() if err != nil { return } rewardM := s.GetDao().FissionCampaignReward reward, err := rewardM.WithContext(s.Ctx).Where(rewardM.ID.Eq(chopReward.RewardID)).Take() if err != nil { err = s.BE().MysqlError(err) return } prewards, err := provider.NewRewards(s.Ctx, cpn.ProjectID, reward.RewardID) if err != nil { return } info := prewards.AutoLang(reward.RewardID, user.LangMark) s.AddAfterRun(func() (err error) { s.Res.Chop = &pb.PlayRes_Chop{ Id: player.ID, ChopRewardId: chopReward.ID, Title: info.Title, ImgUrl: info.ImgUrl, Percent: chopReward.Percent, Finish: chopReward.RecordID > 0, RewardId: reward.ID, RewardNone: !canSelect, } return }) return } type UserTaskRecordTotal struct { TaskId int64 `json:"task_id"` Num int64 `json:"num"` } func (s *Play) _cash(user *model.FissionUser, cpn *model.FissionCampaign) (err error) { cash, err := players.NewCash(s.Ctx, user) if err != nil { return } player := cash.GetPlayer() hasAgain, err := cash.HasAgain() if err != nil { return } var rewards []*pb.PlayRes_GetReward defer s.AddAfterRun(func() (err error) { s.Res.Cash = &pb.PlayRes_Cash{ Id: player.ID, NextStep: player.NextStep, Energy: player.Energy, LotteryNum: int32(player.LotteryNum), ShowPrice: player.ShowPrice, ExpiredIn: carbon.NewCarbon().CreateFromTimestamp(player.ExpiredIn).DiffAbsInSeconds(), Rewards: rewards, HasAgain: hasAgain, } return }) if player.LotteryNum != int8(len(consts.SpinGetId)) { return } m := s.GetDao().FissionCashRecord record, err := m.WithContext(s.Ctx).Where(m.UserID.Eq(user.ID), m.CashID.Eq(player.ID), m.Type.Eq(mtype.FissionCashRecordTypeReward)).Take() if err = dbcheck.DbError(err); err != nil { err = s.BE().MysqlError(err) return } if record == nil { return } recordM := s.GetDao().FissionRewardRecord.SubTable(cpn.ID) records, err := recordM.WithContext(s.Ctx).Where(recordM.ID.In(record.GetDataReward().Ids...)).Find() if err != nil { err = s.BE().MysqlError(err) return } var rewardIds, brIds []int64 for _, v := range records { brIds = append(brIds, v.BaseRewardID) rewardIds = append(rewardIds, v.RewardID) } rewardM := s.GetDao().FissionCampaignReward rewardList, err := rewardM.WithContext(s.Ctx).Where(rewardM.ID.In(rewardIds...)).Find() if err != nil { err = s.BE().MysqlError(err) return } var jumpUrlMap = make(map[int64]string, len(rewardList)) for _, v := range rewardList { jumpUrlMap[v.ID] = v.JumpURL } preward, _ := provider.NewRewards(s.Ctx, cpn.ProjectID, brIds...) for _, v := range records { info, _ := preward.InfoAutoLang(v.BaseRewardID, user.LangMark) one := &pb.PlayRes_GetReward{ HashId: v.HashID, Title: info.Title, Img: info.ImgUrl, JumpUrl: jumpUrlMap[v.RewardID], KvData: nil, ReceiveType: info.ReceiveType, Contact: info.Contact, CreatedAt: v.CreatedAt, OpenToUse: info.OpenToUse, WebUrl: info.WebUrl, AppParam: info.AppParam, PcParam: info.PcParam, } for _, datum := range info.KvData { one.KvData = append(one.KvData, &pb.PlayRes_KV{ Key: datum.Key, Value: datum.Value, }) } rewards = append(rewards, one) } return } // 最后签到 func (s *Play) _lastSign(lastSign string) (ok bool, day string) { // 带时区的签到 day, _, _ = timez.GMTStartAndEndTs(s.cpnControl.GetTz()) day = strings.ReplaceAll(day, "-", "") if lastSign == "" || day > lastSign { return true, day } return false, lastSign } // 通知 func (s *Play) clue(user *model.FissionUser) { clueProvider := provider.NewFissionClue(s.Ctx, user.ID) chance := clueProvider.GetChance() if chance > 0 { s.Res.Clue = append(s.Res.Clue, &pb.PlayRes_Clue{ Type: 1, Chance: chance, }) } preCond := clueProvider.GetPreCond() if preCond > 0 { s.Res.Clue = append(s.Res.Clue, &pb.PlayRes_Clue{ Type: 2, PreCond: preCond, }) } return } func (s *Play) _keep(user *model.FissionUser, cpn *model.FissionCampaign) (err error) { tz := provider.NewCampaignTZ(s.Ctx, cpn, user.LangMark) start, _ := timez.GMTTimeStart(tz.GetTz()) keepDog, err := players.NewKeepDog(s.Ctx, user) if err != nil { return } status, err := keepDog.GetStatus() if err != nil { return } player := keepDog.GetPlayer() s.Res.KeepDog = &pb.PlayRes_Keep{ Id: player.ID, Percent: status.Percent, Num: player.Num, MachineNum: player.MachineNum, FeedLack: status.PropNeedFeed, Collect: player.Collect, SecondPercent: status.SecondPercent, ExpiredSec: player.ExpiredAt - time.Now().Unix(), Reward: nil, LeftCollect: status.Left, Guided: int32(player.Guided), DayFirstInvite: status.DayFirstInvite, DayFirstExpiredSec: start.Unix() - time.Now().Unix() + 86400, MachineLimit: status.MachineLimit, OfflineFull: status.OfflineFull, } if player.RewardID == 0 { return } rewardM := dao.FissionCampaignReward reward, err := rewardM.WithContext(s.Ctx).Where(rewardM.ID.In(player.RewardID)).Take() if err = dbcheck.DbError(err); err != nil { err = s.BE().MysqlError(err) return } if reward == nil { err = s.BE().VerifyError("not found reward") return } preward, err := provider.NewRewards(s.Ctx, cpn.ProjectID, reward.RewardID) if err != nil { return } info := preward.AutoLang(reward.RewardID, user.LangMark) s.Res.KeepDog.Reward = &pb.PlayRes_KeepReward{ Id: reward.ID, Title: info.Title, ImgUrl: info.ImgUrl, RecordId: player.RecordID, } return } // 金币任务玩家 func (s *Play) _gold(user *model.FissionUser, cpn *model.FissionCampaign) (err error) { gold, err := players.NewGold(s.Ctx, user, players.SetCpn(cpn)) if err != nil { return } player, conf := gold.GetPlayer(), gold.GetConf() clue := provider.NewFissionClue(s.Ctx, user.ID).GetGold() s.Res.Gold = &pb.PlayRes_Gold{ Id: player.ID, NextStep: player.NextStep, Energy: player.Energy, ShowPrice: player.ShowPrice, ExpiredIn: carbon.NewCarbon().CreateFromTimestamp(player.ExpiredIn).DiffAbsInSeconds(), GoldNum: player.GoldNum - int32(clue.Add), Rewards: nil, AddNum: int32(clue.Add), HideCoins: 0, } if player.GoldNum >= conf.GoldNum && player.NextStep != mtype.FissionGoldNextStepGoldRain { s.Res.Gold.HideCoins = 1 // 做了任务了也不显示加金币 s.Res.Gold.GoldNum = player.GoldNum s.Res.Gold.AddNum = 0 } if player.LotteryNum < 2 { return } m := s.GetDao().FissionGoldLog record, err := m.WithContext(s.Ctx).Where(m.GoldID.Eq(player.ID), m.Type.Eq(mtype.FissionGoldLogTypeReward)).Take() if err = dbcheck.DbError(err); err != nil { err = s.BE().MysqlError(err) return } if record == nil { return } recordM := s.GetDao().FissionRewardRecord.SubTable(cpn.ID) records, err := recordM.WithContext(s.Ctx).Where(recordM.ID.In(record.GetVal().RecordIds...)).Find() if err != nil { err = s.BE().MysqlError(err) return } var rewardIds, brIds []int64 for _, v := range records { brIds = append(brIds, v.BaseRewardID) rewardIds = append(rewardIds, v.RewardID) } preward, _ := provider.NewRewards(s.Ctx, cpn.ProjectID, brIds...) for _, v := range records { info, _ := preward.InfoAutoLang(v.BaseRewardID, user.LangMark) one := &pb.PlayRes_GetReward{ HashId: v.HashID, Title: info.Title, Img: info.ImgUrl, JumpUrl: "", KvData: nil, ReceiveType: info.ReceiveType, Contact: info.Contact, CreatedAt: v.CreatedAt, OpenToUse: info.OpenToUse, WebUrl: info.WebUrl, AppParam: info.AppParam, PcParam: info.PcParam, } for _, datum := range info.KvData { one.KvData = append(one.KvData, &pb.PlayRes_KV{ Key: datum.Key, Value: datum.Value, }) } s.Res.Gold.Rewards = append(s.Res.Gold.Rewards, one) } return } func (s *Play) _coin(user *model.FissionUser, cpn *model.FissionCampaign) (err error) { coin, err := players.NewCoin(s.Ctx, user, players.SetCpn(cpn)) if err != nil { return } status, err := coin.GetStatus() if err != nil { return } s.Res.Coin = &pb.PlayRes_Coin{ GetCoin: status.GetCoin, AllCoin: status.AllCoin, OpenSec: status.OpenSec, UseNum: status.UseNum, CanGet: status.CanGet, End: status.End, } return } func (s *Play) _vs(user *model.FissionUser, cpn *model.FissionCampaign) (err error) { vs, err := players.NewVs(s.Ctx, user, players.SetCpn(cpn)) if err != nil { return } err = vs.SetInit() if err != nil { return } player, conf := vs.GetPlayer(), vs.GetConf() s.Res.Vs = &pb.PlayRes_Vs{ Chance: player.Chance, } m := s.GetDao().FissionVsVoteSettlement settlements, err := m.WithContext(s.Ctx).Where(m.VsID.Eq(player.ID), m.TipAt.Eq(0)).Find() if err = dbcheck.DbError(err); err != nil { err = s.BE().MysqlError(err) return } for _, v := range settlements { rewards, err1 := vs.SettlementReward(v) if err1 != nil { return } for _, reward := range rewards { one := &pb.PlayRes_GetReward{ HashId: reward.RewardHashId, Title: reward.Title, Img: reward.Img, KvData: make([]*pb.PlayRes_KV, 0, len(reward.KvData)), ReceiveType: reward.ReceiveType, Contact: reward.Contact, CreatedAt: utils.Ternary[int64](v.AcceptAt == 0, time.Now().Unix(), v.AcceptAt), OpenToUse: reward.OpenToUse, WebUrl: reward.WebUrl, AppParam: reward.AppParam, PcParam: reward.PcParam, PropMark: reward.PropMark, RewardNum: reward.PropNum, RewardId: reward.Id, } for _, datum := range reward.KvData { one.KvData = append(one.KvData, &pb.PlayRes_KV{ Key: datum.Key, Value: datum.Value, IsShow: datum.IsShow, }) } s.Res.Vs.WinRewards = append(s.Res.Vs.WinRewards, one) } } if conf.OpenPoint == mtype.No && conf.MallOpen == mtype.No { return } s.Res.Vs.CoinNum, err = vs.GetTCoin() if err != nil { return } s.Res.Vs.CoinTitle, s.Res.Vs.CoinImg, _, err = cmm.NewCMM(s.Ctx, s.GetDao()).GetCoinInfo(cpn.ProjectID, user.LangMark) if err != nil { return } return } func (s *Play) _uno(user *model.FissionUser, cpn *model.FissionCampaign) (err error) { uno, err := players.NewUno(s.Ctx, user, players.SetCpn(cpn), players.SetDao(s.GetDao())) if err != nil { return } err = uno.SetInit() if err != nil { return } cardInfo, err := uno.Cards() if err != nil { return } err = uno.Sign() if err != nil { return } player := uno.GetPlayer() var fn = func(in []*players.UnoCards) (out *pb.PlayRes_UnoGroup) { out = &pb.PlayRes_UnoGroup{ CollectNum: 0, Cards: make([]*pb.PlayRes_UnoCard, 0, len(in)), } for _, card := range in { out.Cards = append(out.Cards, &pb.PlayRes_UnoCard{ CardNo: card.CardNo, CardNum: card.CardNum, }) if card.CardNum > 0 { out.CollectNum++ } } return } s.Res.Uno = &pb.PlayRes_Uno{ Chance: player.Chance, ThreeNum: player.ThreeNum, FiveNum: player.FiveNum, FixNum: player.FixNum, Red: fn(cardInfo[mtype.FissionCampaignUnoGroupRed]), Blue: fn(cardInfo[mtype.FissionCampaignUnoGroupBlue]), Green: fn(cardInfo[mtype.FissionCampaignUnoGroupGreen]), Yellow: fn(cardInfo[mtype.FissionCampaignUnoGroupYellow]), } return } func (s *Play) _gashapon(user *model.FissionUser, cpn *model.FissionCampaign) (err error) { blind, err := players.NewGashapon(s.Ctx, user, players.SetCpn(cpn), players.SetDao(s.GetDao())) if err != nil { return } err = blind.SetInit() if err != nil { return } err = blind.Sign() if err != nil { return } player := blind.GetPlayer() return s._chancePlayer(user, player.Chance) }