up_rank.go 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. package upcrmservice
  2. import (
  3. "context"
  4. "sort"
  5. "time"
  6. "go-common/app/admin/main/up/model/upcrmmodel"
  7. "go-common/app/admin/main/up/util/mathutil"
  8. "go-common/library/log"
  9. xtime "go-common/library/time"
  10. )
  11. var (
  12. //AllRankTyps all rank types
  13. AllRankTyps = []int{
  14. upcrmmodel.UpRankTypeFans30day1k,
  15. upcrmmodel.UpRankTypeFans30day1w,
  16. upcrmmodel.UpRankTypePlay30day1k,
  17. upcrmmodel.UpRankTypePlay30day1w,
  18. upcrmmodel.UpRankTypePlay30day10k,
  19. upcrmmodel.UpRankTypeFans30dayIncreaseCount,
  20. upcrmmodel.UpRankTypeFans30dayIncreasePercent,
  21. }
  22. )
  23. type sortRankFunc func(p1, p2 *upcrmmodel.UpRankInfo) bool
  24. type upRankSorter struct {
  25. datas []*upcrmmodel.UpRankInfo
  26. by sortRankFunc // Closure used in the Less method.
  27. }
  28. // Len is part of sort.Interface.
  29. func (s *upRankSorter) Len() int {
  30. return len(s.datas)
  31. }
  32. // Swap is part of sort.Interface.
  33. func (s *upRankSorter) Swap(i, j int) {
  34. s.datas[i], s.datas[j] = s.datas[j], s.datas[i]
  35. }
  36. // Less is part of sort.Interface. It is implemented by calling the "by" closure in the sorter.
  37. func (s *upRankSorter) Less(i, j int) bool {
  38. return s.by(s.datas[i], s.datas[j])
  39. }
  40. func sortRankInfo(planets []*upcrmmodel.UpRankInfo, sortfunc sortRankFunc) {
  41. ps := &upRankSorter{
  42. datas: planets,
  43. by: sortfunc, // The Sort method's receiver is the function (closure) that defines the sort order.
  44. }
  45. sort.Sort(ps)
  46. }
  47. func sortByValueAsc(p1, p2 *upcrmmodel.UpRankInfo) bool {
  48. if p1.Value < p2.Value {
  49. return true
  50. }
  51. if p1.Value == p2.Value {
  52. return p1.Value2 < p2.Value2
  53. }
  54. return false
  55. }
  56. func sortByValueDesc(p1, p2 *upcrmmodel.UpRankInfo) bool {
  57. if p1.Value > p2.Value {
  58. return true
  59. }
  60. if p1.Value == p2.Value {
  61. return p1.Value2 > p2.Value2
  62. }
  63. return false
  64. }
  65. // 从数据库中更新数据
  66. func (s *Service) refreshUpRankDate(date time.Time) {
  67. rankData, err := s.crmdb.QueryUpRankAll(date)
  68. if err != nil {
  69. log.Error("refresh from db fail, err=%+v", err)
  70. return
  71. }
  72. var typeMap = map[int][]*upcrmmodel.UpRankInfo{}
  73. var upInfoMap = map[int64]*upcrmmodel.InfoQueryResult{}
  74. for _, v := range rankData {
  75. var rankType = int(v.Type)
  76. var rankInfo = &upcrmmodel.UpRankInfo{}
  77. rankInfo.Mid = v.Mid
  78. rankInfo.CopyFromUpRank(&v)
  79. typeMap[rankType] = append(typeMap[rankType], rankInfo)
  80. upInfoMap[v.Mid] = nil
  81. }
  82. log.Info("refresh from db, get for date=%v, len=%d", date, len(rankData))
  83. // interestring code
  84. var mids []int64
  85. for k := range upInfoMap {
  86. mids = append(mids, k)
  87. }
  88. // 查询并合并
  89. var infoData, e = s.upBaseInfoQueryBatch(s.crmdb.QueryUpBaseInfoBatchByMid, mids...)
  90. err = e
  91. if err != nil {
  92. log.Error("get from base info fail, err=%+v", err)
  93. return
  94. }
  95. for _, v := range infoData {
  96. upInfoMap[v.Mid] = v
  97. }
  98. for _, list := range typeMap {
  99. for _, info := range list {
  100. var data, _ = upInfoMap[info.Mid]
  101. if data == nil {
  102. continue
  103. }
  104. info.InfoQueryResult = *data
  105. switch info.RankType {
  106. case upcrmmodel.UpRankTypeFans30day1k,
  107. upcrmmodel.UpRankTypeFans30day1w,
  108. upcrmmodel.UpRankTypePlay30day1k,
  109. upcrmmodel.UpRankTypePlay30day1w,
  110. upcrmmodel.UpRankTypePlay30day10k,
  111. upcrmmodel.UpRankTypeFans30dayIncreaseCount,
  112. upcrmmodel.UpRankTypeFans30dayIncreasePercent:
  113. info.CompleteTime = info.FirstUpTime + xtime.Time(info.Value)
  114. }
  115. }
  116. }
  117. // 排序
  118. for k, list := range typeMap {
  119. var sortFunc sortRankFunc = sortByValueAsc
  120. switch k {
  121. case upcrmmodel.UpRankTypeFans30dayIncreaseCount,
  122. upcrmmodel.UpRankTypeFans30dayIncreasePercent:
  123. sortFunc = sortByValueDesc
  124. }
  125. sortRankInfo(list, sortFunc)
  126. for i, v := range list {
  127. v.Rank = i + 1
  128. }
  129. log.Info("cache rank type=%d, len=%d, date=%v", k, len(list), date)
  130. }
  131. s.uprankCache = typeMap
  132. s.lastCacheDate = date
  133. }
  134. //UpRankQueryList query up rank list
  135. func (s *Service) UpRankQueryList(c context.Context, arg *upcrmmodel.UpRankQueryArgs) (result upcrmmodel.UpRankQueryResult, err error) {
  136. if arg.Page == 0 {
  137. arg.Page = 1
  138. }
  139. if arg.Size <= 0 || arg.Size > 50 {
  140. arg.Size = 20
  141. }
  142. // 1.从内存中读数据
  143. var rankList, ok = s.uprankCache[arg.Type]
  144. if !ok || rankList == nil {
  145. log.Warn("no available rank data in cache, type=%d", arg.Type)
  146. return
  147. }
  148. var startIndex = (arg.Page - 1) * arg.Size
  149. var endIndex = startIndex + arg.Size
  150. var totalCount = len(rankList)
  151. endIndex = mathutil.Min(endIndex, totalCount)
  152. if startIndex < endIndex {
  153. result.Result = rankList[startIndex:endIndex]
  154. }
  155. result.Date = xtime.Time(s.lastCacheDate.Unix())
  156. result.TotalCount = totalCount
  157. result.Size = arg.Size
  158. result.Page = arg.Page
  159. log.Info("get rank list for type=%d", arg.Type)
  160. // 2.如果没有,从数据库中刷数据
  161. return
  162. }