|
|
package campaignuser
|
|
|
|
|
|
import (
|
|
|
"joybuywork/internal/app"
|
|
|
"joybuywork/internal/consts"
|
|
|
"joybuywork/internal/consts/ckey"
|
|
|
"joybuywork/internal/repository/cache"
|
|
|
"joybuywork/internal/repository/dbcheck"
|
|
|
"joybuywork/internal/repository/finder"
|
|
|
"joybuywork/internal/repository/model"
|
|
|
"joybuywork/internal/repository/mtype"
|
|
|
"joybuywork/internal/service/cmm"
|
|
|
"joybuywork/internal/service/provider"
|
|
|
"joybuywork/internal/utils"
|
|
|
"joybuywork/internal/utils/lockdo"
|
|
|
"joybuywork/internal/utils/logic"
|
|
|
"joybuywork/internal/utils/timez"
|
|
|
"joybuywork/internal/utils/verify"
|
|
|
pb "joybuywork/proto/go_proto/w_campaign_user"
|
|
|
"joybuywork/proto/go_proto/workerr"
|
|
|
"strings"
|
|
|
"time"
|
|
|
|
|
|
deventpb "gits.branchcn.com/backend/deeplink/proto/go_proto/devent"
|
|
|
)
|
|
|
|
|
|
type Task struct {
|
|
|
logic.Logic
|
|
|
Req *pb.TaskReq
|
|
|
Res *pb.TaskRes
|
|
|
|
|
|
cpnControl *provider.CampaignTZ
|
|
|
|
|
|
lvLimitMap map[int64][]string
|
|
|
}
|
|
|
|
|
|
func (s *Task) Run() error {
|
|
|
return logic.Run(s)
|
|
|
}
|
|
|
|
|
|
func (s *Task) Exec() (err error) {
|
|
|
user, cpn, err := s.user()
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
return s.task(cpn, user)
|
|
|
}
|
|
|
|
|
|
// 用户信息
|
|
|
func (s *Task) 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
|
|
|
}
|
|
|
|
|
|
user, err = finder.FissionUser(s.Ctx, cpn.ID, s.Req.GetUserId())
|
|
|
if err != nil {
|
|
|
err = s.BE().CacheError(err)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
if user == nil {
|
|
|
err = workerr.NotFound("not found user")
|
|
|
return
|
|
|
}
|
|
|
|
|
|
s.cpnControl = provider.NewCampaignTZ(s.Ctx, cpn, user.LangMark)
|
|
|
|
|
|
return
|
|
|
}
|
|
|
|
|
|
func (s *Task) _newTask(cpn *model.FissionCampaign, user *model.FissionUser) (err error) {
|
|
|
m := s.GetDao().FissionCampaignTicket
|
|
|
list, err := m.WithContext(s.Ctx).Where(m.CampaignID.Eq(cpn.ID)).Find()
|
|
|
if err != nil {
|
|
|
err = s.BE().MysqlError(err)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
taskM := s.GetDao().FissionCampaignTask
|
|
|
tasks, err := taskM.WithContext(s.Ctx).Where(
|
|
|
taskM.CampaignID.Eq(cpn.ID),
|
|
|
taskM.IsDel.Eq(mtype.No),
|
|
|
).Find()
|
|
|
if err != nil {
|
|
|
err = s.BE().MysqlError(err)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
var taskMap = make(map[string]*model.FissionCampaignTask, len(tasks))
|
|
|
for _, task := range tasks {
|
|
|
taskMap[task.TaskMark] = task
|
|
|
}
|
|
|
|
|
|
for _, v := range list {
|
|
|
switch v.Mark {
|
|
|
case mtype.FissionCampaignTicketCustom:
|
|
|
err = s._custom(user, cpn, v, taskMap)
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
case mtype.FissionCampaignTicketFixed:
|
|
|
err = s._fixed(v, taskMap)
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return
|
|
|
}
|
|
|
|
|
|
func (s *Task) _custom(user *model.FissionUser, cpn *model.FissionCampaign, ticket *model.FissionCampaignTicket, taskMap map[string]*model.FissionCampaignTask) (err error) {
|
|
|
if ticket.Open == mtype.No {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
m := s.GetDao().FissionCampaignCond
|
|
|
conds, err := m.WithContext(s.Ctx).Where(
|
|
|
m.CampaignID.Eq(cpn.ID),
|
|
|
m.IsDel.Eq(mtype.No),
|
|
|
m.RewardID.Eq(0),
|
|
|
).Order(m.Sort.Desc(), m.ID).Find()
|
|
|
if err != nil {
|
|
|
err = s.BE().MysqlError(err)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
condM := s.GetDao().FissionUserCond
|
|
|
list, err := condM.WithContext(s.Ctx).Where(condM.UserID.Eq(user.ID)).Find()
|
|
|
if err != nil {
|
|
|
return s.BE().MysqlError(err)
|
|
|
}
|
|
|
|
|
|
var userCondMap = make(map[int64]*model.FissionUserCond)
|
|
|
for _, v := range list {
|
|
|
userCondMap[v.CondID] = v
|
|
|
}
|
|
|
|
|
|
// 用户当前语言是配置的语言
|
|
|
var condLangMap = make(map[int64]*mtype.LangCond)
|
|
|
if verify.InArray[string](user.LangMark, cpn.GetLangMarks()...) {
|
|
|
lang, err1 := cache.NewCampaignLang(s.Ctx).FindByCampaignId(user.CampaignID, user.LangMark)
|
|
|
if err1 != nil {
|
|
|
err = s.BE().CacheError(err1)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
if lang != nil {
|
|
|
for _, v := range lang.GetConds() {
|
|
|
condLangMap[v.CondId] = v
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
var doExp = make(map[int64]struct{})
|
|
|
var dayExp, weekExp []*model.FissionCampaignTask
|
|
|
var dayLimitTaskIds []int64 // 有每日上限的任务
|
|
|
var weekLimitTask []*model.FissionCampaignTask // 有每周上限的任务
|
|
|
var taskIds = make([]int64, 0, len(taskMap))
|
|
|
var levelLimit = make(map[int64][]int64)
|
|
|
var rewardIds []int64
|
|
|
var receiveIds []int64
|
|
|
for _, v := range taskMap {
|
|
|
taskIds = append(taskIds, v.ID)
|
|
|
if v.DayLimit > 0 {
|
|
|
dayLimitTaskIds = append(dayLimitTaskIds, v.ID)
|
|
|
if _, ok := doExp[v.ID]; !ok {
|
|
|
dayExp = append(dayExp, v)
|
|
|
doExp[v.ID] = struct{}{}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if v.WeekLimit > 0 { // 这个一定要放在dayLimit 后面,因为doExp的顺序是 day > week
|
|
|
weekLimitTask = append(weekLimitTask, v)
|
|
|
if _, ok := doExp[v.ID]; !ok {
|
|
|
weekExp = append(weekExp, v)
|
|
|
doExp[v.ID] = struct{}{}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if v.LevelLimit != "" {
|
|
|
levelLimit[v.ID] = v.GetLevelLimit()
|
|
|
}
|
|
|
|
|
|
if v.RewardID > 0 {
|
|
|
rewardIds = append(rewardIds, v.RewardID)
|
|
|
}
|
|
|
|
|
|
if v.AwardMode == mtype.FissionCampaignTaskAwardModeManual {
|
|
|
receiveIds = append(receiveIds, v.ID)
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
// 完成任务获得的总次数
|
|
|
var sumNum struct {
|
|
|
Num int32
|
|
|
}
|
|
|
|
|
|
taskM := s.GetDao().FissionUserTaskRecord
|
|
|
err = taskM.WithContext(s.Ctx).
|
|
|
Select(taskM.Chance.Sum().As("num")).
|
|
|
Where(
|
|
|
taskM.UserID.Eq(user.ID),
|
|
|
taskM.TaskID.In(taskIds...),
|
|
|
taskM.LimitProp.Eq(mtype.No),
|
|
|
).Scan(&sumNum)
|
|
|
if err != nil {
|
|
|
err = s.BE().MysqlError(err)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
// 全部任务完成的任务完成次数
|
|
|
btAllFinish, err := s._btAllFinish(user, ticket, taskMap)
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
// 当天任务完成次数
|
|
|
taskDayCount, err := s._taskDayCount(user, dayLimitTaskIds)
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
// 周任务完成次数
|
|
|
taskWeekCount, err := s._taskWeekCount(user, weekLimitTask)
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
// 任务过期重置
|
|
|
err = s._condExp(ticket.BothType, dayExp, weekExp, userCondMap)
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
// 任务限制
|
|
|
err = s._levelLimit(levelLimit)
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
// 有前置任务
|
|
|
preCond, err := s._preCond(user)
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
// 是否有领奖任务
|
|
|
receiveMap, err := s._receive(user, receiveIds)
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
// 奖品
|
|
|
rewardMap, err := s._reward(cpn.ProjectID, user.LangMark, rewardIds)
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
var projectId int64
|
|
|
var condExtra = make(map[string]*deventpb.GetCustomEventListRes_Info)
|
|
|
var events []string
|
|
|
for _, v := range conds {
|
|
|
events = append(events, v.Event)
|
|
|
projectId = v.ProjectID
|
|
|
}
|
|
|
|
|
|
if len(events) > 0 {
|
|
|
res, _ := app.NewDeepLinkEvent().GetCustomEventList(s.Ctx, &deventpb.GetCustomEventListReq{
|
|
|
ProjectId: projectId,
|
|
|
EventKeyList: events,
|
|
|
LangMark: user.LangMark,
|
|
|
})
|
|
|
for _, v := range res.GetList() {
|
|
|
condExtra[v.GetEventKey()] = v
|
|
|
}
|
|
|
}
|
|
|
|
|
|
s.Res.Custom = &pb.TaskRes_Custom{
|
|
|
Open: int32(ticket.Open),
|
|
|
BothType: int32(ticket.BothType),
|
|
|
Chance: sumNum.Num,
|
|
|
Cond: make([]*pb.TaskRes_Cond, 0, len(conds)),
|
|
|
BothAll: nil,
|
|
|
}
|
|
|
|
|
|
for _, v := range conds {
|
|
|
var one = &pb.TaskRes_Cond{
|
|
|
Id: v.ID,
|
|
|
Desc: v.Desc,
|
|
|
Num: 0,
|
|
|
IfCond: int32(v.IfCond),
|
|
|
Total: "",
|
|
|
Event: v.Event,
|
|
|
EventKey: v.EventKey,
|
|
|
EventVal: v.EventVal,
|
|
|
TaskChance: 0,
|
|
|
TaskLimit: 0,
|
|
|
CanDo: false,
|
|
|
WebUrl: v.WebURL,
|
|
|
AppParam: v.ExtraParam,
|
|
|
TomorrowCanDo: false,
|
|
|
EventType: int32(v.EventType),
|
|
|
ViewType: int32(v.ViewType),
|
|
|
WeekCanDo: 0,
|
|
|
WeekNum: 0,
|
|
|
GoShow: int32(v.GoShow),
|
|
|
AdsStrategyId: v.AdsStrategyID,
|
|
|
IsSuper: int32(v.IsSuper),
|
|
|
HasPre: 0,
|
|
|
Reward: nil,
|
|
|
PropMark: "",
|
|
|
ExpiredSec: 0,
|
|
|
PcParam: v.PcParam,
|
|
|
TaskId: 0,
|
|
|
HasReceive: 0,
|
|
|
TriggerType: int32(v.TriggetType),
|
|
|
GoText: v.GoText,
|
|
|
ClickEffectOpen: int32(v.ClickEffectOpen),
|
|
|
ClickEffect: v.ClickEffect,
|
|
|
ClickEffectUnit: v.ClickEffectUnit,
|
|
|
PullInvite: int32(v.PullInvite),
|
|
|
}
|
|
|
if condLang, ok := condLangMap[v.ID]; ok {
|
|
|
one.Desc = condLang.Desc
|
|
|
one.GoText = condLang.GoText
|
|
|
}
|
|
|
|
|
|
if userCond, ok := userCondMap[v.ID]; ok {
|
|
|
one.Num = userCond.Num
|
|
|
one.Total = userCond.Total
|
|
|
}
|
|
|
|
|
|
if v.OpenJump == mtype.Yes {
|
|
|
if condLang, ok := condLangMap[v.ID]; ok {
|
|
|
one.WebUrl = condLang.WebURL
|
|
|
one.AppParam = condLang.ExtraParam
|
|
|
one.PcParam = condLang.PcParam
|
|
|
}
|
|
|
} else {
|
|
|
if param, ok := condExtra[v.Event]; ok {
|
|
|
one.WebUrl = param.WebUrl
|
|
|
one.AppParam = param.ExtraParam
|
|
|
one.PcParam = param.PcParam
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if ticket.BothType == mtype.FissionCampaignTicketBothTypeAll {
|
|
|
if task, ok := taskMap[mtype.FissionCampaignTaskMarkCondAll]; ok {
|
|
|
if s._beLevelLimit(task.ID, user.LevelMark) {
|
|
|
continue
|
|
|
}
|
|
|
//语言限制
|
|
|
if lm := task.GetLangMarks(); len(lm) > 0 && !verify.InArray(user.LangMark, lm...) {
|
|
|
continue
|
|
|
}
|
|
|
|
|
|
one.CanDo, one.TomorrowCanDo, one.WeekCanDo = s._taskDo(task, btAllFinish, taskDayCount[task.ID], taskWeekCount[task.ID])
|
|
|
one.WeekNum = int32(task.WeekNum)
|
|
|
one.TaskId = task.ID
|
|
|
one.HasReceive = receiveMap[task.ID]
|
|
|
}
|
|
|
} else {
|
|
|
if task, ok := taskMap[utils.FissionCampaignTaskMarkCondOneVal(v.ID)]; ok {
|
|
|
if s._beLevelLimit(task.ID, user.LevelMark) {
|
|
|
continue
|
|
|
}
|
|
|
|
|
|
//语言限制
|
|
|
if lm := task.GetLangMarks(); len(lm) > 0 && !verify.InArray(user.LangMark, lm...) {
|
|
|
continue
|
|
|
}
|
|
|
|
|
|
// 需要前置任务
|
|
|
if task.HasPre == mtype.Yes {
|
|
|
if exp, ok1 := preCond[task.PreCond]; !ok1 {
|
|
|
s.Res.PreCond = append(s.Res.PreCond, task.PreCond)
|
|
|
continue
|
|
|
} else if exp > 0 && exp <= time.Now().Unix() {
|
|
|
continue
|
|
|
} else {
|
|
|
one.ExpiredSec = exp - time.Now().Unix()
|
|
|
}
|
|
|
}
|
|
|
|
|
|
one.HasPre = int32(task.HasPre)
|
|
|
one.TaskChance = task.Chance
|
|
|
one.TaskLimit = task.TaskLimit
|
|
|
one.CanDo, one.TomorrowCanDo, one.WeekCanDo = s._taskDo(task, one.Num, taskDayCount[task.ID], taskWeekCount[task.ID])
|
|
|
one.WeekNum = int32(task.WeekNum)
|
|
|
one.Reward = rewardMap[task.RewardID]
|
|
|
one.PropMark = task.PropMark
|
|
|
one.TaskId = task.ID
|
|
|
one.HasReceive = receiveMap[task.ID]
|
|
|
}
|
|
|
}
|
|
|
|
|
|
s.Res.Custom.Cond = append(s.Res.Custom.Cond, one)
|
|
|
}
|
|
|
|
|
|
if ticket.BothType == mtype.FissionCampaignTicketBothTypeAll {
|
|
|
if task, ok := taskMap[mtype.FissionCampaignTaskMarkCondAll]; ok {
|
|
|
|
|
|
s.Res.Custom.BothAll = &pb.TaskRes_BothAll{
|
|
|
TaskChance: task.Chance,
|
|
|
TaskLimit: task.TaskLimit,
|
|
|
Finish: btAllFinish,
|
|
|
Reward: rewardMap[task.RewardID],
|
|
|
PropMark: task.PropMark,
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return
|
|
|
}
|
|
|
|
|
|
// 周任务完成次数
|
|
|
func (s *Task) _taskWeekCount(user *model.FissionUser, weekLimitTask []*model.FissionCampaignTask) (taskWeekCount map[int64]int64, err error) {
|
|
|
taskWeekCount = make(map[int64]int64, len(weekLimitTask))
|
|
|
if len(weekLimitTask) == 0 {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
for _, task := range weekLimitTask {
|
|
|
start, end := timez.GetWeekEnd(s.cpnControl.GetTz(), int32(task.WeekNum))
|
|
|
key := ckey.FissionUserWeekLimit(start, user.ID, task.ID)
|
|
|
taskWeekCount[task.ID], err = lockdo.Int64(s.Ctx, key, func() (num int64, err error) {
|
|
|
taskRecordM := s.GetDao().FissionUserTaskRecord
|
|
|
return taskRecordM.WithContext(s.Ctx).Where(
|
|
|
taskRecordM.UserID.Eq(user.ID),
|
|
|
taskRecordM.TaskID.Eq(task.ID),
|
|
|
taskRecordM.CreatedAt.Between(start, end),
|
|
|
).Count()
|
|
|
})
|
|
|
}
|
|
|
|
|
|
return
|
|
|
}
|
|
|
|
|
|
// 当天任务完成次数
|
|
|
func (s *Task) _taskDayCount(user *model.FissionUser, dayLimitTaskIds []int64) (taskDayCount map[int64]int64, err error) {
|
|
|
taskDayCount = make(map[int64]int64, len(dayLimitTaskIds))
|
|
|
if len(dayLimitTaskIds) == 0 {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
day, start, end := timez.GMTStartAndEndTs(s.cpnControl.GetTz())
|
|
|
for _, taskId := range dayLimitTaskIds {
|
|
|
key := ckey.FissionUserTaskDayLimit(day, user.ID, taskId)
|
|
|
taskDayCount[taskId], err = lockdo.Int64(s.Ctx, key, func() (num int64, err error) {
|
|
|
taskRecordM := s.GetDao().FissionUserTaskRecord
|
|
|
return taskRecordM.WithContext(s.Ctx).Where(
|
|
|
taskRecordM.UserID.Eq(user.ID),
|
|
|
taskRecordM.TaskID.Eq(taskId),
|
|
|
taskRecordM.CreatedAt.Gte(start),
|
|
|
taskRecordM.CreatedAt.Lte(end),
|
|
|
).Count()
|
|
|
})
|
|
|
}
|
|
|
|
|
|
return
|
|
|
}
|
|
|
|
|
|
func (s *Task) _condExp(bothType int8, dayExp, weekExp []*model.FissionCampaignTask, userCondMap map[int64]*model.FissionUserCond) (err error) {
|
|
|
// 把要过期的
|
|
|
|
|
|
if bothType == mtype.FissionCampaignTicketBothTypeAll {
|
|
|
var start, end int64
|
|
|
if len(dayExp) > 0 {
|
|
|
_, start, end = timez.GMTStartAndEndTs(s.cpnControl.GetTz())
|
|
|
} else if len(weekExp) > 0 {
|
|
|
start, end = timez.GetWeekEnd(s.cpnControl.GetTz(), int32(weekExp[0].WeekNum))
|
|
|
}
|
|
|
|
|
|
if start == 0 {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
condM := s.GetDao().FissionUserCond
|
|
|
for _, cond := range userCondMap {
|
|
|
if cond.TotalExp >= start {
|
|
|
continue
|
|
|
}
|
|
|
_, err = condM.WithContext(s.Ctx).Where(
|
|
|
condM.ID.Eq(cond.ID),
|
|
|
condM.UpdatedAt.Eq(cond.UpdatedAt),
|
|
|
condM.TotalExp.Gt(0),
|
|
|
).UpdateSimple(
|
|
|
condM.TotalExp.Value(end),
|
|
|
condM.Total.Value(""),
|
|
|
condM.CountNum.Value(0),
|
|
|
)
|
|
|
if err != nil {
|
|
|
err = s.BE().MysqlError(err)
|
|
|
return
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return
|
|
|
}
|
|
|
|
|
|
// 任一任务完成的处理
|
|
|
condM := s.GetDao().FissionUserCond
|
|
|
for _, task := range dayExp {
|
|
|
condId := utils.FissionCampaignTaskMarkCondOneCondId(task.TaskMark)
|
|
|
var start, end int64
|
|
|
if len(dayExp) > 0 {
|
|
|
_, start, end = timez.GMTStartAndEndTs(s.cpnControl.GetTz())
|
|
|
} else if len(weekExp) > 0 {
|
|
|
start, end = timez.GetWeekEnd(s.cpnControl.GetTz(), int32(weekExp[0].WeekNum))
|
|
|
}
|
|
|
|
|
|
if start == 0 {
|
|
|
continue
|
|
|
}
|
|
|
|
|
|
cond, ok := userCondMap[condId]
|
|
|
if !ok || cond.TotalExp >= start {
|
|
|
continue
|
|
|
}
|
|
|
|
|
|
_, err = condM.WithContext(s.Ctx).Where(
|
|
|
condM.ID.Eq(cond.ID),
|
|
|
condM.UpdatedAt.Eq(cond.UpdatedAt),
|
|
|
condM.TotalExp.Gt(0),
|
|
|
).UpdateSimple(
|
|
|
condM.TotalExp.Value(end),
|
|
|
condM.Total.Value(""),
|
|
|
condM.CountNum.Value(0),
|
|
|
)
|
|
|
if err != nil {
|
|
|
err = s.BE().MysqlError(err)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return
|
|
|
}
|
|
|
|
|
|
// 完成所有任务的任务完成次数
|
|
|
func (s *Task) _btAllFinish(user *model.FissionUser, ticket *model.FissionCampaignTicket, taskMap map[string]*model.FissionCampaignTask) (btAllFinish int64, err error) {
|
|
|
if ticket.BothType != mtype.FissionCampaignTicketBothTypeAll {
|
|
|
return
|
|
|
}
|
|
|
task, ok := taskMap[mtype.FissionCampaignTaskMarkCondAll]
|
|
|
if !ok {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
key := ckey.FissionUserTaskCpnLimit(user.ID, task.ID)
|
|
|
btAllFinish, err = lockdo.Int64(s.Ctx, key, func() (num int64, err error) {
|
|
|
taskRecordM := s.GetDao().FissionUserTaskRecord
|
|
|
return taskRecordM.WithContext(s.Ctx).Where(taskRecordM.UserID.Eq(user.ID), taskRecordM.TaskID.Eq(task.ID)).Count()
|
|
|
})
|
|
|
|
|
|
if err != nil {
|
|
|
err = s.BE().CacheError(err)
|
|
|
return
|
|
|
}
|
|
|
return
|
|
|
}
|
|
|
|
|
|
func (s *Task) _taskDo(task *model.FissionCampaignTask, taskDoneNum, dayDoneNum, weekDoneNum int64) (canDo, tomorrowDo bool, weekDo int32) {
|
|
|
canDo = true
|
|
|
|
|
|
// 总限制
|
|
|
if task.TaskLimit > 0 && int64(task.TaskLimit) <= taskDoneNum { // 任务总限制不能做了
|
|
|
canDo = false
|
|
|
return
|
|
|
}
|
|
|
|
|
|
if task.WeekLimit > 0 && int64(task.WeekLimit) <= weekDoneNum { // 有周限制,本周不能做了
|
|
|
canDo = false
|
|
|
|
|
|
t, _ := timez.GMTTimeStart(s.cpnControl.GetTz())
|
|
|
w := utils.Ternary[int32](t.Weekday() == 0, 7, int32(t.Weekday())) // 本周的周几
|
|
|
|
|
|
// 1-下周再来,2-周几再来
|
|
|
weekDo = utils.Ternary[int32](w >= int32(task.WeekNum), 1, 2)
|
|
|
|
|
|
return
|
|
|
}
|
|
|
|
|
|
if task.DayLimit > 0 && int64(task.DayLimit) <= dayDoneNum { // 有每日限制,今天不能做了
|
|
|
canDo, tomorrowDo = false, true
|
|
|
return
|
|
|
}
|
|
|
|
|
|
return
|
|
|
}
|
|
|
|
|
|
func (s *Task) _fixed(ticket *model.FissionCampaignTicket, taskMap map[string]*model.FissionCampaignTask) (err error) {
|
|
|
if ticket.Open == mtype.No {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
var task *model.FissionCampaignTask
|
|
|
switch ticket.AppEvent {
|
|
|
case mtype.FissionCampaignTicketAppEventRegister:
|
|
|
task = taskMap[mtype.FissionCampaignTaskMarkRegister]
|
|
|
case mtype.FissionCampaignTicketAppEventInstall:
|
|
|
task = taskMap[mtype.FissionCampaignTaskMarkInstall]
|
|
|
}
|
|
|
|
|
|
if task == nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
s.AddAfterRun(func() (err error) {
|
|
|
s.Res.Fixed = &pb.TaskRes_Fixed{
|
|
|
Open: int32(ticket.Open),
|
|
|
AppEvent: int32(ticket.AppEvent),
|
|
|
TargetNum: task.Num,
|
|
|
Chance: task.Chance,
|
|
|
ChanceLimit: task.ChanceLimit,
|
|
|
CanDo: true,
|
|
|
}
|
|
|
|
|
|
return
|
|
|
})
|
|
|
|
|
|
return
|
|
|
}
|
|
|
|
|
|
// 任务
|
|
|
func (s *Task) task(cpn *model.FissionCampaign, user *model.FissionUser) (err error) {
|
|
|
if !consts.NewEventCpn(cpn.FissionID) {
|
|
|
return s._oldTask(cpn, user)
|
|
|
}
|
|
|
|
|
|
err = s._newTask(cpn, user)
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
return s._day(cpn)
|
|
|
}
|
|
|
|
|
|
// 兼容未升级的活动数据
|
|
|
func (s *Task) _oldTask(cpn *model.FissionCampaign, user *model.FissionUser) (err error) {
|
|
|
conf, err := cache.NewCampaignConfig(s.Ctx).FindByCampaignId(user.CampaignID)
|
|
|
if err != nil {
|
|
|
err = s.BE().CacheError(err)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
if !verify.InArray(conf.Option, mtype.FissionCampaignConfigTargetOptionUse, mtype.FissionCampaignConfigTargetOptionSelf, mtype.FissionCampaignConfigTargetOptionFriend) {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
m := s.GetDao().FissionCampaignCond
|
|
|
conds, err := m.WithContext(s.Ctx).Where(m.CampaignID.Eq(user.CampaignID), m.IsDel.Eq(mtype.No)).Find()
|
|
|
if err != nil {
|
|
|
err = s.BE().MysqlError(err)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
condM := s.GetDao().FissionUserCond
|
|
|
list, err := condM.WithContext(s.Ctx).Where(condM.UserID.Eq(user.ID)).Find()
|
|
|
if err != nil {
|
|
|
return s.BE().MysqlError(err)
|
|
|
}
|
|
|
|
|
|
var userCondMap = make(map[int64]*model.FissionUserCond)
|
|
|
for _, v := range list {
|
|
|
userCondMap[v.CondID] = v
|
|
|
}
|
|
|
|
|
|
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)
|
|
|
}
|
|
|
|
|
|
// 用户当前语言是配置的语言
|
|
|
var condLangMap = make(map[int64]string)
|
|
|
if verify.InArray(user.LangMark, cpn.GetLangMarks()[1:]...) {
|
|
|
lang, err1 := cache.NewCampaignLang(s.Ctx).FindByCampaignId(user.CampaignID, user.LangMark)
|
|
|
if err1 != nil {
|
|
|
err = s.BE().CacheError(err1)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
if lang != nil {
|
|
|
for _, v := range lang.GetConds() {
|
|
|
condLangMap[v.CondId] = v.Desc
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
s.AddAfterRun(func() (err error) {
|
|
|
|
|
|
s.Res.Custom = &pb.TaskRes_Custom{
|
|
|
Open: 1,
|
|
|
BothType: int32(conf.BothType),
|
|
|
Chance: 0,
|
|
|
Cond: make([]*pb.TaskRes_Cond, 0, len(conds)),
|
|
|
BothAll: nil,
|
|
|
}
|
|
|
|
|
|
for _, v := range conds {
|
|
|
one := &pb.TaskRes_Cond{
|
|
|
Id: v.ID,
|
|
|
Desc: v.Desc,
|
|
|
IfCond: int32(v.IfCond),
|
|
|
Event: v.Event,
|
|
|
EventKey: v.EventKey,
|
|
|
EventVal: v.EventVal,
|
|
|
TaskChance: 0,
|
|
|
TaskLimit: 0,
|
|
|
CanDo: true,
|
|
|
}
|
|
|
if desc, ok := condLangMap[v.ID]; ok {
|
|
|
one.Desc = desc
|
|
|
}
|
|
|
|
|
|
if userCond, ok := userCondMap[v.ID]; ok {
|
|
|
one.Num = userCond.Num
|
|
|
one.Total = userCond.Total
|
|
|
}
|
|
|
|
|
|
s.Res.Custom.Cond = append(s.Res.Custom.Cond, one)
|
|
|
}
|
|
|
|
|
|
if conf.BothType == mtype.FissionCampaignTicketBothTypeAll {
|
|
|
var bothAll = &pb.TaskRes_BothAll{
|
|
|
TaskChance: 1,
|
|
|
}
|
|
|
if stat != nil {
|
|
|
bothAll.Finish = stat.TargetNum
|
|
|
}
|
|
|
|
|
|
s.Res.Custom.BothAll = bothAll
|
|
|
}
|
|
|
|
|
|
return
|
|
|
})
|
|
|
|
|
|
return
|
|
|
}
|
|
|
|
|
|
// 每日任务
|
|
|
func (s *Task) _day(cpn *model.FissionCampaign) (err error) {
|
|
|
|
|
|
var chance int32
|
|
|
switch cpn.FissionID {
|
|
|
case consts.IdDice:
|
|
|
m := s.GetDao().FissionCampaignDice
|
|
|
conf, err1 := m.WithContext(s.Ctx).Where(m.CampaignID.Eq(cpn.ID)).Take()
|
|
|
if err1 != nil {
|
|
|
err = s.BE().MysqlError(err1)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
if conf != nil {
|
|
|
chance = conf.DayChance
|
|
|
}
|
|
|
case consts.IdBlindBox:
|
|
|
m := s.GetDao().FissionCampaignBlind
|
|
|
conf, err1 := m.WithContext(s.Ctx).Where(m.CampaignID.Eq(cpn.ID)).Take()
|
|
|
if err1 != nil {
|
|
|
err = s.BE().MysqlError(err1)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
if conf != nil {
|
|
|
chance = conf.DayChance
|
|
|
}
|
|
|
case consts.IdSlotMachine:
|
|
|
m := s.GetDao().FissionCampaignSlot
|
|
|
conf, err1 := m.WithContext(s.Ctx).Where(m.CampaignID.Eq(cpn.ID)).Take()
|
|
|
if err1 != nil {
|
|
|
err = s.BE().MysqlError(err1)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
if conf != nil {
|
|
|
chance = conf.DayChance
|
|
|
}
|
|
|
case consts.IdLuckyGrid:
|
|
|
m := s.GetDao().FissionCampaignGrid
|
|
|
conf, err1 := m.WithContext(s.Ctx).Where(m.CampaignID.Eq(cpn.ID)).Take()
|
|
|
if err1 != nil {
|
|
|
err = s.BE().MysqlError(err1)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
if conf != nil {
|
|
|
chance = conf.DayChance
|
|
|
}
|
|
|
case consts.IdPrizeWheel:
|
|
|
m := s.GetDao().FissionCampaignWheel
|
|
|
conf, err1 := m.WithContext(s.Ctx).Where(m.CampaignID.Eq(cpn.ID)).Take()
|
|
|
if err1 != nil {
|
|
|
err = s.BE().MysqlError(err1)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
if conf != nil {
|
|
|
chance = conf.DayChance
|
|
|
}
|
|
|
case consts.IdFlip:
|
|
|
m := s.GetDao().FissionCampaignFlip
|
|
|
conf, err1 := m.WithContext(s.Ctx).Where(m.CampaignID.Eq(cpn.ID)).Take()
|
|
|
if err1 != nil {
|
|
|
err = s.BE().MysqlError(err1)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
if conf != nil {
|
|
|
chance = conf.DayChance
|
|
|
}
|
|
|
case consts.IdQa, consts.IdQaVideo, consts.IdQaAudio, consts.IdPrizeAnswer:
|
|
|
m := s.GetDao().FissionCampaignQa
|
|
|
conf, err1 := m.WithContext(s.Ctx).Where(m.CampaignID.Eq(cpn.ID)).Take()
|
|
|
if err1 != nil {
|
|
|
err = s.BE().MysqlError(err1)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
if conf != nil {
|
|
|
chance = conf.DayChance
|
|
|
}
|
|
|
default:
|
|
|
|
|
|
}
|
|
|
|
|
|
s.AddAfterRun(func() (err error) {
|
|
|
s.Res.FixDay = &pb.TaskRes_Day{
|
|
|
Open: utils.Ternary[int32](chance > 0, 1, 0),
|
|
|
Chance: chance,
|
|
|
CanDo: true,
|
|
|
}
|
|
|
|
|
|
return
|
|
|
})
|
|
|
|
|
|
return
|
|
|
}
|
|
|
|
|
|
// 用户等级限制
|
|
|
func (s *Task) _levelLimit(taskLvIdMap map[int64][]int64) (err error) {
|
|
|
|
|
|
var titleMap = make(map[int64]string)
|
|
|
var ids []int64
|
|
|
for _, lvIds := range taskLvIdMap {
|
|
|
for _, lvId := range lvIds {
|
|
|
if _, ok := titleMap[lvId]; !ok {
|
|
|
titleMap[lvId] = ""
|
|
|
ids = append(ids, lvId)
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
m := s.GetDao().FissionUserLevel
|
|
|
list, err := m.WithContext(s.Ctx).Where(m.ID.In(ids...), m.DeletedAt.Eq(0)).Find()
|
|
|
if err != nil {
|
|
|
err = s.BE().MysqlError(err)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
for _, v := range list {
|
|
|
titleMap[v.ID] = v.Mark
|
|
|
}
|
|
|
|
|
|
s.lvLimitMap = make(map[int64][]string)
|
|
|
for id, lvIds := range taskLvIdMap {
|
|
|
for _, lvId := range lvIds {
|
|
|
s.lvLimitMap[id] = append(s.lvLimitMap[id], titleMap[lvId])
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return
|
|
|
}
|
|
|
|
|
|
// 是不是等级限制
|
|
|
func (s *Task) _beLevelLimit(taskId int64, levelMark string) bool {
|
|
|
marks, ok := s.lvLimitMap[taskId]
|
|
|
if !ok {
|
|
|
return false
|
|
|
} //没有证明没开限制
|
|
|
|
|
|
return !verify.OneInArray(marks, strings.Split(levelMark, ","))
|
|
|
}
|
|
|
|
|
|
// 前置任务
|
|
|
func (s *Task) _preCond(user *model.FissionUser) (doneMap map[int32]int64, err error) {
|
|
|
m := s.GetDao().FissionUserPreCond
|
|
|
list, err := m.WithContext(s.Ctx).Select(m.PreCond, m.ExpiredAt).Where(m.UserID.Eq(user.ID)).Find()
|
|
|
if err != nil {
|
|
|
err = s.BE().MysqlError(err)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
doneMap = make(map[int32]int64, len(list))
|
|
|
for _, v := range list {
|
|
|
doneMap[v.PreCond] = v.ExpiredAt
|
|
|
}
|
|
|
|
|
|
return
|
|
|
}
|
|
|
|
|
|
// 当天任务完成次数
|
|
|
func (s *Task) _reward(projectId int64, langMark string, rewardIds []int64) (rewardMap map[int64]*pb.TaskRes_Reward, err error) {
|
|
|
rewardMap = make(map[int64]*pb.TaskRes_Reward, len(rewardIds))
|
|
|
if len(rewardIds) == 0 {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
m := s.GetDao().FissionCampaignReward
|
|
|
list, err := m.WithContext(s.Ctx).Where(m.ID.In(rewardIds...)).Find()
|
|
|
if err != nil {
|
|
|
err = s.BE().MysqlError(err)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
var hasPoint bool
|
|
|
var bIds []int64
|
|
|
for _, v := range list {
|
|
|
bIds = append(bIds, v.RewardID)
|
|
|
if !hasPoint && v.PropMark == mtype.FissionCampaignTaskPropMarkPoint {
|
|
|
hasPoint = true
|
|
|
}
|
|
|
}
|
|
|
|
|
|
var pointTitle, pointImg string
|
|
|
if hasPoint {
|
|
|
pointTitle, pointImg, _, _ = cmm.NewCMM(s.Ctx, s.GetDao()).GetCoinInfo(projectId, langMark)
|
|
|
}
|
|
|
|
|
|
bewards, err := provider.NewRewards(s.Ctx, projectId, bIds...)
|
|
|
if err != nil {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
for _, v := range list {
|
|
|
|
|
|
one := &pb.TaskRes_Reward{
|
|
|
Id: v.ID,
|
|
|
}
|
|
|
|
|
|
switch v.PropMark {
|
|
|
case mtype.FissionCampaignTaskPropMarkPoint:
|
|
|
one.Title, one.ImgUrl = pointTitle, pointImg
|
|
|
case mtype.FissionCampaignTaskPropMarkReward:
|
|
|
info, _ := bewards.InfoAutoLang(v.RewardID, langMark)
|
|
|
one.Title, one.ImgUrl = info.Title, info.ImgUrl
|
|
|
}
|
|
|
|
|
|
rewardMap[v.ID] = one
|
|
|
}
|
|
|
|
|
|
return
|
|
|
}
|
|
|
|
|
|
func (s *Task) _receive(user *model.FissionUser, taskIds []int64) (receiveMap map[int64]int32, err error) {
|
|
|
receiveMap = make(map[int64]int32, len(taskIds))
|
|
|
|
|
|
if len(taskIds) == 0 {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
for _, id := range taskIds {
|
|
|
receiveMap[id] = 0
|
|
|
}
|
|
|
|
|
|
m := s.GetDao().FissionUserTaskReward
|
|
|
list, err := m.WithContext(s.Ctx).Select(m.TaskID).Where(m.UserID.Eq(user.ID), m.ReceiveTime.Eq(0), m.TaskID.In(taskIds...)).Find()
|
|
|
if err != nil {
|
|
|
err = s.BE().MysqlError(err)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
for _, v := range list {
|
|
|
receiveMap[v.TaskID] = 1
|
|
|
}
|
|
|
|
|
|
return
|
|
|
}
|