Files
jiang13-bbs/backend/handler/leaderboard.go
freefire cab8230803 feat: 新增排行榜模块
- 新增 leaderboard 服务与 handler、前端排行榜页面
- 路由与首页入口适配
2026-09-25 18:28:12 +08:00

72 lines
2.1 KiB
Go
Raw 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 (
"net/http"
"strconv"
"github.com/freefire/jiang13-bbs/service"
"github.com/gin-gonic/gin"
)
// 榜单参数白名单
var (
lbPeriods = map[string]bool{service.PeriodWeek: true, service.PeriodMonth: true, service.PeriodAll: true}
lbMetrics = map[string]bool{service.MetricAll: true, service.MetricPost: true,
service.MetricComment: true, service.MetricLike: true, service.MetricAnswer: true}
)
// lbParams 解析并校验 period/metric,非法值回退默认并标记 400
func lbParams(c *gin.Context) (period, metric string, bad bool) {
period = c.DefaultQuery("period", service.PeriodAll)
metric = c.DefaultQuery("metric", service.MetricAll)
if !lbPeriods[period] || !lbMetrics[metric] {
return "", "", true
}
return period, metric, false
}
// Leaderboard 用户贡献榜:period=week|month|all × metric=all|post|comment|like|answer(公开接口)
func (h *Handlers) Leaderboard(c *gin.Context) {
period, metric, bad := lbParams(c)
if bad {
c.JSON(http.StatusBadRequest, gin.H{"error": "无效的榜单参数"})
return
}
limit := 50
if v := c.Query("limit"); v != "" {
if n, err := strconv.Atoi(v); err == nil && n > 0 {
limit = n
}
}
if limit > 100 {
limit = 100
}
res, err := h.LeaderboardSvc.Board(period, metric, limit)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "获取排行榜失败"})
return
}
c.JSON(http.StatusOK, res)
}
// LeaderboardMe 当前用户在指定榜单的排名(可选登录;游客返回 me:null)
func (h *Handlers) LeaderboardMe(c *gin.Context) {
period, metric, bad := lbParams(c)
if bad {
c.JSON(http.StatusBadRequest, gin.H{"error": "无效的榜单参数"})
return
}
if v, ok := c.Get("user"); ok {
if claims, ok := v.(*service.UserClaims); ok && claims.ID > 0 {
res, err := h.LeaderboardSvc.MyRank(period, metric, claims.ID)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "获取排名失败"})
return
}
c.JSON(http.StatusOK, gin.H{"me": res})
return
}
}
c.JSON(http.StatusOK, gin.H{"me": nil})
}