Files
Victor_Jay e7092254ab
Some checks failed
CI / Lint + Build (push) Has been cancelled
feat(theme): 管理后台新增模板选择器,支持运行时动态切换主题
新增功能:
- 主题发现模块:扫描 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 + 子导航
2026-06-30 17:43:08 +08:00

85 lines
4.4 KiB
HTML

{{template "settings/_header.html" .}}
<!-- 账号信息 -->
<div class="settings-card">
<div class="settings-card-header">
<h2>账号信息</h2>
<p class="settings-card-desc">账号安全和基本状态</p>
</div>
<div class="settings-card-body">
<div class="info-row">
<span class="info-label">用户 ID</span>
<span class="info-value">{{.User.ID}}</span>
</div>
<div class="info-row">
<span class="info-label">邮箱</span>
<span class="info-value">{{.User.Email}}</span>
</div>
<div class="info-row">
<span class="info-label">账号状态</span>
<span class="info-value">
<span class="status-badge status-{{.User.Status}}">{{.StatusName}}</span>
</span>
</div>
<div class="info-row">
<span class="info-label">注册时间</span>
<span class="info-value">{{.User.CreatedAt.Format "2006-01-02 15:04:05"}}</span>
</div>
{{if .User.LastLoginAt}}
<div class="info-row">
<span class="info-label">上次登录</span>
<span class="info-value">{{.User.LastLoginAt.Format "2006-01-02 15:04:05"}}</span>
</div>
{{end}}
<div class="info-row">
<span class="info-label">最后更新</span>
<span class="info-value">{{.User.UpdatedAt.Format "2006-01-02 15:04:05"}}</span>
</div>
</div>
</div>
<!-- 修改密码 -->
<div class="settings-card">
<div class="settings-card-header">
<h2>修改密码</h2>
<p class="settings-card-desc">修改密码后需重新登录</p>
</div>
<div class="settings-card-body">
<div class="form-group">
<label class="form-label" for="currentPassword">当前密码</label>
<input type="password" id="currentPassword" class="settings-text-input" placeholder="输入当前密码" autocomplete="current-password">
</div>
<div class="form-group">
<label class="form-label" for="newPassword">新密码</label>
<input type="password" id="newPassword" class="settings-text-input" placeholder="至少 8 位,包含大小写字母和数字" autocomplete="new-password">
</div>
<div class="settings-card-footer">
<button id="changePwdBtn" class="settings-save-btn">修改密码</button>
<span class="form-hint">修改成功后需重新登录</span>
</div>
</div>
</div>
<!-- 注销账号 -->
<div class="settings-card settings-card-danger">
<div class="settings-card-header">
<h2>注销账号</h2>
<p class="settings-card-desc">账号将在 7 天后正式注销,期间可随时重新登录撤销注销</p>
</div>
<div class="settings-card-body">
<div class="form-group">
<label class="form-label" for="deletePassword">确认密码</label>
<input type="password" id="deletePassword" class="settings-text-input" placeholder="输入密码确认" autocomplete="current-password">
</div>
<div class="form-group">
<label class="form-label" for="deleteReason">注销原因(选填)</label>
<textarea id="deleteReason" class="settings-textarea" maxlength="500" placeholder="可以告诉我们为什么要离开吗?"></textarea>
</div>
<div class="settings-card-footer">
<button id="deleteAccountBtn" class="settings-danger-btn">确认注销</button>
<span class="form-hint">此操作不可逆,请谨慎处理</span>
</div>
</div>
</div>
{{template "settings/_footer.html" .}}
<script src="/static/js/settings-account.js?v={{assetV "/static/js/settings-account.js"}}" nonce="{{.CSPNonce}}"></script>