package service import ( "encoding/json" "gadmin/config" "gadmin/internal/admin/consts" "gadmin/internal/admin/forms" "gadmin/internal/gorm/model" "gadmin/internal/gorm/query" "gadmin/utility" "gadmin/utility/serializer" "github.com/gin-gonic/gin" "github.com/sirupsen/logrus" "strings" ) // Gem 宝石统计服务 var Gem = new(sGem) type sGem struct{} type GemReportInfo struct { Days []string `json:"days"` Players []int64 `json:"players"` ValidCount []int64 `json:"validCount"` Part1 []int64 `json:"part1"` Part2 []int64 `json:"part2"` Part3 []int64 `json:"part3"` Part4 []int64 `json:"part4"` Part5 []int64 `json:"part5"` Part6 []int64 `json:"part6"` AvgPart1 []int64 `json:"avgPart1"` AvgPart2 []int64 `json:"avgPart2"` AvgPart3 []int64 `json:"avgPart3"` AvgPart4 []int64 `json:"avgPart4"` AvgPart5 []int64 `json:"avgPart5"` AvgPart6 []int64 `json:"avgPart6"` } type GemLogItem struct { Day string `json:"days"` Players int64 `json:"players"` ValidCount int64 `json:"validCount"` Part1 int64 `json:"part1"` Part2 int64 `json:"part2"` Part3 int64 `json:"part3"` Part4 int64 `json:"part4"` Part5 int64 `json:"part5"` Part6 int64 `json:"part6"` AvgPart1 float64 `json:"avgPart1"` AvgPart2 float64 `json:"avgPart2"` AvgPart3 float64 `json:"avgPart3"` AvgPart4 float64 `json:"avgPart4"` AvgPart5 float64 `json:"avgPart5"` AvgPart6 float64 `json:"avgPart6"` } type GemInfo struct { Info GemReportInfo `json:"info"` Rows []GemLogItem `json:"rows"` } // QueryGemLog 统计宝石信息 func (s *sGem) QueryGemLog(params forms.GemReportReq) (respData GemInfo, err error) { var ( resp GemReportInfo rdb = query.Use(config.DB).ReportDayGem rm = rdb.Select(rdb.ALL, rdb.ID, rdb.Date, rdb.PlayerCount.Sum().As("player_count"), rdb.Output.Sum().As("output"), rdb.Part1.Sum().As("part1"), rdb.Part2.Sum().As("part2"), rdb.Part3.Sum().As("part3"), rdb.Part4.Sum().As("part4"), rdb.Part5.Sum().As("part5"), rdb.Part6.Sum().As("part6"), ).Where(rdb.Date.Gte(params.Day), rdb.Date.Lt(params.EndDay)) b = query.Use(config.DB).ReportDayBasic ) if params.ServerId > 0 { rm = rm.Where(rdb.ServerID.Eq(int32(params.ServerId))) } result, err := rm.Group(rdb.Date).Order(rdb.Date.Desc()).Find() if err != nil { return } for _, v := range result { if v != nil { // 有效活跃 var validCount int64 basic, err := b.Where(b.Date.Eq(utility.ParseDate(v.Date))).First() if err == nil && basic != nil { validCount = basic.ActiveCount - basic.NewCount + basic.ValidCount } resp.Days = append(resp.Days, strings.ReplaceAll(v.Date, "T00:00:00+08:00", "")) resp.Players = append(resp.Players, v.PlayerCount) resp.ValidCount = append(resp.ValidCount, validCount) resp.Part1 = append(resp.Part1, v.Part1) resp.Part2 = append(resp.Part2, v.Part2) resp.Part3 = append(resp.Part3, v.Part3) resp.Part4 = append(resp.Part4, v.Part4) resp.Part5 = append(resp.Part5, v.Part5) resp.Part6 = append(resp.Part6, v.Part6) var players int64 = 1 if v.PlayerCount > 1 { players = v.PlayerCount } resp.AvgPart1 = append(resp.AvgPart1, v.Part1*100/players) resp.AvgPart2 = append(resp.AvgPart2, v.Part2*100/players) resp.AvgPart3 = append(resp.AvgPart3, v.Part3*100/players) resp.AvgPart4 = append(resp.AvgPart4, v.Part4*100/players) resp.AvgPart5 = append(resp.AvgPart5, v.Part5*100/players) resp.AvgPart6 = append(resp.AvgPart6, v.Part6*100/players) item := GemLogItem{ Day: strings.ReplaceAll(v.Date, "T00:00:00+08:00", ""), Players: v.PlayerCount, ValidCount: validCount, Part1: v.Part1, Part2: v.Part2, Part3: v.Part3, Part4: v.Part4, Part5: v.Part5, Part6: v.Part6, } item.AvgPart1 = float64(v.Part1*100/players) / 100 item.AvgPart2 = float64(v.Part2*100/players) / 100 item.AvgPart3 = float64(v.Part3*100/players) / 100 item.AvgPart4 = float64(v.Part4*100/players) / 100 item.AvgPart5 = float64(v.Part5*100/players) / 100 item.AvgPart6 = float64(v.Part6*100/players) / 100 respData.Rows = append(respData.Rows, item) } } respData.Info = resp return } // PartStat 部位统计 func (s *sGem) PartStat(ctx *gin.Context, params forms.GemPartStatReq) serializer.Response { var ( q = query.Use(config.DB).GemStat m = q.WithContext(ctx) m2 = q.WithContext(ctx) resp []*forms.PartStatRow models forms.ListRes err error ) if params.ServerId > 0 { m = m.Where(q.ServerID.Eq(int32(params.ServerId))) m2 = m2.Where(q.ServerID.Eq(int32(params.ServerId))) } first, err := m.Order(q.Date.Desc()).First() if err != nil { return serializer.Err(consts.CodeParamErr, "查询出错 lists", err) } if first == nil { return serializer.Err(consts.CodeParamErr, "查询出错 lists2", err) } err = m2.Where(q.Date.Eq(first.Date)).Scan(&resp) if err != nil { return serializer.Err(consts.CodeParamErr, "查询出错 lists3", err) } for _, v := range resp { v.Name = config.GemPartMap[v.Part] } models.List = resp models.Page = 0 models.PerPage = 1 models.PageCount = 1 return serializer.Suc(models) } // Stat 综合统计 func (s *sGem) Stat(ctx *gin.Context, params forms.GemStatReq) ([]*forms.StatRow, error) { var ( q = query.Use(config.DB).ReportDayGem m = q.WithContext(ctx) resp = s.instGemStatRes() models []*model.ReportDayGem err error totalPartCount = make(map[int64]int64) ) if params.ServerId > 0 { m = m.Where(q.ServerID.Eq(int32(params.ServerId))) } if err = m.Scan(&models); err != nil { logrus.Error(err) return nil, err } findIndex := func(part int64, output map[int64]int64) { for _, row := range resp { if row.Index == part { for k, v := range output { if row.Level == k { row.Count += v totalPartCount[part] += v } } } } } partOutput := func(out string) (map[int64]int64, error) { var counter = make(map[int64]int64) if out == "" || out == "null" { return counter, nil } err = json.Unmarshal([]byte(out), &counter) if err != nil { logrus.Error(err) return nil, err } return counter, nil } for _, row := range models { var output map[int64]int64 // 部位1 output, err := partOutput(row.PartOutput1) if err != nil { return nil, err } findIndex(1, output) // 部位2 output, err = partOutput(row.PartOutput2) if err != nil { return nil, err } findIndex(2, output) // 部位3 output, err = partOutput(row.PartOutput3) if err != nil { return nil, err } findIndex(3, output) // 部位4 output, err = partOutput(row.PartOutput4) if err != nil { return nil, err } findIndex(4, output) // 部位5 output, err = partOutput(row.PartOutput5) if err != nil { return nil, err } findIndex(5, output) // 部位6 output, err = partOutput(row.PartOutput6) if err != nil { return nil, err } findIndex(6, output) } // 计算占比 var places int64 = 2 for _, v := range resp { if totalPartCount[v.Index] == 0 { v.Ratio = 0 } else { v.Ratio = utility.RoundToFloat(float64(v.Count)/float64(totalPartCount[v.Index])*100, places) } if v.Level == 0 { v.Count = totalPartCount[v.Index] } } return resp, nil } // instGemStatRes 初始化综合统计数据结构 func (s *sGem) instGemStatRes() (resp []*forms.StatRow) { var ( parts = []int64{1, 2, 3, 4, 5, 6} levels = []int64{0, 1, 2, 3, 4, 5, 6} ) for _, part := range parts { for _, level := range levels { resp = append(resp, &forms.StatRow{ Index: part, Name: config.GemTypeMap[part], Level: level, Count: 0, Ratio: 0, }) } } return resp }