rating.go 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. package service
  2. import (
  3. "context"
  4. "time"
  5. "go-common/app/interface/main/up-rating/model"
  6. "go-common/library/ecode"
  7. "go-common/library/log"
  8. )
  9. const (
  10. _cdateLayout = "2006-01-02"
  11. _taskFinished = 1
  12. )
  13. // UpRating gets data from cache and falls back to db
  14. func (s *Service) UpRating(c context.Context, mid int64) (rating *model.Rating, err error) {
  15. var allow bool
  16. if allow, err = s.allow(c, mid); err != nil {
  17. return
  18. }
  19. if !allow {
  20. err = ecode.UpRatingNoPermission
  21. return
  22. }
  23. var redisErr error
  24. if rating, redisErr = s.dao.GetUpRatingCache(c, mid); redisErr != nil {
  25. log.Error("s.dao.GetUpRatingCache error(%v)", redisErr)
  26. }
  27. if rating == nil {
  28. if rating, err = s.UpRatingDB(c, mid); err != nil {
  29. return
  30. }
  31. if redisErr = s.dao.SetUpRatingCache(c, mid, rating); redisErr != nil {
  32. log.Error("s.dao.SetUpRatingCache error(%v)", redisErr)
  33. }
  34. }
  35. return
  36. }
  37. // UpRatingDB gets data from db
  38. func (s *Service) UpRatingDB(c context.Context, mid int64) (rating *model.Rating, err error) {
  39. rating = &model.Rating{}
  40. if rating.Score, err = s.latestScore(c, mid); err != nil {
  41. return
  42. }
  43. if rating.Score.Magnetic < model.LowerBoundScore {
  44. return nil, ecode.UpRatingScoreLimit
  45. }
  46. if rating.Rank, err = s.rank(rating.Score); err != nil {
  47. log.Error("s.rank error(%v)", err)
  48. return
  49. }
  50. if rating.Prize, err = s.prize(c, rating.Score); err != nil {
  51. log.Error("s.prize error(%v)", err)
  52. return
  53. }
  54. // privileges left for furture development
  55. rating.Privileges = make([]*model.Privilege, 0)
  56. return
  57. }
  58. func (s *Service) rank(score *model.Score) (rank *model.Rank, err error) {
  59. for _, r := range model.Ranks {
  60. if score.Magnetic >= r.Score() {
  61. rank = r.Rank()
  62. return
  63. }
  64. }
  65. rank = model.RankLevelNone.Rank()
  66. return
  67. }
  68. func (s *Service) prize(c context.Context, score *model.Score) (prize *model.Prize, err error) {
  69. pass := false
  70. m := map[model.PrizeLevel]func(){
  71. model.PrizeLevelOne: func() {
  72. if pass = score.Magnetic >= model.TotalScore*0.95; pass {
  73. prize = model.PrizeLevelOne.Prize()
  74. }
  75. },
  76. model.PrizeLevelTwo: func() {
  77. tmp := score
  78. if tmp.Magnetic < model.TotalScore*0.75 {
  79. return
  80. }
  81. for j := 2; j > 0; j-- {
  82. if tmp, err = s.score(c, tmp.MID, prevRatingTime(tmp.CDate)); err != nil || tmp == nil {
  83. return
  84. }
  85. if tmp.Magnetic < model.TotalScore*0.75 {
  86. return
  87. }
  88. }
  89. pass = true
  90. prize = model.PrizeLevelTwo.Prize()
  91. },
  92. model.PrizeLevelThree: func() {
  93. var prev *model.Score
  94. if prev, err = s.score(c, score.MID, prevRatingTime(score.CDate)); err != nil || prev == nil {
  95. return
  96. }
  97. v := score.Magnetic - prev.Magnetic
  98. if pass = v >= model.TotalScore*0.1; pass {
  99. prize = model.PrizeLevelThree.Prize(v)
  100. }
  101. },
  102. model.PrizeLevelFour: func() {
  103. g := func(i int) bool {
  104. return i == 233 || i == 223
  105. }
  106. if pass = g(score.Credit) || g(score.Creative) || g(score.Influence); pass {
  107. prize = model.PrizeLevelFour.Prize()
  108. }
  109. },
  110. model.PrizeLevelFive: func() {
  111. pass = true
  112. prize = model.PrizeLevelFive.Prize()
  113. },
  114. }
  115. for _, p := range model.Prizes {
  116. m[p]()
  117. if err != nil || pass {
  118. break
  119. }
  120. }
  121. return
  122. }
  123. func (s *Service) latestScore(c context.Context, mid int64) (score *model.Score, err error) {
  124. var status int
  125. ratingTime := prevRatingTime(time.Now())
  126. if status, err = s.dao.TaskStatus(c, ratingTime.Format(_cdateLayout)); err != nil {
  127. return
  128. }
  129. if status != _taskFinished {
  130. ratingTime = prevRatingTime(ratingTime)
  131. if status, err = s.dao.TaskStatus(c, ratingTime.Format(_cdateLayout)); err != nil {
  132. return
  133. }
  134. if status != _taskFinished {
  135. err = ecode.UpRatingNoData
  136. return
  137. }
  138. }
  139. return s.score(c, mid, ratingTime)
  140. }
  141. func (s *Service) score(c context.Context, mid int64, ratingTime time.Time) (score *model.Score, err error) {
  142. score, err = s.dao.UpScore(c, int(ratingTime.Month()), mid, ratingTime.Format(_cdateLayout))
  143. if err != nil {
  144. log.Error("s.dao.UpScore err(%v)", err)
  145. return
  146. }
  147. if score == nil {
  148. log.Error("s.dao.UpScore mid(%v) ratingTime(%v) not found", mid, ratingTime.String())
  149. return
  150. }
  151. score.Magnetic = score.Creative + score.Credit + score.Influence
  152. score.StatEnd = time.Date(score.CDate.Year(), score.CDate.Month()+1, 1, 0, 0, 0, 0, score.CDate.Location()).AddDate(0, 0, -1)
  153. score.StatStart = time.Date(score.CDate.Year()-1, score.CDate.Month()+1, 1, 0, 0, 0, 0, score.CDate.Location())
  154. return
  155. }
  156. func prevRatingTime(queryTime time.Time) time.Time {
  157. return time.Date(queryTime.Year(), queryTime.Month()-1, 1, 0, 0, 0, 0, queryTime.Location())
  158. }
  159. func (s *Service) allow(c context.Context, mid int64) (b bool, err error) {
  160. count, err := s.dao.White(c, mid)
  161. if err != nil {
  162. return
  163. }
  164. b = count != 0
  165. return
  166. }