package daytask import ( "app/commons/model/entity" "fmt" "github.com/gin-gonic/gin" "time" ) // RankList 排行榜列表 func (s *Server) RankList(c *gin.Context) { ctx := s.FromContext(c) db := s.DB() userId := ctx.UserId() rankType := ctx.QueryString("type", "task") // task任务排行/invite邀请排行 timeType := ctx.QueryString("timeType", "daily") // daily/weekly/monthly limit := ctx.QueryInt64("limit", 50) if limit > 100 { limit = 100 } type RankInfo struct { Rank int `json:"rank"` UserId int64 `json:"userId" gorm:"column:user_id"` Uid string `json:"uid"` Nickname string `json:"nickname"` Avatar string `json:"avatar"` Count int `json:"count" gorm:"column:cnt"` } ranks := make([]RankInfo, 0) // 使用东八区时区 loc, _ := time.LoadLocation("Asia/Shanghai") now := time.Now().In(loc) // 生成时间条件的辅助函数 - 直接使用时间戳范围比较,避免时区问题 getTimeCondition := func(timeField string) string { var startTime, endTime int64 switch timeType { case "daily": // 今天 00:00:00 到 23:59:59 startOfDay := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, loc) startTime = startOfDay.Unix() endTime = startOfDay.Add(24*time.Hour - time.Second).Unix() case "weekly": // 本周一 00:00:00 到现在 weekday := int(now.Weekday()) if weekday == 0 { weekday = 7 } startOfWeek := time.Date(now.Year(), now.Month(), now.Day()-(weekday-1), 0, 0, 0, 0, loc) startTime = startOfWeek.Unix() endTime = now.Unix() case "monthly": // 本月1号 00:00:00 到现在 startOfMonth := time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, loc) startTime = startOfMonth.Unix() endTime = now.Unix() default: startOfDay := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, loc) startTime = startOfDay.Unix() endTime = startOfDay.Add(24*time.Hour - time.Second).Unix() } return fmt.Sprintf("%s >= %d AND %s <= %d", timeField, startTime, timeField, endTime) } // 根据类型查询不同的排行榜 switch rankType { case "task": // 任务完成数量排行 - 使用审核通过时间(audit_time) taskTimeCondition := getTimeCondition("t.audit_time") db.Raw(` SELECT u.id as user_id, u.uid, u.nickname, u.avatar, COUNT(t.id) as cnt FROM dt_user u INNER JOIN dt_user_task t ON u.id = t.user_id AND t.status = ? AND `+taskTimeCondition+` WHERE u.status = 1 GROUP BY u.id, u.uid, u.nickname, u.avatar HAVING cnt > 0 ORDER BY cnt DESC LIMIT ? `, entity.UserTaskStatusCompleted, limit).Scan(&ranks) case "invite": // 邀请人数排行 - 使用下级用户注册时间(created_at) inviteTimeCondition := getTimeCondition("t.created_at") db.Raw(` SELECT u.id as user_id, u.uid, u.nickname, u.avatar, COUNT(t.id) as cnt FROM dt_user u INNER JOIN dt_user t ON u.id = t.parent_id AND `+inviteTimeCondition+` WHERE u.status = 1 GROUP BY u.id, u.uid, u.nickname, u.avatar HAVING cnt > 0 ORDER BY cnt DESC LIMIT ? `, limit).Scan(&ranks) default: ctx.Fail("invalid_type") return } // 手动设置排名序号 for i := range ranks { ranks[i].Rank = i + 1 } // 查询当前用户排名 var myRank *RankInfo for i := range ranks { if ranks[i].UserId == userId { myRank = &ranks[i] break } } // 如果当前用户不在榜单中,单独查询 if myRank == nil { var user entity.DtUser if err := db.Where("id = ?", userId).First(&user).Error; err == nil { myRank = &RankInfo{ Rank: 0, UserId: user.Id, Uid: user.Uid, Nickname: user.Nickname, Avatar: user.Avatar, Count: 0, } } } ctx.OK(gin.H{ "list": ranks, "myRank": myRank, }) } // RankReward 排行榜奖励配置 func (s *Server) RankReward(c *gin.Context) { ctx := s.FromContext(c) db := s.DB() var configs []entity.DtLeaderboardReward db.Where("status = ?", 1). Order("rank_start ASC"). Find(&configs) type RewardInfo struct { RankStart int `json:"rankStart"` RankEnd int `json:"rankEnd"` Reward float64 `json:"reward"` } rewards := make([]*RewardInfo, 0) for _, config := range configs { rewards = append(rewards, &RewardInfo{ RankStart: config.RankStart, RankEnd: config.RankEnd, Reward: config.Reward, }) } ctx.OK(gin.H{ "list": rewards, }) }