123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294 |
- package service
- import (
- "context"
- "fmt"
- jsoniter "github.com/json-iterator/go"
- "github.com/mhaya/extend/tree"
- clog "github.com/mhaya/logger"
- "go.mongodb.org/mongo-driver/mongo/options"
- "slices"
- "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/adminapi/entity"
- "go.mongodb.org/mongo-driver/bson"
- )
- func GetUserCount() *entity.UserCountResp {
- collection := mdb.MDB.Collection(constant.CNameAccount)
- // 统计当日注册 和总注册人数
- // 获取今天开始的时间戳
- now := time.Now()
- startOfDay := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location())
- endOfDay := startOfDay.Add(24 * time.Hour).Add(-1 * time.Second)
- // 构建查询条件 - 如果查询值为空那就不添加查询条件
- filter := bson.M{}
- // 统计当日注册 和总注册人数
- filter["JoinTime"] = bson.M{
- "$gte": startOfDay.Unix(),
- "$lte": endOfDay.Unix(),
- }
- // 获取注册总数
- totalCount, err := collection.CountDocuments(context.Background(), bson.M{})
- if err != nil {
- return nil
- }
- count, err := mdb.MDB.Collection(constant.CNameAccount).CountDocuments(context.Background(), filter)
- if err != nil {
- return nil
- }
- return &entity.UserCountResp{
- TotalReg: totalCount,
- ToDayReg: count,
- }
- }
- // GetUserList 获取用户列表 并且可以根据用户ID获取下级用户
- func GetUserList(req *entity.UserReq) []*entity.UserListResp {
- collection := mdb.MDB.Collection(constant.CNamePlayer)
- filter := bson.M{}
- if req.Pid != "" {
- filter["pid"] = req.Pid
- }
- if req.UserName != "" {
- //filter["nickName"] = primitive.Regex{Pattern: fmt.Sprintf(".*%s.*", req.UserName), Options: "i"}
- filter["nickName"] = req.UserName
- }
- if req.RangeStart != 0 && req.RangeEnd != 0 {
- filter["createTime"] = bson.M{
- "$gte": req.RangeStart,
- "$lte": req.RangeEnd,
- }
- }
- if req.UserID != "" {
- filter["userName"] = req.UserID
- }
- if req.Tag != "" {
- filter["tag"] = req.Tag
- }
- if req.LoginIp != "" {
- filter["loginIp"] = req.LoginIp
- }
- if req.TagType == 1 {
- filter["pid"] = ""
- }
- // 分页参数
- skip := (req.Page - 1) * req.Size
- // 执行查询
- opts := options.Find()
- // 根据指定字段和排序类型做排序
- sort := bson.D{}
- if req.OrderColumn != "" && req.OrderType != "" {
- sort = bson.D{{req.OrderColumn, req.OrderType}}
- opts.SetSort(sort)
- }
- opts.SetSkip(int64(skip))
- opts.SetLimit(int64(req.Size))
- cursor, err := collection.Find(context.Background(), filter, opts)
- count, _ := collection.CountDocuments(context.Background(), filter)
- if err != nil {
- return nil
- }
- defer cursor.Close(context.Background())
- var result []*entity.UserListResp
- for cursor.Next(context.Background()) {
- var account *models.Player
- if err := cursor.Decode(&account); err != nil {
- return nil
- }
- var totalPlan int
- var curPlan int
- ids := []int{1000, 1001}
- for _, item := range account.FirstClaimReward {
- totalPlan++
- id := item.Reward[0].ItemID
- if slices.Contains(ids, id) {
- continue
- }
- if item.IsClaim == 1 {
- curPlan++
- }
- }
- var tagNum int // 下级及下级以下
- var subNum int // 下级
- var inviteTreeKey string
- if account.TopPid != "" {
- // 非一级
- inviteTreeKey = fmt.Sprintf("%v:%v", constant.InviteTreeKey, account.TopPid)
- } else {
- // 一级
- inviteTreeKey = fmt.Sprintf("%v:%v", constant.InviteTreeKey, account.UserName)
- }
- treeJson, _ := mdb.RDB.Get(context.Background(), inviteTreeKey).Result()
- if treeJson != "" {
- var treeInfo *tree.TreeNode
- jsoniter.Unmarshal([]byte(treeJson), &treeInfo)
- tagNum = treeInfo.CountAllChildren(account.UserName)
- subNum = treeInfo.CountDirectChildren(account.UserName)
- }
- var num int64
- var tag int
- if value, ok := account.Item[0]; ok {
- num = value.Num
- }
- if account.Pid == "" {
- tag = 1
- }
- result = append(result, &entity.UserListResp{
- UserName: account.UserName,
- OpenId: account.OpenId,
- UserNameMaybe: account.UserNameMaybe,
- NickName: account.NickName,
- Pid: account.Pid,
- XID: account.XID,
- TonWall: account.TonWall,
- Email: account.Email,
- Mobile: account.Mobile,
- Avatar: account.Avatar,
- IsCashOut: account.IsCashOut,
- IsRobot: account.IsRobot,
- IsLeader: account.IsLeader,
- IsVip: account.IsVip,
- IsFirstBindingXID: account.IsFirstBindingXID,
- Level: account.Level,
- Exp: account.Exp,
- Gender: account.Gender,
- Birthday: account.Birthday,
- Successions: account.Successions,
- MaxSuccessions: account.MaxSuccessions,
- PrevTime: account.PrevTime,
- LoginTime: account.LoginTime,
- LoginIP: account.LoginIP,
- LoginFailure: account.LoginFailure,
- JoinIP: account.JoinIP,
- Rank: account.Rank,
- JoinTime: account.JoinTime,
- CreateTime: account.CreateTime,
- UpdateTime: account.UpdateTime,
- DailyRefreshTime: account.DailyRefreshTime,
- HourRefreshTime: account.HourRefreshTime,
- WeeklyRefreshTime: account.WeeklyRefreshTime,
- RollDay: account.RollDay,
- Status: account.Status,
- TagNum: tagNum,
- SubNum: subNum,
- Total: count,
- CurPlan: curPlan,
- TotalPlan: totalPlan,
- Tag: tag,
- Score: int64(num),
- })
- }
- // todo 修复数据
- //go repairData()
- return result
- }
- // 修复数据
- func repairData() {
- clog.Debugf("repairData start =>")
- collection := mdb.MDB.Collection(constant.CNamePlayer)
- filter := bson.M{}
- filter["pid"] = ""
- opts := options.Find()
- cursor, _ := collection.Find(context.Background(), filter, opts)
- defer cursor.Close(context.Background())
- var rows int
- for cursor.Next(context.Background()) {
- var account *models.Player
- if err := cursor.Decode(&account); err != nil {
- return
- }
- if account.Pid != "" {
- continue
- }
- rangeKey := fmt.Sprintf("%v:%v:%v", constant.InviteKey, 2, account.UserName)
- child, _ := mdb.RDB.LLen(context.Background(), rangeKey).Uint64()
- if child == 0 {
- continue
- }
- subordinatesTree, err := GetSubordinatesTree(account.UserName)
- if err != nil {
- clog.Error("repairData GetSubordinatesTree execute Fail ", err)
- }
- treeJson, err := jsoniter.MarshalToString(subordinatesTree)
- inviteTreeKey := fmt.Sprintf("%v:%v", constant.InviteTreeKey, account.UserName)
- mdb.RDB.Set(context.Background(), inviteTreeKey, treeJson, 0)
- clog.Debugf("tree: \n\n %v", treeJson)
- rows++
- }
- clog.Debugf("repairData end => repair rows: %v", rows)
- }
- // GetSubordinatesTree 递归查询某个用户的所有下级用户树结构
- func GetSubordinatesTree(userID string) (*tree.TreeNode, error) {
- var root *tree.TreeNode
- ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
- defer cancel()
- collection := mdb.MDB.Collection(constant.CNamePlayer)
- // 查询直接下级用户
- cursor, err := collection.Find(ctx, bson.M{"pid": userID})
- if err != nil {
- return nil, err
- }
- defer cursor.Close(ctx)
- for cursor.Next(ctx) {
- var player models.Player
- if err := cursor.Decode(&player); err != nil {
- return nil, err
- }
- childNode := tree.NewTreeNode(player.UserName)
- if root == nil {
- root = tree.NewTreeNode(userID)
- }
- root.Children = append(root.Children, childNode)
- // 递归查询下级的下级用户
- subTree, err := GetSubordinatesTree(player.UserName)
- if err != nil {
- return nil, err
- }
- if subTree != nil {
- childNode.Children = subTree.Children
- }
- }
- return root, nil
- }
|