Initial commit: TaskPool React panel
- React frontend with route-level code splitting - Backend rebranded from Baihu to TaskPool - DB brand migration script and local compatibility
This commit is contained in:
@@ -0,0 +1,204 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/engigu/taskpool/internal/cache"
|
||||
"github.com/engigu/taskpool/internal/constant"
|
||||
"github.com/engigu/taskpool/internal/database"
|
||||
"github.com/engigu/taskpool/internal/models"
|
||||
"github.com/engigu/taskpool/internal/utils"
|
||||
)
|
||||
|
||||
type SettingsService struct{}
|
||||
|
||||
func NewSettingsService() *SettingsService {
|
||||
return &SettingsService{}
|
||||
}
|
||||
|
||||
// InitSettings 初始化默认设置
|
||||
func (s *SettingsService) InitSettings() error {
|
||||
for section, keys := range constant.DefaultSettings {
|
||||
for key, value := range keys {
|
||||
var count int64
|
||||
database.DB.Model(&models.Setting{}).Where(&models.Setting{Section: section, Key: key}).Count(&count)
|
||||
if count == 0 {
|
||||
if err := database.DB.Create(&models.Setting{
|
||||
ID: utils.GenerateID(),
|
||||
Section: section,
|
||||
Key: key,
|
||||
Value: models.BigText(value),
|
||||
}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化日志清理配置
|
||||
// 检查是否需要从旧的 JSON 迁移
|
||||
oldVal := s.Get(constant.SectionSystem, "log_retention")
|
||||
if oldVal != "" {
|
||||
var oldConfigs map[string]struct {
|
||||
Days int `json:"days"`
|
||||
MaxCount int `json:"max_count"`
|
||||
}
|
||||
if err := json.Unmarshal([]byte(oldVal), &oldConfigs); err == nil {
|
||||
migrationMap := map[string]string{}
|
||||
if cfg, ok := oldConfigs[constant.LogCategorySystemNotice]; ok {
|
||||
migrationMap[constant.KeySystemNoticeDays] = fmt.Sprintf("%d", cfg.Days)
|
||||
migrationMap[constant.KeySystemNoticeMaxCount] = fmt.Sprintf("%d", cfg.MaxCount)
|
||||
}
|
||||
if cfg, ok := oldConfigs[constant.LogCategoryPushLog]; ok {
|
||||
migrationMap[constant.KeyPushLogDays] = fmt.Sprintf("%d", cfg.Days)
|
||||
migrationMap[constant.KeyPushLogMaxCount] = fmt.Sprintf("%d", cfg.MaxCount)
|
||||
}
|
||||
if cfg, ok := oldConfigs[constant.LogCategoryLoginLog]; ok {
|
||||
migrationMap[constant.KeyLoginLogDays] = fmt.Sprintf("%d", cfg.Days)
|
||||
migrationMap[constant.KeyLoginLogMaxCount] = fmt.Sprintf("%d", cfg.MaxCount)
|
||||
}
|
||||
|
||||
if len(migrationMap) > 0 {
|
||||
for k, v := range migrationMap {
|
||||
s.Set(constant.SectionSystem, k, v)
|
||||
}
|
||||
// 迁移完成后删除旧键
|
||||
s.Delete(constant.SectionSystem, "log_retention")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 默认值初始化
|
||||
defaultRetention := map[string]string{
|
||||
constant.KeySystemNoticeDays: "30",
|
||||
constant.KeySystemNoticeMaxCount: "500",
|
||||
constant.KeyPushLogDays: "15",
|
||||
constant.KeyPushLogMaxCount: "5000",
|
||||
constant.KeyLoginLogDays: "30",
|
||||
constant.KeyLoginLogMaxCount: "1000",
|
||||
constant.KeySchedulerLogDays: "30",
|
||||
constant.KeySchedulerLogMaxCount: "10000",
|
||||
}
|
||||
|
||||
for k, v := range defaultRetention {
|
||||
var count int64
|
||||
database.DB.Model(&models.Setting{}).Where(&models.Setting{Section: constant.SectionSystem, Key: k}).Count(&count)
|
||||
if count == 0 {
|
||||
s.Set(constant.SectionSystem, k, v)
|
||||
}
|
||||
}
|
||||
|
||||
// 从 constant.DefaultSettings 初始化所有缺少的通知模板
|
||||
if notifyDefaults, ok := constant.DefaultSettings[constant.SectionNotify]; ok {
|
||||
for k, v := range notifyDefaults {
|
||||
var count int64
|
||||
database.DB.Model(&models.Setting{}).Where(&models.Setting{Section: constant.SectionNotify, Key: k}).Count(&count)
|
||||
if count == 0 {
|
||||
s.Set(constant.SectionNotify, k, v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化或获取 JWT Secret 密码
|
||||
var secCount int64
|
||||
database.DB.Model(&models.Setting{}).Where(&models.Setting{Section: constant.SectionSecurity, Key: constant.KeySecret}).Count(&secCount)
|
||||
var secretValue string
|
||||
if secCount == 0 {
|
||||
// 先尝试从配置文件读取遗留下来的旧设
|
||||
if Config != nil && Config.Security.Secret != "" {
|
||||
secretValue = Config.Security.Secret
|
||||
} else {
|
||||
secretValue = utils.RandomString(32)
|
||||
}
|
||||
if err := database.DB.Create(&models.Setting{
|
||||
ID: utils.GenerateID(),
|
||||
Section: constant.SectionSecurity,
|
||||
Key: constant.KeySecret,
|
||||
Value: models.BigText(secretValue),
|
||||
}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
secretValue = s.Get(constant.SectionSecurity, constant.KeySecret)
|
||||
}
|
||||
constant.Secret = secretValue
|
||||
|
||||
cache.LoadSiteCache()
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get 获取单个设置
|
||||
func (s *SettingsService) Get(section, key string) string {
|
||||
if section == constant.SectionSite {
|
||||
return cache.GetSiteCache(key)
|
||||
}
|
||||
var setting models.Setting
|
||||
res := database.DB.Where(&models.Setting{Section: section, Key: key}).Limit(1).Find(&setting)
|
||||
if res.Error != nil || res.RowsAffected == 0 {
|
||||
if def, ok := constant.DefaultSettings[section][key]; ok {
|
||||
return def
|
||||
}
|
||||
return ""
|
||||
}
|
||||
return string(setting.Value)
|
||||
}
|
||||
|
||||
// Set 设置单个值
|
||||
func (s *SettingsService) Set(section, key, value string) error {
|
||||
var setting models.Setting
|
||||
res := database.DB.Where(&models.Setting{Section: section, Key: key}).Limit(1).Find(&setting)
|
||||
var err error
|
||||
if res.Error != nil || res.RowsAffected == 0 {
|
||||
err = database.DB.Create(&models.Setting{
|
||||
ID: utils.GenerateID(),
|
||||
Section: section,
|
||||
Key: key,
|
||||
Value: models.BigText(value),
|
||||
}).Error
|
||||
} else {
|
||||
err = database.DB.Model(&setting).Update("value", models.BigText(value)).Error
|
||||
}
|
||||
|
||||
if err == nil && section == constant.SectionSite {
|
||||
cache.SetSiteCache(key, value)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// Delete 删除单个设置
|
||||
func (s *SettingsService) Delete(section, key string) error {
|
||||
return database.DB.Where(&models.Setting{Section: section, Key: key}).Delete(&models.Setting{}).Error
|
||||
}
|
||||
|
||||
// GetSection 获取整个 section 的设置
|
||||
func (s *SettingsService) GetSection(section string) map[string]string {
|
||||
if section == constant.SectionSite {
|
||||
return cache.GetSiteCacheAll()
|
||||
}
|
||||
result := make(map[string]string)
|
||||
if defaults, ok := constant.DefaultSettings[section]; ok {
|
||||
for k, v := range defaults {
|
||||
result[k] = v
|
||||
}
|
||||
}
|
||||
var settings []models.Setting
|
||||
database.DB.Where("section = ?", section).Find(&settings)
|
||||
for _, setting := range settings {
|
||||
result[setting.Key] = string(setting.Value)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// SetSection 批量设置
|
||||
func (s *SettingsService) SetSection(section string, values map[string]string) error {
|
||||
for key, value := range values {
|
||||
if err := s.Set(section, key, value); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if section == constant.SectionSite {
|
||||
cache.SetSiteCacheBatch(values)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user