feat: 社区准则改为数据库存储
- AuthController 注入 SiteSettings 依赖,RegisterPage 优先从 DB 读取准则 - DB 中 site.guidelines 为空时 fallback 到静态 guidelines.html 文件 - 管理后台站点设置页新增「内容管理」分区,textarea 编辑社区准则 - 添加准则编辑区垂直布局样式
This commit is contained in:
@ -1,6 +1,7 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"html/template"
|
||||
"net/http"
|
||||
|
||||
"metazone.cc/metalab/internal/common"
|
||||
@ -17,11 +18,12 @@ type AuthController struct {
|
||||
sessionManager *session.Manager
|
||||
rateLimiter rateLimiter
|
||||
cfg *config.Config
|
||||
siteSettings *config.SiteSettings
|
||||
}
|
||||
|
||||
// NewAuthController 构造函数
|
||||
func NewAuthController(authService authUseCase, sm *session.Manager, limiter rateLimiter, cfg *config.Config) *AuthController {
|
||||
return &AuthController{authService: authService, sessionManager: sm, rateLimiter: limiter, cfg: cfg}
|
||||
func NewAuthController(authService authUseCase, sm *session.Manager, limiter rateLimiter, cfg *config.Config, siteSettings *config.SiteSettings) *AuthController {
|
||||
return &AuthController{authService: authService, sessionManager: sm, rateLimiter: limiter, cfg: cfg, siteSettings: siteSettings}
|
||||
}
|
||||
|
||||
// RegisterPage 注册页面(已登录用户重定向到首页)
|
||||
@ -30,10 +32,18 @@ func (ac *AuthController) RegisterPage(c *gin.Context) {
|
||||
c.Redirect(http.StatusFound, "/")
|
||||
return
|
||||
}
|
||||
guidelines, err := theme.LoadContent("templates/MetaLab-2026/guidelines.html")
|
||||
if err != nil {
|
||||
c.String(http.StatusInternalServerError, "加载准则失败")
|
||||
return
|
||||
// 优先从 DB 读取社区准则,为空时 fallback 到静态文件
|
||||
guidelinesHTML := ac.siteSettings.Get("site.guidelines", "")
|
||||
var guidelines template.HTML
|
||||
if guidelinesHTML != "" {
|
||||
guidelines = template.HTML(guidelinesHTML)
|
||||
} else {
|
||||
content, err := theme.LoadContent("templates/MetaLab-2026/guidelines.html")
|
||||
if err != nil {
|
||||
c.String(http.StatusInternalServerError, "加载准则失败")
|
||||
return
|
||||
}
|
||||
guidelines = content
|
||||
}
|
||||
c.HTML(http.StatusOK, "auth/register.html", common.BuildPageData(c, gin.H{
|
||||
"Title": "注册",
|
||||
|
||||
@ -78,7 +78,7 @@ func buildDepsCore(db *gorm.DB, cfg *config.Config, siteSettings *config.SiteSet
|
||||
sessionMgr := session.NewManager(sessionStore, userRepo, cfg)
|
||||
authService := service.NewAuthService(userRepo, sessionMgr, cfg, siteSettings)
|
||||
rateLimiter := middleware.NewRateLimiter()
|
||||
authCtrl := controller.NewAuthController(authService, sessionMgr, rateLimiter, cfg)
|
||||
authCtrl := controller.NewAuthController(authService, sessionMgr, rateLimiter, cfg, siteSettings)
|
||||
avatarSvc := service.NewAvatarService(userRepo)
|
||||
authMdw := middleware.NewAuthMiddleware(cfg, sessionMgr)
|
||||
return userRepo, sessionMgr, authService, rateLimiter, authCtrl, avatarSvc, authMdw
|
||||
|
||||
@ -115,6 +115,23 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 内容管理 -->
|
||||
<div class="settings-section">
|
||||
<div class="section-title">内容管理</div>
|
||||
<div class="section-body">
|
||||
<div class="setting-item setting-item-vertical">
|
||||
<div class="setting-info">
|
||||
<span class="setting-label">社区准则</span>
|
||||
<span class="setting-desc">注册时需用户阅读并同意,支持 HTML 格式</span>
|
||||
</div>
|
||||
<div class="setting-input-block">
|
||||
<textarea id="setting-site-guidelines" class="setting-textarea" rows="12" placeholder="留空则使用默认准则文件"></textarea>
|
||||
<button class="btn btn-sm btn-primary btn-save-block" data-key="site.guidelines" data-input="setting-site-guidelines">保存准则</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 通用设置 -->
|
||||
<div class="settings-section">
|
||||
<div class="section-title">其他设置</div>
|
||||
|
||||
@ -58,6 +58,35 @@
|
||||
.btn-save { width: 56px; text-align: center; }
|
||||
.btn-save:disabled { opacity: 0.5; cursor: not-allowed; }
|
||||
|
||||
/* --- 垂直布局设置项(用于准则等大文本) --- */
|
||||
.setting-item-vertical {
|
||||
flex-direction: column; align-items: stretch;
|
||||
}
|
||||
.setting-item-vertical .setting-info {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.setting-input-block {
|
||||
display: flex; flex-direction: column; gap: 10px;
|
||||
}
|
||||
.setting-textarea {
|
||||
padding: 10px 12px;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 4px;
|
||||
font-size: 13px; line-height: 1.6;
|
||||
font-family: 'Courier New', Consolas, monospace;
|
||||
resize: vertical;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
outline: none;
|
||||
transition: border-color 0.2s;
|
||||
}
|
||||
.setting-textarea:focus { border-color: var(--primary); }
|
||||
.btn-save-block {
|
||||
align-self: flex-end;
|
||||
min-width: 80px;
|
||||
}
|
||||
.btn-save-block:disabled { opacity: 0.5; cursor: not-allowed; }
|
||||
|
||||
/* --- 空状态 --- */
|
||||
.settings-empty {
|
||||
text-align: center; padding: 28px 20px;
|
||||
|
||||
@ -18,6 +18,7 @@
|
||||
// 已有专属 UI 的设置 key,不在"其他设置"中重复显示
|
||||
var DEDICATED_KEYS = {
|
||||
'site.framework': true, 'site.copyright_start': true,
|
||||
'site.guidelines': true,
|
||||
'maintenance.enabled': true,
|
||||
'registration.enabled': true,
|
||||
'audit.enabled': true, 'audit.username_audit': true, 'audit.avatar_audit': true, 'audit.bio_audit': true
|
||||
@ -51,6 +52,18 @@
|
||||
// 文本输入保存按钮
|
||||
bindSaveButtons();
|
||||
|
||||
// 社区准则文本域
|
||||
var guidelinesEl = document.getElementById('setting-site-guidelines');
|
||||
if (guidelinesEl) {
|
||||
guidelinesEl.value = allSettings['site.guidelines'] || '';
|
||||
var guidelinesBtn = document.querySelector('[data-key="site.guidelines"]');
|
||||
if (guidelinesBtn) {
|
||||
guidelinesBtn.addEventListener('click', function() {
|
||||
updateTextSetting('site.guidelines', guidelinesEl.value, guidelinesBtn);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 其他设置(过滤已有专属UI的key)
|
||||
renderOtherSettings(allSettings);
|
||||
} catch (e) {
|
||||
|
||||
Reference in New Issue
Block a user