123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179 |
- package models
- import (
- "fmt"
- "math/rand"
- "time"
- mhayaTime "github.com/mhaya/extend/time"
- "github.com/mhaya/game/game_cluster/internal/data"
- "github.com/mhaya/game/game_cluster/internal/guid"
- clog "github.com/mhaya/logger"
- )
- type PlayerLevelStat struct {
- Platform string `bson:"platform" json:"platform"` // platform: 用户所在的平台,例如“Android”或“IOS”
- Channel string `bson:"channel" json:"channel"` // channel: 用户来源渠道
- ServerLevel map[string]int `json:"serverLevel" bson:"serverLevel"`
- UpdateTime int64 `bson:"updateTime" json:"updateTime"`
- }
- type PlayerServerLoadStat struct {
- Name string `bson:"name" json:"name"`
- TotalUser int64 `bson:"totalUser" json:"totalUser"`
- Load map[string]string `bson:"load" json:"load"`
- UpdateTime int64 `bson:"updateTime" json:"updateTime"`
- }
- type PlayerCountryStat struct {
- Daily int64 `bson:"daily" json:"daily"` // 日期
- Platform string `bson:"platform" json:"platform"` // platform: 用户所在的平台,例如“Android”或“IOS”
- Channel string `bson:"channel" json:"channel"` // channel: 用户来源渠道
- PlayerRegisterCountry map[string]int `bson:"playerRegisterCountry" json:"playerRegisterCountry"` // playerRegisterCountry 玩家注册国家
- UpdateTime int64 `bson:"updateTime" json:"updateTime"`
- }
- type Preserve struct {
- ID int64 `json:"id"`
- Num int `json:"num"`
- Ratio string `json:"ratio"`
- }
- var preserveConfig = []int64{2, 3, 7, 14, 30}
- // GetPlayerPreserve 根据开始和结束时间获取玩家的保留数据。
- // 该函数会检查时间参数是否合理,并限制查询时间范围不超过一周。
- // 参数:
- //
- // startTime - 查询的开始时间戳。
- // EndTime - 查询的结束时间戳。
- //
- // 返回值:
- //
- // 一个map,键是日期的时间戳,值是该日期玩家的保留数据列表。
- // 如果查询时间超过当前时间或查询范围超过一周,返回nil。
- func GetPlayerPreserve(startTime, EndTime int64) map[int64][]*Preserve {
- // 检查开始和结束时间是否在将来,如果是,返回nil。
- if startTime > mhayaTime.Now().Unix() || EndTime > mhayaTime.Now().Unix() {
- return nil
- }
- // 将开始时间转换为Timestamp类型。
- sTime := mhayaTime.CreateFromTimestamp(startTime).TOTimeStamp()
- // 如果结束时间超过当前时间,则将结束时间设置为当前时间。
- if EndTime > mhayaTime.Now().Unix() {
- EndTime = mhayaTime.Now().Unix()
- }
- // 将结束时间转换为Timestamp类型。
- eTime := mhayaTime.CreateFromTimestamp(EndTime).TOTimeStamp()
- // 计算开始时间和结束时间的天数差。
- day := mhayaTime.CreateFromTimestamp(sTime).DiffInDays(mhayaTime.CreateFromTimestamp(eTime))
- // 如果天数差超过7天,返回nil。
- if day > 7 {
- return nil
- }
- // 初始化返回的map。
- var ret = make(map[int64][]*Preserve, 0)
- // 遍历每一天,获取每一天的玩家保留数据。
- for i := 0; i < int(day); i++ {
- // 计算当前日期的时间戳。
- curTime := mhayaTime.CreateFromTimestamp(sTime).Add(time.Duration(i) * 24 * time.Hour).Unix()
- // 获取并存储当前日期的玩家保留数据。
- ret[curTime] = PlayerPreserve(curTime)
- }
- // 返回包含玩家保留数据的map。
- return ret
- }
- // PlayerPreserve 计算玩家保留数据。
- //
- // 参数:
- //
- // startTime - 统计周期的开始时间,用于确定从何时开始统计玩家保留数据。
- //
- // 返回值:
- //
- // []*Preserve - 一个指向Preserve结构体切片的指针,其中每个Preserve结构体包含玩家保留的相关信息。
- func PlayerPreserve(startTime int64) []*Preserve {
- // 初始化保存保留数据的切片。
- var preserve []*Preserve
- // 获取新的玩家映射和当前周期内的新注册玩家数量。
- cur, curNum := GetNewPlayerMap(startTime, DailyRecordNewRegistered)
- // 将第一天的新玩家保留数据添加到结果集中。
- preserve = append(preserve, &Preserve{ID: 1, Num: curNum, Ratio: "100%"})
- // 遍历保留配置,计算每个周期的保留数据。
- for _, v := range preserveConfig {
- // 计算下一个统计周期的开始时间。
- nextTime := mhayaTime.CreateFromTimestamp(startTime).Add(time.Duration(v-1) * 24 * time.Hour).Unix()
- // 获取下一个周期内的老玩家映射和该周期内的老玩家数量。
- next, nextNum := GetNewPlayerMap(nextTime, DailyRecordOldLogin)
- // 如果下一个周期内没有老玩家登录,则将保留数据的数目记为0。
- if nextNum == 0 {
- preserve = append(preserve, &Preserve{ID: v, Num: 0, Ratio: ""})
- } else {
- // 计算在当前周期和下一个周期都出现过的玩家数量。
- var num int
- for key, _ := range next {
- if _, ok := cur[key]; ok {
- num++
- }
- }
- // 计算并添加该周期的保留数据到结果集中。
- preserve = append(preserve, &Preserve{ID: v, Num: num, Ratio: fmt.Sprintf("%.2f", float64(num)/float64(curNum)*100)})
- }
- }
- // 返回计算得到的保留数据。
- return preserve
- }
- func GetNewPlayerMap(startTime int64, op int) (map[string]struct{}, int) {
- var user = make(map[string]struct{})
- platformConfig := data.PlatformConfig.GatMap()
- channelConfig := data.ChannelConfig.GatMap()
- for _, v := range platformConfig {
- for _, v2 := range channelConfig {
- ret, err := GetAppointDailyRecordUserHash(v.Name, v2.Name, startTime, op)
- if err != nil {
- continue
- }
- for k, _ := range ret {
- if _, ok := user[k]; !ok {
- user[k] = struct{}{}
- }
- }
- }
- }
- return user, len(user)
- }
- func TestPreserve(startTime int64, num int) {
- sTime := mhayaTime.CreateFromTimestamp(startTime).TOTimeStamp()
- for i := 0; i < num; i++ {
- userID := guid.Next()
- clog.Debugf("num=%v, user =%v", i, userID)
- SetAppointDailyRecordNewUserRegisterHash("ios", "tg_sign", userID, "1", sTime, DailyRecordNewRegistered)
- for _, v := range preserveConfig {
- r := rand.Intn(100)
- if r < 80 {
- nextTime := mhayaTime.CreateFromTimestamp(sTime).Add(time.Duration(v-1) * 24 * time.Hour).Unix()
- SetAppointDailyRecordNewUserRegisterHash("ios", "tg_sign", userID, "1", nextTime, DailyRecordOldLogin)
- }
- }
- }
- }
|