missiongroup.go 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467
  1. package like
  2. import (
  3. "context"
  4. "net"
  5. "time"
  6. ldao "go-common/app/interface/main/activity/dao/like"
  7. l "go-common/app/interface/main/activity/model/like"
  8. accapi "go-common/app/service/main/account/api"
  9. "go-common/library/ecode"
  10. "go-common/library/log"
  11. "go-common/library/net/metadata"
  12. "go-common/library/sync/errgroup"
  13. )
  14. // MissionLike launch buff activity .
  15. func (s *Service) MissionLike(c context.Context, sid, mid int64) (lid int64, err error) {
  16. var (
  17. subject *l.SubjectItem
  18. now = time.Now().Unix()
  19. missionGroup int64
  20. group *l.MissionGroup
  21. )
  22. if subject, err = s.dao.ActSubject(c, sid); err != nil {
  23. log.Error("s.dao.ActSubject(%d) error(%+v)", sid, err)
  24. return
  25. }
  26. if subject.ID == 0 || subject.Type != l.MISSIONGROUP {
  27. err = ecode.ActivityNotExist
  28. return
  29. }
  30. if subject.Stime.Time().Unix() > now {
  31. err = ecode.ActivityNotStart
  32. return
  33. }
  34. if subject.Etime.Time().Unix() < now {
  35. err = ecode.ActivityOverEnd
  36. return
  37. }
  38. if missionGroup, err = s.dao.LikeMissionBuff(c, sid, mid); err != nil {
  39. log.Error("s.dao.LikeMissionBuff(%d,%d) error(%+v)", sid, mid, err)
  40. return
  41. }
  42. if missionGroup > 0 {
  43. err = ecode.ActivityHasMissionGroup
  44. return
  45. }
  46. group = &l.MissionGroup{
  47. Sid: sid,
  48. Mid: mid,
  49. State: ldao.MissionStateInit,
  50. }
  51. if lid, err = s.dao.MissionGroupAdd(c, group); err != nil {
  52. log.Error("s.dao.MissionGroupAdd(%d,%d) error(%+v)", sid, mid, err)
  53. return
  54. }
  55. s.dao.AddCacheLikeMissionBuff(c, sid, lid, mid)
  56. return
  57. }
  58. // MissionInfo .
  59. func (s *Service) MissionInfo(c context.Context, sid, lid, mid int64) (res *l.MissionInfo, err error) {
  60. var hasBufErr, hasHelpErr error
  61. res = &l.MissionInfo{}
  62. eg, errCtx := errgroup.WithContext(c)
  63. eg.Go(func() error {
  64. res.HasBuff, hasBufErr = s.dao.LikeMissionBuff(errCtx, sid, mid)
  65. if hasBufErr != nil {
  66. log.Error("s.dao.LikeMissionBuff(%d,%d) error(%+v)", sid, mid, hasBufErr)
  67. }
  68. return nil
  69. })
  70. eg.Go(func() error {
  71. res.HasHelp, hasHelpErr = s.dao.ActMission(errCtx, sid, lid, mid)
  72. if hasHelpErr != nil {
  73. log.Error("s.dao.ActMission(%d,%d,%d) error(%+v)", sid, lid, mid, hasHelpErr)
  74. }
  75. return nil
  76. })
  77. eg.Wait()
  78. return
  79. }
  80. // MissionUser .
  81. func (s *Service) MissionUser(c context.Context, sid, lid int64) (res *l.MissionFriends, err error) {
  82. var (
  83. groups map[int64]*l.MissionGroup
  84. group *l.MissionGroup
  85. member *accapi.InfoReply
  86. )
  87. if groups, err = s.dao.MissionGroupItems(c, []int64{lid}); err != nil {
  88. log.Error("s.dao.MissionGroupItems(%v) error(%v)", lid, err)
  89. return
  90. }
  91. if _, ok := groups[lid]; !ok {
  92. err = ecode.ActivityNotExist
  93. return
  94. }
  95. group = groups[lid]
  96. if group.ID == 0 || group.Sid != sid {
  97. err = ecode.ActivityNotExist
  98. return
  99. }
  100. if member, err = s.accClient.Info3(c, &accapi.MidReq{Mid: group.Mid}); err != nil {
  101. log.Error(" s.acc.Info3(c,&accmdl.ArgMids{Mid:%d}) error(%v)", group.Mid, err)
  102. return
  103. }
  104. res = &l.MissionFriends{
  105. Name: member.Info.Name,
  106. Face: member.Info.Face,
  107. Mid: member.Info.Mid,
  108. }
  109. return
  110. }
  111. // MissionLikeAct help to mission group .
  112. func (s *Service) MissionLikeAct(c context.Context, p *l.ParamMissionLikeAct, mid int64) (data *l.MissionLikeAct, err error) {
  113. var (
  114. subject *l.SubjectItem
  115. groups map[int64]*l.MissionGroup
  116. group *l.MissionGroup
  117. memberRly *accapi.ProfileReply
  118. now = time.Now().Unix()
  119. ActMissionID, likeLimit, missionActCount, mLid int64
  120. score = int64(1)
  121. missionActList *l.ActMissionGroup
  122. lottery *l.Lottery
  123. subErr, groupErr, missionErr, caculErr, incrErr error
  124. )
  125. eg, errCtx := errgroup.WithContext(c)
  126. eg.Go(func() error {
  127. subject, subErr = s.dao.ActSubject(errCtx, p.Sid)
  128. return subErr
  129. })
  130. eg.Go(func() error {
  131. groups, groupErr = s.dao.MissionGroupItems(errCtx, []int64{p.Lid})
  132. return groupErr
  133. })
  134. if err = eg.Wait(); err != nil {
  135. log.Error("MissionLikeAct:eg.Wait error(%v)", err)
  136. return
  137. }
  138. if _, ok := groups[p.Lid]; ok {
  139. group = groups[p.Lid]
  140. } else {
  141. err = ecode.ActivityNotExist
  142. return
  143. }
  144. if subject.ID == 0 || subject.Type != l.MISSIONGROUP || group.ID == 0 || group.Sid != p.Sid {
  145. err = ecode.ActivityNotExist
  146. return
  147. }
  148. if group.Mid == mid {
  149. err = ecode.ActivityMGNotYourself
  150. return
  151. }
  152. if memberRly, err = s.accClient.Profile3(c, &accapi.MidReq{Mid: mid}); err != nil {
  153. log.Error(" s.acc.Profile3(c,&accmdl.ArgMid{Mid:%d}) error(%v)", mid, err)
  154. return
  155. }
  156. if err = s.judgeUser(c, subject, memberRly.Profile); err != nil {
  157. return
  158. }
  159. if subject.Lstime.Time().Unix() >= now {
  160. err = ecode.ActivityMissionNotStart
  161. return
  162. }
  163. if subject.Letime.Time().Unix() <= now {
  164. err = ecode.ActivityMissionHasEnd
  165. return
  166. }
  167. if ActMissionID, err = s.dao.ActMission(c, p.Sid, p.Lid, mid); err != nil {
  168. log.Error("s.dao.ActMission(%v) error(%+v)", p, err)
  169. return
  170. }
  171. if ActMissionID > 0 {
  172. err = ecode.ActivityHasMission
  173. return
  174. }
  175. if subject.LikeLimit > 0 {
  176. if likeLimit, err = s.dao.MissionLikeLimit(c, p.Sid, mid); err != nil {
  177. log.Error("s.dao.ActMission(%v) error(%+v)", p, err)
  178. return
  179. }
  180. if likeLimit >= subject.LikeLimit {
  181. err = ecode.ActivityOverMissionLimit
  182. return
  183. }
  184. }
  185. if missionActCount, err = s.dao.SetMissionTop(c, p.Sid, p.Lid, score, now); err != nil {
  186. log.Error("s.dao.SetMissionTop(%v) error(%+v)", p, err)
  187. return
  188. }
  189. missionActList = &l.ActMissionGroup{
  190. Lid: p.Lid,
  191. Sid: p.Sid,
  192. Mid: mid,
  193. Action: score,
  194. IPv6: make([]byte, 0),
  195. }
  196. if IPv6 := net.ParseIP(metadata.String(c, metadata.RemoteIP)); IPv6 != nil {
  197. missionActList.IPv6 = IPv6
  198. }
  199. if mLid, err = s.dao.AddActMission(c, missionActList); err != nil {
  200. log.Error("s.dao.AddActMission(%v) error(%+v)", p, err)
  201. return
  202. }
  203. egT, errCtxT := errgroup.WithContext(c)
  204. egT.Go(func() error {
  205. missionErr = s.dao.AddCacheActMission(errCtxT, p.Sid, mLid, p.Lid, mid)
  206. return missionErr
  207. })
  208. egT.Go(func() error {
  209. caculErr = s.CalculateAchievement(errCtxT, p.Sid, group.Mid, missionActCount)
  210. return caculErr
  211. })
  212. egT.Go(func() error {
  213. _, incrErr = s.dao.InrcMissionLikeLimit(errCtxT, p.Sid, mid, score)
  214. return incrErr
  215. })
  216. if err = egT.Wait(); err != nil {
  217. log.Error("MissionLikeAct:eg.Wait add cache error(%v)", err)
  218. return
  219. }
  220. if lottery, err = s.dao.LotteryIndex(c, s.c.Rule.LotteryActID, int64(0), int64(0), mid); err != nil {
  221. log.Error("s.dao.LotteryIndex(%d) mid(%d) error(%+v)", s.c.Rule.LotteryActID, mid, err)
  222. return
  223. }
  224. data = &l.MissionLikeAct{
  225. Mlid: mLid,
  226. Lottery: lottery,
  227. }
  228. return
  229. }
  230. // CalculateAchievement .
  231. func (s *Service) CalculateAchievement(c context.Context, sid, mid int64, missionCount int64) (err error) {
  232. var (
  233. achieves *l.Achievements
  234. avState int64
  235. )
  236. if achieves, err = s.dao.ActLikeAchieves(c, sid); err != nil {
  237. log.Error("s.dao.ActLikeAchieves(%d,%d) error(%v)", sid, mid, err)
  238. return
  239. }
  240. if len(achieves.Achievements) > 0 {
  241. for _, v := range achieves.Achievements {
  242. if v.Unlock == missionCount {
  243. if v.Award == ldao.HaveAward {
  244. avState = ldao.AwardNotChange
  245. } else {
  246. avState = ldao.AwardNoGet
  247. }
  248. if _, err = s.dao.AddUserAchievment(c, &l.ActLikeUserAchievement{Aid: v.ID, Sid: sid, Mid: mid, Award: avState}); err != nil {
  249. log.Error("s.dao.AddUserAchievment(%d,%d,%v) error(%+v)", sid, mid, v, err)
  250. return
  251. }
  252. break
  253. }
  254. }
  255. }
  256. return
  257. }
  258. // MissionRank get user rank .
  259. func (s *Service) MissionRank(c context.Context, sid, mid int64) (data *l.MissionRank, err error) {
  260. data = &l.MissionRank{Rank: -1}
  261. if data.Lid, err = s.dao.LikeMissionBuff(c, sid, mid); err != nil {
  262. log.Error("s.dao.LikeMissionBuff(%d,%d) error(%+v)", sid, mid, err)
  263. return
  264. }
  265. if data.Lid > 0 {
  266. if data.Score, err = s.dao.MissionLidScore(c, sid, data.Lid); err != nil {
  267. log.Error("s.dao.MissionLidScore(%d,%d) error(%+v)", sid, data.Lid, err)
  268. return
  269. }
  270. if data.Rank, err = s.dao.MissionLidRank(c, sid, data.Lid); err != nil {
  271. log.Error("s.dao.MissionLidRank(%d,%d) error(%+v)", sid, data.Lid, err)
  272. return
  273. }
  274. if data.Rank >= 0 {
  275. data.Rank = data.Rank + 1
  276. }
  277. }
  278. return
  279. }
  280. // MissionTops get the top list .
  281. func (s *Service) MissionTops(c context.Context, sid int64, num int) (data []*l.MissionFriends, err error) {
  282. var (
  283. lids []int64
  284. lidsList map[int64]*l.MissionGroup
  285. mids []int64
  286. membersRly *accapi.InfosReply
  287. )
  288. if lids, err = s.dao.MissionScoreList(c, sid, 0, num-1); err != nil {
  289. log.Error("s.dao.MissionScoreList(%d) error(%+v)", sid, err)
  290. return
  291. }
  292. if len(lids) > 0 {
  293. if lidsList, err = s.dao.MissionGroupItems(c, lids); err != nil {
  294. log.Error("s.dao.MissionGroupItems(%v) error(%v)", lids, err)
  295. return
  296. }
  297. mids = make([]int64, 0, len(lidsList))
  298. for _, v := range lidsList {
  299. if v.ID > 0 {
  300. mids = append(mids, v.Mid)
  301. }
  302. }
  303. if len(mids) > 0 {
  304. if membersRly, err = s.accClient.Infos3(c, &accapi.MidsReq{Mids: mids}); err != nil {
  305. log.Error("s.acc.Infos3(%v) error(%v)", mids, err)
  306. return
  307. }
  308. }
  309. data = make([]*l.MissionFriends, 0, len(lids))
  310. for _, v := range lids {
  311. if _, ok := lidsList[v]; ok {
  312. n := &l.MissionFriends{Mid: lidsList[v].Mid}
  313. if membersRly != nil {
  314. if val, y := membersRly.Infos[lidsList[v].Mid]; y {
  315. n.Name = val.Name
  316. n.Face = val.Face
  317. }
  318. }
  319. data = append(data, n)
  320. }
  321. }
  322. }
  323. return
  324. }
  325. // MissionFriendsList .
  326. func (s *Service) MissionFriendsList(c context.Context, p *l.ParamMissionFriends, mid int64) (data []*l.MissionFriends, err error) {
  327. var (
  328. groups map[int64]*l.MissionGroup
  329. ActList []*l.ActMissionGroup
  330. ActMissions *l.ActMissionGroups
  331. mids []int64
  332. membersRly *accapi.InfosReply
  333. score int64
  334. actLen int
  335. )
  336. if groups, err = s.dao.MissionGroupItems(c, []int64{p.Lid}); err != nil {
  337. log.Error("s.dao.MissionGroupItems(%d) error(%v)", p.Lid, err)
  338. return
  339. }
  340. if _, ok := groups[p.Lid]; !ok {
  341. err = ecode.ActivityNotExist
  342. return
  343. }
  344. if groups[p.Lid].ID == 0 || groups[p.Lid].Mid != mid || groups[p.Lid].Sid != p.Sid {
  345. err = ecode.ActivityNotExist
  346. return
  347. }
  348. if ActMissions, err = s.dao.ActMissionFriends(c, p.Sid, p.Lid); err != nil {
  349. log.Error("s.dao.ActMissionFriends(%v) error(%+v)", p, err)
  350. return
  351. }
  352. ActList = ActMissions.ActMissionGroups
  353. actLen = len(ActList)
  354. score, _ = s.dao.MissionLidScore(c, p.Sid, p.Lid)
  355. if int64(actLen) < score && actLen < p.Size {
  356. // need to update cache
  357. s.dao.DelCacheActMissionFriends(c, p.Sid, p.Lid)
  358. if ActMissions, err = s.dao.ActMissionFriends(c, p.Sid, p.Lid); err != nil {
  359. log.Error("s.dao.ActMissionFriends(%v) error(%+v)", p, err)
  360. return
  361. }
  362. ActList = ActMissions.ActMissionGroups
  363. actLen = len(ActList)
  364. }
  365. if actLen > p.Size {
  366. ActList = ActList[:p.Size]
  367. actLen = p.Size
  368. }
  369. mids = make([]int64, 0, actLen)
  370. for _, v := range ActList {
  371. mids = append(mids, v.Mid)
  372. }
  373. if len(mids) > 0 {
  374. if membersRly, err = s.accClient.Infos3(c, &accapi.MidsReq{Mids: mids}); err != nil {
  375. log.Error("s.acc.Infos3(%v) error(%v)", mids, err)
  376. return
  377. }
  378. }
  379. data = make([]*l.MissionFriends, 0, len(ActList))
  380. for _, v := range ActList {
  381. n := &l.MissionFriends{Mid: v.Mid}
  382. if membersRly != nil {
  383. if val, y := membersRly.Infos[v.Mid]; y {
  384. n.Name = val.Name
  385. n.Face = val.Face
  386. }
  387. }
  388. data = append(data, n)
  389. }
  390. return
  391. }
  392. // MissionAward .
  393. func (s *Service) MissionAward(c context.Context, sid, mid int64) (data []*l.MissionAward, err error) {
  394. var (
  395. achieves *l.Achievements
  396. userAchieves []*l.ActLikeUserAchievement
  397. userAchMap map[int64]*l.ActLikeUserAchievement
  398. achErr error
  399. userErr error
  400. )
  401. eg, errCtx := errgroup.WithContext(c)
  402. eg.Go(func() error {
  403. achieves, achErr = s.dao.ActLikeAchieves(errCtx, sid)
  404. return achErr
  405. })
  406. eg.Go(func() error {
  407. userAchieves, userErr = s.dao.UserAchievement(c, sid, mid)
  408. return userErr
  409. })
  410. if err = eg.Wait(); err != nil {
  411. log.Error("MissionAward:eg.Wait() error(%+v)", err)
  412. return
  413. }
  414. userAchMap = make(map[int64]*l.ActLikeUserAchievement, len(userAchieves))
  415. for _, v := range userAchieves {
  416. userAchMap[v.Aid] = v
  417. }
  418. for _, val := range achieves.Achievements {
  419. n := &l.MissionAward{Name: val.Name, Image: val.Image}
  420. if v, ok := userAchMap[val.ID]; ok {
  421. n.ID = v.ID
  422. n.Award = v.Award
  423. }
  424. data = append(data, n)
  425. }
  426. return
  427. }
  428. // MissionAchieve .
  429. func (s *Service) MissionAchieve(c context.Context, sid, id, mid int64) (res int64, err error) {
  430. var (
  431. useActAchieve *l.ActLikeUserAchievement
  432. award int64
  433. )
  434. if useActAchieve, err = s.dao.ActUserAchieve(c, id); err != nil {
  435. log.Error("s.dao.ActUserAchieve(%d) error(%+v)", id, err)
  436. return
  437. }
  438. if useActAchieve.ID == 0 || useActAchieve.Mid != mid || useActAchieve.Sid != sid {
  439. err = ecode.ActivityNotAward
  440. return
  441. }
  442. if award, err = s.dao.CacheActUserAward(c, id); err != nil {
  443. log.Info("s.dao.CacheActUserAward(%d) error(%v)", id, err)
  444. }
  445. if award > 0 {
  446. err = ecode.ActivityHasAward
  447. return
  448. }
  449. if res, err = s.dao.ActUserAchieveChange(c, id, ldao.AwardHasChange); err != nil {
  450. log.Error("s.dao.ActUserAchieveChange(%d) error(%+v)", id, err)
  451. return
  452. }
  453. s.dao.AddCacheActUserAward(c, id, id)
  454. return
  455. }