package agent import ( "context" "time" "ycc-server/app/main/model" "ycc-server/common/ctxdata" "ycc-server/common/globalkey" "ycc-server/common/xerr" "github.com/Masterminds/squirrel" "github.com/pkg/errors" "ycc-server/app/main/api/internal/svc" "ycc-server/app/main/api/internal/types" "github.com/zeromicro/go-zero/core/logx" ) type GetTeamStatisticsLogic struct { logx.Logger ctx context.Context svcCtx *svc.ServiceContext } func NewGetTeamStatisticsLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetTeamStatisticsLogic { return &GetTeamStatisticsLogic{ Logger: logx.WithContext(ctx), ctx: ctx, svcCtx: svcCtx, } } func (l *GetTeamStatisticsLogic) GetTeamStatistics() (resp *types.TeamStatisticsResp, err error) { userID, err := ctxdata.GetUidFromCtx(l.ctx) if err != nil { return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "获取用户信息失败, %v", err) } // 1. 获取代理信息 agent, err := l.svcCtx.AgentModel.FindOneByUserId(l.ctx, userID) if err != nil { if errors.Is(err, model.ErrNotFound) { return nil, errors.Wrapf(xerr.NewErrMsg("您不是代理"), "") } return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询代理信息失败, %v", err) } // 2. 递归查询所有下级(直接+间接) allSubordinateIds := make(map[int64]bool) directSubordinateIds := make(map[int64]bool) // 递归函数:收集所有下级ID var collectSubordinates func(int64) error collectSubordinates = func(parentId int64) error { // 查询直接下级 builder := l.svcCtx.AgentRelationModel.SelectBuilder(). Where("parent_id = ? AND relation_type = ? AND del_state = ?", parentId, 1, globalkey.DelStateNo) relations, err := l.svcCtx.AgentRelationModel.FindAll(l.ctx, builder, "") if err != nil { return err } for _, relation := range relations { // 如果是第一层,标记为直接下级 if parentId == agent.Id { directSubordinateIds[relation.ChildId] = true } // 添加到所有下级集合 allSubordinateIds[relation.ChildId] = true // 递归查询下级的下级 if err := collectSubordinates(relation.ChildId); err != nil { return err } } return nil } // 开始递归收集所有下级 if err := collectSubordinates(agent.Id); err != nil { return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询下级关系失败, %v", err) } // 3. 获取当前时间用于统计今日和本月新增 now := time.Now() todayStart := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location()) monthStart := time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, now.Location()) // 4. 如果没有下级,返回空数据 if len(allSubordinateIds) == 0 { return &types.TeamStatisticsResp{ TotalCount: 0, DirectCount: 0, IndirectCount: 0, GoldCount: 0, NormalCount: 0, TodayNewMembers: 0, MonthNewMembers: 0, }, nil } // 5. 将下级ID转换为切片用于查询 subordinateIds := make([]int64, 0, len(allSubordinateIds)) for id := range allSubordinateIds { subordinateIds = append(subordinateIds, id) } // 6. 查询所有下级代理信息 builder := l.svcCtx.AgentModel.SelectBuilder(). Where(squirrel.Eq{"id": subordinateIds}). Where("del_state = ?", globalkey.DelStateNo) teamMembers, err := l.svcCtx.AgentModel.FindAll(l.ctx, builder, "") if err != nil { return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询团队成员失败, %v", err) } // 7. 统计 totalCount := int64(len(teamMembers)) // 下级总数(不包括自己) directCount := int64(len(directSubordinateIds)) indirectCount := totalCount - directCount level1Count := int64(0) // 普通 level2Count := int64(0) // 黄金 // 不再统计钻石,因为下级不可能是钻石 todayNewCount := int64(0) monthNewCount := int64(0) for _, member := range teamMembers { // 统计等级(只统计普通和黄金) switch member.Level { case 1: level1Count++ case 2: level2Count++ } // 统计今日和本月新增 if member.CreateTime.After(todayStart) { todayNewCount++ } if member.CreateTime.After(monthStart) { monthNewCount++ } } return &types.TeamStatisticsResp{ TotalCount: totalCount, // 下级总数(不包括自己) DirectCount: directCount, IndirectCount: indirectCount, GoldCount: level2Count, NormalCount: level1Count, TodayNewMembers: todayNewCount, MonthNewMembers: monthNewCount, }, nil }