feat(admin): 完善站点设置、内容回收站与后台菜单分组
新增站点设置与内容管理(含已删除恢复/清除),用户页改用独有运营指标,并按概览/内容/成员与经济/站点重组侧栏。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -3,41 +3,32 @@ package handler
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/freefire/jiang13-bbs/realtime"
|
||||
"github.com/freefire/jiang13-bbs/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// PublicSettings 公开站点设置(无需登录):前端 SSR 据此注入主题 CSS 变量等
|
||||
// GET /api/settings
|
||||
func (h *Handlers) PublicSettings(c *gin.Context) {
|
||||
accent, err := h.Setting.AccentColor()
|
||||
s, err := h.Setting.Public()
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "获取站点设置失败"})
|
||||
return
|
||||
}
|
||||
trust, err := h.Setting.TrustReviewedPublish()
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "获取站点设置失败"})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"accent": accent,
|
||||
"trust_reviewed_publish": trust,
|
||||
})
|
||||
c.JSON(http.StatusOK, s)
|
||||
}
|
||||
|
||||
// updateSettingsRequest 字段均为可选指针:只更新请求里出现的项,避免外观页覆盖审核策略
|
||||
// updateSettingsRequest 字段均为可选指针:只更新请求里出现的项,避免外观页覆盖其它设置
|
||||
type updateSettingsRequest struct {
|
||||
// Accent 主题色 #RRGGBB;空串恢复默认
|
||||
Accent *string `json:"accent"`
|
||||
// TrustReviewedPublish 已过审用户后续内容免审
|
||||
TrustReviewedPublish *bool `json:"trust_reviewed_publish"`
|
||||
Accent *string `json:"accent"`
|
||||
TrustReviewedPublish *bool `json:"trust_reviewed_publish"`
|
||||
SiteName *string `json:"site_name"`
|
||||
SiteDescription *string `json:"site_description"`
|
||||
AllowRegister *bool `json:"allow_register"`
|
||||
PostCooldownHours *int `json:"post_cooldown_hours"`
|
||||
}
|
||||
|
||||
// UpdateSettings 更新站点设置(管理员)
|
||||
// PUT /api/admin/settings
|
||||
func (h *Handlers) UpdateSettings(c *gin.Context) {
|
||||
var req updateSettingsRequest
|
||||
@@ -45,12 +36,12 @@ func (h *Handlers) UpdateSettings(c *gin.Context) {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "请求参数无效"})
|
||||
return
|
||||
}
|
||||
if req.Accent == nil && req.TrustReviewedPublish == nil {
|
||||
if req.Accent == nil && req.TrustReviewedPublish == nil && req.SiteName == nil &&
|
||||
req.SiteDescription == nil && req.AllowRegister == nil && req.PostCooldownHours == nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "未提供任何可更新的设置项"})
|
||||
return
|
||||
}
|
||||
|
||||
savedAccent := ""
|
||||
if req.Accent != nil {
|
||||
if err := h.Setting.SetAccent(*req.Accent); err != nil {
|
||||
if errors.Is(err, service.ErrInvalidAccent) {
|
||||
@@ -60,43 +51,74 @@ func (h *Handlers) UpdateSettings(c *gin.Context) {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "保存站点设置失败"})
|
||||
return
|
||||
}
|
||||
savedAccent = strings.ToLower(strings.TrimSpace(*req.Accent))
|
||||
} else {
|
||||
var err error
|
||||
savedAccent, err = h.Setting.AccentColor()
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "获取站点设置失败"})
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
trustOn := true
|
||||
if req.TrustReviewedPublish != nil {
|
||||
if err := h.Setting.SetTrustReviewedPublish(*req.TrustReviewedPublish); err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "保存站点设置失败"})
|
||||
return
|
||||
}
|
||||
trustOn = *req.TrustReviewedPublish
|
||||
} else {
|
||||
var err error
|
||||
trustOn, err = h.Setting.TrustReviewedPublish()
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "获取站点设置失败"})
|
||||
}
|
||||
if req.SiteName != nil {
|
||||
if err := h.Setting.SetSiteName(*req.SiteName); err != nil {
|
||||
if errors.Is(err, service.ErrInvalidSiteSetting) {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "站点名称过长或无效"})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "保存站点设置失败"})
|
||||
return
|
||||
}
|
||||
}
|
||||
if req.SiteDescription != nil {
|
||||
if err := h.Setting.SetSiteDescription(*req.SiteDescription); err != nil {
|
||||
if errors.Is(err, service.ErrInvalidSiteSetting) {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "站点简介过长"})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "保存站点设置失败"})
|
||||
return
|
||||
}
|
||||
}
|
||||
if req.AllowRegister != nil {
|
||||
if err := h.Setting.SetAllowRegister(*req.AllowRegister); err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "保存站点设置失败"})
|
||||
return
|
||||
}
|
||||
}
|
||||
if req.PostCooldownHours != nil {
|
||||
if err := h.Setting.SetPostCooldownHours(*req.PostCooldownHours); err != nil {
|
||||
if errors.Is(err, service.ErrInvalidSiteSetting) {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "冷静期须为 0–168 小时"})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "保存站点设置失败"})
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 归一化后广播:主题色客户端热换肤;免审开关由下次发帖/发评读库生效
|
||||
saved, err := h.Setting.Public()
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "获取站点设置失败"})
|
||||
return
|
||||
}
|
||||
|
||||
h.Hub.BroadcastAll(realtime.Envelope{
|
||||
Type: realtime.EventSettingsChanged,
|
||||
Data: gin.H{
|
||||
"accent": savedAccent,
|
||||
"trust_reviewed_publish": trustOn,
|
||||
"accent": saved.Accent,
|
||||
"trust_reviewed_publish": saved.TrustReviewedPublish,
|
||||
"site_name": saved.SiteName,
|
||||
"site_description": saved.SiteDescription,
|
||||
"allow_register": saved.AllowRegister,
|
||||
"post_cooldown_hours": saved.PostCooldownHours,
|
||||
},
|
||||
})
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"ok": true,
|
||||
"accent": savedAccent,
|
||||
"trust_reviewed_publish": trustOn,
|
||||
"accent": saved.Accent,
|
||||
"trust_reviewed_publish": saved.TrustReviewedPublish,
|
||||
"site_name": saved.SiteName,
|
||||
"site_description": saved.SiteDescription,
|
||||
"allow_register": saved.AllowRegister,
|
||||
"post_cooldown_hours": saved.PostCooldownHours,
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user