gem.go 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. package service
  2. import (
  3. "encoding/json"
  4. "gadmin/config"
  5. "gadmin/internal/admin/consts"
  6. "gadmin/internal/admin/forms"
  7. "gadmin/internal/gorm/model"
  8. "gadmin/internal/gorm/query"
  9. "gadmin/utility"
  10. "gadmin/utility/serializer"
  11. "github.com/gin-gonic/gin"
  12. "github.com/sirupsen/logrus"
  13. "strings"
  14. )
  15. // Gem 宝石统计服务
  16. var Gem = new(sGem)
  17. type sGem struct{}
  18. type GemReportInfo struct {
  19. Days []string `json:"days"`
  20. Players []int64 `json:"players"`
  21. ValidCount []int64 `json:"validCount"`
  22. Part1 []int64 `json:"part1"`
  23. Part2 []int64 `json:"part2"`
  24. Part3 []int64 `json:"part3"`
  25. Part4 []int64 `json:"part4"`
  26. Part5 []int64 `json:"part5"`
  27. Part6 []int64 `json:"part6"`
  28. AvgPart1 []int64 `json:"avgPart1"`
  29. AvgPart2 []int64 `json:"avgPart2"`
  30. AvgPart3 []int64 `json:"avgPart3"`
  31. AvgPart4 []int64 `json:"avgPart4"`
  32. AvgPart5 []int64 `json:"avgPart5"`
  33. AvgPart6 []int64 `json:"avgPart6"`
  34. }
  35. type GemLogItem struct {
  36. Day string `json:"days"`
  37. Players int64 `json:"players"`
  38. ValidCount int64 `json:"validCount"`
  39. Part1 int64 `json:"part1"`
  40. Part2 int64 `json:"part2"`
  41. Part3 int64 `json:"part3"`
  42. Part4 int64 `json:"part4"`
  43. Part5 int64 `json:"part5"`
  44. Part6 int64 `json:"part6"`
  45. AvgPart1 float64 `json:"avgPart1"`
  46. AvgPart2 float64 `json:"avgPart2"`
  47. AvgPart3 float64 `json:"avgPart3"`
  48. AvgPart4 float64 `json:"avgPart4"`
  49. AvgPart5 float64 `json:"avgPart5"`
  50. AvgPart6 float64 `json:"avgPart6"`
  51. }
  52. type GemInfo struct {
  53. Info GemReportInfo `json:"info"`
  54. Rows []GemLogItem `json:"rows"`
  55. }
  56. // QueryGemLog 统计宝石信息
  57. func (s *sGem) QueryGemLog(params forms.GemReportReq) (respData GemInfo, err error) {
  58. var (
  59. resp GemReportInfo
  60. rdb = query.Use(config.DB).ReportDayGem
  61. rm = rdb.Select(rdb.ALL, rdb.ID, rdb.Date,
  62. rdb.PlayerCount.Sum().As("player_count"),
  63. rdb.Output.Sum().As("output"),
  64. rdb.Part1.Sum().As("part1"),
  65. rdb.Part2.Sum().As("part2"),
  66. rdb.Part3.Sum().As("part3"),
  67. rdb.Part4.Sum().As("part4"),
  68. rdb.Part5.Sum().As("part5"),
  69. rdb.Part6.Sum().As("part6"),
  70. ).Where(rdb.Date.Gte(params.Day), rdb.Date.Lt(params.EndDay))
  71. b = query.Use(config.DB).ReportDayBasic
  72. )
  73. if params.ServerId > 0 {
  74. rm = rm.Where(rdb.ServerID.Eq(int32(params.ServerId)))
  75. }
  76. result, err := rm.Group(rdb.Date).Order(rdb.Date.Desc()).Find()
  77. if err != nil {
  78. return
  79. }
  80. for _, v := range result {
  81. if v != nil {
  82. // 有效活跃
  83. var validCount int64
  84. basic, err := b.Where(b.Date.Eq(utility.ParseDate(v.Date))).First()
  85. if err == nil && basic != nil {
  86. validCount = basic.ActiveCount - basic.NewCount + basic.ValidCount
  87. }
  88. resp.Days = append(resp.Days, strings.ReplaceAll(v.Date, "T00:00:00+08:00", ""))
  89. resp.Players = append(resp.Players, v.PlayerCount)
  90. resp.ValidCount = append(resp.ValidCount, validCount)
  91. resp.Part1 = append(resp.Part1, v.Part1)
  92. resp.Part2 = append(resp.Part2, v.Part2)
  93. resp.Part3 = append(resp.Part3, v.Part3)
  94. resp.Part4 = append(resp.Part4, v.Part4)
  95. resp.Part5 = append(resp.Part5, v.Part5)
  96. resp.Part6 = append(resp.Part6, v.Part6)
  97. var players int64 = 1
  98. if v.PlayerCount > 1 {
  99. players = v.PlayerCount
  100. }
  101. resp.AvgPart1 = append(resp.AvgPart1, v.Part1*100/players)
  102. resp.AvgPart2 = append(resp.AvgPart2, v.Part2*100/players)
  103. resp.AvgPart3 = append(resp.AvgPart3, v.Part3*100/players)
  104. resp.AvgPart4 = append(resp.AvgPart4, v.Part4*100/players)
  105. resp.AvgPart5 = append(resp.AvgPart5, v.Part5*100/players)
  106. resp.AvgPart6 = append(resp.AvgPart6, v.Part6*100/players)
  107. item := GemLogItem{
  108. Day: strings.ReplaceAll(v.Date, "T00:00:00+08:00", ""),
  109. Players: v.PlayerCount,
  110. ValidCount: validCount,
  111. Part1: v.Part1,
  112. Part2: v.Part2,
  113. Part3: v.Part3,
  114. Part4: v.Part4,
  115. Part5: v.Part5,
  116. Part6: v.Part6,
  117. }
  118. item.AvgPart1 = float64(v.Part1*100/players) / 100
  119. item.AvgPart2 = float64(v.Part2*100/players) / 100
  120. item.AvgPart3 = float64(v.Part3*100/players) / 100
  121. item.AvgPart4 = float64(v.Part4*100/players) / 100
  122. item.AvgPart5 = float64(v.Part5*100/players) / 100
  123. item.AvgPart6 = float64(v.Part6*100/players) / 100
  124. respData.Rows = append(respData.Rows, item)
  125. }
  126. }
  127. respData.Info = resp
  128. return
  129. }
  130. // PartStat 部位统计
  131. func (s *sGem) PartStat(ctx *gin.Context, params forms.GemPartStatReq) serializer.Response {
  132. var (
  133. q = query.Use(config.DB).GemStat
  134. m = q.WithContext(ctx)
  135. m2 = q.WithContext(ctx)
  136. resp []*forms.PartStatRow
  137. models forms.ListRes
  138. err error
  139. )
  140. if params.ServerId > 0 {
  141. m = m.Where(q.ServerID.Eq(int32(params.ServerId)))
  142. m2 = m2.Where(q.ServerID.Eq(int32(params.ServerId)))
  143. }
  144. first, err := m.Order(q.Date.Desc()).First()
  145. if err != nil {
  146. return serializer.Err(consts.CodeParamErr, "查询出错 lists", err)
  147. }
  148. if first == nil {
  149. return serializer.Err(consts.CodeParamErr, "查询出错 lists2", err)
  150. }
  151. err = m2.Where(q.Date.Eq(first.Date)).Scan(&resp)
  152. if err != nil {
  153. return serializer.Err(consts.CodeParamErr, "查询出错 lists3", err)
  154. }
  155. for _, v := range resp {
  156. v.Name = config.GemPartMap[v.Part]
  157. }
  158. models.List = resp
  159. models.Page = 0
  160. models.PerPage = 1
  161. models.PageCount = 1
  162. return serializer.Suc(models)
  163. }
  164. // Stat 综合统计
  165. func (s *sGem) Stat(ctx *gin.Context, params forms.GemStatReq) ([]*forms.StatRow, error) {
  166. var (
  167. q = query.Use(config.DB).ReportDayGem
  168. m = q.WithContext(ctx)
  169. resp = s.instGemStatRes()
  170. models []*model.ReportDayGem
  171. err error
  172. totalPartCount = make(map[int64]int64)
  173. )
  174. if params.ServerId > 0 {
  175. m = m.Where(q.ServerID.Eq(int32(params.ServerId)))
  176. }
  177. if err = m.Scan(&models); err != nil {
  178. logrus.Error(err)
  179. return nil, err
  180. }
  181. findIndex := func(part int64, output map[int64]int64) {
  182. for _, row := range resp {
  183. if row.Index == part {
  184. for k, v := range output {
  185. if row.Level == k {
  186. row.Count += v
  187. totalPartCount[part] += v
  188. }
  189. }
  190. }
  191. }
  192. }
  193. partOutput := func(out string) (map[int64]int64, error) {
  194. var counter = make(map[int64]int64)
  195. if out == "" || out == "null" {
  196. return counter, nil
  197. }
  198. err = json.Unmarshal([]byte(out), &counter)
  199. if err != nil {
  200. logrus.Error(err)
  201. return nil, err
  202. }
  203. return counter, nil
  204. }
  205. for _, row := range models {
  206. var output map[int64]int64
  207. // 部位1
  208. output, err := partOutput(row.PartOutput1)
  209. if err != nil {
  210. return nil, err
  211. }
  212. findIndex(1, output)
  213. // 部位2
  214. output, err = partOutput(row.PartOutput2)
  215. if err != nil {
  216. return nil, err
  217. }
  218. findIndex(2, output)
  219. // 部位3
  220. output, err = partOutput(row.PartOutput3)
  221. if err != nil {
  222. return nil, err
  223. }
  224. findIndex(3, output)
  225. // 部位4
  226. output, err = partOutput(row.PartOutput4)
  227. if err != nil {
  228. return nil, err
  229. }
  230. findIndex(4, output)
  231. // 部位5
  232. output, err = partOutput(row.PartOutput5)
  233. if err != nil {
  234. return nil, err
  235. }
  236. findIndex(5, output)
  237. // 部位6
  238. output, err = partOutput(row.PartOutput6)
  239. if err != nil {
  240. return nil, err
  241. }
  242. findIndex(6, output)
  243. }
  244. // 计算占比
  245. var places int64 = 2
  246. for _, v := range resp {
  247. if totalPartCount[v.Index] == 0 {
  248. v.Ratio = 0
  249. } else {
  250. v.Ratio = utility.RoundToFloat(float64(v.Count)/float64(totalPartCount[v.Index])*100, places)
  251. }
  252. if v.Level == 0 {
  253. v.Count = totalPartCount[v.Index]
  254. }
  255. }
  256. return resp, nil
  257. }
  258. // instGemStatRes 初始化综合统计数据结构
  259. func (s *sGem) instGemStatRes() (resp []*forms.StatRow) {
  260. var (
  261. parts = []int64{1, 2, 3, 4, 5, 6}
  262. levels = []int64{0, 1, 2, 3, 4, 5, 6}
  263. )
  264. for _, part := range parts {
  265. for _, level := range levels {
  266. resp = append(resp, &forms.StatRow{
  267. Index: part,
  268. Name: config.GemTypeMap[part],
  269. Level: level,
  270. Count: 0,
  271. Ratio: 0,
  272. })
  273. }
  274. }
  275. return resp
  276. }