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})
|
|||
|
|
}
|