228 lines
6.8 KiB
Go
228 lines
6.8 KiB
Go
package admin
|
||
|
||
import (
|
||
"log"
|
||
"net/http"
|
||
"strconv"
|
||
|
||
"metazone.cc/mce/internal/common"
|
||
"metazone.cc/mce/internal/service"
|
||
"metazone.cc/mce/internal/theme"
|
||
|
||
"github.com/gin-gonic/gin"
|
||
)
|
||
|
||
// SiteSettingController 站点设置控制器(仅 owner 可访问)
|
||
type SiteSettingController struct {
|
||
settingService siteSettingUseCase
|
||
defaults *service.AuditDefaults
|
||
themeReload service.ThemeReloader // 主题重载回调(切换后实时生效)
|
||
}
|
||
|
||
// NewSiteSettingController 构造函数
|
||
func NewSiteSettingController(settingService siteSettingUseCase, defaults *service.AuditDefaults) *SiteSettingController {
|
||
return &SiteSettingController{settingService: settingService, defaults: defaults}
|
||
}
|
||
|
||
// SetThemeReloader 注入主题重载回调(main.go 中设置)
|
||
func (sc *SiteSettingController) SetThemeReloader(reload service.ThemeReloader) {
|
||
sc.themeReload = reload
|
||
}
|
||
|
||
// SiteSettingsPage 旧站点设置页 — 301 重定向到品牌页
|
||
func (sc *SiteSettingController) SiteSettingsPage(c *gin.Context) {
|
||
c.Redirect(http.StatusMovedPermanently, "/admin/settings/brand")
|
||
}
|
||
|
||
// BrandPage 品牌与合规设置页
|
||
func (sc *SiteSettingController) BrandPage(c *gin.Context) {
|
||
c.HTML(http.StatusOK, "admin/site-settings/brand.html", common.BuildAdminPageData(c, gin.H{
|
||
"Title": "站点设置 - 品牌与合规",
|
||
"ExtraCSS": "/admin/static/css/site-settings.css",
|
||
"ExtraJS": "/admin/static/js/site-settings.js",
|
||
"ActiveSetting": "brand",
|
||
}))
|
||
}
|
||
|
||
// SecurityPage 安全与维护设置页
|
||
func (sc *SiteSettingController) SecurityPage(c *gin.Context) {
|
||
c.HTML(http.StatusOK, "admin/site-settings/security.html", common.BuildAdminPageData(c, gin.H{
|
||
"Title": "站点设置 - 安全与维护",
|
||
"ExtraCSS": "/admin/static/css/site-settings.css",
|
||
"ExtraJS": "/admin/static/js/site-settings.js",
|
||
"ActiveSetting": "security",
|
||
}))
|
||
}
|
||
|
||
// RegistrationPage 注册策略设置页
|
||
func (sc *SiteSettingController) RegistrationPage(c *gin.Context) {
|
||
c.HTML(http.StatusOK, "admin/site-settings/registration.html", common.BuildAdminPageData(c, gin.H{
|
||
"Title": "站点设置 - 注册策略",
|
||
"ExtraCSS": "/admin/static/css/site-settings.css",
|
||
"ExtraJS": "/admin/static/js/site-settings.js",
|
||
"ActiveSetting": "registration",
|
||
}))
|
||
}
|
||
|
||
// ContentPage 审核与内容设置页
|
||
func (sc *SiteSettingController) ContentPage(c *gin.Context) {
|
||
c.HTML(http.StatusOK, "admin/site-settings/content.html", common.BuildAdminPageData(c, gin.H{
|
||
"Title": "站点设置 - 审核与内容",
|
||
"ExtraCSS": "/admin/static/css/site-settings.css",
|
||
"ExtraJS": "/admin/static/js/site-settings.js",
|
||
"ActiveSetting": "content",
|
||
}))
|
||
}
|
||
|
||
// ThemePage 外观主题设置页
|
||
func (sc *SiteSettingController) ThemePage(c *gin.Context) {
|
||
c.HTML(http.StatusOK, "admin/site-settings/theme.html", common.BuildAdminPageData(c, gin.H{
|
||
"Title": "站点设置 - 外观主题",
|
||
"ExtraCSS": "/admin/static/css/site-settings.css",
|
||
"ExtraJS": "/admin/static/js/site-settings-theme.js",
|
||
"ActiveSetting": "theme",
|
||
}))
|
||
}
|
||
|
||
// GetSettings 获取所有站点设置
|
||
func (sc *SiteSettingController) GetSettings(c *gin.Context) {
|
||
all := sc.settingService.GetSettings()
|
||
audit := sc.settingService.GetAuditSettings(sc.defaults)
|
||
log.Printf("[GetSettings] all=%d keys audit=%+v", len(all), audit)
|
||
if v, ok := all["registration.enabled"]; ok {
|
||
log.Printf("[GetSettings] registration.enabled=%q", v)
|
||
}
|
||
common.Ok(c, gin.H{
|
||
"all": all,
|
||
"audit": audit,
|
||
})
|
||
}
|
||
|
||
// UpdateSetting 更新单项设置
|
||
func (sc *SiteSettingController) UpdateSetting(c *gin.Context) {
|
||
var req struct {
|
||
Key string `json:"key" binding:"required"`
|
||
Value string `json:"value"`
|
||
}
|
||
if err := c.ShouldBindJSON(&req); err != nil {
|
||
common.Error(c, http.StatusBadRequest, "参数错误")
|
||
return
|
||
}
|
||
|
||
if err := sc.settingService.UpdateSetting(req.Key, req.Value); err != nil {
|
||
common.Error(c, http.StatusInternalServerError, "保存失败")
|
||
return
|
||
}
|
||
|
||
common.OkMessage(c, "设置已更新")
|
||
}
|
||
|
||
// UpdateBoolSetting 更新布尔设置
|
||
func (sc *SiteSettingController) UpdateBoolSetting(c *gin.Context) {
|
||
var req struct {
|
||
Key string `json:"key" binding:"required"`
|
||
Value string `json:"value" binding:"required"`
|
||
}
|
||
if err := c.ShouldBindJSON(&req); err != nil {
|
||
common.Error(c, http.StatusBadRequest, "参数错误")
|
||
return
|
||
}
|
||
|
||
v, err := service.ParseBool(req.Value)
|
||
if err != nil {
|
||
common.Error(c, http.StatusBadRequest, "值必须为 true 或 false")
|
||
return
|
||
}
|
||
|
||
if err := sc.settingService.UpdateBoolSetting(req.Key, v); err != nil {
|
||
common.Error(c, http.StatusInternalServerError, "保存失败")
|
||
return
|
||
}
|
||
|
||
common.OkMessage(c, "设置已更新")
|
||
}
|
||
|
||
// GetBoolSetting 获取单个布尔设置的当前值
|
||
func (sc *SiteSettingController) GetBoolSetting(c *gin.Context) {
|
||
key := c.Query("key")
|
||
if key == "" {
|
||
common.Error(c, http.StatusBadRequest, "缺少 key 参数")
|
||
return
|
||
}
|
||
|
||
defaultVal := c.DefaultQuery("default", "false")
|
||
d, _ := strconv.ParseBool(defaultVal)
|
||
|
||
val := sc.settingService.GetAuditSettings(sc.defaults)
|
||
// 简单键值查找
|
||
switch key {
|
||
case "audit.enabled":
|
||
common.Ok(c, gin.H{"value": val.Enabled})
|
||
case "audit.username_audit":
|
||
common.Ok(c, gin.H{"value": val.UsernameAudit})
|
||
case "audit.avatar_audit":
|
||
common.Ok(c, gin.H{"value": val.AvatarAudit})
|
||
case "audit.bio_audit":
|
||
common.Ok(c, gin.H{"value": val.BioAudit})
|
||
default:
|
||
common.Ok(c, gin.H{"value": d})
|
||
}
|
||
}
|
||
|
||
// GetThemes 获取所有可用主题列表
|
||
func (sc *SiteSettingController) GetThemes(c *gin.Context) {
|
||
themes, err := theme.DiscoverThemes("templates")
|
||
if err != nil {
|
||
common.Error(c, http.StatusInternalServerError, "读取主题列表失败")
|
||
return
|
||
}
|
||
if themes == nil {
|
||
themes = []theme.ThemeInfo{}
|
||
}
|
||
// 读取当前主题
|
||
all := sc.settingService.GetSettings()
|
||
currentTheme := "MetaLab-2026"
|
||
if t, ok := all["site.theme"]; ok && t != "" {
|
||
currentTheme = t
|
||
}
|
||
common.Ok(c, gin.H{
|
||
"themes": themes,
|
||
"current": currentTheme,
|
||
})
|
||
}
|
||
|
||
// UpdateTheme 切换主题
|
||
func (sc *SiteSettingController) UpdateTheme(c *gin.Context) {
|
||
var req struct {
|
||
Theme string `json:"theme" binding:"required"`
|
||
}
|
||
if err := c.ShouldBindJSON(&req); err != nil {
|
||
common.Error(c, http.StatusBadRequest, "参数错误")
|
||
return
|
||
}
|
||
|
||
// 验证主题是否存在
|
||
themes, err := theme.DiscoverThemes("templates")
|
||
if err != nil {
|
||
common.Error(c, http.StatusInternalServerError, "读取主题列表失败")
|
||
return
|
||
}
|
||
found := false
|
||
for _, t := range themes {
|
||
if t.Dir == req.Theme {
|
||
found = true
|
||
break
|
||
}
|
||
}
|
||
if !found {
|
||
common.Error(c, http.StatusBadRequest, "主题不存在")
|
||
return
|
||
}
|
||
|
||
if err := sc.settingService.UpdateTheme(req.Theme, sc.themeReload); err != nil {
|
||
common.Error(c, http.StatusInternalServerError, "主题切换失败")
|
||
return
|
||
}
|
||
common.OkMessage(c, "主题已切换")
|
||
}
|