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.

1429 lines
33 KiB
Go

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)
}