65 lines
2.3 KiB
Go
65 lines
2.3 KiB
Go
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})
|
||
}
|