1036 lines
29 KiB
Go
1036 lines
29 KiB
Go
package newcomer
|
||
|
||
import (
|
||
"context"
|
||
"reflect"
|
||
"sort"
|
||
"strings"
|
||
"time"
|
||
|
||
"fmt"
|
||
"go-common/app/interface/main/creative/model/newcomer"
|
||
accapi "go-common/app/service/main/account/api"
|
||
"go-common/library/ecode"
|
||
"go-common/library/log"
|
||
xtime "go-common/library/time"
|
||
)
|
||
|
||
const (
|
||
creatorMID int64 = 37090048 //创作中心哔哩哔哩号
|
||
msgPendantCode = "1_17_4"
|
||
msgPendantTitle = "恭喜你通关UP主任务-新手任务!"
|
||
msgPendantContent = "新手任务通关奖励“小试身手”头像挂件已发送至你的“个人中心-我的头像-我的挂件”中,快来查看和佩戴吧!更多任务奖励正在准备中,敬请期待哦~"
|
||
)
|
||
|
||
// UserTaskInfo def user task info
|
||
type UserTaskInfo struct {
|
||
Mid int64
|
||
UserTaskLevel int8
|
||
Follower int64
|
||
IsChange bool
|
||
}
|
||
|
||
// AppIndexNewcomer index newcomer
|
||
func (s *Service) AppIndexNewcomer(c context.Context, mid int64, plat string) (res *newcomer.AppIndexNewcomer, err error) {
|
||
if !s.c.TaskCondition.AppIndexSwitch {
|
||
return
|
||
}
|
||
var (
|
||
count int64
|
||
todoTasks []*newcomer.UserTask
|
||
)
|
||
res = &newcomer.AppIndexNewcomer{
|
||
H5URL: s.c.H5Page.Mission,
|
||
}
|
||
// check task bind
|
||
count, err = s.CheckUserTaskBind(c, mid)
|
||
if err != nil {
|
||
return
|
||
}
|
||
showTaskIDs := make([]int64, 0)
|
||
if count > 0 {
|
||
// already get tasks
|
||
res.TaskReceived = newcomer.BindTask
|
||
todoTasks, err = s.newc.UserTasksByMID(c, mid)
|
||
if err != nil {
|
||
log.Error("AppIndexNewcomer s.newc.UserTasks mid(%d)|error(%v)", mid, err)
|
||
return
|
||
}
|
||
// get at most 2 tasks
|
||
maxCnt := 0
|
||
for _, v := range todoTasks {
|
||
if maxCnt >= 2 {
|
||
break
|
||
}
|
||
showTaskIDs = append(showTaskIDs, v.TaskID)
|
||
maxCnt++
|
||
}
|
||
} else {
|
||
// not bind
|
||
res.TaskReceived = newcomer.NoBindTask
|
||
if len(s.TaskCache) < 2 {
|
||
return
|
||
}
|
||
for i := 0; i < 2; i++ {
|
||
t := s.TaskCache[i]
|
||
showTaskIDs = append(showTaskIDs, t.ID)
|
||
}
|
||
}
|
||
|
||
// fill app tasks struct
|
||
for _, v := range showTaskIDs {
|
||
if t, ok := s.TaskMapCache[v]; ok {
|
||
appt := &newcomer.AppTasks{
|
||
ID: t.ID,
|
||
Title: t.Title,
|
||
Type: t.Type,
|
||
}
|
||
// get redirect url
|
||
if _, ok := newcomer.TaskRedirectMap[plat]; ok {
|
||
if r, ook := newcomer.TaskRedirectMap[plat][t.TargetType]; ook {
|
||
appt.Label = r[0]
|
||
appt.Redirect = r[1]
|
||
}
|
||
}
|
||
res.AppTasks = append(res.AppTasks, appt)
|
||
}
|
||
}
|
||
if len(res.AppTasks) == 0 {
|
||
res = nil
|
||
}
|
||
return
|
||
}
|
||
|
||
// IndexNewcomer index newcomer
|
||
func (s *Service) IndexNewcomer(c context.Context, mid int64) (res *newcomer.IndexNewcomer, err error) {
|
||
res = &newcomer.IndexNewcomer{}
|
||
|
||
// check task bind
|
||
count, err := s.CheckUserTaskBind(c, mid)
|
||
if err != nil {
|
||
return
|
||
}
|
||
if count > 0 {
|
||
res.TaskReceived = newcomer.BindTask
|
||
} else {
|
||
res.TaskReceived = newcomer.NoBindTask
|
||
}
|
||
|
||
var (
|
||
upCount int // Number of submissions
|
||
viewCount int64 // Number of plays
|
||
)
|
||
// if archives == 0 && plays == 0 , means zero data
|
||
dt := time.Now().AddDate(0, 0, -1).Add(-12 * time.Hour).Format("20060102")
|
||
stat, err := s.data.UpStat(c, mid, dt)
|
||
if err != nil {
|
||
log.Error("IndexNewcomer s.data.UpStat mid(%d)|error(%v)", mid, err)
|
||
} else {
|
||
viewCount = stat.View
|
||
}
|
||
up, err := s.arc.UpCount(c, mid)
|
||
if err != nil {
|
||
log.Error("IndexNewcomer s.arc.UpCount mid(%d)|error(%v)", mid, err)
|
||
} else {
|
||
upCount = up
|
||
}
|
||
log.Info("IndexNewcomer mid(%d)|stat.view(%d)|upcount(%d)", mid, viewCount, upCount)
|
||
|
||
if upCount > 0 || viewCount > 0 {
|
||
log.Info("IndexNewcomer upCount>0||viewCount>0 mid(%d)|stat.view(%d)|upcount(%d)", mid, viewCount, upCount)
|
||
// check no receive reward
|
||
noReceiveCount := 0
|
||
noReceiveCount, CountErr := s.getNoReceiveRewardCount(c, mid)
|
||
if CountErr != nil {
|
||
log.Error("IndexNewcomer s.newc.noReceiveRewardCount mid(%d)|error(%v)", mid, err)
|
||
}
|
||
res.NoReceive = noReceiveCount
|
||
res.SubZero = false
|
||
} else {
|
||
res.SubZero = true
|
||
}
|
||
// add three task
|
||
tasks := make([]*newcomer.Task, 0)
|
||
if len(s.TaskCache) > 3 {
|
||
for i := 0; i < 3; i++ {
|
||
tasks = append(tasks, s.TaskCache[i])
|
||
}
|
||
res.Tasks = tasks
|
||
} else {
|
||
log.Error("IndexNewcomer s.newc len(s.TaskCache)<3 mid(%d)|error(%v)", mid, err)
|
||
}
|
||
|
||
return
|
||
}
|
||
|
||
// getNoReceiveRewardCount get no receive reward count
|
||
func (s *Service) getNoReceiveRewardCount(c context.Context, mid int64) (count int, err error) {
|
||
userTasks, err := s.newc.UserTasks(c, mid)
|
||
if err != nil {
|
||
log.Error("getNoReceiveRewardCount s.newc.UserTasks mid(%d)|error(%v)", mid, err)
|
||
return
|
||
}
|
||
tasks := s.getTasksInfoByType(userTasks, newcomer.DefualtTaskType)
|
||
if len(tasks) == 0 {
|
||
return
|
||
}
|
||
var (
|
||
taskGroupMap map[int64][]*newcomer.Task
|
||
taskTypeMap map[int8][]*newcomer.Task
|
||
availableCount int
|
||
receivedCount int
|
||
groupIDs []int64
|
||
giftIDs []int64
|
||
)
|
||
// group by groupID & taskType
|
||
taskGroupMap, taskTypeMap = s.groupByTasks(tasks)
|
||
groupIDs = make([]int64, 0, len(taskGroupMap))
|
||
for k, v := range taskGroupMap {
|
||
if _, ok := s.TaskGroupRewardMapCache[k]; ok {
|
||
if s.getTaskCompleteCount(v) == len(v) {
|
||
availableCount++
|
||
}
|
||
groupIDs = append(groupIDs, k)
|
||
}
|
||
}
|
||
giftIDs = make([]int64, 0, len(taskTypeMap))
|
||
for k, v := range taskTypeMap {
|
||
if _, ok := s.GiftRewardMapCache[k]; ok {
|
||
if s.getTaskCompleteCount(v) == len(v) {
|
||
availableCount++
|
||
}
|
||
giftIDs = append(giftIDs, int64(k))
|
||
}
|
||
}
|
||
r1, err := s.newc.BaseRewardCount(c, mid, groupIDs) // 基础奖励 已领取个数
|
||
if err != nil {
|
||
log.Error("getNoReceiveRewardCount s.newc.BaseRewardCount mid(%v)|error(%v)", mid, err)
|
||
return
|
||
}
|
||
r2, err := s.newc.GiftRewardCount(c, mid, giftIDs) // 礼包奖励 已领取个数
|
||
if err != nil {
|
||
log.Error("getNoReceiveRewardCount s.newc.GiftRewardCount mid(%v)|error(%v)", mid, err)
|
||
return
|
||
}
|
||
receivedCount = int(r1 + r2)
|
||
// 可领取未领取的奖励 = 可领取 - 已领取
|
||
count = availableCount - receivedCount
|
||
if count < 0 {
|
||
count = 0
|
||
}
|
||
log.Info("getNoReceiveRewardCount mid(%d)|availableCount(%d)|receivedCount(%d)|count(%d)", mid, availableCount, receivedCount, count)
|
||
return
|
||
}
|
||
|
||
// getUserTaskInfo determine the userTaskLevel
|
||
func (s *Service) getUserTaskInfo(c context.Context, mid int64, tasks []*newcomer.Task) (u *UserTaskInfo, err error) {
|
||
u = &UserTaskInfo{
|
||
Mid: mid,
|
||
UserTaskLevel: newcomer.UserTaskLevel01,
|
||
IsChange: false,
|
||
}
|
||
var (
|
||
count int // Number of unfinished novice tasks
|
||
follower int64
|
||
profileStat *accapi.ProfileStatReply
|
||
taskTypeMap map[int8][]*newcomer.Task
|
||
taskMap map[int64]*newcomer.Task
|
||
)
|
||
|
||
// whether the advanced task is hidden
|
||
if s.isHiddenTaskType(newcomer.AdvancedTaskType) {
|
||
u.UserTaskLevel = newcomer.UserTaskLevel01
|
||
return
|
||
}
|
||
|
||
taskMap = make(map[int64]*newcomer.Task)
|
||
taskTypeMap = make(map[int8][]*newcomer.Task)
|
||
for _, task := range tasks {
|
||
if task == nil {
|
||
continue
|
||
}
|
||
t, ok := s.TaskMapCache[task.ID]
|
||
if !ok {
|
||
continue
|
||
}
|
||
tp := *t
|
||
tp.CompleteSate = task.CompleteSate
|
||
taskTypeMap[tp.Type] = append(taskTypeMap[tp.Type], &tp)
|
||
taskMap[tp.ID] = &tp
|
||
}
|
||
|
||
// If the user already has an advanced task, return UserTaskLevel02
|
||
if _, ok := taskTypeMap[newcomer.AdvancedTaskType]; ok {
|
||
u.UserTaskLevel = newcomer.UserTaskLevel02
|
||
return
|
||
}
|
||
|
||
// Calculate whether the novice task is not fully completed (compare with cache)
|
||
newcomerTasks := s.getTasksByType(newcomer.NewcomerTaskType)
|
||
if len(newcomerTasks) == 0 {
|
||
return
|
||
}
|
||
count = len(newcomerTasks)
|
||
for _, t := range newcomerTasks {
|
||
if task, ok := taskMap[t.ID]; ok {
|
||
if task.CompleteSate == newcomer.TaskCompleted {
|
||
count--
|
||
}
|
||
}
|
||
}
|
||
// judge fans count
|
||
profileStat, profileErr := s.acc.ProfileWithStat(c, mid)
|
||
if profileStat == nil || profileErr != nil {
|
||
log.Error("genUserTaskInfo s.acc.ProfileWithStat mid(%d)|error(%v)", mid, err)
|
||
follower = 0
|
||
} else {
|
||
follower = profileStat.Follower
|
||
}
|
||
//Number of unfinished tasks || fans >=100
|
||
if count == 0 || follower >= s.c.TaskCondition.Fans {
|
||
// insert advancedTask
|
||
tasks = s.TaskTypeMapCache[newcomer.AdvancedTaskType]
|
||
if len(tasks) == 0 {
|
||
log.Warn("genUserTaskInfo no taskType==newcomer.AdvancedTaskType mid(%d)", mid)
|
||
return
|
||
}
|
||
args, placeStr := genBatchParamsBindTasks(tasks, mid)
|
||
_, err = s.newc.BindTasks(c, mid, placeStr, args)
|
||
if err != nil {
|
||
log.Error("genUserTaskInfo s.newc.BindTasks mid(%d)|error(%v)", mid, err)
|
||
return
|
||
}
|
||
u.UserTaskLevel = newcomer.UserTaskLevel02
|
||
u.IsChange = true // user level changed
|
||
s.putCheckTaskState(mid) // add to checkTaskQueue
|
||
}
|
||
|
||
return
|
||
}
|
||
|
||
//RewardReceive insert reward receive records.
|
||
func (s *Service) RewardReceive(c context.Context, mid int64, rid int64, ty int8, ip string) (res string, err error) {
|
||
var (
|
||
rewardIDs []int64
|
||
rewards []*newcomer.Reward
|
||
lockSuccess bool
|
||
)
|
||
|
||
// check completed
|
||
err = s.isRewardComplete(c, mid, rid, ty)
|
||
if err != nil {
|
||
return
|
||
}
|
||
|
||
// prevent concurrent collection
|
||
key := s.getReceiveKey(rid, ty, mid)
|
||
if lockSuccess, err = s.newc.Lock(c, key, 1000); !lockSuccess || err != nil {
|
||
if err == nil {
|
||
log.Info("RewardReceive s.newc.Lock mid(%d)|rid(%d)|ty(%d)", mid, rid, ty)
|
||
res = s.c.TaskCondition.ReceiveMsg
|
||
return
|
||
}
|
||
log.Error("RewardReceive s.newc.Lock mid(%d)|rid(%d)|ty(%d)|error(%v)", mid, rid, ty, err)
|
||
}
|
||
|
||
// check received
|
||
err = s.isRewardReceived(c, mid, rid, ty)
|
||
if err != nil {
|
||
return
|
||
}
|
||
|
||
// get rewards
|
||
if ty == newcomer.RewardGiftType {
|
||
rewardIDs, err = s.newc.GiftRewards(c, int8(rid))
|
||
if err != nil {
|
||
log.Error("RewardReceive s.newc.GiftRewards mid(%d)|rewardID(%d)|ty(%d)|err(%v)", mid, rid, ty, err)
|
||
return
|
||
}
|
||
} else {
|
||
rewardIDs, err = s.newc.TaskGroupRewards(c, rid)
|
||
if err != nil {
|
||
log.Error("RewardReceive s.newc.TaskGroupRewards mid(%d)|rewardID(%d)|ty(%d)|err(%v)", mid, rid, ty, err)
|
||
return
|
||
}
|
||
}
|
||
if len(rewardIDs) == 0 {
|
||
err = ecode.RequestErr
|
||
return
|
||
}
|
||
rewards = make([]*newcomer.Reward, 0)
|
||
for _, v := range rewardIDs {
|
||
if r, ok := s.RewardMapCache[v]; ok {
|
||
rewards = append(rewards, r)
|
||
}
|
||
}
|
||
// get user info
|
||
profile, err := s.acc.Profile(c, mid, ip)
|
||
if err != nil || profile == nil {
|
||
log.Error("RewardReceive s.acc.Profile mid(%d)|rewardID(%d)|ty(%d)|err(%v)", mid, rid, ty, err)
|
||
return
|
||
}
|
||
|
||
// receive rewards
|
||
rrs := make([]*newcomer.RewardReceive2, 0)
|
||
for _, v := range rewards {
|
||
r := &newcomer.RewardReceive2{}
|
||
r.MID = mid
|
||
r.OID = rid
|
||
r.Type = ty
|
||
r.RewardID = v.ID
|
||
r.RewardType = v.Type
|
||
if v.IsActive == newcomer.RewardNeedActivate {
|
||
r.State = newcomer.RewardCanActivate
|
||
} else {
|
||
err = s.callBusiness(c, profile, v)
|
||
if err != nil {
|
||
log.Error("RewardReceive s.callBusiness mid(%d)|reward(%+v)|error(%v)", mid, v, err)
|
||
r.State = newcomer.RewardCanActivate
|
||
} else {
|
||
r.State = newcomer.RewardActivatedNotClick
|
||
}
|
||
}
|
||
rrs = append(rrs, r)
|
||
}
|
||
_, err = s.newc.RewardReceive2(c, mid, rrs)
|
||
if err != nil {
|
||
log.Error("RewardReceive s.newc.RewardReceive mid(%d)|rewardID(%d)|ty(%d)|err(%v)", mid, rid, ty, err)
|
||
s.newc.UnLock(c, key)
|
||
return
|
||
}
|
||
res = s.c.TaskCondition.ReceiveMsg
|
||
log.Info("RewardReceive success mid(%d)|rewardID(%d)|ty(%d)", mid, rid, ty)
|
||
return
|
||
}
|
||
|
||
// Determine if the reward can be collected
|
||
func (s *Service) isRewardComplete(c context.Context, mid int64, rid int64, ty int8) error {
|
||
tids := make([]int64, 0)
|
||
tasks := make([]*newcomer.Task, 0)
|
||
if ty == newcomer.RewardBaseType {
|
||
tasks = s.getTasksByGroupID(rid)
|
||
} else if ty == newcomer.RewardGiftType {
|
||
tasks = s.getTasksByType(int8(rid))
|
||
}
|
||
for _, t := range tasks {
|
||
if t == nil {
|
||
continue
|
||
}
|
||
tids = append(tids, t.ID)
|
||
}
|
||
if len(tids) == 0 {
|
||
log.Error("isRewardComplete len(tids) == 0 | mid(%d)", mid)
|
||
return ecode.CreativeNewcomerNotCompleteErr
|
||
}
|
||
|
||
count, err := s.newc.RewardCompleteState(c, mid, tids)
|
||
if err != nil {
|
||
log.Error("isRewardComplete s.newc.RewardCompleteState mid(%d)|rewardID(%d)|ty(%d)|err(%v)", mid, rid, ty, err)
|
||
return err
|
||
}
|
||
if count != 0 {
|
||
err = ecode.CreativeNewcomerNotCompleteErr
|
||
log.Error("isRewardComplete mission not completed mid(%d)|rewardID(%d)|ty(%d)|err(%v)", mid, rid, ty, err)
|
||
return err
|
||
}
|
||
return nil
|
||
}
|
||
|
||
// Determine whether to receive it repeatedly
|
||
func (s *Service) isRewardReceived(c context.Context, mid int64, rid int64, ty int8) error {
|
||
isReceived, err := s.newc.IsRewardReceived(c, mid, rid, ty)
|
||
if err != nil {
|
||
log.Error("isRewardReceived s.newc.IsGiftReceived mid(%d)|rewardID(%d)|ty(%d)|err(%v)", mid, rid, ty, err)
|
||
return err
|
||
}
|
||
if isReceived {
|
||
err = ecode.CreativeNewcomerRepeatRewardErr
|
||
log.Error("isRewardReceived receive multiple times mid(%d)|rewardID(%d)|ty(%d)|err(%v)", mid, rid, ty, err)
|
||
return err
|
||
}
|
||
return nil
|
||
}
|
||
|
||
// Calling the business side interface
|
||
func (s *Service) callBusiness(c context.Context, profile *accapi.Profile, v *newcomer.Reward) (err error) {
|
||
switch v.Type {
|
||
case newcomer.Bcoin: //B币券
|
||
err = s.newc.BCoin(c, profile.Mid, v.PriceID, int64(v.PrizeUnit))
|
||
case newcomer.MemberBuy: //会员购
|
||
err = s.newc.Mall(c, profile.Mid, v.PriceID, profile.Name)
|
||
case newcomer.IncentivePlan: //激励计划
|
||
err = s.SendRewardReceiveLog(c, profile.Mid)
|
||
case newcomer.BigMember: //大会员服务
|
||
err = s.newc.BigMemberCoupon(c, profile.Mid, v.PriceID)
|
||
case newcomer.PersonalCenter: //个人中心
|
||
err = s.newc.Pendant(c, profile.Mid, v.PriceID, int64(v.Expire))
|
||
if err != nil {
|
||
return
|
||
}
|
||
//发送消息通知
|
||
if e := s.newc.SendNotify(c, []int64{profile.Mid}, msgPendantCode, msgPendantTitle, msgPendantContent); e != nil {
|
||
log.Error("callBusiness s.newc.SendNotify mid(%d)|err(%v)", profile.Mid, err)
|
||
}
|
||
}
|
||
return
|
||
}
|
||
|
||
//RewardActivate insert reward receive records.
|
||
func (s *Service) RewardActivate(c context.Context, mid, id int64, ip string) (res int64, err error) {
|
||
r, err := s.newc.RewardReceiveByID(c, mid, id)
|
||
if err != nil {
|
||
log.Error("RewardActivate s.newc.RewardIDByReceiveID mid(%d)|receiveID(%d)|err(%v)", mid, id, err)
|
||
return
|
||
}
|
||
// check repeat collection
|
||
if r.State != newcomer.RewardCanActivate {
|
||
err = ecode.CreativeNewcomerRepeatRewardErr
|
||
log.Error("RewardActivate check repeat collection mid(%d)|receiveID(%d)|state(%d)|err(%v)", mid, id, r.State, err)
|
||
return
|
||
}
|
||
|
||
// check expire
|
||
reward, ok := s.RewardMapCache[r.RewardID]
|
||
if !ok || reward == nil {
|
||
err = ecode.RequestErr
|
||
log.Error("RewardActivate check expire mid(%d)|receiveID(%d)|rewardID(%d)|err(%v)", mid, id, r.RewardID, err)
|
||
return
|
||
}
|
||
var expireTime int64
|
||
if r.RewardType == newcomer.Bcoin { //奖品到期时间
|
||
expireTime = reward.CTime.Time().Unix() + int64(reward.Expire*24*3600) //B币券显示截止时间
|
||
} else {
|
||
expireTime = r.ReceiveTime.Time().Unix() + int64(reward.Expire*24*3600)
|
||
}
|
||
if (time.Now().Unix() - expireTime) > 0 {
|
||
err = ecode.CreativeNewcomerReceiveExpireErr
|
||
log.Error("RewardActivate check expire mid(%d)|receiveID(%d)|rewardID(%d)|err(%v)", mid, id, r.RewardID, err)
|
||
return
|
||
}
|
||
|
||
// get new receive record
|
||
nr, err := s.newc.RewardReceiveByOldInfo(c, r)
|
||
if err != nil || nr == nil {
|
||
log.Error("RewardActivate s.newc.RewardReceiveByOldInfo mid(%d)|receive(%+v)|error(%v)", mid, r, err)
|
||
return
|
||
}
|
||
|
||
// prevent concurrent collection
|
||
var lockSuccess bool
|
||
key := s.getActivateKey(mid, id)
|
||
if lockSuccess, err = s.newc.Lock(c, key, 1000); !lockSuccess || err != nil {
|
||
if err == nil {
|
||
log.Info("RewardActivate s.newc.Lock mid(%d)|id(%d)", mid, id)
|
||
res = 0
|
||
return
|
||
}
|
||
log.Error("RewardActivate s.newc.Lock mid(%d)|id(%d)|error(%v)", mid, id, err)
|
||
}
|
||
|
||
profile, err := s.acc.Profile(c, mid, ip)
|
||
if err != nil || profile == nil {
|
||
log.Error("RewardActivate s.acc.Profile mid(%d)|receiveID(%d)|rewardID(%d)|err(%v)", mid, id, r.RewardID, err)
|
||
return
|
||
}
|
||
if err = s.callBusiness(c, profile, reward); err != nil {
|
||
log.Error("RewardActivate callBusiness mid(%d)|receiveID(%d)|rewardID(%d)|err(%v)", mid, id, r.RewardID, err)
|
||
return
|
||
}
|
||
|
||
res, err = s.newc.RewardActivate2(c, mid, id, nr.ID)
|
||
if err != nil {
|
||
log.Error("s.newc.RewardActivate mid(%d)|id(%d)|err(%v)", mid, id, err)
|
||
s.newc.UnLock(c, key)
|
||
return
|
||
}
|
||
log.Info("RewardActivate success mid(%d)|receiveID(%d)", mid, id)
|
||
return
|
||
}
|
||
|
||
//RewardReceives get reward receive records.
|
||
func (s *Service) RewardReceives(c context.Context, mid int64) (res []*newcomer.RewardReceiveGroup, err error) {
|
||
var items map[int8][]*newcomer.RewardReceive
|
||
items, err = s.newc.RewardReceives(c, mid)
|
||
if err != nil {
|
||
log.Error("s.newc.RewardReceives mid(%d)|err(%v)", mid, err)
|
||
return
|
||
}
|
||
if len(items) == 0 {
|
||
log.Error("s.newc.RewardReceives len(items) == 0")
|
||
return
|
||
}
|
||
|
||
keys := reflect.ValueOf(items).MapKeys()
|
||
pids := make([]int64, 0, len(keys)) //存储当前奖励 类型对应的 分类id
|
||
for _, v := range keys {
|
||
if k, ok := v.Interface().(int8); ok {
|
||
if pid, ook := s.RewardTyPIDMapCache[k]; ook {
|
||
pids = append(pids, pid)
|
||
}
|
||
}
|
||
}
|
||
sort.Slice(pids, func(i, j int) bool { //按奖励 类型对应id升序
|
||
return pids[i] < pids[j]
|
||
})
|
||
rkTypes := make([]int8, 0, len(keys)) //存储按照 奖励分类添加顺序排列的 奖励类型
|
||
for _, pid := range pids {
|
||
if ty, ok := s.RewardPIDTyMapCache[pid]; ok {
|
||
rkTypes = append(rkTypes, ty)
|
||
}
|
||
}
|
||
|
||
log.Info("RewardReceives mid(%d)|pids(%+v)|rkTypes(%+v)", mid, pids, rkTypes)
|
||
|
||
res = make([]*newcomer.RewardReceiveGroup, 0)
|
||
for _, k := range rkTypes {
|
||
|
||
item, ok := items[k]
|
||
if !ok || len(item) == 0 {
|
||
log.Error("RewardReceives items[k] k(%v) item(%+v) ok(%v)", k, item, ok)
|
||
return
|
||
}
|
||
|
||
pid, ok := s.RewardTyPIDMapCache[k]
|
||
if !ok || pid == 0 {
|
||
log.Error("RewardReceives s.RewardTyPIDMapCache[k] pid(%v) ok(%v)", pid, ok)
|
||
return
|
||
}
|
||
|
||
pr, ok := s.RewardMapCache[pid]
|
||
if !ok || pr == nil { //获取奖励类别名称和logo
|
||
log.Error("RewardReceives s.RewardMapCache[pid] pid(%d) pr(%+v) ok3(%v)", pid, pr, ok)
|
||
return
|
||
}
|
||
|
||
s0 := make([]*newcomer.RewardReceive, 0, len(item))
|
||
s1 := make([]*newcomer.RewardReceive, 0, len(item))
|
||
s2 := make([]*newcomer.RewardReceive, 0, len(item))
|
||
for _, v := range item {
|
||
r, ok := s.RewardMapCache[v.RewardID]
|
||
if !ok || r == nil {
|
||
log.Error("RewardReceives s.RewardMapCache[v.RewardID] v.RewardID(%v) r(%+v) ok(%v)", v.RewardID, r, ok)
|
||
return
|
||
}
|
||
|
||
v.RewardName = r.Name //获取奖品名称
|
||
var expireTime int64
|
||
if v.RewardType == newcomer.Bcoin { //奖品到期时间
|
||
expireTime = r.CTime.Time().Unix() + int64(r.Expire*24*3600)
|
||
v.ExpireTime = xtime.Time(expireTime) //B币券显示截止时间
|
||
} else {
|
||
expireTime = v.ReceiveTime.Time().Unix() + int64(r.Expire*24*3600)
|
||
v.ExpireTime = xtime.Time(expireTime)
|
||
}
|
||
// set RewardExpireNotClick state
|
||
if (time.Now().Unix() - expireTime) > 0 {
|
||
v.State = newcomer.RewardExpireNotClick
|
||
}
|
||
|
||
switch v.State { //按照0-可激活 >1-已激活不可点击>2-已过期不可点击 优先级展示
|
||
case newcomer.RewardCanActivate:
|
||
s0 = append(s0, v)
|
||
case newcomer.RewardActivatedNotClick:
|
||
s1 = append(s1, v)
|
||
case newcomer.RewardExpireNotClick:
|
||
s2 = append(s2, v)
|
||
}
|
||
}
|
||
|
||
r := &newcomer.RewardReceiveGroup{
|
||
Count: len(item),
|
||
RewardType: pr.Type,
|
||
RewardTypeName: pr.Name,
|
||
RewardTypeLogo: pr.Logo,
|
||
Comment: pr.Comment,
|
||
Items: append(append(s0, s1...), s2...),
|
||
}
|
||
res = append(res, r)
|
||
}
|
||
return
|
||
}
|
||
|
||
// TaskBind user bind tasks
|
||
func (s *Service) TaskBind(c context.Context, mid int64) (res int64, err error) {
|
||
count, err := s.CheckUserTaskBind(c, mid)
|
||
if err != nil {
|
||
return
|
||
}
|
||
if count > 0 {
|
||
err = ecode.CreativeNewcomerReBindTaskErr
|
||
return
|
||
}
|
||
|
||
// Determining the number of fans owned by users
|
||
profileStat, err := s.acc.ProfileWithStat(c, mid)
|
||
if err != nil {
|
||
log.Error("TaskBind s.acc.ProfileWithStat mid(%d)|error(%v)", mid, err)
|
||
return
|
||
}
|
||
log.Info("TaskBind s.acc.ProfileWithStat mid(%d)|follower(%d)", mid, profileStat.Follower)
|
||
var tasks []*newcomer.Task
|
||
if profileStat.Follower >= s.c.TaskCondition.Fans {
|
||
tasks = s.TaskTypeMapCache[newcomer.DefualtTaskType]
|
||
} else {
|
||
tasks = s.TaskTypeMapCache[newcomer.NewcomerTaskType]
|
||
}
|
||
|
||
args, placeStr := genBatchParamsBindTasks(tasks, mid)
|
||
res, err = s.newc.BindTasks(c, mid, placeStr, args)
|
||
if err != nil {
|
||
log.Error("TaskBind s.newc.BindTasks mid(%v)|error(%v)", mid, err)
|
||
return
|
||
}
|
||
|
||
// sync check task status
|
||
s.syncCheckTaskStatus(c, mid, tasks)
|
||
return
|
||
}
|
||
|
||
// genBatchParamsBindTasks generate batch insert parameters
|
||
func genBatchParamsBindTasks(tasks []*newcomer.Task, mid int64) ([]interface{}, string) {
|
||
place := make([]string, 0)
|
||
args := make([]interface{}, 0)
|
||
for _, v := range tasks {
|
||
place = append(place, "(?, ?, ?, ?, ?)")
|
||
args = append(args, mid, v.ID, v.GroupID, v.Type, -1)
|
||
}
|
||
placeStr := strings.Join(place, ",")
|
||
return args, placeStr
|
||
}
|
||
|
||
//CheckUserTaskBind determine if the user has bound the task
|
||
func (s *Service) CheckUserTaskBind(c context.Context, mid int64) (count int64, err error) {
|
||
count, err = s.newc.UserTaskBind(c, mid)
|
||
if err != nil {
|
||
log.Error("CheckUserTaskBind s.newc.UserTaskBind mid(%v)|error(%v)", mid, err)
|
||
return
|
||
}
|
||
return
|
||
}
|
||
|
||
//TaskMakeup fix unfinish task state
|
||
func (s *Service) TaskMakeup(c context.Context, mid int64) (err error) {
|
||
tasks, err := s.newc.UserTasks(c, mid)
|
||
if err != nil {
|
||
log.Error("TaskMakeup s.newc.UserTasks mid(%d)|error(%v)", mid, err)
|
||
err = ecode.RequestErr
|
||
return
|
||
}
|
||
infoTasks := s.getTasksInfoByType(tasks, newcomer.DefualtTaskType)
|
||
ts := make([]*newcomer.Task, 0)
|
||
for _, v := range infoTasks {
|
||
if v == nil {
|
||
continue
|
||
}
|
||
if v.CompleteSate == newcomer.TaskIncomplete {
|
||
ts = append(ts, v)
|
||
}
|
||
}
|
||
s.syncCheckTaskStatus(c, mid, ts)
|
||
return
|
||
}
|
||
|
||
//TaskPubList to apply task list
|
||
func (s *Service) TaskPubList(c context.Context, mid int64) (res *newcomer.PubTaskList, err error) {
|
||
res = &newcomer.PubTaskList{}
|
||
tasks, err := s.newc.UserTasks(c, mid)
|
||
if err != nil {
|
||
log.Error("PubTaskList s.newc.UserTasks mid(%d)|error(%v)", mid, err)
|
||
return
|
||
}
|
||
if len(tasks) == 0 {
|
||
log.Warn("PubTaskList No binding task | mid(%d)", mid)
|
||
res.TaskReceived = newcomer.NoBindTask
|
||
return
|
||
}
|
||
res.TaskReceived = newcomer.BindTask
|
||
ts := s.getTasksInfoByType(tasks, newcomer.DefualtTaskType)
|
||
if len(ts) == 0 {
|
||
log.Error("PubTaskList no task | mid(%d)", mid)
|
||
return
|
||
}
|
||
for _, task := range ts {
|
||
if task == nil {
|
||
continue
|
||
}
|
||
tt := &newcomer.PubTask{
|
||
ID: task.ID,
|
||
Title: task.Title,
|
||
Desc: task.Desc,
|
||
Type: task.Type,
|
||
State: task.CompleteSate,
|
||
}
|
||
res.Tasks = append(res.Tasks, tt)
|
||
}
|
||
|
||
return
|
||
}
|
||
|
||
// TaskList for task detail
|
||
func (s *Service) TaskList(c context.Context, mid int64, ty int8) (res *newcomer.TaskRewardList, err error) {
|
||
var (
|
||
u *UserTaskInfo
|
||
tasks []*newcomer.Task
|
||
taskTypeMap = make(map[int8][]*newcomer.Task)
|
||
taskGroupMap = make(map[int64][]*newcomer.Task)
|
||
)
|
||
|
||
// get user tasks
|
||
userTasks, err := s.newc.UserTasks(c, mid)
|
||
if err != nil {
|
||
log.Error("TaskList s.newc.UserTasks mid(%d)|error(%v)", mid, err)
|
||
return
|
||
}
|
||
if len(userTasks) == 0 {
|
||
// return :User did not receive the task
|
||
res = &newcomer.TaskRewardList{
|
||
TaskReceived: newcomer.NoBindTask,
|
||
TaskType: ty,
|
||
}
|
||
log.Warn("TaskList user did not receive the task mid(%d)", mid)
|
||
return
|
||
}
|
||
|
||
// get user info
|
||
u, err = s.getUserTaskInfo(c, mid, userTasks)
|
||
if err != nil {
|
||
return
|
||
}
|
||
|
||
// Judging according to the "user logic level", showing the task type
|
||
if ty == newcomer.DefualtTaskType {
|
||
ty = u.UserTaskLevel
|
||
} else if ty == newcomer.AdvancedTaskType {
|
||
if ty > u.UserTaskLevel {
|
||
log.Warn("TaskList user unlocked this task mid(%d)", mid)
|
||
// return :User has not unlocked this type of task
|
||
res = &newcomer.TaskRewardList{
|
||
TaskReceived: newcomer.BindTask,
|
||
TaskType: ty,
|
||
}
|
||
return
|
||
}
|
||
}
|
||
|
||
// get tasks
|
||
tasks = s.getTasksInfoByType(userTasks, newcomer.DefualtTaskType)
|
||
if len(tasks) == 0 {
|
||
err = ecode.CreativeNewcomerNoTask
|
||
log.Error("TaskList s.GetTaskByType len(tasks) == 0")
|
||
return
|
||
}
|
||
|
||
// group by groupID & taskType
|
||
for _, t := range tasks {
|
||
if t == nil {
|
||
continue
|
||
}
|
||
if t.Type == ty {
|
||
taskGroupMap[t.GroupID] = append(taskGroupMap[t.GroupID], t)
|
||
}
|
||
taskTypeMap[t.Type] = append(taskTypeMap[t.Type], t)
|
||
}
|
||
|
||
// task_kind
|
||
taskKinds := s.getTaskKindsData(u, taskTypeMap)
|
||
|
||
// task_gift
|
||
taskGift, err := s.getTaskGiftData(c, mid, taskTypeMap, newcomer.FromWeb)
|
||
if err != nil {
|
||
return
|
||
}
|
||
|
||
// task_groups
|
||
tgs, err := s.getTaskGroupData(c, mid, taskGroupMap)
|
||
if err != nil {
|
||
return
|
||
}
|
||
|
||
res = &newcomer.TaskRewardList{
|
||
TaskReceived: newcomer.BindTask,
|
||
TaskType: ty,
|
||
TaskKinds: taskKinds,
|
||
TaskGroups: tgs,
|
||
TaskGift: taskGift,
|
||
}
|
||
return
|
||
}
|
||
|
||
// getTaskGroupData for get task_group data
|
||
func (s *Service) getTaskGroupData(c context.Context, mid int64, taskMap map[int64][]*newcomer.Task) (tgs []*newcomer.TaskRewardGroup, err error) {
|
||
if len(taskMap) == 0 {
|
||
return
|
||
}
|
||
tgs = make([]*newcomer.TaskRewardGroup, 0, len(taskMap))
|
||
ranks := make([]int64, 0, len(taskMap))
|
||
groups := make([]int64, 0, len(taskMap))
|
||
rankGroupMap := make(map[int64]int64)
|
||
// sort by groupID
|
||
for key := range taskMap {
|
||
taskGroup, ok := s.TaskGroupMapCache[key]
|
||
if !ok {
|
||
continue
|
||
}
|
||
ranks = append(ranks, taskGroup.Rank)
|
||
groups = append(groups, key)
|
||
rankGroupMap[taskGroup.Rank] = key
|
||
}
|
||
sort.Slice(ranks, func(i, j int) bool {
|
||
return ranks[i] < ranks[j]
|
||
})
|
||
|
||
// get TaskRewardGroup
|
||
for _, k := range ranks {
|
||
taskGroup, ok := taskMap[rankGroupMap[k]]
|
||
if !ok || len(taskGroup) == 0 {
|
||
log.Error("genTaskGroupData taskGroup not exist ID(%d)", rankGroupMap[k])
|
||
continue
|
||
}
|
||
rewardState := newcomer.RewardNotAvailable //奖励领取状态
|
||
total := len(taskGroup) // 任务组总数
|
||
complete := s.getTaskCompleteCount(taskGroup) // 完成的任务数量
|
||
if complete == total {
|
||
rewardState = newcomer.RewardAvailable
|
||
}
|
||
rewards := s.getRewardsByGroupID(rankGroupMap[k]) // 任务组对应的奖励
|
||
|
||
tg := &newcomer.TaskRewardGroup{
|
||
TaskType: taskGroup[0].Type,
|
||
Tasks: taskGroup,
|
||
Rewards: rewards,
|
||
GroupID: rankGroupMap[k],
|
||
RewardState: int8(rewardState),
|
||
Completed: int64(complete),
|
||
Total: int64(total),
|
||
}
|
||
tgs = append(tgs, tg)
|
||
}
|
||
|
||
// determine if the reward is received
|
||
rewardRecvGroup, err := s.newc.RewardReceivedGroup(c, mid, groups)
|
||
if err != nil {
|
||
log.Error("genTaskGroupData s.newc.RewardReceivedGroup mid(%d)|error(%v)", mid, err)
|
||
return
|
||
}
|
||
for _, v := range tgs {
|
||
for _, j := range rewardRecvGroup {
|
||
if v.GroupID == int64(j) {
|
||
v.RewardState = newcomer.RewardReceived
|
||
}
|
||
}
|
||
}
|
||
return
|
||
}
|
||
|
||
// getTaskGiftData for get task_gift data
|
||
func (s *Service) getTaskGiftData(c context.Context, mid int64, taskTypeMap map[int8][]*newcomer.Task, from int8) (taskGift []*newcomer.TaskGift, err error) {
|
||
if len(taskTypeMap) == 0 {
|
||
return
|
||
}
|
||
taskGift = make([]*newcomer.TaskGift, 0, len(taskTypeMap))
|
||
// get gifts by taskType
|
||
gifts := make(map[int8][]*newcomer.Reward)
|
||
for k := range taskTypeMap {
|
||
gifts[k] = s.getRewardsByTaskType(k)
|
||
}
|
||
|
||
for tType, giftRewards := range gifts {
|
||
giftState := newcomer.RewardAvailable
|
||
complete := s.getTaskCompleteCount(taskTypeMap[tType])
|
||
total := len(taskTypeMap[tType])
|
||
if complete != total {
|
||
if from == newcomer.FromWeb {
|
||
giftState = newcomer.RewardNotAvailable
|
||
} else if from == newcomer.FromH5 {
|
||
giftState = newcomer.RewardUnlock
|
||
}
|
||
}
|
||
|
||
// judge the gift is received
|
||
isGiftReceived, err := s.newc.IsRewardReceived(c, mid, int64(tType), newcomer.RewardGiftType)
|
||
if err != nil {
|
||
log.Error("genTaskGiftData s.newc.IsGiftReceived mid(%d)|error(%v)", mid, err)
|
||
continue
|
||
}
|
||
if isGiftReceived {
|
||
giftState = newcomer.RewardReceived
|
||
}
|
||
|
||
tg := &newcomer.TaskGift{
|
||
State: int8(giftState),
|
||
Type: tType,
|
||
Rewards: giftRewards,
|
||
}
|
||
taskGift = append(taskGift, tg)
|
||
}
|
||
return
|
||
}
|
||
|
||
// getTaskKindsData for get task_kinds data
|
||
func (s *Service) getTaskKindsData(u *UserTaskInfo, taskTypeMap map[int8][]*newcomer.Task) (taskKinds []*newcomer.TaskKind) {
|
||
taskKinds = make([]*newcomer.TaskKind, 0, len(taskTypeMap))
|
||
for tType, tasks := range taskTypeMap {
|
||
complete := s.getTaskCompleteCount(tasks) // 完成数量
|
||
total := len(tasks) // 总数
|
||
state := newcomer.RewardNotAvailable // 完成状态
|
||
if complete == len(tasks) {
|
||
state = newcomer.RewardAvailable
|
||
}
|
||
kind := &newcomer.TaskKind{
|
||
Type: tType,
|
||
Completed: int64(complete),
|
||
Total: int64(total),
|
||
State: int8(state),
|
||
}
|
||
// determine the unlock type by user_task level
|
||
switch tType {
|
||
case newcomer.NewcomerTaskType:
|
||
taskKinds = append(taskKinds, kind)
|
||
case newcomer.AdvancedTaskType:
|
||
if u.UserTaskLevel == newcomer.UserTaskLevel01 {
|
||
kind.State = newcomer.RewardUnlock
|
||
}
|
||
taskKinds = append(taskKinds, kind)
|
||
}
|
||
}
|
||
return
|
||
}
|
||
|
||
// getTaskCompleteCount get tasks complete count
|
||
func (s *Service) getTaskCompleteCount(task []*newcomer.Task) int {
|
||
complete := 0
|
||
for _, t := range task {
|
||
if t == nil {
|
||
continue
|
||
}
|
||
if t.CompleteSate == newcomer.TaskCompleted {
|
||
complete++
|
||
}
|
||
}
|
||
return complete
|
||
}
|
||
|
||
// groupByTasks group by groupID & taskType
|
||
func (s *Service) groupByTasks(tasks []*newcomer.Task) (taskGroupMap map[int64][]*newcomer.Task, taskTypeMap map[int8][]*newcomer.Task) {
|
||
taskGroupMap = make(map[int64][]*newcomer.Task)
|
||
taskTypeMap = make(map[int8][]*newcomer.Task)
|
||
for _, t := range tasks {
|
||
if t == nil {
|
||
continue
|
||
}
|
||
taskGroupMap[t.GroupID] = append(taskGroupMap[t.GroupID], t)
|
||
taskTypeMap[t.Type] = append(taskTypeMap[t.Type], t)
|
||
}
|
||
return
|
||
}
|
||
|
||
// getReceiveKey get receive redis key
|
||
func (s *Service) getReceiveKey(oid int64, ty int8, mid int64) string {
|
||
return fmt.Sprintf("%d_%d_%d", oid, ty, mid)
|
||
}
|
||
|
||
// getActivateKey get active key
|
||
func (s *Service) getActivateKey(mid int64, id int64) string {
|
||
return fmt.Sprintf("%d_%d", mid, id)
|
||
}
|