Compare commits
3 Commits
1eb3cc7c86
...
426bedda65
| Author | SHA1 | Date | |
|---|---|---|---|
| 426bedda65 | |||
| d4a833f149 | |||
| 3f4d827926 |
@ -11,6 +11,7 @@ import (
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"metazone.cc/mce/internal/model"
|
||||
@ -19,22 +20,31 @@ import (
|
||||
)
|
||||
|
||||
// assetHashes 静态资源文件哈希表(URL 路径 → 短哈希,文件不变哈希不变)
|
||||
var assetHashes map[string]string
|
||||
var (
|
||||
assetHashes map[string]string
|
||||
assetMu sync.RWMutex
|
||||
)
|
||||
|
||||
// ComputeAssetHashes 遍历 static 目录,计算每个文件的 CRC32 作为版本号
|
||||
// 构建本地 map 后原子替换,避免并发读写冲突
|
||||
func ComputeAssetHashes(templateDir string) {
|
||||
assetHashes = make(map[string]string)
|
||||
mu := make(map[string]string)
|
||||
// 前端主题:templates/MetaLab-2026/static → URL /static/
|
||||
walkStaticDir(filepath.Join(templateDir, "static"), "/static")
|
||||
walkStaticDirInto(mu, filepath.Join(templateDir, "static"), "/static")
|
||||
// 共享资源:templates/shared/static → URL /shared/static/
|
||||
walkStaticDir(filepath.Join(filepath.Dir(templateDir), "shared", "static"), "/shared/static")
|
||||
walkStaticDirInto(mu, filepath.Join(filepath.Dir(templateDir), "shared", "static"), "/shared/static")
|
||||
// 管理后台:templates/admin/static → URL /admin/static/
|
||||
walkStaticDir(filepath.Join(filepath.Dir(templateDir), "admin", "static"), "/admin/static")
|
||||
log.Printf("[AssetHashes] computed %d file hashes", len(assetHashes))
|
||||
walkStaticDirInto(mu, filepath.Join(filepath.Dir(templateDir), "admin", "static"), "/admin/static")
|
||||
|
||||
assetMu.Lock()
|
||||
assetHashes = mu
|
||||
assetMu.Unlock()
|
||||
|
||||
log.Printf("[AssetHashes] computed %d file hashes", len(mu))
|
||||
}
|
||||
|
||||
// walkStaticDir 遍历目录,计算每个 .js/.css 的 CRC32,存入 assetHashes
|
||||
func walkStaticDir(dir, urlPrefix string) {
|
||||
// walkStaticDirInto 遍历目录,计算每个 .js/.css 的 CRC32,存入目标 map
|
||||
func walkStaticDirInto(dst map[string]string, dir, urlPrefix string) {
|
||||
_ = filepath.WalkDir(dir, func(path string, d fs.DirEntry, err error) error {
|
||||
if err != nil || d.IsDir() {
|
||||
return nil
|
||||
@ -52,14 +62,17 @@ func walkStaticDir(dir, urlPrefix string) {
|
||||
// 生成 URL 路径:urlPrefix + 相对于 dir 的子路径
|
||||
rel, _ := filepath.Rel(dir, path)
|
||||
urlPath := urlPrefix + "/" + filepath.ToSlash(rel)
|
||||
assetHashes[urlPath] = shortHash
|
||||
dst[urlPath] = shortHash
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
// AssetV 返回指定静态资源的哈希版本号(模板函数)
|
||||
// AssetV 返回指定静态资源的哈希版本号(模板函数,并发安全)
|
||||
func AssetV(path string) string {
|
||||
if h, ok := assetHashes[path]; ok {
|
||||
assetMu.RLock()
|
||||
h, ok := assetHashes[path]
|
||||
assetMu.RUnlock()
|
||||
if ok {
|
||||
return h
|
||||
}
|
||||
return "0"
|
||||
|
||||
@ -41,4 +41,3 @@
|
||||
</div>
|
||||
</div>
|
||||
{{template "admin/layout/footer.html" .}}
|
||||
<script src="/admin/static/js/site-settings-theme.js?v={{assetV "/admin/static/js/site-settings-theme.js"}}" nonce="{{.CSPNonce}}"></script>
|
||||
|
||||
@ -50,7 +50,7 @@
|
||||
|
||||
if (t.id === 'maintenance-enabled') {
|
||||
el.checked = allSettings[t.key] === 'true';
|
||||
} else if (t.id === 'registration-enabled') {
|
||||
} else if (t.key.indexOf('registration.') === 0) {
|
||||
el.checked = allSettings[t.key] !== 'false';
|
||||
} else {
|
||||
el.checked = audit[t.key.split('.')[1]] === true;
|
||||
@ -63,6 +63,12 @@
|
||||
// 文本输入保存按钮
|
||||
bindSaveButtons();
|
||||
|
||||
// 密码强度下拉(服务端渲染默认值,需从 API 覆盖以显示最新保存值)
|
||||
var strengthSelect = document.getElementById('setting-password-strength');
|
||||
if (strengthSelect && allSettings['password.strength']) {
|
||||
strengthSelect.value = allSettings['password.strength'];
|
||||
}
|
||||
|
||||
// 社区准则文本域
|
||||
var guidelinesEl = document.getElementById('setting-site-guidelines');
|
||||
if (guidelinesEl) {
|
||||
|
||||
Reference in New Issue
Block a user