LicenseManger/internal/utils/config_persist.go

233 lines
3.2 KiB
Go

package utils
import (
"encoding/json"
"fmt"
"os"
"path/filepath"
"sync"
"time"
)
type ConfigVersion struct {
Version int `json:"version"`
UpdatedAt time.Time `json:"updated_at"`
UpdatedBy string `json:"updated_by"`
Comment string `json:"comment"`
}
type ConfigWithVersion struct {
Config *Config `json:"config"`
Version ConfigVersion `json:"version"`
}
var (
configMutex sync.RWMutex
configFile = "config/config.json" // JSON格式更适合动态更新
)
// SaveConfig 保存配置到文件
func SaveConfig(config *Config, updatedBy, comment string) error {
configMutex.Lock()
defer configMutex.Unlock()
// 读取当前版本
currentVersion := 0
if existing, err := LoadPersistedConfig(); err == nil {
currentVersion = existing.Version.Version
}
// 创建新的配置版本
configWithVersion := ConfigWithVersion{
Config: config,
Version: ConfigVersion{
Version: currentVersion + 1,
UpdatedAt: time.Now(),
UpdatedBy: updatedBy,
Comment: comment,
},
}
// 确保配置目录存在
configDir := filepath.Dir(configFile)
if err := os.MkdirAll(configDir, 0755); err != nil {
return err
}
// 备份旧配置
if err := backupConfig(); err != nil {
return err
}
// 将配置转换为JSON
data, err := json.MarshalIndent(configWithVersion, "", " ")
if err != nil {
return err
}
// 写入文件
return os.WriteFile(configFile, data, 0644)
}
// LoadPersistedConfig 加载持久化的配置
func LoadPersistedConfig() (*ConfigWithVersion, error) {
configMutex.RLock()
defer configMutex.RUnlock()
// 检查配置文件是否存在
if _, err := os.Stat(configFile); os.IsNotExist(err) {
// 如果不存在,创建默认配置
config, err := LoadConfig()
if err != nil {
return nil, err
}
return &ConfigWithVersion{
Config: config,
Version: ConfigVersion{
Version: 1,
UpdatedAt: time.Now(),
UpdatedBy: "system",
Comment: "初始配置",
},
}, nil
}
// 读取配置文件
data, err := os.ReadFile(configFile)
if err != nil {
return nil, err
}
// 解析JSON配置
var configWithVersion ConfigWithVersion
if err := json.Unmarshal(data, &configWithVersion); err != nil {
return nil, err
}
return &configWithVersion, nil
}
// MergeConfig 合并配置(环境变量优先)
func MergeConfig(persisted, env *Config) *Config {
if env.Server.Port != "" {
persisted.Server.Port = env.Server.Port
}
if env.Server.Mode != "" {
persisted.Server.Mode = env.Server.Mode
}
// ... 其他配置项的合并 ...
return persisted
}
// backupConfig 备份配置文件
func backupConfig() error {
if _, err := os.Stat(configFile); os.IsNotExist(err) {
return nil
}
// 确保备份目录存在
backupDir := "config/backups"
if err := os.MkdirAll(backupDir, 0755); err != nil {
return err
}
// 读取当前配置
data, err := os.ReadFile(configFile)
if err != nil {
return err
}
// 创建备份文件名
backupFile := filepath.Join(backupDir,
fmt.Sprintf("config_%s.json", time.Now().Format("20060102150405")))
// 写入备份文件
return os.WriteFile(backupFile, data, 0644)
}