point.go 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. package bws
  2. import (
  3. "context"
  4. "sort"
  5. "time"
  6. bwsmdl "go-common/app/interface/main/activity/model/bws"
  7. "go-common/library/ecode"
  8. "go-common/library/log"
  9. xtime "go-common/library/time"
  10. )
  11. func (s *Service) points(c context.Context, bid int64) (rs map[string][]*bwsmdl.Point, err error) {
  12. var (
  13. points *bwsmdl.Points
  14. dp, game, clockin, egg []*bwsmdl.Point
  15. )
  16. if points, err = s.dao.Points(c, bid); err != nil || points == nil || len(points.Points) == 0 {
  17. log.Error("s.dao.Points error(%v)", err)
  18. err = ecode.ActivityPointFail
  19. return
  20. }
  21. for _, point := range points.Points {
  22. switch point.LockType {
  23. case _dpType:
  24. dp = append(dp, point)
  25. case _gameType:
  26. game = append(game, point)
  27. case _clockinType:
  28. clockin = append(clockin, point)
  29. case _eggType:
  30. egg = append(egg, point)
  31. }
  32. }
  33. rs = make(map[string][]*bwsmdl.Point, 4)
  34. if len(dp) == 0 {
  35. rs[_dp] = _emptPoints
  36. } else {
  37. rs[_dp] = dp
  38. }
  39. if len(game) == 0 {
  40. rs[_game] = _emptPoints
  41. } else {
  42. rs[_game] = game
  43. }
  44. if len(clockin) == 0 {
  45. rs[_clockin] = _emptPoints
  46. } else {
  47. rs[_clockin] = clockin
  48. }
  49. if len(egg) == 0 {
  50. rs[_egg] = _emptPoints
  51. } else {
  52. rs[_egg] = egg
  53. }
  54. return
  55. }
  56. // Points points list
  57. func (s *Service) Points(c context.Context, p *bwsmdl.ParamPoints) (rs map[string][]*bwsmdl.Point, err error) {
  58. var points map[string][]*bwsmdl.Point
  59. if points, err = s.points(c, p.Bid); err != nil {
  60. return
  61. }
  62. rs = make(map[string][]*bwsmdl.Point)
  63. switch p.Tp {
  64. case _allType:
  65. rs = points
  66. case _dpType:
  67. rs[_dp] = points[_dp]
  68. case _gameType:
  69. rs[_game] = points[_game]
  70. case _clockinType:
  71. rs[_clockin] = points[_clockin]
  72. case _eggType:
  73. rs[_egg] = points[_egg]
  74. }
  75. return
  76. }
  77. // Point point
  78. func (s *Service) Point(c context.Context, p *bwsmdl.ParamID) (rs *bwsmdl.Point, err error) {
  79. var (
  80. points *bwsmdl.Points
  81. )
  82. if points, err = s.dao.Points(c, p.Bid); err != nil || points == nil || len(points.Points) == 0 {
  83. log.Error("s.dao.Points error(%v)", err)
  84. err = ecode.ActivityPointFail
  85. return
  86. }
  87. for _, point := range points.Points {
  88. if point.ID == p.ID {
  89. rs = point
  90. break
  91. }
  92. }
  93. if rs == nil {
  94. err = ecode.ActivityIDNotExists
  95. }
  96. return
  97. }
  98. // Unlock unlock point.
  99. func (s *Service) Unlock(c context.Context, owner int64, arg *bwsmdl.ParamUnlock) (err error) {
  100. var (
  101. point *bwsmdl.Point
  102. userPoints []*bwsmdl.UserPointDetail
  103. userAchieves []*bwsmdl.UserAchieveDetail
  104. achieves *bwsmdl.Achievements
  105. unLockCnt, hp int64
  106. addAchieve *bwsmdl.Achievement
  107. lockAchieves []*bwsmdl.Achievement
  108. )
  109. if arg.Key == "" {
  110. if arg.Key, err = s.midToKey(c, arg.Mid); err != nil {
  111. return
  112. }
  113. }
  114. if point, err = s.Point(c, &bwsmdl.ParamID{ID: arg.Pid, Bid: arg.Bid}); err != nil {
  115. return
  116. }
  117. if point.Ower != owner && !s.isAdmin(owner) {
  118. err = ecode.ActivityNotOwner
  119. return
  120. }
  121. if point.LockType == _gameType {
  122. if arg.GameResult != bwsmdl.GameResWin && arg.GameResult != bwsmdl.GameResFail {
  123. err = ecode.ActivityGameResult
  124. return
  125. }
  126. }
  127. if userPoints, err = s.userPoints(c, arg.Bid, arg.Key); err != nil {
  128. return
  129. }
  130. userPidMap := make(map[int64]int64, len(userPoints))
  131. for _, v := range userPoints {
  132. if point.LockType != _gameType && v.Pid == point.ID {
  133. err = ecode.ActivityHasUnlock
  134. return
  135. }
  136. if _, ok := userPidMap[v.Pid]; !ok && v.LockType == point.LockType {
  137. if v.LockType == _gameType {
  138. if v.Points == v.Unlocked {
  139. unLockCnt++
  140. userPidMap[v.Pid] = v.Pid
  141. }
  142. } else {
  143. unLockCnt++
  144. userPidMap[v.Pid] = v.Pid
  145. }
  146. }
  147. hp += v.Points
  148. }
  149. lockPoint := point.Unlocked
  150. if point.LockType == _gameType && arg.GameResult == bwsmdl.GameResFail {
  151. lockPoint = point.LoseUnlocked
  152. }
  153. if hp+lockPoint < 0 {
  154. err = ecode.ActivityLackHp
  155. return
  156. }
  157. if userAchieves, err = s.userAchieves(c, arg.Bid, arg.Key); err != nil {
  158. return
  159. }
  160. if err = s.addUserPoint(c, arg.Bid, arg.Pid, lockPoint, arg.Key); err != nil {
  161. return
  162. }
  163. if achieves, err = s.dao.Achievements(c, arg.Bid); err != nil || len(achieves.Achievements) == 0 {
  164. log.Error("s.dao.Achievements error(%v)", err)
  165. err = ecode.ActivityAchieveFail
  166. return
  167. }
  168. for _, v := range achieves.Achievements {
  169. if point.LockType == v.LockType {
  170. lockAchieves = append(lockAchieves, v)
  171. }
  172. }
  173. if len(lockAchieves) > 0 {
  174. sort.Slice(lockAchieves, func(i, j int) bool { return lockAchieves[i].Unlock > lockAchieves[j].Unlock })
  175. if point.LockType == _gameType {
  176. if arg.GameResult == bwsmdl.GameResWin {
  177. unLockCnt++
  178. }
  179. } else {
  180. unLockCnt++
  181. }
  182. for _, ach := range lockAchieves {
  183. if unLockCnt >= ach.Unlock {
  184. addAchieve = ach
  185. break
  186. }
  187. }
  188. }
  189. if addAchieve != nil {
  190. for _, v := range userAchieves {
  191. if v.Aid == addAchieve.ID {
  192. return
  193. }
  194. }
  195. s.addAchieve(c, arg.Mid, addAchieve, arg.Key)
  196. }
  197. return
  198. }
  199. func (s *Service) userPoints(c context.Context, bid int64, key string) (res []*bwsmdl.UserPointDetail, err error) {
  200. var (
  201. usPoints []*bwsmdl.UserPoint
  202. points *bwsmdl.Points
  203. )
  204. if usPoints, err = s.dao.UserPoints(c, bid, key); err != nil {
  205. err = ecode.ActivityUserPointFail
  206. return
  207. }
  208. if len(usPoints) == 0 {
  209. return
  210. }
  211. if points, err = s.dao.Points(c, bid); err != nil || points == nil || len(points.Points) == 0 {
  212. log.Error("s.dao.Points error(%v)", err)
  213. err = ecode.ActivityPointFail
  214. return
  215. }
  216. pointsMap := make(map[int64]*bwsmdl.Point, len(points.Points))
  217. for _, v := range points.Points {
  218. pointsMap[v.ID] = v
  219. }
  220. for _, v := range usPoints {
  221. detail := &bwsmdl.UserPointDetail{UserPoint: v}
  222. if point, ok := pointsMap[v.Pid]; ok {
  223. detail.Name = point.Name
  224. detail.Icon = point.Icon
  225. detail.Fid = point.Fid
  226. detail.Image = point.Image
  227. detail.Unlocked = point.Unlocked
  228. detail.LockType = point.LockType
  229. detail.Dic = point.Dic
  230. detail.Rule = point.Rule
  231. detail.Bid = point.Bid
  232. }
  233. res = append(res, detail)
  234. }
  235. return
  236. }
  237. func (s *Service) addUserPoint(c context.Context, bid, pid, points int64, key string) (err error) {
  238. var usPtID int64
  239. if usPtID, err = s.dao.AddUserPoint(c, bid, pid, points, key); err != nil {
  240. err = ecode.ActivityUnlockFail
  241. return
  242. }
  243. err = s.dao.AppendUserPointsCache(c, bid, key, &bwsmdl.UserPoint{ID: usPtID, Pid: pid, Points: points, Ctime: xtime.Time(time.Now().Unix())})
  244. return
  245. }