Quellcode durchsuchen

增加-数据结构

userxzz vor 9 Monaten
Ursprung
Commit
177fa873f9

+ 1 - 0
game/game_cluster/nodes/webadmin/common/page.go

@@ -0,0 +1 @@
+package common

+ 115 - 0
game/game_cluster/nodes/webadmin/controller/synthesis.go

@@ -16,6 +16,7 @@ func NewSynthesis() *Synthesis {
 	}
 }
 
+// FindUserLogDaily 查询用户日活跃
 func (s *Synthesis) FindUserLogDaily(ctx *gin.Context) {
 	req := &entity.UserLogDailyReq{}
 	if err := ctx.ShouldBindJSON(req); err != nil {
@@ -39,3 +40,117 @@ func (s *Synthesis) FindUserLogDaily(ctx *gin.Context) {
 		"data": resp,
 	})
 }
+
+// FindUserRetention 查询用户留存
+func (s *Synthesis) FindUserRetention(ctx *gin.Context) {
+	req := &entity.UserRetentionReq{}
+	if err := ctx.ShouldBindJSON(req); err != nil {
+		ctx.JSON(200, gin.H{
+			"code": 400,
+			"msg":  err.Error(),
+		})
+		return
+	}
+	resp, err := s.sev.FindUserRetention(req)
+	if err != nil {
+		ctx.JSON(200, gin.H{
+			"code": 400,
+			"msg":  err.Error(),
+		})
+		return
+	} else {
+		ctx.JSON(200, gin.H{
+			"code": 200,
+			"msg":  "success",
+			"data": resp,
+		})
+	}
+
+}
+
+// FindUserCountryCount 查询用户国家分布
+func (s *Synthesis) FindUserCountryCount(ctx *gin.Context) {
+	resp, err := s.sev.FindUserCountryCount()
+	if err != nil {
+		ctx.JSON(200, gin.H{
+			"code": 400,
+			"msg":  err.Error(),
+		})
+		return
+	} else {
+		ctx.JSON(200, gin.H{
+			"code": 200,
+			"msg":  "success",
+			"data": resp,
+		})
+	}
+}
+
+// FindWithdrawal 查询提现记录
+func (s *Synthesis) FindWithdrawal(ctx *gin.Context) {
+	req := &entity.UserWithdrawalReq{}
+	if err := ctx.ShouldBindJSON(req); err != nil {
+		ctx.JSON(200, gin.H{
+			"code": 400,
+			"msg":  err.Error(),
+		})
+		return
+	}
+	resp, err := s.sev.FindWithdrawal(req)
+	if err != nil {
+		ctx.JSON(200, gin.H{
+			"code": 400,
+			"msg":  err.Error(),
+		})
+		return
+	} else {
+		ctx.JSON(200, gin.H{
+			"code": 200,
+			"msg":  "success",
+			"data": resp,
+		})
+	}
+}
+
+// WithdrawalStatus 修改提现状态
+func (s *Synthesis) WithdrawalStatus(ctx *gin.Context) {
+	req := &entity.UserWithdrawalStatus{}
+	if err := ctx.ShouldBindJSON(req); err != nil {
+		ctx.JSON(200, gin.H{
+			"code": 400,
+			"msg":  err.Error(),
+		})
+		return
+	}
+	err := s.sev.WithdrawalStatus(req)
+	if err != nil {
+		ctx.JSON(200, gin.H{
+			"code": 400,
+			"msg":  err.Error(),
+		})
+		return
+	} else {
+		ctx.JSON(200, gin.H{
+			"code": 200,
+			"msg":  "success",
+		})
+	}
+}
+
+// FindUserLevel 查询用户等级
+func (s *Synthesis) FindUserLevel(ctx *gin.Context) {
+	resp, err := s.sev.FindUserLevel()
+	if err != nil {
+		ctx.JSON(200, gin.H{
+			"code": 400,
+			"msg":  err.Error(),
+		})
+		return
+	} else {
+		ctx.JSON(200, gin.H{
+			"code": 200,
+			"msg":  "success",
+			"data": resp,
+		})
+	}
+}

+ 2 - 0
game/game_cluster/nodes/webadmin/entity/user_country_count.go

@@ -5,3 +5,5 @@ type UserCountryResp struct {
 	IPCount    int    `json:"ip_count"`   // IP数量
 	Percentage int    `json:"percentage"` // 百分比
 }
