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