Bladeren bron

增加-数据结构

userxzz 9 maanden geleden
bovenliggende
commit
597e33c684

+ 5 - 4
game/game_cluster/internal/mdb/models/PlayerStat.go

@@ -2,12 +2,13 @@ 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"
-	"math/rand"
-	"time"
 )
 
 type PlayerLevelStat struct {
@@ -25,7 +26,7 @@ type PlayerServerLoadStat struct {
 }
 
 type PlayerCountryStat struct {
-	Daily                 int64          `bson:"daily" json:"daily"`                                 //日期
+	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 玩家注册国家
@@ -38,7 +39,7 @@ type Preserve struct {
 	Ratio string `json:"ratio"`
 }
 
-var preserveConfig = []int64{2, 3, 7, 15, 30}
+var preserveConfig = []int64{2, 3, 7, 14, 30}
 
 // GetPlayerPreserve 获取用户留存
 func GetPlayerPreserve(startTime, EndTime int64) map[int64][]*Preserve {

+ 11 - 3
game/game_cluster/nodes/webadmin/entity/user_country_count.go

@@ -1,9 +1,17 @@
 package entity
 
 type UserCountryResp struct {
-	Country    string `json:"country"`    // 国家
-	IPCount    int    `json:"ip_count"`   // IP数量
-	Percentage int    `json:"percentage"` // 百分比
+	Country    string  `json:"country"`    // 国家
+	IPCount    int     `json:"ip_count"`   // IP数量
+	Percentage float64 `json:"percentage"` // 百分比
 }
 type UserCountryReq struct {
 }
+
+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"`
+}

+ 22 - 5
game/game_cluster/nodes/webadmin/entity/user_reg_count.go

@@ -1,12 +1,10 @@
 package entity
 
-import (
-	"github.com/mhaya/game/game_cluster/nodes/webadmin/model"
-)
-
 // UserRetentionResp 用于存储用户的留存数据
 type UserRetentionResp struct {
-	*model.UserRetentionData
+	ID               string    `bson:"_id"`               // 用户唯一标识符
+	RegistrationDate int64     `bson:"registration_date"` // 注册日期
+	RetentionData    Retention `bson:"retention_data"`
 }
 
 type UserRetentionReq struct {
@@ -15,3 +13,22 @@ type UserRetentionReq struct {
 	Page      int   `json:"page"`       // 页码
 	Size      int   `json:"size"`       // 每页数量
 }
+
+// UserRetentionData 用于存储用户的留存数据
+type UserRetentionData struct {
+}
+
+// DayRetention 用于存储单一天数的留存数据
+type DayRetention struct {
+	LoggedIn  interface{} `bson:"logged_in"`  // 是否在指定天数内登录
+	LoginDate int64       `bson:"login_date"` // 登录日期
+}
+
+// Retention 用于存储不同天数的留存数据
+type Retention struct {
+	Day1  DayRetention `bson:"day_1"`
+	Day3  DayRetention `bson:"day_3"`
+	Day7  DayRetention `bson:"day_7"`
+	Day14 DayRetention `bson:"day_14"`
+	Day30 DayRetention `bson:"day_30"`
+}

+ 97 - 70
game/game_cluster/nodes/webadmin/service/synthesis.go

@@ -2,12 +2,12 @@ package service
 
 import (
 	"context"
+	"math"
 	"time"
 
 	"github.com/mhaya/game/game_cluster/internal/mdb"
 	"github.com/mhaya/game/game_cluster/internal/mdb/models"
 	"github.com/mhaya/game/game_cluster/nodes/webadmin/entity"
-	"github.com/mhaya/game/game_cluster/nodes/webadmin/model"
 	"github.com/spf13/cast"
 	"go.mongodb.org/mongo-driver/bson"
 	"go.mongodb.org/mongo-driver/mongo"
@@ -174,63 +174,86 @@ func (s *Synthesis) WithdrawalStatus(req *entity.UserWithdrawalStatus) error {
 //
 // 返回值为 UserCountryResp 的切片和错误。
 func (s *Synthesis) FindUserCountryCount() ([]*entity.UserCountryResp, error) {
-	// 设置超时的上下文
-	ctx, cancel := context.WithTimeout(context.Background(), 100*time.Second)
-	defer cancel()
-
-	// 获取数据库的集合
-	collection := s.db.Collection("user_country_count")
-
-	// 设置百分比阈值
-	threshold := 1
+	// 选择数据库和集合
+	collection := mdb.MDB.Collection("playerCountryStat")
+
+	// 定义聚合管道
+	// 定义聚合管道
+	pipeline := []bson.D{
+		{
+			{Key: "$project", Value: bson.D{
+				{Key: "playerRegisterCountry", Value: bson.D{{Key: "$objectToArray", Value: "$playerRegisterCountry"}}},
+			}},
+		},
+		{
+			{Key: "$unwind", Value: "$playerRegisterCountry"},
+		},
+		{
+			{Key: "$group", Value: bson.D{
+				{Key: "_id", Value: "$playerRegisterCountry.k"},
+				{Key: "totalValue", Value: bson.D{{Key: "$sum", Value: "$playerRegisterCountry.v"}}},
+			}},
+		},
+		{
+			{Key: "$project", Value: bson.D{
+				{Key: "_id", Value: 0},
+				{Key: "countryKey", Value: "$_id"},
+				{Key: "totalValue", Value: 1},
+			}},
+		},
+	}
 
 	// 执行聚合查询
-	var results []*entity.UserCountryResp
-	cursor, err := collection.Find(ctx, bson.M{}, options.Find())
+	cursor, err := collection.Aggregate(context.TODO(), pipeline)
 	if err != nil {
-		return nil, err
+		panic(err)
 	}
-	defer cursor.Close(ctx)
+	defer cursor.Close(context.TODO())
 
-	// 解析结果
-	for cursor.Next(ctx) {
-		var result model.UserCountryCount
-		if err := cursor.Decode(&result); err != nil {
-			return nil, err
-		}
-		results = append(results, &entity.UserCountryResp{
-			Country:    result.Country,
-			IPCount:    result.IPCount,
-			Percentage: result.Percentage,
-		})
+	// 遍历查询结果
+	var results []bson.M
+	if err := cursor.All(context.TODO(), &results); err != nil {
+		panic(err)
 	}
-
-	if err := cursor.Err(); err != nil {
-		return nil, err
+	var totalIPCount int64
+	var data []*entity.UserCountryResp
+	// 将结果转换为 UserCountryResp
+	for _, r := range results {
+		var resp entity.UserCountryResp
+		resp.Country = r["countryKey"].(string)
+		resp.IPCount = int(r["totalValue"].(int32))
+		totalIPCount += int64(resp.IPCount)
+		data = append(data, &resp)
+	}
+	for _, v := range data {
+		// 保留小数点后两位
+		v.Percentage = math.Round(float64(v.IPCount)/float64(totalIPCount)*10000) / 100
 	}
 
 	// 根据阈值过滤结果
 	otherCount := 0
-	otherPercentage := 0
+	otherPercentage := 0.00
 	filteredResults := make([]*entity.UserCountryResp, 0)
-
-	for _, r := range results {
+	threshold := 1.00
+	for _, r := range data {
 		if r.Percentage >= threshold {
 			filteredResults = append(filteredResults, r)
+			// 保留小数点后两位
+			r.Percentage = math.Round(r.Percentage*100) / 100
+			otherPercentage += r.Percentage
 		} else {
 			otherCount += r.IPCount
-			otherPercentage += r.Percentage
 		}
 	}
-
 	// 将其他国家添加到过滤后的结果中
 	if otherCount > 0 {
+		p := 100.00 - math.Round(otherPercentage*100)/100
 		filteredResults = append(filteredResults, &entity.UserCountryResp{
-			Country: "other",
-			IPCount: otherCount,
+			Country:    "other",
+			IPCount:    otherCount,
+			Percentage: math.Round(p*100) / 100,
 		})
 	}
-
 	return filteredResults, nil
 
 }
@@ -241,44 +264,48 @@ func (s *Synthesis) FindUserCountryCount() ([]*entity.UserCountryResp, error) {
 // 3. 计算留存率
 // 4. 返回结果
 func (s *Synthesis) FindUserRetention(req *entity.UserRetentionReq) ([]*entity.UserRetentionResp, error) {
-	ctx, cancel := context.WithTimeout(context.Background(), 100*time.Second)
-	defer cancel()
-	collection := s.db.Collection("user_reg_count")
-
-	// 构建过滤器
-	filter := bson.M{}
-	if req.StartTime != 0 {
-		filter["registration_date"] = bson.M{
-			"$gte": req.StartTime,
-			"$lte": req.EndTime,
-		} // 日期范围
-	}
-	// 设置分页选项
-	findOptions := options.Find()
-	findOptions.SetSkip(int64((req.Page - 1) * req.Size))
-	findOptions.SetLimit(int64(req.Size))
-
+	playerPreserve := models.GetPlayerPreserve(req.StartTime, req.EndTime)
 	// 查询数据
 	var results []*entity.UserRetentionResp
-	cursor, err := collection.Find(ctx, filter, findOptions)
-	if err != nil {
-		return nil, err
-	}
-	defer cursor.Close(ctx)
 
-	// 解析结果
-	for cursor.Next(ctx) {
-		var result model.UserRetentionData
-		if err := cursor.Decode(&result); err != nil {
-			return nil, err
+	for key, v := range playerPreserve {
+		var resp entity.UserRetentionResp
+		var retention entity.Retention
+		for _, vv := range v {
+			if vv.ID == 1 {
+				retention.Day1 = entity.DayRetention{
+					LoggedIn:  vv.Ratio,
+					LoginDate: key,
+				}
+			}
+			if vv.ID == 3 {
+				retention.Day3 = entity.DayRetention{
+					LoggedIn:  vv.Ratio,
+					LoginDate: key,
+				}
+			}
+			if vv.ID == 7 {
+				retention.Day7 = entity.DayRetention{
+					LoggedIn:  vv.Ratio,
+					LoginDate: key,
+				}
+			}
+			if vv.ID == 14 {
+				retention.Day14 = entity.DayRetention{
+					LoggedIn:  vv.Ratio,
+					LoginDate: key,
+				}
+			}
+			if vv.ID == 30 {
+				retention.Day30 = entity.DayRetention{
+					LoggedIn:  vv.Ratio,
+					LoginDate: key,
+				}
+			}
 		}
-		results = append(results, &entity.UserRetentionResp{
-			UserRetentionData: &result,
-		})
-	}
-
-	if err := cursor.Err(); err != nil {
-		return nil, err
+		resp.RegistrationDate = key
+		resp.RetentionData = retention
+		results = append(results, &resp)
 	}
 
 	return results, nil