package service import ( "fmt" "gadmin/config" "gadmin/internal/admin/consts" "gadmin/internal/admin/forms" "gadmin/internal/gorm/model" "gadmin/internal/gorm/query" "gadmin/package/gmdata" "gadmin/utility/player" "gadmin/utility/serializer" "github.com/gin-gonic/gin" "github.com/jinzhu/now" "github.com/spf13/cast" "sort" "strings" "time" ) // GrandMaster 最强王者 var GrandMaster = new(sGrandMaster) type sGrandMaster struct{} func (s *sGrandMaster) Get(ctx *gin.Context, req forms.GetGrandmasterReq) serializer.Response { DB, err := player.GetDBByUserId(req.Playerid) if err != nil { return serializer.Err(consts.CodeParamErr, "GetDBByUserId err", err) } var ( q = query.Use(config.GDBGroup[DB]).Grandmaster m = q.WithContext(ctx).Where(q.Playerid.Eq(req.Playerid)) models *model.Grandmaster ) if err = m.Scan(&models); err != nil { return serializer.Err(consts.CodeParamErr, "查询出错 ", err) } return serializer.Suc(models) } func (s *sGrandMaster) SetDanScore(ctx *gin.Context, req forms.SetGrandmasterDanScoreReq) serializer.Response { /* var err error DB, err := player.GetDBByUserId(req.Playerid) if err != nil { return serializer.Err(consts.CodeParamErr, err.Error(), err) } msg := msg2.GmSetDanScore{ MsgId: character.GenerateMsgId(), PlayerID: req.Playerid, DanScore: req.DanScore, OperatorId: token.GetUID(ctx), } rpc_share.MsgMap[msg.MsgId] = fmt.Sprintf("GM为修改段位积分 PlayerID: %d, DanScore: %v", req.Playerid, req.DanScore) var resp *msg2.ResponseGmSetDanScore res, err := config.GmNats.GmRequest(DB, "GmSetDanScore", msg) if err != nil { return serializer.Err(consts.CodeParamErr, err.Error(), err) } if err = json.Unmarshal(res, &resp); err != nil { return serializer.Err(consts.CodeParamErr, err.Error(), err) } rpc_share.LogChan <- rpc_share.LogMsg{ MsgID: msg.MsgId, Data: resp, }*/ return serializer.Suc(req) } type GrandMasterReportInfo struct { Days []string `json:"days"` Players []int64 `json:"players"` } type GrandMasterLogItem struct { Day string `json:"days"` Players int64 `json:"players"` } type GrandMasterInfo struct { Info GrandMasterReportInfo `json:"info"` Rows []GrandMasterLogItem `json:"rows"` } type ReportDayGrandMaster struct { model.ReportDayGrandmaster } // QueryLog 统计报表 func (s *sGrandMaster) QueryLog(params forms.GrandmasterReportReq) (result []*ReportDayGrandMaster, err error) { rdb := query.Use(config.DB).ReportDayGrandmaster m := rdb.Where(rdb.Date.Gte(params.Day), rdb.Date.Lt(params.EndDay)).Order(rdb.Date.Desc()) switch params.ChannelId { case consts.ChannelIdNone: // 不选择渠道 case consts.ChannelIdAllAdv, consts.ChannelIdAllWx, consts.ChannelIdAllTT: // 所有的广告渠道 m = m.Where(rdb.ChannelID.In(Channel.GetIdsByType(params.ChannelId)...)) default: // 指定渠道 m = m.Where(rdb.ChannelID.Eq(params.ChannelId)) } if params.ServerId > 0 { m = m.Where(rdb.ServerID.Eq(int32(params.ServerId))) } distributes, err := m.Find() if err != nil { return } add := func(row *model.ReportDayGrandmaster) { var exist bool for _, v := range result { if v.Date == row.Date { exist = true v.PlayerCount += row.PlayerCount v.OpenPlayerCount += row.OpenPlayerCount v.PartCount += row.PartCount v.AllMatchSeconds += row.AllMatchSeconds v.BattleWavesCount += row.BattleWavesCount v.AllBattleSeconds += row.AllBattleSeconds v.LeaveUsers += row.LeaveUsers } } if exist == false { v := new(ReportDayGrandMaster) v.Date = row.Date v.ChannelID = row.ChannelID v.PlayerCount += row.PlayerCount v.OpenPlayerCount += row.OpenPlayerCount v.PartCount += row.PartCount v.AllMatchSeconds += row.AllMatchSeconds v.BattleWavesCount += row.BattleWavesCount v.AllBattleSeconds += row.AllBattleSeconds v.LeaveUsers += row.LeaveUsers result = append(result, v) } } for _, distribute := range distributes { add(distribute) } for _, v := range result { v.Date = strings.ReplaceAll(v.Date, "T00:00:00+08:00", "") } return } type GrandmasterWaves struct { Waves int `json:"waves"` Total int64 `json:"total"` } func (s *sGrandMaster) Waves(params forms.GrandmasterWavesReq) (results []GrandmasterWaves, err error) { key := config.UKey("GrandmasterWaves", params) if err = config.GetCacheScan(key, &results); err != nil { return } if len(results) != 0 { return } var ( grandMasterModel = &model.GrandmasterLog{} m = config.DB.Model(&model.GrandmasterLog{}).Scopes(model.TableOfYearMonth(grandMasterModel.TableName(), time.Now())). Select("battle_waves as waves, COUNT(*) AS total"). Where("event_id in(4,5) and date = ? and `battle_waves` BETWEEN ? AND ?", time.Unix(params.Date/1000, 0).Format("2006-01-02"), params.StartWaves, params.EndWaves) ) if params.ServerId > 0 { m = m.Where("server_id = ?", params.ServerId) } m.Group("battle_waves").Scan(&results) results = s.completeMissingLevels(params, results) if len(results) > 0 { config.SetCache(key, results, now.BeginningOfDay().Unix()+86400) } return } func (s *sGrandMaster) completeMissingLevels(params forms.GrandmasterWavesReq, results []GrandmasterWaves) []GrandmasterWaves { var completedResults []GrandmasterWaves levels := make(map[int]bool) for _, result := range results { levels[result.Waves] = true completedResults = append(completedResults, result) } for i := params.StartWaves; i <= params.EndWaves; i++ { if !levels[int(i)] { completedResults = append(completedResults, GrandmasterWaves{Waves: int(i), Total: 0}) } } sort.Slice(completedResults, func(i, j int) bool { return completedResults[i].Waves < completedResults[j].Waves // 根据等级从小到大排序 }) return completedResults } type GrandmasterSeconds struct { Seconds int `json:"seconds"` Total int64 `json:"total"` } func (s *sGrandMaster) Seconds(params forms.GrandmasterSecondsReq) (results []GrandmasterSeconds, err error) { key := config.UKey("GrandmasterSeconds", params) if err = config.GetCacheScan(key, &results); err != nil { return } if len(results) != 0 { return } var ( grandMasterModel = &model.GrandmasterLog{} m = config.DB.Model(&model.GrandmasterLog{}).Scopes(model.TableOfYearMonth(grandMasterModel.TableName(), time.Now())). Select("battle_seconds as seconds, COUNT(*) AS total"). Where("event_id in(4,5) and date = ? and `battle_seconds` BETWEEN ? AND ?", time.Unix(params.Date/1000, 0).Format("2006-01-02"), params.StartSeconds, params.EndSeconds) ) if params.ServerId > 0 { m = m.Where("server_id = ?", params.ServerId) } m.Group("battle_seconds").Scan(&results) results = s.completeMissingSeconds(params, results) if len(results) > 0 { config.SetCache(key, results, now.BeginningOfDay().Unix()+86400) } return } func (s *sGrandMaster) completeMissingSeconds(params forms.GrandmasterSecondsReq, results []GrandmasterSeconds) []GrandmasterSeconds { var completedResults []GrandmasterSeconds levels := make(map[int]bool) for _, result := range results { levels[result.Seconds] = true completedResults = append(completedResults, result) } for i := params.StartSeconds; i <= params.EndSeconds; i++ { if !levels[int(i)] { completedResults = append(completedResults, GrandmasterSeconds{Seconds: int(i), Total: 0}) } } sort.Slice(completedResults, func(i, j int) bool { return completedResults[i].Seconds < completedResults[j].Seconds // 根据等级从小到大排序 }) return completedResults } type GrandmasterDan struct { DanID int `json:"id"` DanName string `json:"danName"` Total int64 `json:"total"` } type ByDanID []*GrandmasterDan func (a ByDanID) Len() int { return len(a) } func (a ByDanID) Swap(i, j int) { a[i], a[j] = a[j], a[i] } func (a ByDanID) Less(i, j int) bool { return a[i].DanID < a[j].DanID } func (s *sGrandMaster) Dan(params forms.GrandmasterDanReq) (results []*GrandmasterDan, err error) { key := config.UKey("GrandmasterDan", params) if err = config.GetCacheScan(key, &results); err != nil { return } if len(results) != 0 { return } type Log struct { UserID int Score int64 } var logs []*Log grandMasterModel := &model.GrandmasterLog{} tableName := fmt.Sprintf("%s_%s", grandMasterModel.TableName(), time.Now().Format("200601")) if !config.DB.Migrator().HasTable(tableName) { tableName = grandMasterModel.TableName() } subQuery := `(SELECT user_id, MAX(event_at) AS last_event_at FROM %s where date = '%v' and event_id = 5` subQuery = fmt.Sprintf(subQuery, tableName, time.Unix(params.Date/1000, 0).Format("2006-01-02")) if params.ServerId > 0 { subQuery += " and server_id = " + cast.ToString(params.ServerId) } subQuery += ` GROUP BY user_id) AS B` joins := "INNER JOIN " + subQuery + " ON A.user_id = B.user_id AND A.event_at = B.last_event_at and A.date = '%v' and A.event_id = 5" joins = fmt.Sprintf(joins, time.Unix(params.Date/1000, 0).Format("2006-01-02")) if params.ServerId > 0 { joins += " and A.server_id = " + cast.ToString(params.ServerId) } joins += ` GROUP BY user_id, dan_score` query1 := config.DB.Table(fmt.Sprintf("%s as A", tableName)).Select("A.user_id, A.dan_score as score").Joins(joins).Scan(&logs) if query1.Error != nil { return nil, query1.Error } if len(logs) == 0 { results = make([]*GrandmasterDan, 0) return } addResult := func(dan *gmdata.KingSeasonDan) { for i, v := range results { if v.DanID == dan.Id { results[i].Total++ return } } results = append(results, &GrandmasterDan{ DanID: dan.Id, DanName: dan.DanName, Total: 1, }) } for _, v := range logs { dan := gmdata.GetDanByScore(v.Score) if dan == nil { continue } addResult(dan) } sort.Sort(ByDanID(results)) if len(results) > 0 { config.SetCache(key, results, now.BeginningOfDay().Unix()+86400) } return } type GrandmasterMatch struct { Seconds int64 `json:"seconds"` Total int64 `json:"total"` } func (s *sGrandMaster) Match(params forms.GrandmasterMatchReq) (results []*GrandmasterMatch, err error) { //key := config.UKey("GrandmasterMatch", params) //if err = config.GetCacheScan(key, &results); err != nil { // return //} // //if len(results) != 0 { // return //} var ( m = config.DB.Model(&model.GrandmasterMatch{}). Select("seconds, times AS total"). Where("type = ?", params.Type). Where("`seconds` BETWEEN ? AND ?", params.StartSeconds, params.EndSeconds) ) m.Scan(&results) results = s.completeMissingMatch(params, results) //if len(results) > 0 { // config.SetCache(key, results, now.BeginningOfDay().Unix()+86400) //} return } func (s *sGrandMaster) completeMissingMatch(params forms.GrandmasterMatchReq, results []*GrandmasterMatch) []*GrandmasterMatch { var completedResults []*GrandmasterMatch levels := make(map[int]bool) for _, result := range results { levels[int(result.Seconds)] = true completedResults = append(completedResults, result) } for i := params.StartSeconds; i <= params.EndSeconds; i++ { if !levels[int(i)] { completedResults = append(completedResults, &GrandmasterMatch{Seconds: int64(i), Total: 0}) } } sort.Slice(completedResults, func(i, j int) bool { return completedResults[i].Seconds < completedResults[j].Seconds // 根据等级从小到大排序 }) return completedResults }