statistics.go 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. package service
  2. import (
  3. "context"
  4. "fmt"
  5. "time"
  6. "go-common/app/admin/main/up-rating/dao/global"
  7. "go-common/app/admin/main/up-rating/model"
  8. "go-common/library/log"
  9. "go-common/library/xstr"
  10. )
  11. var (
  12. _layout = "2006-01-02"
  13. _segment = 10
  14. )
  15. // StatisGraph get statistics graph data
  16. func (s *Service) StatisGraph(c context.Context, ctype int64, tagID string, Compare int) (data interface{}, err error) {
  17. totalScore, err := s.getTypeScore(c, ctype)
  18. if err != nil {
  19. log.Error("s.getTypeScore error(%v)", err)
  20. return
  21. }
  22. nowStatis, now, err := s.GetLastRatingStatis(c, ctype, tagID)
  23. if err != nil {
  24. log.Error("s.GetRatingStatis error(%v)", err)
  25. return
  26. }
  27. last := now.AddDate(0, -1*Compare, 0)
  28. lastStatis, err := s.GetRatingStatis(c, ctype, tagID, getStartMonthlyDate(last))
  29. if err != nil {
  30. log.Error("s.GetRatingStatis error(%v)", err)
  31. return
  32. }
  33. data = map[string]interface{}{
  34. "xAxis": getSections(int(totalScore)),
  35. "this_month": statisSections(nowStatis, int(totalScore)),
  36. "compare": statisSections(lastStatis, int(totalScore)),
  37. }
  38. return
  39. }
  40. // StatisList get statistics list
  41. func (s *Service) StatisList(c context.Context, ctype int64, tagID string, Compare int) (list []*model.RatingStatis, err error) {
  42. list = make([]*model.RatingStatis, 0)
  43. totalScore, err := s.getTypeScore(c, ctype)
  44. if err != nil {
  45. log.Error("s.getTypeScore error(%v)", err)
  46. return
  47. }
  48. nowStatis, now, err := s.GetLastRatingStatis(c, ctype, tagID)
  49. if err != nil {
  50. log.Error("s.GetRatingStatis error(%v)", err)
  51. return
  52. }
  53. last := now.AddDate(0, -1*Compare, 0)
  54. lastStatis, err := s.GetRatingStatis(c, ctype, tagID, getStartMonthlyDate(last))
  55. if err != nil {
  56. log.Error("s.GetRatingStatis error(%v)", err)
  57. return
  58. }
  59. list = statisProportion(nowStatis, lastStatis, getSections(int(totalScore)), int(totalScore))
  60. return
  61. }
  62. // StatisExport export statis
  63. func (s *Service) StatisExport(c context.Context, ctype int64, tagID string, Compare int) (res []byte, err error) {
  64. list, err := s.StatisList(c, ctype, tagID, Compare)
  65. if err != nil {
  66. log.Error("s.StatisList error(%v)", err)
  67. return
  68. }
  69. res, err = formatCSV(formatStatis(list, ctype))
  70. if err != nil {
  71. log.Error("StatisExport formatCSV error(%v)", err)
  72. }
  73. return
  74. }
  75. func statisProportion(now, last []*model.RatingStatis, sections []string, totalScore int) (list []*model.RatingStatis) {
  76. var totalUps, lastTotalUps int64
  77. list = make([]*model.RatingStatis, _segment)
  78. for i := 0; i < _segment; i++ {
  79. list[i] = &model.RatingStatis{
  80. Tips: sections[i],
  81. }
  82. }
  83. offset := totalScore / _segment
  84. for _, s := range now {
  85. totalUps += s.Ups
  86. idx := int(s.Section) * 10 / offset
  87. if idx >= _segment {
  88. idx--
  89. }
  90. list[idx].Ups += s.Ups
  91. list[idx].Score += s.Score
  92. list[idx].CreativityScore += s.CreativityScore
  93. list[idx].InfluenceScore += s.InfluenceScore
  94. list[idx].CreditScore += s.CreditScore
  95. list[idx].Fans += s.Fans
  96. list[idx].Avs += s.Avs
  97. list[idx].Coin += s.Coin
  98. list[idx].Play += s.Play
  99. }
  100. for _, s := range last {
  101. lastTotalUps += s.Ups
  102. idx := int(s.Section) * 10 / offset
  103. if idx >= _segment {
  104. idx--
  105. }
  106. list[idx].Compare += s.Ups
  107. }
  108. for i := 0; i < len(list); i++ {
  109. if totalUps > 0 {
  110. list[i].Proportion = fmt.Sprintf("%.02f", float64(list[i].Ups*100)/float64(totalUps))
  111. }
  112. if lastTotalUps > 0 {
  113. list[i].ComparePropor = fmt.Sprintf("%.02f", float64(list[i].Compare*100)/float64(lastTotalUps))
  114. }
  115. if list[i].Ups > 0 {
  116. list[i].Score /= list[i].Ups
  117. list[i].CreativityScore /= list[i].Ups
  118. list[i].InfluenceScore /= list[i].Ups
  119. list[i].CreditScore /= list[i].Ups
  120. list[i].Fans /= list[i].Ups
  121. list[i].Avs /= list[i].Ups
  122. list[i].Coin /= list[i].Ups
  123. list[i].Play /= list[i].Ups
  124. }
  125. }
  126. return
  127. }
  128. func getSections(score int) (sections []string) {
  129. sections = make([]string, _segment)
  130. offset := score / _segment
  131. for i := 0; i < len(sections); i++ {
  132. sections[i] = fmt.Sprintf("%d-%d", i*offset, (i+1)*offset)
  133. }
  134. return sections
  135. }
  136. func statisSections(statis []*model.RatingStatis, totalScore int) (ups []int64) {
  137. ups = make([]int64, _segment)
  138. offset := totalScore / _segment
  139. for _, s := range statis {
  140. idx := int(s.Section) * 10 / offset
  141. if idx >= len(ups) {
  142. idx--
  143. }
  144. ups[idx] += s.Ups
  145. }
  146. return
  147. }
  148. // GetLastRatingStatis get last rating statis
  149. func (s *Service) GetLastRatingStatis(c context.Context, ctype int64, tagID string) (statis []*model.RatingStatis, date time.Time, err error) {
  150. statis = make([]*model.RatingStatis, 0)
  151. times := 0
  152. date = getStartMonthlyDate(time.Now()).AddDate(0, -1, 0)
  153. for times < 2 {
  154. statis, err = s.GetRatingStatis(c, ctype, tagID, date)
  155. if err != nil {
  156. return
  157. }
  158. if len(statis) > 0 {
  159. break
  160. }
  161. times++
  162. date = date.AddDate(0, -1, 0)
  163. }
  164. if times == 2 && len(statis) == 0 {
  165. err = fmt.Errorf("get last statis error")
  166. return
  167. }
  168. return
  169. }
  170. // GetRatingStatis get rating statis
  171. func (s *Service) GetRatingStatis(c context.Context, ctype int64, tagID string, date time.Time) (statis []*model.RatingStatis, err error) {
  172. return s.dao.GetRatingStatis(c, ctype, date.Format(_layout), tagID)
  173. }
  174. func getStartMonthlyDate(date time.Time) time.Time {
  175. return time.Date(date.Year(), date.Month(), 1, 0, 0, 0, 0, time.Local)
  176. }
  177. // GetTrendAsc get trend asc
  178. func (s *Service) GetTrendAsc(c context.Context, ctype string, tags []int64, date time.Time, frl, fru int, mid int64, offset, limit int) (total int, ts []*model.Trend, err error) {
  179. q := query(ctype, tags, frl, mid)
  180. dsr := getStartMonthlyDate(date).Format(_layout)
  181. total, err = s.dao.AscTrendCount(c, dsr, q)
  182. if err != nil {
  183. return
  184. }
  185. q += fmt.Sprintf(" ORDER BY %s_diff DESC,id LIMIT %d,%d", ctype, offset, limit)
  186. ts, err = s.dao.GetTrendAsc(c, ctype, dsr, q)
  187. if err != nil {
  188. return
  189. }
  190. err = fillUpNames(c, ts)
  191. return
  192. }
  193. //GetTrendDesc get trend desc
  194. func (s *Service) GetTrendDesc(c context.Context, ctype string, tags []int64, date time.Time, frl, fru int, mid int64, offset, limit int) (total int, ts []*model.Trend, err error) {
  195. q := query(ctype, tags, frl, mid)
  196. dsr := getStartMonthlyDate(date).Format(_layout)
  197. total, err = s.dao.DescTrendCount(c, dsr, q)
  198. if err != nil {
  199. return
  200. }
  201. q += fmt.Sprintf(" ORDER BY %s_diff,id LIMIT %d,%d", ctype, offset, limit)
  202. ts, err = s.dao.GetTrendDesc(c, ctype, dsr, q)
  203. if err != nil {
  204. return
  205. }
  206. err = fillUpNames(c, ts)
  207. return
  208. }
  209. func fillUpNames(c context.Context, ts []*model.Trend) (err error) {
  210. var mids []int64
  211. for _, trend := range ts {
  212. mids = append(mids, trend.MID)
  213. }
  214. if len(mids) == 0 {
  215. return
  216. }
  217. ns, err := global.Names(c, mids)
  218. if err != nil {
  219. return
  220. }
  221. for _, trend := range ts {
  222. trend.Nickname = ns[trend.MID]
  223. }
  224. return
  225. }
  226. func getSection(ctype string, frl int) (section int, typ int) {
  227. if ctype == "magnetic" {
  228. typ = 0
  229. interval := 600 / 10
  230. section = frl / interval
  231. }
  232. if ctype == "creativity" {
  233. typ = 1
  234. interval := 200 / 10
  235. section = frl / interval
  236. }
  237. if ctype == "influence" {
  238. typ = 2
  239. interval := 200 / 10
  240. section = frl / interval
  241. }
  242. if ctype == "credit" {
  243. typ = 3
  244. interval := 200 / 10
  245. section = frl / interval
  246. }
  247. return
  248. }
  249. func query(ctype string, tags []int64, frl int, mid int64) (q string) {
  250. if len(tags) > 0 {
  251. q += fmt.Sprintf(" AND tag_id IN (%s)", xstr.JoinInts(tags))
  252. }
  253. section, typ := getSection(ctype, frl)
  254. q += fmt.Sprintf(" AND section=%d", section)
  255. q += fmt.Sprintf(" AND ctype=%d", typ)
  256. if mid > 0 {
  257. q += fmt.Sprintf(" AND mid=%d", mid)
  258. }
  259. return
  260. }