8 Commits 76b1d495ae ... 5fcdde4b72

Auteur SHA1 Bericht Datum
  Alvin 5fcdde4b72 update 完善玩家详情 8 maanden geleden
  Alvin 0cc9590144 update 玩家详情增加字段 8 maanden geleden
  Alvin ccea7518b1 update 完善获取转盘中奖记录 8 maanden geleden
  Alvin 18816208c4 update 完善获取转盘中奖记录 8 maanden geleden
  Alvin dcb9d127af update 修改玩家列表等级过滤 8 maanden geleden
  Alvin e71ac66af5 update 修改开始时间、结束时间默认值 8 maanden geleden
  Alvin 821d5eb7d7 update 新增获取玩家中奖记录(默认查询最近三天)接口 8 maanden geleden
  Alvin 587a64e3a0 update 新增玩家列表接口、玩家详情接口 8 maanden geleden

+ 64 - 0
game/game_cluster/internal/mdb/models/reward.go

@@ -1,7 +1,10 @@
 package models
 
 import (
+	cutils "github.com/mhaya/extend/utils"
+	"github.com/mhaya/game/game_cluster/internal/constant"
 	"github.com/mhaya/game/game_cluster/internal/data"
+	"go.mongodb.org/mongo-driver/bson"
 )
 
 const (
@@ -34,3 +37,64 @@ type PlayerReward map[int]*PlayerRewardBase
 func NewPlayerReward() map[int]*PlayerRewardBase {
 	return make(map[int]*PlayerRewardBase)
 }
+
+type ToPlayerRewardBase struct {
+	UserName   string          `json:"userName" bson:"userName"`
+	AddReward  []*ToItemReward `json:"AddReward" bson:"addReward"`
+	Desc       interface{}     `json:"desc" bson:"desc"`
+	CreateTime int64           `json:"createTime" bson:"createTime"`
+}
+
+type ToItemReward struct {
+	ItemID   int     // itemID:道具ID
+	Amount   float64 // amount:数量
+	ItemName string  // itemName:道具名称
+}
+
+type ToDesc struct {
+	ID    int `json:"id" bson:"id"`
+	CurID int `json:"cur_id" bson:"curid"`
+}
+
+func (uw *PlayerRewardBase) To() *ToPlayerRewardBase {
+	return &ToPlayerRewardBase{
+		UserName: uw.UserName,
+		AddReward: func() []*ToItemReward {
+			ret := make([]*ToItemReward, 0, 8)
+			for _, v := range uw.AddReward {
+				itemName := ""
+				cfg, exist := data.ItemConfig.Get(v.ItemID)
+				if exist {
+					itemName = cfg.ItemKey
+				}
+
+				ret = append(ret, &ToItemReward{
+					ItemID: v.ItemID,
+					Amount: func() float64 {
+						if itemName == "u" || itemName == "ton" {
+							return cutils.QuoInt64ByRatioToFloat64(int64(v.Amount), constant.MoneyRatio)
+						}
+
+						return float64(v.Amount)
+					}(),
+					ItemName: itemName,
+				})
+			}
+
+			return ret
+		}(),
+		Desc: func() *ToDesc {
+			if uw.Desc == nil {
+				return nil
+			}
+
+			drawMap := uw.Desc.(bson.D).Map()
+			return &ToDesc{
+				ID:    int(drawMap["id"].(int32)),
+				CurID: int(drawMap["curid"].(int32)),
+			}
+		}(),
+		// Desc:       uw.Desc,
+		CreateTime: uw.CreateTime,
+	}
+}

+ 91 - 0
game/game_cluster/nodes/webadmin/controller/player.go

@@ -0,0 +1,91 @@
+package controller
+
+import (
+	"github.com/gin-gonic/gin"
+	"github.com/mhaya/game/game_cluster/nodes/webadmin/entity"
+	"github.com/mhaya/game/game_cluster/nodes/webadmin/service"
+)
+
+type PlayerManage struct {
+	sev *service.PlayerManage
+}
+
+func NewPlayerManage() *PlayerManage {
+	return &PlayerManage{
+		sev: service.NewPlayerManage(),
+	}
+}
+
+func (w *PlayerManage) GetPlayerlist(ctx *gin.Context) {
+	req := entity.PlayerListReq{}
+	if err := ctx.ShouldBindJSON(&req); err != nil {
+		ctx.JSON(200, gin.H{
+			"code": 400,
+			"msg":  err.Error(),
+		})
+		return
+	}
+	resp, total, err := w.sev.List(ctx, req)
+	if err != nil {
+		ctx.JSON(200, gin.H{
+			"code": 400,
+			"msg":  err.Error(),
+		})
+		return
+	}
+	ctx.JSON(200, gin.H{
+		"code":  200,
+		"data":  resp,
+		"msg":   "success",
+		"total": total,
+	})
+}
+
+func (w *PlayerManage) GetPlayerInfo(ctx *gin.Context) {
+	req := entity.PlayerInfoReq{}
+	if err := ctx.ShouldBindJSON(&req); err != nil {
+		ctx.JSON(200, gin.H{
+			"code": 400,
+			"msg":  err.Error(),
+		})
+		return
+	}
+	resp, err := w.sev.PlayerInfo(ctx, req)
+	if err != nil {
+		ctx.JSON(200, gin.H{
+			"code": 400,
+			"msg":  err.Error(),
+		})
+		return
+	}
+	ctx.JSON(200, gin.H{
+		"code": 200,
+		"data": resp,
+		"msg":  "success",
+	})
+}
+
+func (w *PlayerManage) GetRewardList(ctx *gin.Context) {
+	req := entity.RewardListReq{}
+	if err := ctx.ShouldBindJSON(&req); err != nil {
+		ctx.JSON(200, gin.H{
+			"code": 400,
+			"msg":  err.Error(),
+		})
+		return
+	}
+	resp, total, err := w.sev.RewardList(ctx, req)
+	if err != nil {
+		ctx.JSON(200, gin.H{
+			"code": 400,
+			"msg":  err.Error(),
+		})
+		return
+	}
+	ctx.JSON(200, gin.H{
+		"code":  200,
+		"data":  resp,
+		"msg":   "success",
+		"total": total,
+	})
+}

+ 103 - 0
game/game_cluster/nodes/webadmin/entity/admin.go

@@ -1,5 +1,7 @@
 package entity
 
+import "github.com/mhaya/game/game_cluster/internal/mdb/models"
+
 // AdminResp \game\game_cluster\nodes\webadmin\entity\admin.go
 type AdminResp struct {
 	ToKen  string `json:"token"`
@@ -57,3 +59,104 @@ type AdminUpdateStatusReq struct {
 	Username string `json:"username"`
 	Status   int    `json:"status"`
 }
+
+type PlayerListReq struct {
+	Page        int    `json:"page" binding:"required"`
+	Size        int    `json:"size" binding:"required"`
+	UserName    string `json:"userName"`                    // 用户名
+	NickName    string `json:"nickName" bson:"nickName"`    // 昵称
+	OpenId      string `json:"openId" bson:"openId"`        // 对应tgid
+	Pid         string `json:"pid" bson:"pid"`              // 上级ID
+	XID         string `json:"xID" bson:"xID"`              // 绑定推特ID
+	TonWall     string `json:"tonWall" bson:"tonWall"`      // 绑定钱包地址
+	Email       string `json:"email" bson:"email"`          // 邮箱
+	LevelMin    int    `json:"levelMin" bson:"level"`       // 等级最小值
+	LevelMax    int    `json:"levelMax" bson:"level"`       // 等级最大值
+	Status      int    `json:"status" bson:"status"`        // 状态 1:有效 2:禁用
+	LoginIP     string `json:"loginIP" bson:"loginIP"`      // 登录IP
+	JoinTimeMin int64  `json:"joinTimeMin" bson:"joinTime"` // 注册时间最小值
+	JoinTimeMax int64  `json:"joinTimeMax" bson:"joinTime"` // 注册时间最大值
+}
+
+type PlayerListResp struct {
+	UserName      string `json:"userName" bson:"userName"`           // 用户名
+	OpenId        string `json:"openId" bson:"openId"`               // 对应tgid
+	UserNameMaybe string `json:"userNameMaybe" bson:"userNameMaybe"` // 昵称
+	NickName      string `json:"nickName" bson:"nickName"`           // 昵称
+	Pid           string `json:"pid" bson:"pid"`                     // 上级ID
+	XID           string `json:"xID" bson:"xID"`                     // 绑定推特ID
+	TonWall       string `json:"tonWall" bson:"tonWall"`             // 绑定钱包地址
+	Email         string `json:"email" bson:"email"`                 // 邮箱
+	Level         int    `json:"level" bson:"level"`                 // 等级
+	Status        int    `json:"status" bson:"status"`               // 状态  1:有效 2:禁用
+	LoginTime     int64  `json:"loginTime" bson:"loginTime"`         // 登陆时间
+	LoginIP       string `json:"loginIP" bson:"loginIP"`             // 登录IP
+	JoinIP        string `json:"joinIP" bson:"joinIP"`               // 注册IP
+	JoinTime      int64  `json:"joinTime" bson:"joinTime"`           // 注册时间
+}
+
+type PlayerInfoReq struct {
+	UserName string `json:"userName" binding:"required"` // 用户名
+}
+
+type PlayerInfoResp struct {
+	UserName       string               `json:"userName" bson:"userName"`             // 用户名
+	OpenId         string               `json:"openId" bson:"openId"`                 // 对应tgid
+	UserNameMaybe  string               `json:"userNameMaybe" bson:"userNameMaybe"`   // 昵称
+	NickName       string               `json:"nickName" bson:"nickName"`             // 昵称
+	Pid            string               `json:"pid" bson:"pid"`                       // 上级ID
+	XID            string               `json:"xID" bson:"xID"`                       // 绑定推特ID
+	TonWall        string               `json:"tonWall" bson:"tonWall"`               // 绑定钱包地址
+	Email          string               `json:"email" bson:"email"`                   // 邮箱
+	Level          int                  `json:"level" bson:"level"`                   // 等级
+	Status         int                  `json:"status" bson:"status"`                 // 状态  1:有效 2:禁用
+	LoginTime      int64                `json:"loginTime" bson:"loginTime"`           // 登陆时间
+	LoginIP        string               `json:"loginIP" bson:"loginIP"`               // 登录IP
+	JoinIP         string               `json:"joinIP" bson:"joinIP"`                 // 注册IP
+	JoinTime       int64                `json:"joinTime" bson:"joinTime"`             // 注册时间
+	Avatar         string               `json:"avatar" bson:"avatar"`                 // 头像
+	IsRobot        int                  `json:"isRobot" bson:"isRobot"`               // 是否为机器人
+	IsLeader       int                  `json:"isLeader" bson:"isLeader"`             // 是否是社区长
+	IsVip          int                  `json:"isVip" bson:"isVip"`                   // 是否为VIP
+	Successions    int                  `json:"successions" bson:"successions"`       // 连续登陆天数
+	MaxSuccessions int                  `json:"maxSuccessions" bson:"maxSuccessions"` // 最大连续等级天数
+	PrevTime       int64                `json:"prevTime" bson:"prevTime"`             // 上次登陆时间
+	UpdateTime     int64                `json:"updateTime" bson:"updateTime"`         // 更新时间
+	IsDrawShare    int                  `json:"isDrawShare" bson:"isDrawShare"`       // 0未领取,1已领取
+	DrawShareTime  int64                `json:"drawShareTime" bson:"drawShareTime"`   // 领取时间
+	FirstReward    int                  `json:"firstReward" bson:"firstReward"`       // 是否已领取首次登陆奖励
+	Item           models.ItemBasePack  `json:"item" bson:"item"`                     // 道具
+	SinIn          models.SignIn        `json:"sinIn" bson:"sinIn"`                   // 签到
+	DailyTask      models.DailyTask     `json:"dailyTask" bson:"dailyTask"`           // 日常任务
+	AchieveTask    models.AchieveTask   `json:"achieveTask" bson:"achieveTask"`       // 成就任务
+	RankReward     models.RankReward    `json:"rankReward" bson:"rankReward"`         // 排行奖励
+	Invite         models.Invite        `json:"invite" bson:"invite"`                 // 邀请
+	InviteReward   *models.InviteReward `json:"inviteReward" bson:"inviteReward"`     // 邀请奖励
+	Roll           *models.Roll         `json:"roll" bson:"roll"`                     // 抽奖
+}
+
+type RewardListReq struct {
+	Page      int    `json:"page" binding:"required"`
+	Size      int    `json:"size" binding:"required"`
+	UserName  string `json:"userName"`   // 用户名
+	StartTime int64  `json:"start_time"` // 开始时间
+	EndTime   int64  `json:"end_time"`   // 结束时间
+}
+
+type RewardListResp struct {
+	UserName   string        `json:"userName" bson:"userName"` // 用户名
+	AddReward  []*ItemReward `json:"AddReward" bson:"addReward"`
+	Desc       *Desc         `json:"desc" bson:"desc"`
+	CreateTime int64         `json:"createTime" bson:"createTime"`
+}
+
+type Desc struct {
+	ID    int `json:"id"`     // 中奖位置
+	CurID int `json:"cur_id"` // 规则id
+}
+
+type ItemReward struct {
+	ItemID   int    // itemID:道具ID
+	Amount   int    // amount:数量
+	ItemName string // itemName:道具名称
+}

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

@@ -69,6 +69,9 @@ func (c *Controller) InitApiRouter(u *gin.RouterGroup) {
 	u.POST("/whitelist/add", controller.NewWhitelist().AddWhitelist)
 	u.POST("/whitelist/remove", controller.NewWhitelist().RemoveWhitelist)
 	u.POST("/whitelist/list", controller.NewWhitelist().GetWhitelist)
+	u.POST("/player/list", controller.NewPlayerManage().GetPlayerlist)
+	u.POST("/player/info", controller.NewPlayerManage().GetPlayerInfo)
+	u.POST("/player/rewardList", controller.NewPlayerManage().GetRewardList)
 }
 
 // func (c *Controller) InitMdb() {

+ 246 - 0
game/game_cluster/nodes/webadmin/service/playerMange.go

@@ -0,0 +1,246 @@
+package service
+
+import (
+	"context"
+	"log"
+	"time"
+
+	mhayaTime "github.com/mhaya/extend/time"
+	"github.com/mhaya/game/game_cluster/internal/constant"
+	"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"
+	"go.mongodb.org/mongo-driver/bson"
+	"go.mongodb.org/mongo-driver/mongo/options"
+)
+
+type PlayerManage struct {
+}
+
+func NewPlayerManage() *PlayerManage {
+	return &PlayerManage{}
+}
+
+// 获取玩家列表
+func (a *PlayerManage) List(ctx context.Context, req entity.PlayerListReq) ([]*entity.PlayerListResp, int64, error) {
+	page := req.Page
+	// 验证参数
+	if page <= 0 {
+		page = 1
+	}
+	pageSize := req.Size
+	if pageSize <= 0 {
+		pageSize = 10
+	}
+
+	// 构建查询条件
+	filter := bson.M{}
+	if req.UserName != "" {
+		filter["userName"] = bson.M{"$regex": escapeRegex(req.UserName), "$options": "i"}
+	}
+	if req.NickName != "" {
+		filter["nickName"] = bson.M{"$regex": escapeRegex(req.NickName), "$options": "i"}
+	}
+	if req.OpenId != "" {
+		filter["openId"] = req.OpenId
+	}
+	if req.Pid != "" {
+		filter["pid"] = req.Pid
+	}
+	if req.XID != "" {
+		filter["xID"] = req.XID
+	}
+	if req.TonWall != "" {
+		filter["tonWall"] = req.TonWall
+	}
+	if req.Email != "" {
+		filter["email"] = req.Email
+	}
+	if req.LevelMin > 0 && req.LevelMax == 0 {
+		filter["level"] = bson.M{
+			"$gte": req.LevelMin,
+			"$lte": 1000, // 等级最大值
+		}
+	}
+	if req.LevelMin >= 0 && req.LevelMax > 0 && req.LevelMin <= req.LevelMax {
+		filter["level"] = bson.M{
+			"$gte": req.LevelMin,
+			"$lte": req.LevelMax,
+		}
+	}
+	if req.Status > 0 {
+		filter["status"] = req.Status
+	}
+	if req.LoginIP != "" {
+		filter["loginIP"] = req.LoginIP
+	}
+	if req.JoinTimeMin > 0 && req.JoinTimeMax > 0 && req.JoinTimeMin <= req.JoinTimeMax {
+		filter["joinTime"] = bson.M{
+			"$gte": req.JoinTimeMin,
+			"$lte": req.JoinTimeMax,
+		}
+	}
+
+	// 设置分页选项
+	skip := (page - 1) * pageSize
+	limit := pageSize
+	findOptions := options.Find().SetSkip(int64(skip)).SetLimit(int64(limit))
+
+	// 执行查询
+	cursor, err := mdb.MDB.Collection(constant.CNamePlayer).Find(ctx, filter, findOptions)
+	if err != nil {
+		return nil, 0, err
+	}
+	defer func() {
+		if closeErr := cursor.Close(ctx); closeErr != nil {
+			log.Printf("Error closing cursor: %v", closeErr)
+		}
+	}()
+
+	// 解析结果
+	results := make([]*entity.PlayerListResp, 0)
+	for cursor.Next(ctx) {
+		var result entity.PlayerListResp
+		if err := cursor.Decode(&result); err != nil {
+			return nil, 0, err
+		}
+		results = append(results, &result)
+	}
+	if err := cursor.Err(); err != nil {
+		return nil, 0, err
+	}
+
+	count := 0
+	playerServerLoadStats, err := NewAdmin().GetServerStatus(ctx)
+	if err != nil {
+		return nil, 0, err
+	}
+
+	for _, v := range playerServerLoadStats {
+		count += int(v.TotalUser)
+	}
+
+	return results, int64(count), nil
+}
+
+// 获取玩家详情
+func (a *PlayerManage) PlayerInfo(ctx context.Context, req entity.PlayerInfoReq) (*entity.PlayerInfoResp, error) {
+	var player models.Player
+	err := mdb.MDB.Collection(constant.CNamePlayer).FindOne(context.Background(), bson.M{"userName": req.UserName}).Decode(&player)
+	if err != nil {
+		return nil, err
+	}
+
+	return &entity.PlayerInfoResp{
+		UserName:       player.UserName,
+		OpenId:         player.OpenId,
+		UserNameMaybe:  player.UserNameMaybe,
+		NickName:       player.NickName,
+		Pid:            player.Pid,
+		XID:            player.XID,
+		TonWall:        player.TonWall,
+		Email:          player.Email,
+		Level:          player.Level,
+		Status:         player.Status,
+		LoginTime:      player.LoginTime,
+		LoginIP:        player.LoginIP,
+		JoinIP:         player.JoinIP,
+		JoinTime:       player.JoinTime,
+		Avatar:         player.Avatar,
+		IsRobot:        player.IsRobot,
+		IsLeader:       player.IsLeader,
+		IsVip:          player.IsVip,
+		Successions:    player.Successions,
+		MaxSuccessions: player.MaxSuccessions,
+		PrevTime:       player.PrevTime,
+		UpdateTime:     player.UpdateTime,
+		IsDrawShare:    player.Share.IsDrawShare,
+		DrawShareTime:  player.Share.DrawShareTime,
+		FirstReward:    player.FirstReward,
+		Item:           player.Item,
+		SinIn:          player.SinIn,
+		DailyTask:      player.DailyTask,
+		AchieveTask:    player.AchieveTask,
+		RankReward:     player.RankReward,
+		Invite:         player.Invite,
+		InviteReward:   player.InviteReward,
+		Roll:           player.Roll,
+	}, nil
+}
+
+// 获取玩家中奖记录(默认查询最近三天)
+func (a *PlayerManage) RewardList(ctx context.Context, req entity.RewardListReq) ([]*models.ToPlayerRewardBase, int64, error) {
+	page := req.Page
+	// 验证参数
+	if page <= 0 {
+		page = 1
+	}
+	pageSize := req.Size
+	if pageSize <= 0 {
+		pageSize = 10
+	}
+
+	// 构建查询条件
+	filter := bson.M{}
+	if req.UserName != "" {
+		filter["userName"] = bson.M{"$regex": escapeRegex(req.UserName), "$options": "i"}
+	}
+	filter["source"] = models.SourceDraw
+
+	startTime := mhayaTime.Now().Add(-3 * 24 * time.Hour).Unix()
+	endTime := mhayaTime.Now().Unix()
+	if req.StartTime > 0 && req.StartTime >= startTime {
+		if req.StartTime <= req.EndTime || req.EndTime == 0 {
+			startTime = req.StartTime
+		}
+	}
+
+	if req.EndTime > 0 && req.EndTime <= endTime {
+		if req.StartTime <= req.EndTime {
+			endTime = req.EndTime
+		}
+	}
+
+	filter["createTime"] = bson.M{
+		"$gte": startTime,
+		"$lte": endTime,
+	}
+
+	// 设置分页选项
+	skip := (page - 1) * pageSize
+	limit := pageSize
+	findOptions := options.Find().SetSkip(int64(skip)).SetLimit(int64(limit))
+
+	collection := mdb.MDB.Collection(constant.CNamePlayerReward)
+	// 获取总数total
+	count, err := collection.CountDocuments(ctx, filter)
+	if err != nil {
+		return nil, 0, err
+	}
+
+	// 执行查询
+	cursor, err := collection.Find(ctx, filter, findOptions)
+	if err != nil {
+		return nil, 0, err
+	}
+	defer func() {
+		if closeErr := cursor.Close(ctx); closeErr != nil {
+			log.Printf("Error closing cursor: %v", closeErr)
+		}
+	}()
+
+	// 解析结果
+	results := make([]*models.ToPlayerRewardBase, 0)
+	for cursor.Next(ctx) {
+		var result models.PlayerRewardBase
+		if err := cursor.Decode(&result); err != nil {
+			return nil, 0, err
+		}
+		results = append(results, result.To())
+	}
+	if err := cursor.Err(); err != nil {
+		return nil, 0, err
+	}
+
+	return results, count, nil
+}