+type UserCountryReq struct {
+}

+ 2 - 2
game/game_cluster/nodes/webadmin/entity/user_lavel_count.go

@@ -1,6 +1,6 @@
 package entity
 
 type UserLevelCountResp struct {
-	Level     int `json:"level"`
-	UserCount int `json:"user_count"`
+	Level     int `json:"level" bson:"level"`
+	UserCount int `json:"user_count" bson:"user_count"`
 }

+ 13 - 13
game/game_cluster/nodes/webadmin/entity/user_log_daily.go

@@ -1,19 +1,19 @@
 package entity
 
 type UserLogDailyResp struct {
-	Platform    string  `bson:"platform"  json:"platform,omitempty"`        // platform: 用户所在的平台,例如“Android”或“IOS”
-	Channel     string  `bson:"channel" json:"channel,omitempty"`           // channel: 用户来源渠道
-	Registered  int     `bson:"registered" json:"registered,omitempty"`     // registered: 新用户注册的数量
-	LoggedIn    int     `bson:"logged_in" json:"logged_in,omitempty"`       // logged_in: 登陆产品的用户数量
-	NewLogin    int     `bson:"new_login" json:"new_login,omitempty"`       // new_login: 登陆产品的新注册用户数量
-	OldLogin    int     `bson:"old_login" json:"old_login,omitempty"`       // old_login: 登陆产品的老用户数量
-	ActiveUsers int     `bson:"active_users" json:"active_users,omitempty"` // active_users: 登录游戏后投掷过骰子的用户数量
-	NewActive   int     `bson:"new_active" json:"new_active,omitempty"`     // new_active: 登录游戏后投掷过骰子的新用户数量
-	OldActive   int     `bson:"old_active" json:"old_active,omitempty"`     // old_active: 登录游戏后投掷过骰子的老用户数量
-	TotalPoints int     `bson:"total_points" json:"total_points,omitempty"` // total_points: 全服积分产出总值
-	UProduced   float64 `bson:"u_produced" json:"u_produced,omitempty"`     // u_produced: 全服U的产出总值
-	UCashout    float64 `bson:"u_cashout" json:"u_cashout,omitempty"`       // u_cashout: 全服U的提现总值
-	Timestamp   int64   `bson:"timestamp" json:"timestamp,omitempty"`       // timestamp: 数据记录的时间戳
+	Platform    string  `bson:"platform"  json:"platform"`        // platform: 用户所在的平台,例如“Android”或“IOS”
+	Channel     string  `bson:"channel" json:"channel"`           // channel: 用户来源渠道
+	Registered  int     `bson:"registered" json:"registered"`     // registered: 新用户注册的数量
+	LoggedIn    int     `bson:"logged_in" json:"logged_in"`       // logged_in: 登陆产品的用户数量
+	NewLogin    int     `bson:"new_login" json:"new_login"`       // new_login: 登陆产品的新注册用户数量
+	OldLogin    int     `bson:"old_login" json:"old_login"`       // old_login: 登陆产品的老用户数量
+	ActiveUsers int     `bson:"active_users" json:"active_users"` // active_users: 登录游戏后投掷过骰子的用户数量
+	NewActive   int     `bson:"new_active" json:"new_active"`     // new_active: 登录游戏后投掷过骰子的新用户数量
+	OldActive   int     `bson:"old_active" json:"old_active"`     // old_active: 登录游戏后投掷过骰子的老用户数量
+	TotalPoints int     `bson:"total_points" json:"total_points"` // total_points: 全服积分产出总值
+	UProduced   float64 `bson:"u_produced" json:"u_produced"`     // u_produced: 全服U的产出总值
+	UCashout    float64 `bson:"u_cashout" json:"u_cashout"`       // u_cashout: 全服U的提现总值
+	Timestamp   int64   `bson:"daily" json:"timestamp"`           // timestamp: 数据记录的时间戳
 }
 
 // UserLogDailyReq 用户日志

+ 7 - 0
game/game_cluster/nodes/webadmin/entity/user_reg_count.go

