- 48 个 Go 文件所有注释(行注释/块注释/行尾注释,含 _test.go)翻译为中文 - 保留技术标识符:SECURITY_TODO(n)、unsafe-inline、sqlite/mysql、路由参数等 - 代码、字符串字面量、日志消息保持英文原文,零逻辑改动 - go build/vet 通过,go test -count=1 ./... 全绿
131 lines
3.6 KiB
Go
131 lines
3.6 KiB
Go
package models
|
|
|
|
import (
|
|
"sync"
|
|
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
// configCache 保存平台配置的进程级缓存,使每次请求的渲染与上传校验
|
|
// 都不必访问数据库。缓存启动时填充一次,每当管理员保存设置页面时刷新
|
|
// (参见 RefreshConfigCache / 各管理处理器)。
|
|
var configCache = struct {
|
|
mu sync.RWMutex
|
|
site *SiteSetting
|
|
upload *UploadConfig
|
|
comment *CommentConfig
|
|
types []UploadFileType
|
|
baseURLs []DownloadBaseURL
|
|
navLinks []NavLink
|
|
}{
|
|
site: &SiteSetting{},
|
|
upload: &UploadConfig{Enabled: true, DefaultMaxSize: DefaultUploadMaxSize, StorageDir: "attachments"},
|
|
}
|
|
|
|
// LoadConfigCache 将所有平台配置从数据库读入进程缓存。
|
|
// 在 InitDB 之后于启动时调用一次。
|
|
func LoadConfigCache(db *gorm.DB) {
|
|
configCache.mu.Lock()
|
|
defer configCache.mu.Unlock()
|
|
|
|
var s SiteSetting
|
|
if err := db.First(&s, 1).Error; err == nil {
|
|
configCache.site = &s
|
|
} else {
|
|
configCache.site = &SiteSetting{ID: 1}
|
|
}
|
|
|
|
var u UploadConfig
|
|
if err := db.First(&u, 1).Error; err == nil {
|
|
configCache.upload = &u
|
|
} else {
|
|
configCache.upload = &UploadConfig{ID: 1, Enabled: true, DefaultMaxSize: DefaultUploadMaxSize, StorageDir: "attachments"}
|
|
}
|
|
|
|
var cc CommentConfig
|
|
if err := db.First(&cc, 1).Error; err == nil {
|
|
configCache.comment = &cc
|
|
} else {
|
|
configCache.comment = defaultCommentConfig()
|
|
}
|
|
|
|
var t []UploadFileType
|
|
if err := db.Order("sort asc, id asc").Find(&t).Error; err == nil {
|
|
configCache.types = t
|
|
}
|
|
|
|
var b []DownloadBaseURL
|
|
if err := db.Order("is_default desc, priority asc, id asc").Find(&b).Error; err == nil {
|
|
configCache.baseURLs = b
|
|
}
|
|
|
|
var n []NavLink
|
|
if err := db.Where("enabled = ?", true).Order("sort asc, id asc").Find(&n).Error; err == nil {
|
|
configCache.navLinks = n
|
|
}
|
|
}
|
|
|
|
// RefreshConfigCache 重新加载所有缓存中的平台配置。管理处理器在写入变更后
|
|
// 调用此方法,以便下一次请求能看到更新。
|
|
func RefreshConfigCache(db *gorm.DB) {
|
|
LoadConfigCache(db)
|
|
}
|
|
|
|
// GetSiteSetting 返回缓存的站点设置指针(只读副本语义:调用方不得修改)。
|
|
func GetSiteSetting() *SiteSetting {
|
|
configCache.mu.RLock()
|
|
defer configCache.mu.RUnlock()
|
|
return configCache.site
|
|
}
|
|
|
|
// GetUploadConfig 返回缓存的上传策略。
|
|
func GetUploadConfig() *UploadConfig {
|
|
configCache.mu.RLock()
|
|
defer configCache.mu.RUnlock()
|
|
return configCache.upload
|
|
}
|
|
|
|
// GetCommentConfig 返回缓存的评论策略。
|
|
func GetCommentConfig() *CommentConfig {
|
|
configCache.mu.RLock()
|
|
defer configCache.mu.RUnlock()
|
|
return configCache.comment
|
|
}
|
|
|
|
// GetUploadFileTypes 返回缓存的允许文件类型列表。
|
|
func GetUploadFileTypes() []UploadFileType {
|
|
configCache.mu.RLock()
|
|
defer configCache.mu.RUnlock()
|
|
return configCache.types
|
|
}
|
|
|
|
// GetDownloadBaseURLs 返回缓存的下载基础 URL 列表。
|
|
func GetDownloadBaseURLs() []DownloadBaseURL {
|
|
configCache.mu.RLock()
|
|
defer configCache.mu.RUnlock()
|
|
return configCache.baseURLs
|
|
}
|
|
|
|
// DefaultDownloadBaseURL 返回用于构建附件下载链接的基础 URL:
|
|
// 首选标记为 IsDefault 且启用的行,否则选择优先级最高的启用行。
|
|
// 若未配置任何项则返回空字符串。
|
|
func DefaultDownloadBaseURL() string {
|
|
configCache.mu.RLock()
|
|
defer configCache.mu.RUnlock()
|
|
|
|
// 行按 is_default desc、priority asc 排序,因此第一个启用行即为正确选择。
|
|
for _, b := range configCache.baseURLs {
|
|
if b.Enabled {
|
|
return b.BaseURL
|
|
}
|
|
}
|
|
return ""
|
|
}
|
|
|
|
// GetNavLinks 返回缓存的启用导航链接列表,按排序顺序排列。
|
|
func GetNavLinks() []NavLink {
|
|
configCache.mu.RLock()
|
|
defer configCache.mu.RUnlock()
|
|
return configCache.navLinks
|
|
}
|