Files
nl-game-api/internal/handler/rank.go
2026-08-14 13:17:03 +08:00

65 lines
2.3 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package handler
import (
"github.com/gin-gonic/gin"
"nl-game-api-gin/internal/database"
"nl-game-api-gin/internal/middleware"
"nl-game-api-gin/internal/model"
"nl-game-api-gin/pkg/resp"
)
// rankUser 排行榜条目
type rankUser struct {
UserID int `json:"user_id"` // 用户ID
Nickname string `json:"nickname"` // 昵称
Avatar string `json:"avatar"` // 头像
TotalPoints int `json:"total_points"` // 累计积分
}
// PointsRank 积分排行榜前50 + 我的名次
func PointsRank(c *gin.Context) {
list := make([]rankUser, 0)
database.DB.Table("users").
Select("id AS user_id, nickname, avatar, total_points").
Where("status = 1 AND deleted_at = 0").
Order("total_points DESC, id ASC").Limit(50).Scan(&list)
// 我的名次 = 比我累计积分高的人数 + 1
uid := middleware.UID(c)
var me model.User
database.DB.First(&me, uid)
var higher int64
database.DB.Model(&model.User{}).
Where("status = 1 AND (total_points > ? OR (total_points = ? AND id < ?))", me.TotalPoints, me.TotalPoints, uid).
Count(&higher)
resp.OK(c, gin.H{"list": list, "my_rank": higher + 1, "my_points": me.TotalPoints})
}
// gameRankItem 单游戏排行条目
type gameRankItem struct {
UserID int `json:"user_id"` // 用户ID
Nickname string `json:"nickname"` // 昵称
Avatar string `json:"avatar"` // 头像
Best int `json:"best"` // 该游戏最高分
}
// GameRank 指定游戏的最高分排行每人取最高一条前50
func GameRank(c *gin.Context) {
var game model.Game
if err := database.DB.Where("code = ?", c.Param("code")).First(&game).Error; err != nil {
resp.Fail(c, "游戏不存在")
return
}
list := make([]gameRankItem, 0)
database.DB.Raw(`SELECT t.user_id, u.nickname, u.avatar, t.best
FROM (SELECT user_id, MAX(score) AS best FROM game_records WHERE game_id = ? GROUP BY user_id) t
JOIN users u ON u.id = t.user_id AND u.status = 1 AND u.deleted_at = 0
ORDER BY t.best DESC, t.user_id ASC LIMIT 50`, game.ID).Scan(&list)
// 我的最高分
var myBest int
database.DB.Model(&model.GameRecord{}).
Where("user_id = ? AND game_id = ?", middleware.UID(c), game.ID).
Select("COALESCE(MAX(score),0)").Scan(&myBest)
resp.OK(c, gin.H{"game": game, "list": list, "my_best": myBest})
}