@@ -8,3 +8,10 @@ import (
 type UserRetentionResp struct {
 	*model.UserRetentionData
 }
+
+type UserRetentionReq struct {
+	StartTime int64 `json:"start_time"` // 开始时间
+	EndTime   int64 `json:"end_time"`   // 结束时间
+	Page      int   `json:"page"`       // 页码
+	Size      int   `json:"size"`       // 每页数量
+}

+ 17 - 15
game/game_cluster/nodes/webadmin/entity/user_withdrawal.go

@@ -2,25 +2,27 @@ package entity
 
 // UserWithdrawalResp \game\game_cluster\nodes\webadmin\entity\user_withdrawal.go
 type UserWithdrawalResp struct {
-	UserName    string `json:"userName" bson:"userName"`        // 用户名字
-	NickName    string `json:"nickName" bson:"nickName"`        // 昵称
-	Status      int    `json:"status" bson:"status"`            // 0:未审核 1:审核通过 2:审核失败
-	Amount      int    `json:"amount" bson:"amount"`            //
-	AfterAmount int    `json:"afterAmount" bson:"after_amount"` //
-	Type        int    `json:"type" bson:"type"`                // 货币内型
-	Address     string `json:"address" bson:"address"`          // 地址
-	CreateAt    int64  `json:"createAt" bson:"createAt"`
+	UserName    string `json:"user_name" bson:"user_name"`       // 用户ID
+	NickName    string `json:"nick_name" bson:"nick_name"`       // 昵称
+	Status      int    `json:"status" bson:"status"`             // 0:未审核 1:审核通过 2:审核失败
+	Amount      int    `json:"amount" bson:"amount"`             // 提现金额
+	AfterAmount int    `json:"after_amount" bson:"after_amount"` // 提现后金额
+	Type        int    `json:"type" bson:"type"`                 // 货币内型
+	Address     string `json:"address" bson:"address"`           // 地址
+	CreateAt    int64  `json:"createAt" bson:"createAt"`         // 提现时间
 	UpdateAt    int64  `json:"updateAt" bson:"updateAt"`
 }
 
 type UserWithdrawalReq struct {
-	UserName  string `json:"userName" bson:"userName"` // 用户名字
-	NickName  string `json:"nickName" bson:"nickName"` // 昵称
-	StartTime int64  `json:"start_time"`               // 开始时间
-	EndTime   int64  `json:"end_time"`                 // 结束时间
-	Page      int    `json:"page"`                     // 页码
-	Size      int    `json:"size"`                     // 每页数量
+	UserName  string `json:"user_name" bson:"user_name"` // 用户ID
+	NickName  string `json:"nick_name" bson:"nick_name"` // 昵称
+	StartTime int64  `json:"start_time"`                 // 开始时间
+	EndTime   int64  `json:"end_time"`                   // 结束时间
+	Page      int    `json:"page"`                       // 页码
+	Size      int    `json:"size"`                       // 每页数量
 }
 
-type UserWithdrawal struct {
+type UserWithdrawalStatus struct {
+	UserName string `json:"user_name" bson:"user_name"` // 用户ID
+	Status   int    `json:"status" bson:"status"`       // 0:未审核 1:审核通过 2:审核失败
 }

+ 3 - 3
game/game_cluster/nodes/webadmin/model/user_country_count.go

@@ -1,7 +1,7 @@
 package model
 
 type UserCountryCount struct {
-	Country    string `json:"country"`    // 国家
-	IPCount    int    `json:"ip_count"`   // IP数量
-	Percentage int    `json:"percentage"` // 百分比
+	Country    string `json:"country" bson:"country"`       // 国家
+	IPCount    int    `json:"ip_count" bson:"ip_count"`     // IP数量
+	Percentage int    `json:"percentage" bson:"percentage"` // 百分比
 }

+ 3 - 3
game/game_cluster/nodes/webadmin/model/user_reg_count.go

@@ -2,8 +2,8 @@ package model
 
 // UserRetentionData 用于存储用户的留存数据
 type UserRetentionData struct {
-	UserID           string    `bson:"_id"` // 用户唯一标识符
-	RegistrationDate int64     // 注册日期
+	ID               string    `bson:"_id"`               // 用户唯一标识符
+	RegistrationDate int64     `bson:"registration_date"` // 注册日期
 	RetentionData    Retention `bson:"retention_data"`
 }
 
@@ -18,6 +18,6 @@ type Retention struct {
 
 // DayRetention 用于存储单一天数的留存数据
 type DayRetention struct {
-	LoggedIn  bool  `bson:"logged_in"`  // 是否在指定天数内登录
+	LoggedIn  int   `bson:"logged_in"`  // 是否在指定天数内登录
 	LoginDate int64 `bson:"login_date"` // 登录日期
 }

+ 6 - 0
game/game_cluster/nodes/webadmin/router/router.go

@@ -41,6 +41,12 @@ func (c *Controller) InitApiRouter(u *gin.RouterGroup) {
 		context.JSON(http.StatusOK, "")
 	})
 	u.POST("/user/log/daily", controller.NewSynthesis().FindUserLogDaily)
+	u.POST("/user/retention", controller.NewSynthesis().FindUserRetention)
+	u.POST("/user/country", controller.NewSynthesis().FindUserCountryCount)
+	u.POST("/user/withdrawal", controller.NewSynthesis().FindWithdrawal)
+	u.POST("/user/withdrawal/status", controller.NewSynthesis().WithdrawalStatus)
+	u.POST("/user/level", controller.NewSynthesis().FindUserLevel)
+
 }
 
 // func (c *Controller) InitMdb() {

+ 204 - 9
game/game_cluster/nodes/webadmin/service/synthesis.go

@@ -5,8 +5,10 @@ import (
 	"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"
-	mdb2 "github.com/mhaya/game/game_cluster/nodes/webadmin/mdb"
+	"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"
 	"go.mongodb.org/mongo-driver/mongo/options"
@@ -18,17 +20,17 @@ type Synthesis struct {
 
 func NewSynthesis() *Synthesis {
 	return &Synthesis{
-		db: mdb2.MdbAdmin,
+		db: mdb.MDB,
 	}
 }
 
-func (s *Synthesis) FindMDBUserLogDaily(req *entity.UserLogDailyReq) ([]*entity.UserLogDailyResp, error) {
+func (s *Synthesis) FindMDBUserLogDaily(req *entity.UserLogDailyReq) ([]entity.UserLogDailyResp, error) {
 	// 定义上下文
 	ctx, cancel := context.WithTimeout(context.Background(), 100*time.Second)
 	defer cancel()
 
 	// 指定集合
-	collection := s.db.Collection("user_logs_daily")
+	collection := mdb.MDB.Collection("playerDailyRecord")
 
 	// 构建查询条件 - 如果查询值为空那就不添加查询条件
 	filter := bson.M{}
@@ -40,7 +42,7 @@ func (s *Synthesis) FindMDBUserLogDaily(req *entity.UserLogDailyReq) ([]*entity.
 		}
 	}
 
-	if req.Platform != "" {
+	if req.Platform != "" && req.Platform != "all" {
 		filter["platform"] = req.Platform
 	}
 
@@ -63,18 +65,44 @@ func (s *Synthesis) FindMDBUserLogDaily(req *entity.UserLogDailyReq) ([]*entity.
 	defer cursor.Close(ctx)
 
 	// 解析查询结果
-	var results []*entity.UserLogDailyResp
+	var results []entity.UserLogDailyResp
+
 	for cursor.Next(ctx) {
 		var result entity.UserLogDailyResp
 		err := cursor.Decode(&result)
 		if err != nil {
 			return nil, err
 		}
-		results = append(results, &result)
+		results = append(results, result)
 	}
+	// 同一天的数据全部放到platform= ALl 且数据累加
+	// 如果没有platform=all 的那就新增一个 同一个时间段只能有一个 platform=all
+	// 将同一天的数据累加到platform=all的记录中
+	allPlatformRecordMap := make(map[int64]*entity.UserLogDailyResp)
 
-	if err := cursor.Err(); err != nil {
-		return nil, err
+	for _, result := range results {
+		allPlatformRecordMap[result.Timestamp] = &entity.UserLogDailyResp{
+			Timestamp: result.Timestamp,
+			Platform:  "all",
+		}
+	}
+	for _, v := range results {
+		if v.Timestamp == allPlatformRecordMap[v.Timestamp].Timestamp {
+			allPlatformRecordMap[v.Timestamp].Registered += v.Registered
+			allPlatformRecordMap[v.Timestamp].LoggedIn += v.LoggedIn
+			allPlatformRecordMap[v.Timestamp].NewActive += v.NewActive
+			allPlatformRecordMap[v.Timestamp].OldActive += v.OldActive
+			allPlatformRecordMap[v.Timestamp].TotalPoints += v.TotalPoints
+			allPlatformRecordMap[v.Timestamp].UProduced += v.UProduced
+			allPlatformRecordMap[v.Timestamp].UCashout += v.UCashout
+			allPlatformRecordMap[v.Timestamp].NewLogin += v.NewLogin
+			allPlatformRecordMap[v.Timestamp].OldLogin += v.OldLogin
+		}
+	}
+
+	// 替换原有结果
+	for _, record := range allPlatformRecordMap {
+		results = append(results, *record)
 	}
 
 	return results, nil
@@ -129,3 +157,170 @@ func (s *Synthesis) FindWithdrawal(req *entity.UserWithdrawalReq) ([]*entity.Use
 
 	return results, nil
 }
+
+// WithdrawalStatus 更新提现状态
+func (s *Synthesis) WithdrawalStatus(req *entity.UserWithdrawalStatus) error {
+	ctx, cancel := context.WithTimeout(context.Background(), 100*time.Second)
+	defer cancel()
+	collection := mdb.MDB.Collection("CashOutRecord")
+	_, err := collection.UpdateOne(ctx, bson.M{"userName": req.UserName}, bson.M{"$set": bson.M{"status": req.Status}})
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
+// FindUserCountryCount 查询用户国家分布
+//
+// 返回值为 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
+
+	// 执行聚合查询
+	var results []*entity.UserCountryResp
+	cursor, err := collection.Find(ctx, bson.M{}, options.Find())
+	if err != nil {
+		return nil, err
+	}
+	defer cursor.Close(ctx)
+
+	// 解析结果
+	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,
+		})
+	}
+
+	if err := cursor.Err(); err != nil {
+		return nil, err
+	}
+
+	// 根据阈值过滤结果
+	otherCount := 0
+	otherPercentage := 0
+	filteredResults := make([]*entity.UserCountryResp, 0)
+
+	for _, r := range results {
+		if r.Percentage >= threshold {
+			filteredResults = append(filteredResults, r)
+		} else {
+			otherCount += r.IPCount
+			otherPercentage += r.Percentage
+		}
+	}
+
+	// 将其他国家添加到过滤后的结果中
+	if otherCount > 0 {
+		filteredResults = append(filteredResults, &entity.UserCountryResp{
+			Country: "other",
+			IPCount: otherCount,
+		})
+	}
+
+	return filteredResults, nil
+
+}
+
+// FindUserRetention UserRetentionResp 用户留存率
+// 1. 获取指定日期范围内的注册用户数量
+// 2. 获取指定日期范围内的活跃用户数量
+// 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))
+
+	// 查询数据
+	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
+		}
+		results = append(results, &entity.UserRetentionResp{
+			UserRetentionData: &result,
+		})
+	}
+
+	if err := cursor.Err(); err != nil {
+		return nil, err
+	}
+
+	return results, nil
+}
+
+// FindUserLevel 用户等级统计
+func (s *Synthesis) FindUserLevel() ([]*entity.UserLevelCountResp, error) {
+	ctx, cancel := context.WithTimeout(context.Background(), 100*time.Second)
+	defer cancel()
+	collection := mdb.MDB.Collection("playerLevelStat")
+
+	// 查询所有文档
+	cursor, err := collection.Find(ctx, bson.M{})
+	if err != nil {
+		return nil, err
+	}
+	defer cursor.Close(ctx)
+
+	var results []*entity.UserLevelCountResp
+	var reData []*models.PlayerLevelStat
+	for cursor.Next(ctx) {
+		var result models.PlayerLevelStat
+		if err := cursor.Decode(&result); err != nil {
+			return nil, err
+		}
+		reData = append(reData, &result)
+	}
+	if err := cursor.Err(); err != nil {
+		return nil, err
+	}
+	dataMap := make(map[string]int)
+	for _, v := range reData {
+		for key, v1 := range v.ServerLevel {
+			dataMap[key] += v1
+		}
+	}
+	for k, v := range dataMap {
+		results = append(results, &entity.UserLevelCountResp{
+			Level:     cast.ToInt(k),
+			UserCount: v,
+		})
+	}
+
+	return results, nil
+}