- 新增徽章系统:badge 服务与 handler、管理端配置页、BadgeChip/LevelBadge 展示组件 - 新增等级模型:model/level 及前端 levels 元数据 - 管理端经济模块拆分为 points/badges/levels 独立页面,EconomySettings 迁入设置 - 积分、签到、评论等服务适配等级与徽章逻辑
152 lines
4.2 KiB
Go
152 lines
4.2 KiB
Go
package handler
|
||
|
||
import (
|
||
"errors"
|
||
"net/http"
|
||
"strconv"
|
||
|
||
"github.com/gin-gonic/gin"
|
||
|
||
"github.com/freefire/jiang13-bbs/middleware"
|
||
"github.com/freefire/jiang13-bbs/service"
|
||
)
|
||
|
||
type badgeRequest struct {
|
||
Name string `json:"name"`
|
||
Icon string `json:"icon"`
|
||
Color string `json:"color"`
|
||
}
|
||
|
||
type badgeGrantRequest struct {
|
||
UserID uint `json:"user_id" binding:"required"`
|
||
}
|
||
|
||
// badgeError 按业务错误映射响应
|
||
func badgeError(c *gin.Context, err error) {
|
||
switch {
|
||
case errors.Is(err, service.ErrBadgeNotFound):
|
||
c.JSON(http.StatusNotFound, gin.H{"error": err.Error()})
|
||
case errors.Is(err, service.ErrBadgeNameExists):
|
||
c.JSON(http.StatusConflict, gin.H{"error": err.Error()})
|
||
case errors.Is(err, service.ErrBadgeInvalid):
|
||
c.JSON(http.StatusBadRequest, gin.H{"error": "徽章名称(1-16 字)或颜色无效"})
|
||
case errors.Is(err, service.ErrBadgeUserGone):
|
||
c.JSON(http.StatusNotFound, gin.H{"error": err.Error()})
|
||
default:
|
||
c.JSON(http.StatusInternalServerError, gin.H{"error": "徽章操作失败"})
|
||
}
|
||
}
|
||
|
||
// AdminListBadges 全部徽章(含持有数)
|
||
func (h *Handlers) AdminListBadges(c *gin.Context) {
|
||
badges, err := h.Badge.List()
|
||
if err != nil {
|
||
c.JSON(http.StatusInternalServerError, gin.H{"error": "获取徽章列表失败"})
|
||
return
|
||
}
|
||
c.JSON(http.StatusOK, gin.H{"badges": badges})
|
||
}
|
||
|
||
// AdminCreateBadge 新建徽章
|
||
func (h *Handlers) AdminCreateBadge(c *gin.Context) {
|
||
var req badgeRequest
|
||
if err := c.ShouldBindJSON(&req); err != nil {
|
||
c.JSON(http.StatusBadRequest, gin.H{"error": "请求参数无效"})
|
||
return
|
||
}
|
||
badge, err := h.Badge.Create(req.Name, req.Icon, req.Color)
|
||
if err != nil {
|
||
badgeError(c, err)
|
||
return
|
||
}
|
||
c.JSON(http.StatusOK, gin.H{"badge": badge})
|
||
}
|
||
|
||
// AdminUpdateBadge 修改徽章
|
||
func (h *Handlers) AdminUpdateBadge(c *gin.Context) {
|
||
id, err := strconv.ParseUint(c.Param("id"), 10, 64)
|
||
if err != nil {
|
||
c.JSON(http.StatusBadRequest, gin.H{"error": "请求参数无效"})
|
||
return
|
||
}
|
||
var req badgeRequest
|
||
if err := c.ShouldBindJSON(&req); err != nil {
|
||
c.JSON(http.StatusBadRequest, gin.H{"error": "请求参数无效"})
|
||
return
|
||
}
|
||
badge, err := h.Badge.Update(uint(id), req.Name, req.Icon, req.Color)
|
||
if err != nil {
|
||
badgeError(c, err)
|
||
return
|
||
}
|
||
c.JSON(http.StatusOK, gin.H{"badge": badge})
|
||
}
|
||
|
||
// AdminDeleteBadge 删除徽章(级联删除授予记录)
|
||
func (h *Handlers) AdminDeleteBadge(c *gin.Context) {
|
||
id, err := strconv.ParseUint(c.Param("id"), 10, 64)
|
||
if err != nil {
|
||
c.JSON(http.StatusBadRequest, gin.H{"error": "请求参数无效"})
|
||
return
|
||
}
|
||
if err := h.Badge.Delete(uint(id)); err != nil {
|
||
badgeError(c, err)
|
||
return
|
||
}
|
||
c.JSON(http.StatusOK, gin.H{"ok": true})
|
||
}
|
||
|
||
// AdminGrantBadge 授予徽章(幂等)
|
||
func (h *Handlers) AdminGrantBadge(c *gin.Context) {
|
||
claims := middleware.CurrentUser(c)
|
||
id, err := strconv.ParseUint(c.Param("id"), 10, 64)
|
||
if err != nil {
|
||
c.JSON(http.StatusBadRequest, gin.H{"error": "请求参数无效"})
|
||
return
|
||
}
|
||
var req badgeGrantRequest
|
||
if err := c.ShouldBindJSON(&req); err != nil {
|
||
c.JSON(http.StatusBadRequest, gin.H{"error": "请求参数无效"})
|
||
return
|
||
}
|
||
if err := h.Badge.Grant(uint(id), req.UserID, claims.ID); err != nil {
|
||
badgeError(c, err)
|
||
return
|
||
}
|
||
c.JSON(http.StatusOK, gin.H{"ok": true})
|
||
}
|
||
|
||
// AdminRevokeBadge 撤销授予
|
||
func (h *Handlers) AdminRevokeBadge(c *gin.Context) {
|
||
id, err := strconv.ParseUint(c.Param("id"), 10, 64)
|
||
if err != nil {
|
||
c.JSON(http.StatusBadRequest, gin.H{"error": "请求参数无效"})
|
||
return
|
||
}
|
||
userID, err := strconv.ParseUint(c.Param("userId"), 10, 64)
|
||
if err != nil {
|
||
c.JSON(http.StatusBadRequest, gin.H{"error": "请求参数无效"})
|
||
return
|
||
}
|
||
if err := h.Badge.Revoke(uint(id), uint(userID)); err != nil {
|
||
badgeError(c, err)
|
||
return
|
||
}
|
||
c.JSON(http.StatusOK, gin.H{"ok": true})
|
||
}
|
||
|
||
// AdminBadgeHolders 某徽章全部持有者(后台授予面板用)
|
||
func (h *Handlers) AdminBadgeHolders(c *gin.Context) {
|
||
id, err := strconv.ParseUint(c.Param("id"), 10, 64)
|
||
if err != nil {
|
||
c.JSON(http.StatusBadRequest, gin.H{"error": "请求参数无效"})
|
||
return
|
||
}
|
||
holders, err := h.Badge.Holders(uint(id))
|
||
if err != nil {
|
||
c.JSON(http.StatusInternalServerError, gin.H{"error": "获取持有者失败"})
|
||
return
|
||
}
|
||
c.JSON(http.StatusOK, gin.H{"holders": holders})
|
||
}
|