Some checks failed
CI / Lint + Build (push) Has been cancelled
新增功能:
- 主题发现模块:扫描 templates/ 目录下含 theme.json 的目录
- 站点设置新增 site.theme 键,DB 持久化 + 内存缓存
- 运行时切换主题:保存后即时重载 Gin 模板 + 静态资源哈希
- 管理后台 '外观主题' 页面:列表展示、选择、一键切换
- 动态静态资源服务:根据当前主题目录提供 CSS/JS
修复:
- account.html 残留孤儿 {{end}} 模板语法错误
- 动态静态资源 handler 误判 Gin *filepath 路径前缀为绝对路径
变更文件(12 modified + 3 new):
- cmd/server/main.go: 动态主题加载 + 运行时重载 + 动态静态服务
- internal/theme/discovery.go: 新增主题扫描
- internal/config/site_settings.go: ThemeName()
- internal/service/site_setting_service.go: ThemeReloader + UpdateTheme
- internal/controller/admin/: ISP 扩展 + GetThemes/UpdateTheme/ThemePage
- internal/controller/auth_controller.go: 准则路径动态化
- internal/router/: InjectThemeReloader + 新路由
- templates/: 外观主题页面 + JS + CSS + 子导航
97 lines
2.8 KiB
Go
97 lines
2.8 KiB
Go
package service
|
||
|
||
import (
|
||
"strconv"
|
||
)
|
||
|
||
// siteSettingsManager 站点设置服务所需的最小接口(ISP)
|
||
type siteSettingsManager interface {
|
||
Get(key, defaultVal string) string
|
||
GetBool(key string, defaultVal bool) bool
|
||
Set(key, value string) error
|
||
SetBool(key string, value bool) error
|
||
All() map[string]string
|
||
}
|
||
|
||
// SiteSettingService 站点设置业务逻辑
|
||
type SiteSettingService struct {
|
||
settings siteSettingsManager
|
||
}
|
||
|
||
// NewSiteSettingService 构造函数
|
||
func NewSiteSettingService(settings siteSettingsManager) *SiteSettingService {
|
||
return &SiteSettingService{settings: settings}
|
||
}
|
||
|
||
// GetSettings 获取所有站点设置(仅 owner 可见)
|
||
func (s *SiteSettingService) GetSettings() map[string]string {
|
||
return s.settings.All()
|
||
}
|
||
|
||
// UpdateSetting 更新单项设置
|
||
func (s *SiteSettingService) UpdateSetting(key, value string) error {
|
||
return s.settings.Set(key, value)
|
||
}
|
||
|
||
// UpdateBoolSetting 更新布尔设置
|
||
func (s *SiteSettingService) UpdateBoolSetting(key string, value bool) error {
|
||
return s.settings.SetBool(key, value)
|
||
}
|
||
|
||
// GetBool gets a boolean setting with a default
|
||
func (s *SiteSettingService) GetBool(key string, defaultVal bool) bool {
|
||
return s.settings.GetBool(key, defaultVal)
|
||
}
|
||
|
||
// --- 审核相关设置快捷方法 ---
|
||
|
||
// AuditSettings 审核相关站点设置集合(用于前端展示)
|
||
type AuditSettings struct {
|
||
Enabled bool `json:"enabled"`
|
||
UsernameAudit bool `json:"username_audit"`
|
||
AvatarAudit bool `json:"avatar_audit"`
|
||
BioAudit bool `json:"bio_audit"`
|
||
}
|
||
|
||
// GetAuditSettings 获取审核相关设置
|
||
func (s *SiteSettingService) GetAuditSettings(defaultCfg *AuditDefaults) *AuditSettings {
|
||
return &AuditSettings{
|
||
Enabled: s.settings.GetBool("audit.enabled", defaultCfg.Enabled),
|
||
UsernameAudit: s.settings.GetBool("audit.username_audit", defaultCfg.UsernameAudit),
|
||
AvatarAudit: s.settings.GetBool("audit.avatar_audit", defaultCfg.AvatarAudit),
|
||
BioAudit: s.settings.GetBool("audit.bio_audit", defaultCfg.BioAudit),
|
||
}
|
||
}
|
||
|
||
// AuditDefaults config.yaml 中的审核默认值
|
||
type AuditDefaults struct {
|
||
Enabled bool
|
||
UsernameAudit bool
|
||
AvatarAudit bool
|
||
BioAudit bool
|
||
}
|
||
|
||
// GetBoolSetting is a generic getter used by controllers
|
||
func (s *SiteSettingService) GetBoolSetting(key string, defaultVal bool) bool {
|
||
return s.settings.GetBool(key, defaultVal)
|
||
}
|
||
|
||
// ParseBool 解析字符串为布尔值
|
||
func ParseBool(v string) (bool, error) {
|
||
return strconv.ParseBool(v)
|
||
}
|
||
|
||
// ThemeReloader 主题重载回调:切换主题后实时生效
|
||
type ThemeReloader func(themeName string) error
|
||
|
||
// UpdateTheme 切换主题并触发重载
|
||
func (s *SiteSettingService) UpdateTheme(themeName string, reload ThemeReloader) error {
|
||
if err := s.settings.Set("site.theme", themeName); err != nil {
|
||
return err
|
||
}
|
||
if reload != nil {
|
||
return reload(themeName)
|
||
}
|
||
return nil
|
||
}
|