package model import ( "backend/util" "fmt" "sort" "strconv" ) type Statistics struct { AppId int `json:"AppId"` ServerList []int `json:"ServerList"` Emit []string `json:"Emit"` } func (s *Statistics) StatisticsLevel() (interface{}, error) { AppConfig, err := util.GetAppConfig(s.AppId) if err != nil { return nil, err } res := make([]map[string]interface{}, 0) res1 := make(map[int]int) type dbres struct { Sum int `db:"sum"` Level int `db:"level"` } for _, v := range s.ServerList { Db := util.MPool.GetMysqlDB(AppConfig, v) if Db == nil { return nil, fmt.Errorf("failed to get mysql database") } var result []dbres err = Db.Select(&result, "select count(*) as sum , `level` from t_player_baseinfo group by `level`") if err != nil { return nil, fmt.Errorf("failed to get level count: %v", err) } for r := range result { res1[result[r].Level] += result[r].Sum } Db.Close() } keys := make([]int, 0, len(res1)) for k := range res1 { keys = append(keys, k) } sort.Ints(keys) for _, k := range keys { res = append(res, map[string]interface{}{ "Level": k, "Sum": res1[k], }) } return map[string]interface{}{ "data": res, "total": len(res), }, nil } func (s *Statistics) StatisticsInfo() (interface{}, error) { AppConfig, err := util.GetAppConfig(s.AppId) if err != nil { return nil, err } LogDb := util.MPool.GetTopicDB(AppConfig.Topic) defer LogDb.Close() if LogDb == nil { return nil, fmt.Errorf("failed to get mysql database") } StartTime, _ := util.GetZeroTimestamp(AppConfig.Tz, 0) EndTime, _ := util.GetZeroTimestamp(AppConfig.Tz, 1) var Register int var TotalRegistger int var Recharge float64 var TotalRecharge float64 var RechargeUser int err = LogDb.Get(&Register, "select count(*) as sum from log_login where Event = 'register' and Timestamp >= ? and Timestamp <= ?", StartTime, EndTime) if err != nil { return nil, fmt.Errorf("failed to get register count: %v", err) } err = LogDb.Get(&TotalRegistger, "select count(*) as sum from log_login where Event = 'register'") if err != nil { return nil, fmt.Errorf("failed to get total register count: %v", err) } err = LogDb.Get(&Recharge, "select IFNULL(SUM(Price), 0) as sum from log_order where Timestamp >= ? and Timestamp <= ?", StartTime, EndTime) if err != nil { return nil, fmt.Errorf("failed to get recharge count: %v", err) } err = LogDb.Get(&TotalRecharge, "select IFNULL(SUM(Price), 0) as sum from log_order") if err != nil { return nil, fmt.Errorf("failed to get total recharge count: %v", err) } // 充值人数统计 err = LogDb.Get(&RechargeUser, "select count(distinct Uid) as sum from log_order where Timestamp >= ? and Timestamp <= ?", StartTime, EndTime) if err != nil { return nil, fmt.Errorf("failed to get recharge count: %v", err) } var TotalRechargeUser int // 充值总人数统计 err = LogDb.Get(&TotalRechargeUser, "select count(distinct Uid) as sum from log_order") if err != nil { return nil, fmt.Errorf("failed to get total recharge count: %v", err) } type RemainCount struct { Register int `db:"register"` SecondRemain int `db:"SecondRemain"` } var rc RemainCount err = LogDb.Get(&rc, "select sum(`Register`) as register, sum(`SecondRemain`) as SecondRemain from remain") if err != nil { return nil, fmt.Errorf("failed to get recharge count: %v", err) } rechargeFloat, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", Recharge), 64) totalRechargeFloat, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", TotalRecharge), 64) return map[string]interface{}{ "register": Register, "totalRegister": TotalRegistger, "recharge": rechargeFloat, "totalRecharge": totalRechargeFloat, "rechargeUser": RechargeUser, "totalRechargeUser": TotalRechargeUser, "remain": util.FloatDecimals(100*float64(rc.SecondRemain)/float64(rc.Register), 2), }, nil } func (s *Statistics) StatisticsHeat() (interface{}, error) { AppConfig, err := util.GetAppConfig(s.AppId) if err != nil { return nil, err } LogDb := util.MPool.GetTopicDB(AppConfig.Topic) defer LogDb.Close() if LogDb == nil { return nil, fmt.Errorf("failed to get mysql database") } now := util.Now() value := make([]int, 0, 24) value2 := make([]int, 0, 24) key := make([]string, 0, 24) for i := 0; i < 24; i++ { key = append(key, fmt.Sprintf("%02d:00", i)) } type r struct { Sum1 int `db:"sum1"` Sum2 int `db:"sum2"` } var result r for i := 0; i < 24; i++ { err := LogDb.Get(&result, "select count(*) as sum1, count(distinct Uid) as sum2 from log_event where Timestamp >= ? and Timestamp <= ?", now-int64(i)*3600-3600, now-int64(i)*3600) if err != nil { return nil, fmt.Errorf("failed to get heat count: %v", err) } value = append(value, result.Sum1) value2 = append(value2, result.Sum2) key[i] = fmt.Sprintf("%02d:00", util.GetHour(now-int64(i)*3600, AppConfig.Tz)) } if len(value) < 2 { return value, nil } // 反转key和value for i, j := 0, len(value)-1; i < j; i, j = i+1, j-1 { key[i], key[j] = key[j], key[i] value2[i], value2[j] = value2[j], value2[i] value[i], value[j] = value[j], value[i] } return map[string]interface{}{ "key": key, "value": value, "value2": value2, }, nil } func (s *Statistics) StatisticsOrder() (interface{}, error) { AppConfig, err := util.GetAppConfig(s.AppId) if err != nil { return nil, err } LogDb := util.MPool.GetTopicDB(AppConfig.Topic) defer LogDb.Close() if LogDb == nil { return nil, fmt.Errorf("failed to get mysql database") } // 订单统计 var result []struct { Param string `db:"Param"` } err = LogDb.Select(&result, "select Param from log_event where `Event` = 'logout' and Timestamp <= ?", util.Now()-86400*7) if err != nil { return nil, fmt.Errorf("failed to get order count: %v", err) } type r struct { count int m map[int]int } hard := r{} hard.m = make(map[int]int) mid := r{} mid.m = make(map[int]int) for _, v := range result { paramMap := util.ParseParam(v.Param) orderList := paramMap["order_list"].(map[string]interface{}) if paramMap["after_level"].(float64) < 12 { continue } hardNum := 0 midNum := 0 for _, order := range orderList { orderMap := order.(map[string]interface{}) MergeList := make([]string, 0) if mergeIDs, ok := orderMap["MergeId"].([]any); ok && mergeIDs != nil { for _, m := range mergeIDs { mInt := fmt.Sprintf("%v", m) MergeList = append(MergeList, mInt) } } // 检测是否包含难度符文 if int(orderMap["Diff"].(float64)) == 3 && util.CheckContainChess(MergeList, s.Emit) { hardNum++ } if int(orderMap["Diff"].(float64)) == 2 && util.CheckContainChess(MergeList, s.Emit) { midNum++ } } if hardNum > 0 { hard.count++ hard.m[hardNum]++ } if midNum > 0 { mid.count++ mid.m[midNum]++ } } type rr struct { Type string `json:"Type"` Num int `json:"Num"` Sum int `json:"Sum"` Prop float64 `json:"Prop"` } hardData := make([]rr, 10) for i := 0; i <= 4; i++ { num := 0 if i == 0 { num = hard.count } if v, ok := hard.m[i]; ok { num = v } prop := 0.0 if hard.count > 0 { prop = util.FloatDecimals(100*float64(num)/float64(hard.count), 2) } hardData[i] = rr{ Type: "高难度", Num: i, Sum: num, Prop: prop, } } for i := 5; i <= 9; i++ { num := 0 if i-5 == 0 { num = mid.count } if v, ok := mid.m[i-5]; ok { num = v } prop := 0.0 if mid.count > 0 { prop = util.FloatDecimals(100*float64(num)/float64(mid.count), 2) } hardData[i] = rr{ Type: "中难度", Num: i - 5, Sum: num, Prop: prop, } } return map[string]interface{}{ "data": hardData, "data2": mid, }, nil }