task.go 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035
  1. package newcomer
  2. import (
  3. "context"
  4. "reflect"
  5. "sort"
  6. "strings"
  7. "time"
  8. "fmt"
  9. "go-common/app/interface/main/creative/model/newcomer"
  10. accapi "go-common/app/service/main/account/api"
  11. "go-common/library/ecode"
  12. "go-common/library/log"
  13. xtime "go-common/library/time"
  14. )
  15. const (
  16. creatorMID int64 = 37090048 //创作中心哔哩哔哩号
  17. msgPendantCode = "1_17_4"
  18. msgPendantTitle = "恭喜你通关UP主任务-新手任务!"
  19. msgPendantContent = "新手任务通关奖励“小试身手”头像挂件已发送至你的“个人中心-我的头像-我的挂件”中,快来查看和佩戴吧!更多任务奖励正在准备中,敬请期待哦~"
  20. )
  21. // UserTaskInfo def user task info
  22. type UserTaskInfo struct {
  23. Mid int64
  24. UserTaskLevel int8
  25. Follower int64
  26. IsChange bool
  27. }
  28. // AppIndexNewcomer index newcomer
  29. func (s *Service) AppIndexNewcomer(c context.Context, mid int64, plat string) (res *newcomer.AppIndexNewcomer, err error) {
  30. if !s.c.TaskCondition.AppIndexSwitch {
  31. return
  32. }
  33. var (
  34. count int64
  35. todoTasks []*newcomer.UserTask
  36. )
  37. res = &newcomer.AppIndexNewcomer{
  38. H5URL: s.c.H5Page.Mission,
  39. }
  40. // check task bind
  41. count, err = s.CheckUserTaskBind(c, mid)
  42. if err != nil {
  43. return
  44. }
  45. showTaskIDs := make([]int64, 0)
  46. if count > 0 {
  47. // already get tasks
  48. res.TaskReceived = newcomer.BindTask
  49. todoTasks, err = s.newc.UserTasksByMID(c, mid)
  50. if err != nil {
  51. log.Error("AppIndexNewcomer s.newc.UserTasks mid(%d)|error(%v)", mid, err)
  52. return
  53. }
  54. // get at most 2 tasks
  55. maxCnt := 0
  56. for _, v := range todoTasks {
  57. if maxCnt >= 2 {
  58. break
  59. }
  60. showTaskIDs = append(showTaskIDs, v.TaskID)
  61. maxCnt++
  62. }
  63. } else {
  64. // not bind
  65. res.TaskReceived = newcomer.NoBindTask
  66. if len(s.TaskCache) < 2 {
  67. return
  68. }
  69. for i := 0; i < 2; i++ {
  70. t := s.TaskCache[i]
  71. showTaskIDs = append(showTaskIDs, t.ID)
  72. }
  73. }
  74. // fill app tasks struct
  75. for _, v := range showTaskIDs {
  76. if t, ok := s.TaskMapCache[v]; ok {
  77. appt := &newcomer.AppTasks{
  78. ID: t.ID,
  79. Title: t.Title,
  80. Type: t.Type,
  81. }
  82. // get redirect url
  83. if _, ok := newcomer.TaskRedirectMap[plat]; ok {
  84. if r, ook := newcomer.TaskRedirectMap[plat][t.TargetType]; ook {
  85. appt.Label = r[0]
  86. appt.Redirect = r[1]
  87. }
  88. }
  89. res.AppTasks = append(res.AppTasks, appt)
  90. }
  91. }
  92. if len(res.AppTasks) == 0 {
  93. res = nil
  94. }
  95. return
  96. }
  97. // IndexNewcomer index newcomer
  98. func (s *Service) IndexNewcomer(c context.Context, mid int64) (res *newcomer.IndexNewcomer, err error) {
  99. res = &newcomer.IndexNewcomer{}
  100. // check task bind
  101. count, err := s.CheckUserTaskBind(c, mid)
  102. if err != nil {
  103. return
  104. }
  105. if count > 0 {
  106. res.TaskReceived = newcomer.BindTask
  107. } else {
  108. res.TaskReceived = newcomer.NoBindTask
  109. }
  110. var (
  111. upCount int // Number of submissions
  112. viewCount int64 // Number of plays
  113. )
  114. // if archives == 0 && plays == 0 , means zero data
  115. dt := time.Now().AddDate(0, 0, -1).Add(-12 * time.Hour).Format("20060102")
  116. stat, err := s.data.UpStat(c, mid, dt)
  117. if err != nil {
  118. log.Error("IndexNewcomer s.data.UpStat mid(%d)|error(%v)", mid, err)
  119. } else {
  120. viewCount = stat.View
  121. }
  122. up, err := s.arc.UpCount(c, mid)
  123. if err != nil {
  124. log.Error("IndexNewcomer s.arc.UpCount mid(%d)|error(%v)", mid, err)
  125. } else {
  126. upCount = up
  127. }
  128. log.Info("IndexNewcomer mid(%d)|stat.view(%d)|upcount(%d)", mid, viewCount, upCount)
  129. if upCount > 0 || viewCount > 0 {
  130. log.Info("IndexNewcomer upCount>0||viewCount>0 mid(%d)|stat.view(%d)|upcount(%d)", mid, viewCount, upCount)
  131. // check no receive reward
  132. noReceiveCount := 0
  133. noReceiveCount, CountErr := s.getNoReceiveRewardCount(c, mid)
  134. if CountErr != nil {
  135. log.Error("IndexNewcomer s.newc.noReceiveRewardCount mid(%d)|error(%v)", mid, err)
  136. }
  137. res.NoReceive = noReceiveCount
  138. res.SubZero = false
  139. } else {
  140. res.SubZero = true
  141. }
  142. // add three task
  143. tasks := make([]*newcomer.Task, 0)
  144. if len(s.TaskCache) > 3 {
  145. for i := 0; i < 3; i++ {
  146. tasks = append(tasks, s.TaskCache[i])
  147. }
  148. res.Tasks = tasks
  149. } else {
  150. log.Error("IndexNewcomer s.newc len(s.TaskCache)<3 mid(%d)|error(%v)", mid, err)
  151. }
  152. return
  153. }
  154. // getNoReceiveRewardCount get no receive reward count
  155. func (s *Service) getNoReceiveRewardCount(c context.Context, mid int64) (count int, err error) {
  156. userTasks, err := s.newc.UserTasks(c, mid)
  157. if err != nil {
  158. log.Error("getNoReceiveRewardCount s.newc.UserTasks mid(%d)|error(%v)", mid, err)
  159. return
  160. }
  161. tasks := s.getTasksInfoByType(userTasks, newcomer.DefualtTaskType)
  162. if len(tasks) == 0 {
  163. return
  164. }
  165. var (
  166. taskGroupMap map[int64][]*newcomer.Task
  167. taskTypeMap map[int8][]*newcomer.Task
  168. availableCount int
  169. receivedCount int
  170. groupIDs []int64
  171. giftIDs []int64
  172. )
  173. // group by groupID & taskType
  174. taskGroupMap, taskTypeMap = s.groupByTasks(tasks)
  175. groupIDs = make([]int64, 0, len(taskGroupMap))
  176. for k, v := range taskGroupMap {
  177. if _, ok := s.TaskGroupRewardMapCache[k]; ok {
  178. if s.getTaskCompleteCount(v) == len(v) {
  179. availableCount++
  180. }
  181. groupIDs = append(groupIDs, k)
  182. }
  183. }
  184. giftIDs = make([]int64, 0, len(taskTypeMap))
  185. for k, v := range taskTypeMap {
  186. if _, ok := s.GiftRewardMapCache[k]; ok {
  187. if s.getTaskCompleteCount(v) == len(v) {
  188. availableCount++
  189. }
  190. giftIDs = append(giftIDs, int64(k))
  191. }
  192. }
  193. r1, err := s.newc.BaseRewardCount(c, mid, groupIDs) // 基础奖励 已领取个数
  194. if err != nil {
  195. log.Error("getNoReceiveRewardCount s.newc.BaseRewardCount mid(%v)|error(%v)", mid, err)
  196. return
  197. }
  198. r2, err := s.newc.GiftRewardCount(c, mid, giftIDs) // 礼包奖励 已领取个数
  199. if err != nil {
  200. log.Error("getNoReceiveRewardCount s.newc.GiftRewardCount mid(%v)|error(%v)", mid, err)
  201. return
  202. }
  203. receivedCount = int(r1 + r2)
  204. // 可领取未领取的奖励 = 可领取 - 已领取
  205. count = availableCount - receivedCount
  206. if count < 0 {
  207. count = 0
  208. }
  209. log.Info("getNoReceiveRewardCount mid(%d)|availableCount(%d)|receivedCount(%d)|count(%d)", mid, availableCount, receivedCount, count)
  210. return
  211. }
  212. // getUserTaskInfo determine the userTaskLevel
  213. func (s *Service) getUserTaskInfo(c context.Context, mid int64, tasks []*newcomer.Task) (u *UserTaskInfo, err error) {
  214. u = &UserTaskInfo{
  215. Mid: mid,
  216. UserTaskLevel: newcomer.UserTaskLevel01,
  217. IsChange: false,
  218. }
  219. var (
  220. count int // Number of unfinished novice tasks
  221. follower int64
  222. profileStat *accapi.ProfileStatReply
  223. taskTypeMap map[int8][]*newcomer.Task
  224. taskMap map[int64]*newcomer.Task
  225. )
  226. // whether the advanced task is hidden
  227. if s.isHiddenTaskType(newcomer.AdvancedTaskType) {
  228. u.UserTaskLevel = newcomer.UserTaskLevel01
  229. return
  230. }
  231. taskMap = make(map[int64]*newcomer.Task)
  232. taskTypeMap = make(map[int8][]*newcomer.Task)
  233. for _, task := range tasks {
  234. if task == nil {
  235. continue
  236. }
  237. t, ok := s.TaskMapCache[task.ID]
  238. if !ok {
  239. continue
  240. }
  241. tp := *t
  242. tp.CompleteSate = task.CompleteSate
  243. taskTypeMap[tp.Type] = append(taskTypeMap[tp.Type], &tp)
  244. taskMap[tp.ID] = &tp
  245. }
  246. // If the user already has an advanced task, return UserTaskLevel02
  247. if _, ok := taskTypeMap[newcomer.AdvancedTaskType]; ok {
  248. u.UserTaskLevel = newcomer.UserTaskLevel02
  249. return
  250. }
  251. // Calculate whether the novice task is not fully completed (compare with cache)
  252. newcomerTasks := s.getTasksByType(newcomer.NewcomerTaskType)
  253. if len(newcomerTasks) == 0 {
  254. return
  255. }
  256. count = len(newcomerTasks)
  257. for _, t := range newcomerTasks {
  258. if task, ok := taskMap[t.ID]; ok {
  259. if task.CompleteSate == newcomer.TaskCompleted {
  260. count--
  261. }
  262. }
  263. }
  264. // judge fans count
  265. profileStat, profileErr := s.acc.ProfileWithStat(c, mid)
  266. if profileStat == nil || profileErr != nil {
  267. log.Error("genUserTaskInfo s.acc.ProfileWithStat mid(%d)|error(%v)", mid, err)
  268. follower = 0
  269. } else {
  270. follower = profileStat.Follower
  271. }
  272. //Number of unfinished tasks || fans >=100
  273. if count == 0 || follower >= s.c.TaskCondition.Fans {
  274. // insert advancedTask
  275. tasks = s.TaskTypeMapCache[newcomer.AdvancedTaskType]
  276. if len(tasks) == 0 {
  277. log.Warn("genUserTaskInfo no taskType==newcomer.AdvancedTaskType mid(%d)", mid)
  278. return
  279. }
  280. args, placeStr := genBatchParamsBindTasks(tasks, mid)
  281. _, err = s.newc.BindTasks(c, mid, placeStr, args)
  282. if err != nil {
  283. log.Error("genUserTaskInfo s.newc.BindTasks mid(%d)|error(%v)", mid, err)
  284. return
  285. }
  286. u.UserTaskLevel = newcomer.UserTaskLevel02
  287. u.IsChange = true // user level changed
  288. s.putCheckTaskState(mid) // add to checkTaskQueue
  289. }
  290. return
  291. }
  292. //RewardReceive insert reward receive records.
  293. func (s *Service) RewardReceive(c context.Context, mid int64, rid int64, ty int8, ip string) (res string, err error) {
  294. var (
  295. rewardIDs []int64
  296. rewards []*newcomer.Reward
  297. lockSuccess bool
  298. )
  299. // check completed
  300. err = s.isRewardComplete(c, mid, rid, ty)
  301. if err != nil {
  302. return
  303. }
  304. // prevent concurrent collection
  305. key := s.getReceiveKey(rid, ty, mid)
  306. if lockSuccess, err = s.newc.Lock(c, key, 1000); !lockSuccess || err != nil {
  307. if err == nil {
  308. log.Info("RewardReceive s.newc.Lock mid(%d)|rid(%d)|ty(%d)", mid, rid, ty)
  309. res = s.c.TaskCondition.ReceiveMsg
  310. return
  311. }
  312. log.Error("RewardReceive s.newc.Lock mid(%d)|rid(%d)|ty(%d)|error(%v)", mid, rid, ty, err)
  313. }
  314. // check received
  315. err = s.isRewardReceived(c, mid, rid, ty)
  316. if err != nil {
  317. return
  318. }
  319. // get rewards
  320. if ty == newcomer.RewardGiftType {
  321. rewardIDs, err = s.newc.GiftRewards(c, int8(rid))
  322. if err != nil {
  323. log.Error("RewardReceive s.newc.GiftRewards mid(%d)|rewardID(%d)|ty(%d)|err(%v)", mid, rid, ty, err)
  324. return
  325. }
  326. } else {
  327. rewardIDs, err = s.newc.TaskGroupRewards(c, rid)
  328. if err != nil {
  329. log.Error("RewardReceive s.newc.TaskGroupRewards mid(%d)|rewardID(%d)|ty(%d)|err(%v)", mid, rid, ty, err)
  330. return
  331. }
  332. }
  333. if len(rewardIDs) == 0 {
  334. err = ecode.RequestErr
  335. return
  336. }
  337. rewards = make([]*newcomer.Reward, 0)
  338. for _, v := range rewardIDs {
  339. if r, ok := s.RewardMapCache[v]; ok {
  340. rewards = append(rewards, r)
  341. }
  342. }
  343. // get user info
  344. profile, err := s.acc.Profile(c, mid, ip)
  345. if err != nil || profile == nil {
  346. log.Error("RewardReceive s.acc.Profile mid(%d)|rewardID(%d)|ty(%d)|err(%v)", mid, rid, ty, err)
  347. return
  348. }
  349. // receive rewards
  350. rrs := make([]*newcomer.RewardReceive2, 0)
  351. for _, v := range rewards {
  352. r := &newcomer.RewardReceive2{}
  353. r.MID = mid
  354. r.OID = rid
  355. r.Type = ty
  356. r.RewardID = v.ID
  357. r.RewardType = v.Type
  358. if v.IsActive == newcomer.RewardNeedActivate {
  359. r.State = newcomer.RewardCanActivate
  360. } else {
  361. err = s.callBusiness(c, profile, v)
  362. if err != nil {
  363. log.Error("RewardReceive s.callBusiness mid(%d)|reward(%+v)|error(%v)", mid, v, err)
  364. r.State = newcomer.RewardCanActivate
  365. } else {
  366. r.State = newcomer.RewardActivatedNotClick
  367. }
  368. }
  369. rrs = append(rrs, r)
  370. }
  371. _, err = s.newc.RewardReceive2(c, mid, rrs)
  372. if err != nil {
  373. log.Error("RewardReceive s.newc.RewardReceive mid(%d)|rewardID(%d)|ty(%d)|err(%v)", mid, rid, ty, err)
  374. s.newc.UnLock(c, key)
  375. return
  376. }
  377. res = s.c.TaskCondition.ReceiveMsg
  378. log.Info("RewardReceive success mid(%d)|rewardID(%d)|ty(%d)", mid, rid, ty)
  379. return
  380. }
  381. // Determine if the reward can be collected
  382. func (s *Service) isRewardComplete(c context.Context, mid int64, rid int64, ty int8) error {
  383. tids := make([]int64, 0)
  384. tasks := make([]*newcomer.Task, 0)
  385. if ty == newcomer.RewardBaseType {
  386. tasks = s.getTasksByGroupID(rid)
  387. } else if ty == newcomer.RewardGiftType {
  388. tasks = s.getTasksByType(int8(rid))
  389. }
  390. for _, t := range tasks {
  391. if t == nil {
  392. continue
  393. }
  394. tids = append(tids, t.ID)
  395. }
  396. if len(tids) == 0 {
  397. log.Error("isRewardComplete len(tids) == 0 | mid(%d)", mid)
  398. return ecode.CreativeNewcomerNotCompleteErr
  399. }
  400. count, err := s.newc.RewardCompleteState(c, mid, tids)
  401. if err != nil {
  402. log.Error("isRewardComplete s.newc.RewardCompleteState mid(%d)|rewardID(%d)|ty(%d)|err(%v)", mid, rid, ty, err)
  403. return err
  404. }
  405. if count != 0 {
  406. err = ecode.CreativeNewcomerNotCompleteErr
  407. log.Error("isRewardComplete mission not completed mid(%d)|rewardID(%d)|ty(%d)|err(%v)", mid, rid, ty, err)
  408. return err
  409. }
  410. return nil
  411. }
  412. // Determine whether to receive it repeatedly
  413. func (s *Service) isRewardReceived(c context.Context, mid int64, rid int64, ty int8) error {
  414. isReceived, err := s.newc.IsRewardReceived(c, mid, rid, ty)
  415. if err != nil {
  416. log.Error("isRewardReceived s.newc.IsGiftReceived mid(%d)|rewardID(%d)|ty(%d)|err(%v)", mid, rid, ty, err)
  417. return err
  418. }
  419. if isReceived {
  420. err = ecode.CreativeNewcomerRepeatRewardErr
  421. log.Error("isRewardReceived receive multiple times mid(%d)|rewardID(%d)|ty(%d)|err(%v)", mid, rid, ty, err)
  422. return err
  423. }
  424. return nil
  425. }
  426. // Calling the business side interface
  427. func (s *Service) callBusiness(c context.Context, profile *accapi.Profile, v *newcomer.Reward) (err error) {
  428. switch v.Type {
  429. case newcomer.Bcoin: //B币券
  430. err = s.newc.BCoin(c, profile.Mid, v.PriceID, int64(v.PrizeUnit))
  431. case newcomer.MemberBuy: //会员购
  432. err = s.newc.Mall(c, profile.Mid, v.PriceID, profile.Name)
  433. case newcomer.IncentivePlan: //激励计划
  434. err = s.SendRewardReceiveLog(c, profile.Mid)
  435. case newcomer.BigMember: //大会员服务
  436. err = s.newc.BigMemberCoupon(c, profile.Mid, v.PriceID)
  437. case newcomer.PersonalCenter: //个人中心
  438. err = s.newc.Pendant(c, profile.Mid, v.PriceID, int64(v.Expire))
  439. if err != nil {
  440. return
  441. }
  442. //发送消息通知
  443. if e := s.newc.SendNotify(c, []int64{profile.Mid}, msgPendantCode, msgPendantTitle, msgPendantContent); e != nil {
  444. log.Error("callBusiness s.newc.SendNotify mid(%d)|err(%v)", profile.Mid, err)
  445. }
  446. }
  447. return
  448. }
  449. //RewardActivate insert reward receive records.
  450. func (s *Service) RewardActivate(c context.Context, mid, id int64, ip string) (res int64, err error) {
  451. r, err := s.newc.RewardReceiveByID(c, mid, id)
  452. if err != nil {
  453. log.Error("RewardActivate s.newc.RewardIDByReceiveID mid(%d)|receiveID(%d)|err(%v)", mid, id, err)
  454. return
  455. }
  456. // check repeat collection
  457. if r.State != newcomer.RewardCanActivate {
  458. err = ecode.CreativeNewcomerRepeatRewardErr
  459. log.Error("RewardActivate check repeat collection mid(%d)|receiveID(%d)|state(%d)|err(%v)", mid, id, r.State, err)
  460. return
  461. }
  462. // check expire
  463. reward, ok := s.RewardMapCache[r.RewardID]
  464. if !ok || reward == nil {
  465. err = ecode.RequestErr
  466. log.Error("RewardActivate check expire mid(%d)|receiveID(%d)|rewardID(%d)|err(%v)", mid, id, r.RewardID, err)
  467. return
  468. }
  469. var expireTime int64
  470. if r.RewardType == newcomer.Bcoin { //奖品到期时间
  471. expireTime = reward.CTime.Time().Unix() + int64(reward.Expire*24*3600) //B币券显示截止时间
  472. } else {
  473. expireTime = r.ReceiveTime.Time().Unix() + int64(reward.Expire*24*3600)
  474. }
  475. if (time.Now().Unix() - expireTime) > 0 {
  476. err = ecode.CreativeNewcomerReceiveExpireErr
  477. log.Error("RewardActivate check expire mid(%d)|receiveID(%d)|rewardID(%d)|err(%v)", mid, id, r.RewardID, err)
  478. return
  479. }
  480. // get new receive record
  481. nr, err := s.newc.RewardReceiveByOldInfo(c, r)
  482. if err != nil || nr == nil {
  483. log.Error("RewardActivate s.newc.RewardReceiveByOldInfo mid(%d)|receive(%+v)|error(%v)", mid, r, err)
  484. return
  485. }
  486. // prevent concurrent collection
  487. var lockSuccess bool
  488. key := s.getActivateKey(mid, id)
  489. if lockSuccess, err = s.newc.Lock(c, key, 1000); !lockSuccess || err != nil {
  490. if err == nil {
  491. log.Info("RewardActivate s.newc.Lock mid(%d)|id(%d)", mid, id)
  492. res = 0
  493. return
  494. }
  495. log.Error("RewardActivate s.newc.Lock mid(%d)|id(%d)|error(%v)", mid, id, err)
  496. }
  497. profile, err := s.acc.Profile(c, mid, ip)
  498. if err != nil || profile == nil {
  499. log.Error("RewardActivate s.acc.Profile mid(%d)|receiveID(%d)|rewardID(%d)|err(%v)", mid, id, r.RewardID, err)
  500. return
  501. }
  502. if err = s.callBusiness(c, profile, reward); err != nil {
  503. log.Error("RewardActivate callBusiness mid(%d)|receiveID(%d)|rewardID(%d)|err(%v)", mid, id, r.RewardID, err)
  504. return
  505. }
  506. res, err = s.newc.RewardActivate2(c, mid, id, nr.ID)
  507. if err != nil {
  508. log.Error("s.newc.RewardActivate mid(%d)|id(%d)|err(%v)", mid, id, err)
  509. s.newc.UnLock(c, key)
  510. return
  511. }
  512. log.Info("RewardActivate success mid(%d)|receiveID(%d)", mid, id)
  513. return
  514. }
  515. //RewardReceives get reward receive records.
  516. func (s *Service) RewardReceives(c context.Context, mid int64) (res []*newcomer.RewardReceiveGroup, err error) {
  517. var items map[int8][]*newcomer.RewardReceive
  518. items, err = s.newc.RewardReceives(c, mid)
  519. if err != nil {
  520. log.Error("s.newc.RewardReceives mid(%d)|err(%v)", mid, err)
  521. return
  522. }
  523. if len(items) == 0 {
  524. log.Error("s.newc.RewardReceives len(items) == 0")
  525. return
  526. }
  527. keys := reflect.ValueOf(items).MapKeys()
  528. pids := make([]int64, 0, len(keys)) //存储当前奖励 类型对应的 分类id
  529. for _, v := range keys {
  530. if k, ok := v.Interface().(int8); ok {
  531. if pid, ook := s.RewardTyPIDMapCache[k]; ook {
  532. pids = append(pids, pid)
  533. }
  534. }
  535. }
  536. sort.Slice(pids, func(i, j int) bool { //按奖励 类型对应id升序
  537. return pids[i] < pids[j]
  538. })
  539. rkTypes := make([]int8, 0, len(keys)) //存储按照 奖励分类添加顺序排列的 奖励类型
  540. for _, pid := range pids {
  541. if ty, ok := s.RewardPIDTyMapCache[pid]; ok {
  542. rkTypes = append(rkTypes, ty)
  543. }
  544. }
  545. log.Info("RewardReceives mid(%d)|pids(%+v)|rkTypes(%+v)", mid, pids, rkTypes)
  546. res = make([]*newcomer.RewardReceiveGroup, 0)
  547. for _, k := range rkTypes {
  548. item, ok := items[k]
  549. if !ok || len(item) == 0 {
  550. log.Error("RewardReceives items[k] k(%v) item(%+v) ok(%v)", k, item, ok)
  551. return
  552. }
  553. pid, ok := s.RewardTyPIDMapCache[k]
  554. if !ok || pid == 0 {
  555. log.Error("RewardReceives s.RewardTyPIDMapCache[k] pid(%v) ok(%v)", pid, ok)
  556. return
  557. }
  558. pr, ok := s.RewardMapCache[pid]
  559. if !ok || pr == nil { //获取奖励类别名称和logo
  560. log.Error("RewardReceives s.RewardMapCache[pid] pid(%d) pr(%+v) ok3(%v)", pid, pr, ok)
  561. return
  562. }
  563. s0 := make([]*newcomer.RewardReceive, 0, len(item))
  564. s1 := make([]*newcomer.RewardReceive, 0, len(item))
  565. s2 := make([]*newcomer.RewardReceive, 0, len(item))
  566. for _, v := range item {
  567. r, ok := s.RewardMapCache[v.RewardID]
  568. if !ok || r == nil {
  569. log.Error("RewardReceives s.RewardMapCache[v.RewardID] v.RewardID(%v) r(%+v) ok(%v)", v.RewardID, r, ok)
  570. return
  571. }
  572. v.RewardName = r.Name //获取奖品名称
  573. var expireTime int64
  574. if v.RewardType == newcomer.Bcoin { //奖品到期时间
  575. expireTime = r.CTime.Time().Unix() + int64(r.Expire*24*3600)
  576. v.ExpireTime = xtime.Time(expireTime) //B币券显示截止时间
  577. } else {
  578. expireTime = v.ReceiveTime.Time().Unix() + int64(r.Expire*24*3600)
  579. v.ExpireTime = xtime.Time(expireTime)
  580. }
  581. // set RewardExpireNotClick state
  582. if (time.Now().Unix() - expireTime) > 0 {
  583. v.State = newcomer.RewardExpireNotClick
  584. }
  585. switch v.State { //按照0-可激活 >1-已激活不可点击>2-已过期不可点击 优先级展示
  586. case newcomer.RewardCanActivate:
  587. s0 = append(s0, v)
  588. case newcomer.RewardActivatedNotClick:
  589. s1 = append(s1, v)
  590. case newcomer.RewardExpireNotClick:
  591. s2 = append(s2, v)
  592. }
  593. }
  594. r := &newcomer.RewardReceiveGroup{
  595. Count: len(item),
  596. RewardType: pr.Type,
  597. RewardTypeName: pr.Name,
  598. RewardTypeLogo: pr.Logo,
  599. Comment: pr.Comment,
  600. Items: append(append(s0, s1...), s2...),
  601. }
  602. res = append(res, r)
  603. }
  604. return
  605. }
  606. // TaskBind user bind tasks
  607. func (s *Service) TaskBind(c context.Context, mid int64) (res int64, err error) {
  608. count, err := s.CheckUserTaskBind(c, mid)
  609. if err != nil {
  610. return
  611. }
  612. if count > 0 {
  613. err = ecode.CreativeNewcomerReBindTaskErr
  614. return
  615. }
  616. // Determining the number of fans owned by users
  617. profileStat, err := s.acc.ProfileWithStat(c, mid)
  618. if err != nil {
  619. log.Error("TaskBind s.acc.ProfileWithStat mid(%d)|error(%v)", mid, err)
  620. return
  621. }
  622. log.Info("TaskBind s.acc.ProfileWithStat mid(%d)|follower(%d)", mid, profileStat.Follower)
  623. var tasks []*newcomer.Task
  624. if profileStat.Follower >= s.c.TaskCondition.Fans {
  625. tasks = s.TaskTypeMapCache[newcomer.DefualtTaskType]
  626. } else {
  627. tasks = s.TaskTypeMapCache[newcomer.NewcomerTaskType]
  628. }
  629. args, placeStr := genBatchParamsBindTasks(tasks, mid)
  630. res, err = s.newc.BindTasks(c, mid, placeStr, args)
  631. if err != nil {
  632. log.Error("TaskBind s.newc.BindTasks mid(%v)|error(%v)", mid, err)
  633. return
  634. }
  635. // sync check task status
  636. s.syncCheckTaskStatus(c, mid, tasks)
  637. return
  638. }
  639. // genBatchParamsBindTasks generate batch insert parameters
  640. func genBatchParamsBindTasks(tasks []*newcomer.Task, mid int64) ([]interface{}, string) {
  641. place := make([]string, 0)
  642. args := make([]interface{}, 0)
  643. for _, v := range tasks {
  644. place = append(place, "(?, ?, ?, ?, ?)")
  645. args = append(args, mid, v.ID, v.GroupID, v.Type, -1)
  646. }
  647. placeStr := strings.Join(place, ",")
  648. return args, placeStr
  649. }
  650. //CheckUserTaskBind determine if the user has bound the task
  651. func (s *Service) CheckUserTaskBind(c context.Context, mid int64) (count int64, err error) {
  652. count, err = s.newc.UserTaskBind(c, mid)
  653. if err != nil {
  654. log.Error("CheckUserTaskBind s.newc.UserTaskBind mid(%v)|error(%v)", mid, err)
  655. return
  656. }
  657. return
  658. }
  659. //TaskMakeup fix unfinish task state
  660. func (s *Service) TaskMakeup(c context.Context, mid int64) (err error) {
  661. tasks, err := s.newc.UserTasks(c, mid)
  662. if err != nil {
  663. log.Error("TaskMakeup s.newc.UserTasks mid(%d)|error(%v)", mid, err)
  664. err = ecode.RequestErr
  665. return
  666. }
  667. infoTasks := s.getTasksInfoByType(tasks, newcomer.DefualtTaskType)
  668. ts := make([]*newcomer.Task, 0)
  669. for _, v := range infoTasks {
  670. if v == nil {
  671. continue
  672. }
  673. if v.CompleteSate == newcomer.TaskIncomplete {
  674. ts = append(ts, v)
  675. }
  676. }
  677. s.syncCheckTaskStatus(c, mid, ts)
  678. return
  679. }
  680. //TaskPubList to apply task list
  681. func (s *Service) TaskPubList(c context.Context, mid int64) (res *newcomer.PubTaskList, err error) {
  682. res = &newcomer.PubTaskList{}
  683. tasks, err := s.newc.UserTasks(c, mid)
  684. if err != nil {
  685. log.Error("PubTaskList s.newc.UserTasks mid(%d)|error(%v)", mid, err)
  686. return
  687. }
  688. if len(tasks) == 0 {
  689. log.Warn("PubTaskList No binding task | mid(%d)", mid)
  690. res.TaskReceived = newcomer.NoBindTask
  691. return
  692. }
  693. res.TaskReceived = newcomer.BindTask
  694. ts := s.getTasksInfoByType(tasks, newcomer.DefualtTaskType)
  695. if len(ts) == 0 {
  696. log.Error("PubTaskList no task | mid(%d)", mid)
  697. return
  698. }
  699. for _, task := range ts {
  700. if task == nil {
  701. continue
  702. }
  703. tt := &newcomer.PubTask{
  704. ID: task.ID,
  705. Title: task.Title,
  706. Desc: task.Desc,
  707. Type: task.Type,
  708. State: task.CompleteSate,
  709. }
  710. res.Tasks = append(res.Tasks, tt)
  711. }
  712. return
  713. }
  714. // TaskList for task detail
  715. func (s *Service) TaskList(c context.Context, mid int64, ty int8) (res *newcomer.TaskRewardList, err error) {
  716. var (
  717. u *UserTaskInfo
  718. tasks []*newcomer.Task
  719. taskTypeMap = make(map[int8][]*newcomer.Task)
  720. taskGroupMap = make(map[int64][]*newcomer.Task)
  721. )
  722. // get user tasks
  723. userTasks, err := s.newc.UserTasks(c, mid)
  724. if err != nil {
  725. log.Error("TaskList s.newc.UserTasks mid(%d)|error(%v)", mid, err)
  726. return
  727. }
  728. if len(userTasks) == 0 {
  729. // return :User did not receive the task
  730. res = &newcomer.TaskRewardList{
  731. TaskReceived: newcomer.NoBindTask,
  732. TaskType: ty,
  733. }
  734. log.Warn("TaskList user did not receive the task mid(%d)", mid)
  735. return
  736. }
  737. // get user info
  738. u, err = s.getUserTaskInfo(c, mid, userTasks)
  739. if err != nil {
  740. return
  741. }
  742. // Judging according to the "user logic level", showing the task type
  743. if ty == newcomer.DefualtTaskType {
  744. ty = u.UserTaskLevel
  745. } else if ty == newcomer.AdvancedTaskType {
  746. if ty > u.UserTaskLevel {
  747. log.Warn("TaskList user unlocked this task mid(%d)", mid)
  748. // return :User has not unlocked this type of task
  749. res = &newcomer.TaskRewardList{
  750. TaskReceived: newcomer.BindTask,
  751. TaskType: ty,
  752. }
  753. return
  754. }
  755. }
  756. // get tasks
  757. tasks = s.getTasksInfoByType(userTasks, newcomer.DefualtTaskType)
  758. if len(tasks) == 0 {
  759. err = ecode.CreativeNewcomerNoTask
  760. log.Error("TaskList s.GetTaskByType len(tasks) == 0")
  761. return
  762. }
  763. // group by groupID & taskType
  764. for _, t := range tasks {
  765. if t == nil {
  766. continue
  767. }
  768. if t.Type == ty {
  769. taskGroupMap[t.GroupID] = append(taskGroupMap[t.GroupID], t)
  770. }
  771. taskTypeMap[t.Type] = append(taskTypeMap[t.Type], t)
  772. }
  773. // task_kind
  774. taskKinds := s.getTaskKindsData(u, taskTypeMap)
  775. // task_gift
  776. taskGift, err := s.getTaskGiftData(c, mid, taskTypeMap, newcomer.FromWeb)
  777. if err != nil {
  778. return
  779. }
  780. // task_groups
  781. tgs, err := s.getTaskGroupData(c, mid, taskGroupMap)
  782. if err != nil {
  783. return
  784. }
  785. res = &newcomer.TaskRewardList{
  786. TaskReceived: newcomer.BindTask,
  787. TaskType: ty,
  788. TaskKinds: taskKinds,
  789. TaskGroups: tgs,
  790. TaskGift: taskGift,
  791. }
  792. return
  793. }
  794. // getTaskGroupData for get task_group data
  795. func (s *Service) getTaskGroupData(c context.Context, mid int64, taskMap map[int64][]*newcomer.Task) (tgs []*newcomer.TaskRewardGroup, err error) {
  796. if len(taskMap) == 0 {
  797. return
  798. }
  799. tgs = make([]*newcomer.TaskRewardGroup, 0, len(taskMap))
  800. ranks := make([]int64, 0, len(taskMap))
  801. groups := make([]int64, 0, len(taskMap))
  802. rankGroupMap := make(map[int64]int64)
  803. // sort by groupID
  804. for key := range taskMap {
  805. taskGroup, ok := s.TaskGroupMapCache[key]
  806. if !ok {
  807. continue
  808. }
  809. ranks = append(ranks, taskGroup.Rank)
  810. groups = append(groups, key)
  811. rankGroupMap[taskGroup.Rank] = key
  812. }
  813. sort.Slice(ranks, func(i, j int) bool {
  814. return ranks[i] < ranks[j]
  815. })
  816. // get TaskRewardGroup
  817. for _, k := range ranks {
  818. taskGroup, ok := taskMap[rankGroupMap[k]]
  819. if !ok || len(taskGroup) == 0 {
  820. log.Error("genTaskGroupData taskGroup not exist ID(%d)", rankGroupMap[k])
  821. continue
  822. }
  823. rewardState := newcomer.RewardNotAvailable //奖励领取状态
  824. total := len(taskGroup) // 任务组总数
  825. complete := s.getTaskCompleteCount(taskGroup) // 完成的任务数量
  826. if complete == total {
  827. rewardState = newcomer.RewardAvailable
  828. }
  829. rewards := s.getRewardsByGroupID(rankGroupMap[k]) // 任务组对应的奖励
  830. tg := &newcomer.TaskRewardGroup{
  831. TaskType: taskGroup[0].Type,
  832. Tasks: taskGroup,
  833. Rewards: rewards,
  834. GroupID: rankGroupMap[k],
  835. RewardState: int8(rewardState),
  836. Completed: int64(complete),
  837. Total: int64(total),
  838. }
  839. tgs = append(tgs, tg)
  840. }
  841. // determine if the reward is received
  842. rewardRecvGroup, err := s.newc.RewardReceivedGroup(c, mid, groups)
  843. if err != nil {
  844. log.Error("genTaskGroupData s.newc.RewardReceivedGroup mid(%d)|error(%v)", mid, err)
  845. return
  846. }
  847. for _, v := range tgs {
  848. for _, j := range rewardRecvGroup {
  849. if v.GroupID == int64(j) {
  850. v.RewardState = newcomer.RewardReceived
  851. }
  852. }
  853. }
  854. return
  855. }
  856. // getTaskGiftData for get task_gift data
  857. func (s *Service) getTaskGiftData(c context.Context, mid int64, taskTypeMap map[int8][]*newcomer.Task, from int8) (taskGift []*newcomer.TaskGift, err error) {
  858. if len(taskTypeMap) == 0 {
  859. return
  860. }
  861. taskGift = make([]*newcomer.TaskGift, 0, len(taskTypeMap))
  862. // get gifts by taskType
  863. gifts := make(map[int8][]*newcomer.Reward)
  864. for k := range taskTypeMap {
  865. gifts[k] = s.getRewardsByTaskType(k)
  866. }
  867. for tType, giftRewards := range gifts {
  868. giftState := newcomer.RewardAvailable
  869. complete := s.getTaskCompleteCount(taskTypeMap[tType])
  870. total := len(taskTypeMap[tType])
  871. if complete != total {
  872. if from == newcomer.FromWeb {
  873. giftState = newcomer.RewardNotAvailable
  874. } else if from == newcomer.FromH5 {
  875. giftState = newcomer.RewardUnlock
  876. }
  877. }
  878. // judge the gift is received
  879. isGiftReceived, err := s.newc.IsRewardReceived(c, mid, int64(tType), newcomer.RewardGiftType)
  880. if err != nil {
  881. log.Error("genTaskGiftData s.newc.IsGiftReceived mid(%d)|error(%v)", mid, err)
  882. continue
  883. }
  884. if isGiftReceived {
  885. giftState = newcomer.RewardReceived
  886. }
  887. tg := &newcomer.TaskGift{
  888. State: int8(giftState),
  889. Type: tType,
  890. Rewards: giftRewards,
  891. }
  892. taskGift = append(taskGift, tg)
  893. }
  894. return
  895. }
  896. // getTaskKindsData for get task_kinds data
  897. func (s *Service) getTaskKindsData(u *UserTaskInfo, taskTypeMap map[int8][]*newcomer.Task) (taskKinds []*newcomer.TaskKind) {
  898. taskKinds = make([]*newcomer.TaskKind, 0, len(taskTypeMap))
  899. for tType, tasks := range taskTypeMap {
  900. complete := s.getTaskCompleteCount(tasks) // 完成数量
  901. total := len(tasks) // 总数
  902. state := newcomer.RewardNotAvailable // 完成状态
  903. if complete == len(tasks) {
  904. state = newcomer.RewardAvailable
  905. }
  906. kind := &newcomer.TaskKind{
  907. Type: tType,
  908. Completed: int64(complete),
  909. Total: int64(total),
  910. State: int8(state),
  911. }
  912. // determine the unlock type by user_task level
  913. switch tType {
  914. case newcomer.NewcomerTaskType:
  915. taskKinds = append(taskKinds, kind)
  916. case newcomer.AdvancedTaskType:
  917. if u.UserTaskLevel == newcomer.UserTaskLevel01 {
  918. kind.State = newcomer.RewardUnlock
  919. }
  920. taskKinds = append(taskKinds, kind)
  921. }
  922. }
  923. return
  924. }
  925. // getTaskCompleteCount get tasks complete count
  926. func (s *Service) getTaskCompleteCount(task []*newcomer.Task) int {
  927. complete := 0
  928. for _, t := range task {
  929. if t == nil {
  930. continue
  931. }
  932. if t.CompleteSate == newcomer.TaskCompleted {
  933. complete++
  934. }
  935. }
  936. return complete
  937. }
  938. // groupByTasks group by groupID & taskType
  939. func (s *Service) groupByTasks(tasks []*newcomer.Task) (taskGroupMap map[int64][]*newcomer.Task, taskTypeMap map[int8][]*newcomer.Task) {
  940. taskGroupMap = make(map[int64][]*newcomer.Task)
  941. taskTypeMap = make(map[int8][]*newcomer.Task)
  942. for _, t := range tasks {
  943. if t == nil {
  944. continue
  945. }
  946. taskGroupMap[t.GroupID] = append(taskGroupMap[t.GroupID], t)
  947. taskTypeMap[t.Type] = append(taskTypeMap[t.Type], t)
  948. }
  949. return
  950. }
  951. // getReceiveKey get receive redis key
  952. func (s *Service) getReceiveKey(oid int64, ty int8, mid int64) string {
  953. return fmt.Sprintf("%d_%d_%d", oid, ty, mid)
  954. }
  955. // getActivateKey get active key
  956. func (s *Service) getActivateKey(mid int64, id int64) string {
  957. return fmt.Sprintf("%d_%d", mid, id)
  958. }