Files
NetworkAuth/services/settings.go

202 lines
5.2 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package services
import (
"NetworkAuth/database"
"NetworkAuth/models"
"strconv"
"sync"
"github.com/sirupsen/logrus"
)
// ============================================================================
// 结构体定义
// ============================================================================
// SettingsService 设置服务
type SettingsService struct {
mu sync.RWMutex
cache map[string]string
}
// ============================================================================
// 全局变量
// ============================================================================
var settingsService *SettingsService
var settingsOnce sync.Once
// ============================================================================
// 公共函数
// ============================================================================
// GetSettingsService 获取设置服务单例
func GetSettingsService() *SettingsService {
settingsOnce.Do(func() {
settingsService = &SettingsService{
cache: make(map[string]string),
}
// 初始化时加载所有设置
settingsService.loadAllSettings()
})
return settingsService
}
// ResetSettingsService 充置设置服务单例,主要用于重新加载设置(比如安装后)
func ResetSettingsService() {
settingsService = &SettingsService{
cache: make(map[string]string),
}
settingsService.loadAllSettings()
}
// ============================================================================
// 私有函数
// ============================================================================
// loadAllSettings 从数据库加载所有设置到缓存
func (s *SettingsService) loadAllSettings() {
db, err := database.GetDB()
if err != nil {
logrus.WithError(err).Error("获取数据库连接失败")
return
}
// 如果数据库未初始化,直接返回,保持缓存为空
if db == nil {
return
}
// 检查 settings 表是否存在,如果不存在则不查询
if !db.Migrator().HasTable(&models.Settings{}) {
logrus.Info("settings 表不存在,跳过加载设置")
return
}
var settings []models.Settings
if err := db.Find(&settings).Error; err != nil {
logrus.WithError(err).Error("加载设置失败")
return
}
s.mu.Lock()
defer s.mu.Unlock()
for _, setting := range settings {
s.cache[setting.Name] = setting.Value
}
logrus.WithField("count", len(settings)).Debug("设置缓存加载完成")
}
// Set 设置值(用于测试或运行时更新)
func (s *SettingsService) Set(name, value string) {
s.mu.Lock()
defer s.mu.Unlock()
s.cache[name] = value
}
// GetSettingRealtime 实时获取设置值优先使用Redis缓存自动回源数据库
// 相比 GetString 的内存缓存此方法能感知其他实例或直接数据库的变更在Redis TTL过期后
func (s *SettingsService) GetSettingRealtime(name string) (*models.Settings, error) {
db, err := database.GetDB()
if err != nil {
return nil, err
}
return FindSettingByName(name, db)
}
// GetString 获取字符串类型的设置值
func (s *SettingsService) GetString(name, defaultValue string) string {
s.mu.RLock()
defer s.mu.RUnlock()
if value, exists := s.cache[name]; exists {
return value
}
return defaultValue
}
// GetInt 获取整数类型的设置值
func (s *SettingsService) GetInt(name string, defaultValue int) int {
strValue := s.GetString(name, "")
if strValue == "" {
return defaultValue
}
if intValue, err := strconv.Atoi(strValue); err == nil {
return intValue
}
return defaultValue
}
// GetBool 获取布尔类型的设置值
func (s *SettingsService) GetBool(name string, defaultValue bool) bool {
strValue := s.GetString(name, "")
if strValue == "" {
return defaultValue
}
return strValue == "1" || strValue == "true"
}
// RefreshCache 刷新设置缓存
func (s *SettingsService) RefreshCache() {
s.loadAllSettings()
}
// IsMaintenanceMode 检查是否开启维护模式
func (s *SettingsService) IsMaintenanceMode() bool {
return s.GetBool("maintenance_mode", false)
}
// GetJWTSecret 获取JWT密钥
func (s *SettingsService) GetJWTSecret() string {
return s.GetString("jwt_secret", "")
}
// GetEncryptionKey 获取加密密钥
func (s *SettingsService) GetEncryptionKey() string {
return s.GetString("encryption_key", "")
}
// GetJWTRefresh 已废弃,请使用 GetRefreshTokenExpireDays
func (s *SettingsService) GetJWTRefresh() int {
return 0
}
// GetJWTExpire 获取 accessToken 有效期(小时)
func (s *SettingsService) GetJWTExpire() int {
v := s.GetInt("jwt_expire", 2)
if v <= 0 {
return 2
}
return v
}
// GetRefreshTokenExpireDays 获取 refreshToken 有效期(天)
func (s *SettingsService) GetRefreshTokenExpireDays() int {
v := s.GetInt("refresh_token_expire_days", 7)
if v <= 0 {
return 7
}
return v
}
// GetSessionAbsoluteExpireDays 获取会话绝对过期上限(天)
func (s *SettingsService) GetSessionAbsoluteExpireDays() int {
v := s.GetInt("session_absolute_expire_days", 30)
if v <= 0 {
return 30
}
return v
}
// GetCookieConfig 获取Cookie配置
func (s *SettingsService) GetCookieConfig() (secure bool, sameSite string, domain string, maxAge int) {
secure = s.GetBool("cookie_secure", true)
sameSite = s.GetString("cookie_same_site", "Lax")
domain = s.GetString("cookie_domain", "")
maxAge = s.GetInt("cookie_max_age", 86400)
return
}