|
|
package players
|
|
|
|
|
|
import (
|
|
|
"context"
|
|
|
"joybuywork/internal/app"
|
|
|
"joybuywork/internal/consts"
|
|
|
"joybuywork/internal/consts/ckey"
|
|
|
"joybuywork/internal/plugins/jsonm"
|
|
|
"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/cmm"
|
|
|
"joybuywork/internal/service/provider"
|
|
|
"joybuywork/internal/service/provider/award"
|
|
|
"joybuywork/internal/service/provider/projectuser"
|
|
|
"joybuywork/internal/utils"
|
|
|
"joybuywork/internal/utils/timez"
|
|
|
"joybuywork/internal/utils/verify"
|
|
|
"math"
|
|
|
"strconv"
|
|
|
"time"
|
|
|
|
|
|
"gits.branchcn.com/backend/microcode/plugins/derivative/lock"
|
|
|
"gorm.io/gen/field"
|
|
|
)
|
|
|
|
|
|
const (
|
|
|
voteOk = iota
|
|
|
voteEnd // 非投票时间无法投票
|
|
|
voteLack // 投票机会不足
|
|
|
votePointLack // 积分不足
|
|
|
voteLimit // 投票已达最大次数
|
|
|
voteFail // 投票失败
|
|
|
voteNotSameTeam // 不能投同队伍
|
|
|
)
|
|
|
|
|
|
type Vs struct {
|
|
|
Player
|
|
|
player *model.FissionV
|
|
|
conf *model.FissionCampaignV
|
|
|
|
|
|
fissionPlayerSetInitOnceKey string
|
|
|
}
|
|
|
|
|
|
func NewVs(ctx context.Context, user *model.FissionUser, opts ...Option) (player *Vs, err error) {
|
|
|
player = &Vs{}
|
|
|
|
|
|
err = player.Init(ctx, user, consts.IdVs, opts...)
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
err = player.initPlayer()
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
return
|
|
|
}
|
|
|
|
|
|
func (s *Vs) Exchange(item *model.RedeemMallItem) (err error) {
|
|
|
player := s.GetPlayer()
|
|
|
val, _ := jsonm.MarshalToString(mtype.VsLogVal{
|
|
|
PointsNum: item.CoinNum,
|
|
|
MallId: item.MallID,
|
|
|
MallItemId: item.ID,
|
|
|
})
|
|
|
|
|
|
log := withdefault.FissionVsLog(&model.FissionVsLog{
|
|
|
UserID: player.UserID,
|
|
|
CampaignID: player.CampaignID,
|
|
|
VsID: player.ID,
|
|
|
Type: mtype.FissionVsLogTypeExchange,
|
|
|
Source: mtype.FissionLogSourceExchange,
|
|
|
Val: val,
|
|
|
})
|
|
|
|
|
|
err = s._addLog(log)
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
vsM := s.GetDao().FissionV
|
|
|
_, err = vsM.WithContext(s.Ctx).Where(vsM.ID.Eq(player.ID)).UpdateSimple(vsM.CoinUse.Add(item.CoinNum))
|
|
|
if err != nil {
|
|
|
err = s.BE().MysqlError(err)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
return
|
|
|
}
|
|
|
|
|
|
func (s *Vs) FirstVisit() (rewards []*EventReward, err error) {
|
|
|
ok, rewards, err := s.eventOk(mtype.FissionCampaignEventMarkFirstVisit)
|
|
|
if err != nil || !ok {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
player := s.GetPlayer()
|
|
|
var chance int32
|
|
|
var point int32
|
|
|
var logs = make([]*model.FissionVsLog, 0, len(rewards))
|
|
|
for _, v := range rewards {
|
|
|
|
|
|
var val string
|
|
|
var t int8
|
|
|
|
|
|
switch v.PropMark {
|
|
|
case mtype.FissionCampaignRewardPropMarkPoint:
|
|
|
t = mtype.FissionVsLogTypeAddPoint
|
|
|
val, _ = jsonm.ToObjString(mtype.VsLogVal{
|
|
|
PointsNum: v.Chance,
|
|
|
})
|
|
|
|
|
|
point += v.Chance
|
|
|
case mtype.FissionCampaignRewardPropMarkReward:
|
|
|
t = mtype.FissionVsLogTypeReward
|
|
|
val, _ = jsonm.ToObjString(mtype.VsLogVal{
|
|
|
RewardId: v.Reward.Record.RewardID,
|
|
|
RecordId: v.Reward.Record.ID,
|
|
|
})
|
|
|
case mtype.FissionCampaignRewardPropMarkChance:
|
|
|
t = mtype.FissionVsLogTypeAddVote
|
|
|
val, _ = jsonm.ToObjString(mtype.VsLogVal{
|
|
|
Chance: v.Chance,
|
|
|
})
|
|
|
chance++
|
|
|
}
|
|
|
|
|
|
logs = append(logs, withdefault.FissionVsLog(&model.FissionVsLog{
|
|
|
UserID: player.UserID,
|
|
|
CampaignID: player.CampaignID,
|
|
|
VsID: player.ID,
|
|
|
Type: t,
|
|
|
Source: mtype.FissionLogSourceFirstVisit,
|
|
|
Val: val,
|
|
|
}))
|
|
|
}
|
|
|
|
|
|
err = s._addLog(logs...)
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
if chance > 0 || point > 0 {
|
|
|
m := s.GetDao().FissionV
|
|
|
_, err = m.WithContext(s.Ctx).Where(m.ID.Eq(player.ID)).UpdateSimple(m.Chance.Add(chance), m.CoinGet.Add(point))
|
|
|
if err != nil {
|
|
|
err = s.BE().MysqlError(err)
|
|
|
return
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return
|
|
|
}
|
|
|
|
|
|
func (s *Vs) TipReward() (err error) {
|
|
|
player := s.GetPlayer()
|
|
|
|
|
|
var ids []int64
|
|
|
m := s.GetDao().FissionVsVoteSettlement
|
|
|
err = m.WithContext(s.Ctx).Select(m.ID).Where(m.VsID.Eq(player.ID), m.TipAt.Eq(0)).Pluck(m.ID, &ids)
|
|
|
if err != nil {
|
|
|
err = s.BE().MysqlError(err)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
if len(ids) == 0 {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
_, err = m.WithContext(s.Ctx).Where(m.ID.In(ids...)).UpdateColumnSimple(m.TipAt.Value(time.Now().Unix()))
|
|
|
if err != nil {
|
|
|
err = s.BE().MysqlError(err)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
return
|
|
|
}
|
|
|
|
|
|
func (s *Vs) SettlementReward(settlement *model.FissionVsVoteSettlement) (rewards []*Reward, err error) {
|
|
|
player := s.GetPlayer()
|
|
|
|
|
|
if settlement.AcceptAt > 0 {
|
|
|
|
|
|
if settlement.TipAt > 0 {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
m := s.GetDao().FissionRewardRecord
|
|
|
records, err1 := m.WithContext(s.Ctx).Where(m.ID.In(settlement.GetRecordIds()...)).Find()
|
|
|
if err1 != nil {
|
|
|
err1 = s.BE().MysqlError(err1)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
var brMap = make(map[int64]struct{})
|
|
|
var brIds []int64
|
|
|
for _, record := range records {
|
|
|
if _, ok := brMap[record.BaseRewardID]; !ok && record.BaseRewardID > 0 {
|
|
|
brIds = append(brIds, record.BaseRewardID)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
preward, err1 := provider.NewRewards(s.Ctx, s.cpn.ProjectID, brIds...)
|
|
|
if err1 != nil {
|
|
|
err = err1
|
|
|
return
|
|
|
}
|
|
|
|
|
|
rewards = make([]*Reward, 0, len(records))
|
|
|
for _, record := range records {
|
|
|
|
|
|
switch record.PropMark {
|
|
|
case mtype.FissionCampaignRewardPropMarkReward:
|
|
|
info, _ := preward.InfoAutoLang(record.BaseRewardID, s.user.LangMark)
|
|
|
|
|
|
rewards = append(rewards, &Reward{
|
|
|
Id: record.RewardID,
|
|
|
PropMark: record.PropMark,
|
|
|
Title: info.Title,
|
|
|
Img: info.ImgUrl,
|
|
|
KvData: info.KvData,
|
|
|
ReceiveType: info.ReceiveType,
|
|
|
Contact: info.Contact,
|
|
|
OpenToUse: info.OpenToUse,
|
|
|
WebUrl: info.WebUrl,
|
|
|
AppParam: info.AppParam,
|
|
|
PcParam: info.PcParam,
|
|
|
PropNum: record.RewardNum,
|
|
|
RewardHashId: record.HashID,
|
|
|
})
|
|
|
|
|
|
case mtype.FissionCampaignRewardPropMarkPoint:
|
|
|
|
|
|
rewards = append(rewards, &Reward{
|
|
|
Id: record.RewardID,
|
|
|
PropMark: record.PropMark,
|
|
|
Title: record.Title,
|
|
|
Img: record.ImgURL,
|
|
|
PropNum: record.RewardNum,
|
|
|
RewardHashId: record.HashID,
|
|
|
})
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return
|
|
|
}
|
|
|
|
|
|
lc := app.NewRedisLock(s.Ctx, ckey.FissionVoteAcceptOnce(settlement.ID), lock.SetExpire(10*time.Second))
|
|
|
defer lc.Release()
|
|
|
if !lc.SoftLock() {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
m := s.GetDao().FissionVsVote
|
|
|
vote, err := m.WithContext(s.Ctx).Where(m.ID.Eq(settlement.VoteID)).Take()
|
|
|
if err = dbcheck.DbError(err); err != nil {
|
|
|
err = s.BE().MysqlError(err)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
if vote == nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
scheduleM := s.GetDao().FissionCampaignVsSchedule
|
|
|
schedule, err := scheduleM.WithContext(s.Ctx).Where(scheduleM.ID.Eq(vote.ScheduleID)).Take()
|
|
|
if err = dbcheck.DbError(err); err != nil {
|
|
|
err = s.BE().MysqlError(err)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
if schedule == nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
rewardM := s.GetDao().FissionCampaignReward
|
|
|
reward, err := rewardM.WithContext(s.Ctx).Where(rewardM.ID.Eq(schedule.RewardID)).Take()
|
|
|
if err = dbcheck.DbError(err); err != nil {
|
|
|
err = s.BE().MysqlError(err)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
if reward == nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
odds, _ := strconv.ParseFloat(settlement.Odds, 64)
|
|
|
if reward.PropMark == mtype.FissionCampaignTaskPropMarkPoint && odds != 1 {
|
|
|
rewardNum := int32(math.Floor(float64(reward.RewardNum) * odds))
|
|
|
reward.RewardNum = rewardNum
|
|
|
}
|
|
|
|
|
|
var num = vote.FreeVote + vote.PointVote
|
|
|
var accepts = make([]*model.FissionCampaignReward, 0)
|
|
|
for i := 0; i < int(num); i++ {
|
|
|
accepts = append(accepts, reward)
|
|
|
}
|
|
|
|
|
|
res, _, err := award.NewAwardReward(s.Ctx, s.GetDao(), s.cpn.ProjectID, s.user).DeductStockBatch(accepts, true)
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
var coinGet int32
|
|
|
var recordIds []int64
|
|
|
rewards = make([]*Reward, 0, len(res))
|
|
|
for _, v := range res {
|
|
|
record := v.Record
|
|
|
info := v.Info
|
|
|
rewards = append(rewards, &Reward{
|
|
|
Id: record.RewardID,
|
|
|
PropMark: record.PropMark,
|
|
|
Title: info.Title,
|
|
|
Img: info.ImgUrl,
|
|
|
KvData: info.KvData,
|
|
|
ReceiveType: info.ReceiveType,
|
|
|
Contact: info.Contact,
|
|
|
OpenToUse: info.OpenToUse,
|
|
|
WebUrl: info.WebUrl,
|
|
|
AppParam: info.AppParam,
|
|
|
PcParam: info.PcParam,
|
|
|
PropNum: record.RewardNum,
|
|
|
RewardHashId: record.HashID,
|
|
|
})
|
|
|
recordIds = append(recordIds, record.ID)
|
|
|
|
|
|
if s.GetConf().ClaimType != mtype.FissionCampaignVsClaimTypeAuto {
|
|
|
s.appTrack().VsAcceptReward(record.CreatedAt, schedule.ID, record.RewardID, record.ID)
|
|
|
}
|
|
|
|
|
|
if record.PropMark == mtype.FissionCampaignRewardPropMarkPoint {
|
|
|
coinGet += record.RewardNum
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
idStr, _ := jsonm.ToSliceString(recordIds)
|
|
|
sltM := s.GetDao().FissionVsVoteSettlement
|
|
|
_, err = sltM.WithContext(s.Ctx).Where(sltM.ID.Eq(settlement.ID)).UpdateColumnSimple(
|
|
|
sltM.AcceptAt.Value(time.Now().Unix()),
|
|
|
sltM.RecordIds.Value(idStr),
|
|
|
)
|
|
|
if err != nil {
|
|
|
err = s.BE().MysqlError(err)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
if coinGet > 0 {
|
|
|
playerM := s.GetDao().FissionV
|
|
|
_, err = playerM.WithContext(s.Ctx).Where(playerM.ID.Eq(player.ID)).UpdateColumnSimple(playerM.CoinGet.Add(coinGet))
|
|
|
if err != nil {
|
|
|
err = s.BE().MysqlError(err)
|
|
|
return
|
|
|
}
|
|
|
}
|
|
|
|
|
|
val, _ := jsonm.MarshalToString(mtype.VsLogVal{
|
|
|
RewardId: reward.ID,
|
|
|
ScheduleId: settlement.ScheduleID,
|
|
|
Odds: settlement.Odds,
|
|
|
Num: num,
|
|
|
})
|
|
|
|
|
|
log := withdefault.FissionVsLog(&model.FissionVsLog{
|
|
|
UserID: player.UserID,
|
|
|
CampaignID: player.CampaignID,
|
|
|
VsID: player.ID,
|
|
|
Type: mtype.FissionVsLogTypeSettlement,
|
|
|
Source: mtype.FissionLogSourceSettlement,
|
|
|
Val: val,
|
|
|
})
|
|
|
|
|
|
err = s._addLog(log)
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
return
|
|
|
}
|
|
|
|
|
|
// ReceiveReward 手动领取奖励
|
|
|
func (s *Vs) 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 *Vs) FinishTask(tasks ...*model.FissionCampaignTask) (err error) {
|
|
|
_, err = s.taskFinish(tasks, true)
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
return
|
|
|
}
|
|
|
|
|
|
// 完成任务
|
|
|
func (s *Vs) taskFinish(tasks []*model.FissionCampaignTask, checkManual bool) (chance int32, err error) {
|
|
|
player := s.GetPlayer()
|
|
|
var coinGet int32
|
|
|
var logs []*model.FissionVsLog
|
|
|
for _, task := range tasks {
|
|
|
if checkManual && task.AwardMode == mtype.FissionCampaignTaskAwardModeManual {
|
|
|
continue
|
|
|
}
|
|
|
|
|
|
var val string
|
|
|
var t int8
|
|
|
switch task.PropMark {
|
|
|
case mtype.FissionCampaignTaskPropMarkChance:
|
|
|
chance += task.Chance
|
|
|
val, _ = jsonm.MarshalToString(mtype.VsLogVal{
|
|
|
TaskId: task.ID,
|
|
|
Chance: task.Chance,
|
|
|
})
|
|
|
t = mtype.FissionVsLogTypeAddVote
|
|
|
case mtype.FissionCampaignTaskPropMarkPoint:
|
|
|
val, _ = jsonm.MarshalToString(mtype.VsLogVal{
|
|
|
TaskId: task.ID,
|
|
|
PointsNum: task.Chance,
|
|
|
})
|
|
|
t = mtype.FissionVsLogTypeAddPoint
|
|
|
coinGet += task.Chance
|
|
|
case mtype.FissionCampaignTaskPropMarkReward:
|
|
|
val, _ = jsonm.MarshalToString(mtype.VsLogVal{
|
|
|
TaskId: task.ID,
|
|
|
RewardId: task.RewardID,
|
|
|
})
|
|
|
t = mtype.FissionVsLogTypeReward
|
|
|
}
|
|
|
|
|
|
log := withdefault.FissionVsLog(&model.FissionVsLog{
|
|
|
UserID: player.UserID,
|
|
|
CampaignID: player.CampaignID,
|
|
|
VsID: player.ID,
|
|
|
Type: t,
|
|
|
Source: "",
|
|
|
Val: 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 chance > 0 || coinGet > 0 {
|
|
|
m := s.GetDao().FissionV
|
|
|
_, err = m.WithContext(s.Ctx).Where(m.ID.Eq(player.ID)).UpdateSimple(m.Chance.Add(chance), m.CoinGet.Add(coinGet))
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
}
|
|
|
|
|
|
err = s._addLog(logs...)
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
return
|
|
|
}
|
|
|
|
|
|
func (s *Vs) Vote(scheduleId, teamId int64) (status int32, err error) {
|
|
|
s.Tran()
|
|
|
defer func() {
|
|
|
s.TranCommit(err)
|
|
|
}()
|
|
|
player, conf := s.GetPlayer(), s.GetConf()
|
|
|
|
|
|
scheduleM := s.GetDao().FissionCampaignVsSchedule
|
|
|
schedule, err := scheduleM.WithContext(s.Ctx).Where(scheduleM.ID.Eq(scheduleId)).Take()
|
|
|
if err != nil {
|
|
|
err = s.BE().MysqlError(err)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
if schedule.GetStatus() != mtype.FissionCampaignVsScheduleStatusVote {
|
|
|
return voteEnd, nil
|
|
|
}
|
|
|
|
|
|
var winType int8 = mtype.FissionCampaignVsScheduleWinTypeWin
|
|
|
if teamId == 0 {
|
|
|
if !verify.InArray[string](mtype.FissionCampaignVsScheduleOtherVoteDraw, schedule.GetOtherVote()...) {
|
|
|
return voteFail, nil
|
|
|
}
|
|
|
|
|
|
winType = mtype.FissionCampaignVsScheduleWinTypeDraw
|
|
|
}
|
|
|
|
|
|
m := s.GetDao().FissionVsVote
|
|
|
vote, err := m.WithContext(s.Ctx).Where(m.VsID.Eq(player.ID), m.ScheduleID.Eq(scheduleId)).Take()
|
|
|
if err = dbcheck.DbError(err); err != nil {
|
|
|
err = s.BE().MysqlError(err)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
if vote == nil {
|
|
|
vote = withdefault.FissionVsVote(&model.FissionVsVote{
|
|
|
CampaignID: player.CampaignID,
|
|
|
UserID: player.UserID,
|
|
|
VsID: player.ID,
|
|
|
ScheduleID: scheduleId,
|
|
|
WinType: winType,
|
|
|
WinTeamID: teamId,
|
|
|
IsWin: 0,
|
|
|
})
|
|
|
|
|
|
err = m.WithContext(s.Ctx).Create(vote)
|
|
|
if err != nil {
|
|
|
err = s.BE().MysqlError(err)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
defer func() {
|
|
|
if status != voteOk {
|
|
|
_, _ = m.WithContext(s.Ctx).Delete(vote)
|
|
|
}
|
|
|
}()
|
|
|
}
|
|
|
|
|
|
if vote.WinType != winType || vote.WinTeamID != teamId || (teamId > 0 && !verify.InArray[int64](teamId, schedule.GetVsTeamIds()...)) {
|
|
|
return voteNotSameTeam, nil
|
|
|
}
|
|
|
|
|
|
if vote.FreeVote+vote.PointVote >= conf.EachLimitNum {
|
|
|
return voteLimit, nil
|
|
|
}
|
|
|
|
|
|
if player.Chance > 0 {
|
|
|
val, _ := jsonm.MarshalToString(mtype.VsLogVal{
|
|
|
Chance: 1,
|
|
|
ScheduleId: scheduleId,
|
|
|
WinType: winType,
|
|
|
WinTeamId: teamId,
|
|
|
})
|
|
|
|
|
|
log := withdefault.FissionVsLog(&model.FissionVsLog{
|
|
|
UserID: player.UserID,
|
|
|
CampaignID: player.CampaignID,
|
|
|
VsID: player.ID,
|
|
|
Type: mtype.FissionVsLogTypeVote,
|
|
|
Source: mtype.FissionLogSourceVote,
|
|
|
Val: val,
|
|
|
})
|
|
|
|
|
|
err = s._addLog(log)
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
vsM := s.GetDao().FissionV
|
|
|
_, err = vsM.WithContext(s.Ctx).Where(vsM.ID.Eq(player.ID)).UpdateSimple(vsM.Chance.Sub(1))
|
|
|
if err != nil {
|
|
|
err = s.BE().MysqlError(err)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
_, err = m.WithContext(s.Ctx).Where(m.ID.Eq(vote.ID)).UpdateColumnSimple(m.FreeVote.Add(1))
|
|
|
if err != nil {
|
|
|
err = s.BE().MysqlError(err)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
err = s._voteAdd()
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
s.appTrack().VsVote(time.Now().Unix(), scheduleId, int32(winType), teamId)
|
|
|
|
|
|
return voteOk, nil
|
|
|
}
|
|
|
|
|
|
if conf.OpenPoint == mtype.No {
|
|
|
return voteLack, nil
|
|
|
}
|
|
|
|
|
|
pu, err := projectuser.NewProjectUser(s.Ctx,
|
|
|
projectuser.WithInit(s.cpn.ProjectID, s.user.SubUserID),
|
|
|
projectuser.WithDao(s.GetDao()),
|
|
|
)
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
ok, err := pu.Deduct(mtype.ProjectUserCoinUseSourceCampaign, mtype.ProjectUserCoinDerVote, player.CampaignID, conf.PointsNum)
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
if !ok {
|
|
|
s.Rollback("项目用户积分不足")
|
|
|
return voteLack, nil
|
|
|
}
|
|
|
|
|
|
val, _ := jsonm.MarshalToString(mtype.VsLogVal{
|
|
|
Chance: 1,
|
|
|
ScheduleId: scheduleId,
|
|
|
WinType: winType,
|
|
|
WinTeamId: teamId,
|
|
|
PointsNum: conf.PointsNum,
|
|
|
})
|
|
|
|
|
|
log := withdefault.FissionVsLog(&model.FissionVsLog{
|
|
|
UserID: player.UserID,
|
|
|
CampaignID: player.CampaignID,
|
|
|
VsID: player.ID,
|
|
|
Type: mtype.FissionVsLogTypeVote,
|
|
|
Source: mtype.FissionLogSourceVote,
|
|
|
Val: val,
|
|
|
})
|
|
|
|
|
|
err = s._addLog(log)
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
vsM := s.GetDao().FissionV
|
|
|
_, err = vsM.WithContext(s.Ctx).Where(vsM.ID.Eq(player.ID)).UpdateSimple(vsM.CoinUse.Add(conf.PointsNum))
|
|
|
if err != nil {
|
|
|
err = s.BE().MysqlError(err)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
_, err = m.WithContext(s.Ctx).Where(m.ID.Eq(vote.ID)).UpdateColumnSimple(m.PointVote.Add(1))
|
|
|
if err != nil {
|
|
|
err = s.BE().MysqlError(err)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
err = s._voteAdd()
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
s.appTrack().PointsUse(time.Now().Unix(), conf.PointsNum)
|
|
|
s.appTrack().VsVote(time.Now().Unix(), scheduleId, int32(winType), teamId)
|
|
|
|
|
|
return voteOk, nil
|
|
|
}
|
|
|
|
|
|
type Schedule struct {
|
|
|
Id int64
|
|
|
Desc string
|
|
|
VsImg string
|
|
|
VsDate string
|
|
|
VsTz int32
|
|
|
VoteCountdown int64
|
|
|
Status int32
|
|
|
OpenOdds int32
|
|
|
OddsLeft string
|
|
|
OddsRight string
|
|
|
OddsDraw string
|
|
|
WinType int32
|
|
|
WinTeamId int64
|
|
|
Scores []*Score
|
|
|
OtherVote []string
|
|
|
Teams []*Team
|
|
|
UserVote *UserVote
|
|
|
Reward *Reward
|
|
|
Votes []*Vote
|
|
|
}
|
|
|
|
|
|
type Score struct {
|
|
|
TeamId int64
|
|
|
Score string
|
|
|
}
|
|
|
|
|
|
type UserVote struct {
|
|
|
UserWinType int32
|
|
|
UserWinTeamId int64
|
|
|
IsWin bool
|
|
|
VoteNum int32
|
|
|
}
|
|
|
|
|
|
type Team struct {
|
|
|
Id int64
|
|
|
Name string
|
|
|
LogoImg string
|
|
|
Score string
|
|
|
}
|
|
|
|
|
|
type Reward struct {
|
|
|
Id int64
|
|
|
PropMark string
|
|
|
Title string
|
|
|
Img string
|
|
|
KvData []*mtype.RewardKV
|
|
|
ReceiveType int32
|
|
|
Contact string //联系方式
|
|
|
OpenToUse int32 //开启去使用(0-否,1-是)
|
|
|
WebUrl string //Web端的跳转地址
|
|
|
AppParam string //App端的跳转参数
|
|
|
PcParam string //pc端的跳转参数
|
|
|
PropNum int32
|
|
|
RewardHashId string //领取的用户奖品hash_id
|
|
|
}
|
|
|
|
|
|
type Vote struct {
|
|
|
WinType int32 `json:"win_type"`
|
|
|
WinTeamId int64 `json:"win_team_id"`
|
|
|
Num int64 `json:"num"`
|
|
|
}
|
|
|
|
|
|
func (s *Vs) Schedules(tabType int32) (list []*Schedule, err error) {
|
|
|
player, conf := s.GetPlayer(), s.GetConf()
|
|
|
|
|
|
teamM := s.GetDao().FissionCampaignVsTeam
|
|
|
teams, err := teamM.WithContext(s.Ctx).Where(teamM.CampaignID.Eq(s.user.CampaignID)).Find()
|
|
|
if err != nil {
|
|
|
err = s.BE().MysqlError(err)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
var teamMap = make(map[int64]*model.FissionCampaignVsTeam, len(teams))
|
|
|
for _, v := range teams {
|
|
|
teamMap[v.ID] = v
|
|
|
}
|
|
|
|
|
|
voteM := s.GetDao().FissionVsVote
|
|
|
votes, err := voteM.WithContext(s.Ctx).Where(
|
|
|
voteM.CampaignID.Eq(s.user.CampaignID),
|
|
|
voteM.VsID.Eq(player.ID),
|
|
|
).Find()
|
|
|
if err != nil {
|
|
|
err = s.BE().MysqlError(err)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
var voteMap = make(map[int64]*model.FissionVsVote, len(votes))
|
|
|
for _, v := range votes {
|
|
|
voteMap[v.ScheduleID] = v
|
|
|
}
|
|
|
|
|
|
scheduleM := s.GetDao().FissionCampaignVsSchedule
|
|
|
schedules, err := scheduleM.WithContext(s.Ctx).Where(
|
|
|
scheduleM.CampaignID.Eq(player.CampaignID),
|
|
|
scheduleM.VsAt.Gt(0),
|
|
|
).Order(scheduleM.VsAt.Asc()).Find()
|
|
|
if err != nil {
|
|
|
err = s.BE().MysqlError(err)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
var rewardIds []int64
|
|
|
for _, v := range schedules {
|
|
|
rewardIds = append(rewardIds, v.RewardID)
|
|
|
}
|
|
|
|
|
|
rewardM := s.GetDao().FissionCampaignReward
|
|
|
rewards, err := rewardM.WithContext(s.Ctx).Where(rewardM.ID.In(rewardIds...)).Find()
|
|
|
if err != nil {
|
|
|
err = s.BE().MysqlError(err)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
var hasPoint bool
|
|
|
var brdIds []int64
|
|
|
var brdMap = make(map[int64]struct{})
|
|
|
for _, v := range rewards {
|
|
|
if _, ok := brdMap[v.RewardID]; !ok && v.RewardID > 0 {
|
|
|
brdIds = append(brdIds, v.RewardID)
|
|
|
}
|
|
|
|
|
|
if v.PropMark == mtype.FissionCampaignRewardPropMarkPoint {
|
|
|
hasPoint = true
|
|
|
}
|
|
|
}
|
|
|
|
|
|
preward, err := provider.NewRewards(s.Ctx, s.cpn.ProjectID, brdIds...)
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
var title, imgUrl string
|
|
|
if hasPoint {
|
|
|
title, imgUrl, _, err = cmm.NewCMM(s.Ctx, s.GetDao()).GetCoinInfo(s.cpn.ProjectID, s.user.LangMark)
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
}
|
|
|
|
|
|
var rewardMap = make(map[int64]*Reward, len(rewards))
|
|
|
for _, reward := range rewards {
|
|
|
one := &Reward{
|
|
|
Id: reward.ID,
|
|
|
PropMark: reward.PropMark,
|
|
|
Title: title,
|
|
|
Img: imgUrl,
|
|
|
KvData: nil,
|
|
|
ReceiveType: 0,
|
|
|
Contact: "",
|
|
|
OpenToUse: 0,
|
|
|
WebUrl: "",
|
|
|
AppParam: "",
|
|
|
PcParam: "",
|
|
|
PropNum: reward.RewardNum,
|
|
|
}
|
|
|
|
|
|
if reward.PropMark == mtype.FissionCampaignRewardPropMarkReward {
|
|
|
info, _ := preward.InfoAutoLang(reward.RewardID, s.user.LangMark)
|
|
|
one.Title = info.Title
|
|
|
one.Img = info.ImgUrl
|
|
|
one.KvData = info.KvData
|
|
|
one.ReceiveType = info.ReceiveType
|
|
|
one.Contact = info.Contact
|
|
|
one.OpenToUse = info.OpenToUse
|
|
|
one.WebUrl = info.WebUrl
|
|
|
one.AppParam = info.AppParam
|
|
|
one.PcParam = info.PcParam
|
|
|
}
|
|
|
|
|
|
rewardMap[reward.ID] = one
|
|
|
}
|
|
|
|
|
|
var scheduleLang = make(map[int64]*mtype.VsSchedulePkTeam)
|
|
|
if verify.InArray[string](s.user.LangMark, s.cpn.GetLangMarks()[1:]...) {
|
|
|
var lang *model.FissionCampaignLang
|
|
|
lang, err = cache.NewCampaignLang(s.Ctx).FindByCampaignId(player.CampaignID, s.user.LangMark)
|
|
|
if err != nil {
|
|
|
err = s.BE().CacheError(err)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
for _, v := range lang.GetVs() {
|
|
|
for _, pk := range v.PkTeams {
|
|
|
scheduleLang[pk.Id] = pk
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
var fn = func(v *model.FissionCampaignVsSchedule) {
|
|
|
|
|
|
slt := v.GetSettlement()
|
|
|
scoreMap := make(map[int64]string, len(slt.Scores))
|
|
|
|
|
|
for _, v := range slt.Scores {
|
|
|
scoreMap[v.TeamId] = v.Score
|
|
|
}
|
|
|
|
|
|
one := &Schedule{
|
|
|
Id: v.ID,
|
|
|
Desc: v.Desc,
|
|
|
VsImg: v.VsImg,
|
|
|
VsDate: timez.GMTTime(conf.VsTz, v.VsAt).Format(timez.PointYmdHi),
|
|
|
VsTz: conf.VsTz,
|
|
|
VoteCountdown: v.VoteEnd - time.Now().Unix(),
|
|
|
Status: v.GetStatus(),
|
|
|
OpenOdds: int32(v.OpenOdds),
|
|
|
OddsLeft: v.OddsLeft,
|
|
|
OddsRight: v.OddsRight,
|
|
|
OddsDraw: v.OddsDraw,
|
|
|
WinType: slt.WinType,
|
|
|
WinTeamId: slt.WinTeamId,
|
|
|
Scores: make([]*Score, 0, len(slt.Scores)),
|
|
|
OtherVote: v.GetOtherVote(),
|
|
|
Teams: make([]*Team, 0, len(v.GetVsTeamIds())),
|
|
|
UserVote: nil,
|
|
|
Reward: rewardMap[v.RewardID],
|
|
|
Votes: nil,
|
|
|
}
|
|
|
|
|
|
for _, v := range slt.Scores {
|
|
|
one.Scores = append(one.Scores, &Score{
|
|
|
TeamId: v.TeamId,
|
|
|
Score: v.Score,
|
|
|
})
|
|
|
}
|
|
|
|
|
|
if vote, ok := voteMap[v.ID]; ok {
|
|
|
one.UserVote = &UserVote{
|
|
|
UserWinType: int32(vote.WinType),
|
|
|
UserWinTeamId: vote.WinTeamID,
|
|
|
IsWin: vote.IsWin == mtype.Yes,
|
|
|
VoteNum: vote.FreeVote + vote.PointVote,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
for _, teamId := range v.GetVsTeamIds() {
|
|
|
two := &Team{
|
|
|
Id: teamId,
|
|
|
}
|
|
|
|
|
|
if team, ok := teamMap[teamId]; ok {
|
|
|
two.Name = team.Name
|
|
|
two.LogoImg = team.LogoImg
|
|
|
two.Score = scoreMap[teamId]
|
|
|
}
|
|
|
|
|
|
one.Teams = append(one.Teams, two)
|
|
|
}
|
|
|
|
|
|
if lang, ok := scheduleLang[v.ID]; ok && lang != nil {
|
|
|
one.Desc = lang.Desc
|
|
|
one.VsImg = lang.VsImg
|
|
|
|
|
|
for i, v := range lang.Teams {
|
|
|
if v.Id > 0 {
|
|
|
one.Teams[i].Name = v.Name
|
|
|
one.Teams[i].LogoImg = v.LogoImg
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
one.Votes, err = s._voteNum(v.ID)
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
list = append(list, one)
|
|
|
}
|
|
|
|
|
|
for _, v := range schedules {
|
|
|
if tabType == 1 && !verify.InArray[int32](v.GetStatus(), mtype.FissionCampaignVsScheduleStatusVote, mtype.FissionCampaignVsScheduleStatusRunning) {
|
|
|
continue
|
|
|
}
|
|
|
|
|
|
_, ok := voteMap[v.ID]
|
|
|
if tabType == 3 && !ok {
|
|
|
continue
|
|
|
}
|
|
|
|
|
|
fn(v)
|
|
|
}
|
|
|
|
|
|
if len(list) > 0 || tabType != 1 {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
l := len(schedules)
|
|
|
for i := l; i > 0; i-- {
|
|
|
one := schedules[i-1]
|
|
|
if one.IsSettlement == mtype.Yes {
|
|
|
fn(one)
|
|
|
break
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return
|
|
|
}
|
|
|
|
|
|
// SetInit 获得初始次数
|
|
|
func (s *Vs) 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().FissionV
|
|
|
_, 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
|
|
|
}
|
|
|
|
|
|
val, _ := jsonm.MarshalToString(mtype.VsLogVal{
|
|
|
Chance: conf.InitChance,
|
|
|
})
|
|
|
|
|
|
log := withdefault.FissionVsLog(&model.FissionVsLog{
|
|
|
UserID: player.UserID,
|
|
|
CampaignID: player.CampaignID,
|
|
|
VsID: player.ID,
|
|
|
Type: mtype.FissionVsLogTypeAddVote,
|
|
|
Source: mtype.FissionLogSourceInit,
|
|
|
Val: val,
|
|
|
})
|
|
|
|
|
|
err = s._addLog(log)
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
s.player.Chance += conf.InitChance
|
|
|
|
|
|
return
|
|
|
}
|
|
|
|
|
|
// GetConf 获取玩法配置
|
|
|
func (s *Vs) GetConf() *model.FissionCampaignV {
|
|
|
if s.conf == nil {
|
|
|
s.conf, _ = cache.NewCampaignVs(s.Ctx).FindByCampaignId(s.user.CampaignID)
|
|
|
}
|
|
|
|
|
|
return s.conf
|
|
|
}
|
|
|
|
|
|
// GetPlayer 获取玩家基础数据
|
|
|
func (s *Vs) GetPlayer() *model.FissionV {
|
|
|
return s.player
|
|
|
}
|
|
|
|
|
|
// 玩家
|
|
|
func (s *Vs) 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)
|
|
|
}()
|
|
|
|
|
|
if player != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
player, err = s.firstOrCreate()
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
return
|
|
|
}
|
|
|
|
|
|
// 创建玩家基础数据
|
|
|
func (s *Vs) firstOrCreate() (player *model.FissionV, 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 *Vs) _dbFirst() (*model.FissionV, error) {
|
|
|
playerM := dao.FissionV
|
|
|
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 *Vs) createPlayer() (player *model.FissionV, err error) {
|
|
|
playerM := dao.FissionV
|
|
|
player = withdefault.FissionVs(&model.FissionV{
|
|
|
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 *Vs) _addLog(logs ...*model.FissionVsLog) (err error) {
|
|
|
err = s.GetDao().FissionVsLog.WithContext(s.Ctx).Create(logs...)
|
|
|
if err != nil {
|
|
|
err = s.BE().MysqlError(err)
|
|
|
return
|
|
|
}
|
|
|
return
|
|
|
}
|
|
|
|
|
|
func (s *Vs) _voteNum(scheduleId int64) (votes []*Vote, err error) {
|
|
|
m := s.GetDao().FissionVsVote
|
|
|
|
|
|
voteNumField := field.NewUnsafeFieldRaw("free_vote + point_vote")
|
|
|
|
|
|
err = m.WithContext(s.Ctx).
|
|
|
Select(m.WinType, m.WinTeamID, voteNumField.Sum().As("num")).
|
|
|
Where(m.ScheduleID.Eq(scheduleId)).
|
|
|
Group(m.WinType, m.WinTeamID).
|
|
|
Scan(&votes)
|
|
|
if err != nil {
|
|
|
err = s.BE().MysqlError(err)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
return
|
|
|
}
|
|
|
|
|
|
func (s *Vs) _voteAdd() (err error) {
|
|
|
m := s.GetDao().FissionV
|
|
|
_, err = m.WithContext(s.Ctx).Where(m.ID.Eq(s.GetPlayer().ID)).UpdateSimple(m.VoteNum.Add(1))
|
|
|
if err != nil {
|
|
|
err = s.BE().MysqlError(err)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
s.player.VoteNum++
|
|
|
|
|
|
return
|
|
|
}
|