153 lines
3.7 KiB
Go
153 lines
3.7 KiB
Go
/*
|
||
@Time : 2020/6/28 21:48
|
||
@Author : xuyiqing
|
||
@File : config.py
|
||
*/
|
||
|
||
package config
|
||
|
||
import (
|
||
"fmt"
|
||
"time"
|
||
|
||
"github.com/fsnotify/fsnotify"
|
||
"github.com/spf13/viper"
|
||
)
|
||
|
||
const (
|
||
EnvDevelopment = "development"
|
||
EnvProduction = "production"
|
||
)
|
||
|
||
type DataBaseConfig struct {
|
||
Host string
|
||
Port string
|
||
User string
|
||
Password string
|
||
DBName string
|
||
Charset string
|
||
Prefix string
|
||
Driver string
|
||
DSN string
|
||
MaxConns int `mapstructure:"max_conns"`
|
||
}
|
||
|
||
type Jwt struct {
|
||
SecretKey string
|
||
}
|
||
|
||
type Project struct {
|
||
StaticUrlMapPath []interface{}
|
||
TemplateGlob string
|
||
MediaFilePath string
|
||
CurrentTheme string
|
||
}
|
||
|
||
type ServerConfig struct {
|
||
Port string
|
||
EnableGzip bool `mapstructure:"enable_gzip"`
|
||
CSRFSecret string `mapstructure:"csrf_secret"`
|
||
ReadTimeout time.Duration
|
||
WriteTimeout time.Duration
|
||
}
|
||
|
||
type ThemeConfig struct {
|
||
Current string
|
||
AllowUpload bool `mapstructure:"allow_upload"`
|
||
}
|
||
type SecurityConfig struct {
|
||
JWTSecret string `mapstructure:"jwt_secret"`
|
||
CORSAllowedOrigins []string `mapstructure:"cors_allowed_origins"`
|
||
}
|
||
type Config struct {
|
||
Env string
|
||
Server ServerConfig
|
||
DataBase DataBaseConfig
|
||
Theme ThemeConfig
|
||
JwtSecretKey Jwt
|
||
Project Project
|
||
Security SecurityConfig
|
||
}
|
||
|
||
var globalConfig *Config // 新增全局配置变量
|
||
|
||
func LoadConfig(configPath string) (*Config, error) {
|
||
// 1. 基础配置
|
||
viper.SetConfigFile(configPath)
|
||
// 设置配置文件的名称(不包括扩展名)
|
||
viper.SetConfigName("config")
|
||
// 设置配置文件所在的目录
|
||
viper.AddConfigPath("./config")
|
||
// 设置配置文件的类型为YAML
|
||
viper.SetConfigType("yaml")
|
||
// 3. 自动读取环境变量(自动转换大写和下划线)
|
||
viper.AutomaticEnv()
|
||
viper.SetEnvPrefix("BLOG") // 环境变量前缀 BLOG_xxx
|
||
|
||
// 2. 设置默认值
|
||
viper.SetDefault("server.port", 3000)
|
||
viper.SetDefault("database.max_conns", 10)
|
||
viper.SetDefault("theme.allow_upload", false)
|
||
// 读取配置文件
|
||
if err := viper.ReadInConfig(); err != nil {
|
||
if _, ok := err.(viper.ConfigFileNotFoundError); ok {
|
||
return nil, fmt.Errorf("配置文件未找到: %s", configPath)
|
||
}
|
||
return nil, fmt.Errorf("读取配置文件失败: %w", err)
|
||
}
|
||
|
||
//监控并重新读取配置文件
|
||
viper.WatchConfig()
|
||
viper.OnConfigChange(func(e fsnotify.Event) {
|
||
// 配置文件发生变更之后会调用的回调函数
|
||
fmt.Println("Config file changed:", e.Name)
|
||
})
|
||
|
||
// 5. 反序列化到结构体
|
||
var cfg Config
|
||
if err := viper.Unmarshal(&cfg); err != nil {
|
||
return nil, fmt.Errorf("配置解析失败: %w", err)
|
||
}
|
||
|
||
// 6. 校验必要配置项
|
||
// if cfg.Security.JWTSecret == "" {
|
||
// return nil, fmt.Errorf("安全配置错误: jwt_secret 必须设置")
|
||
// }
|
||
|
||
// 获取配置值
|
||
mysqlHost := viper.GetString("database.Host")
|
||
jwtSecretKey := viper.GetString("jwt.SecretKey")
|
||
serverPort := viper.GetInt("server.Port")
|
||
templateGlob := viper.GetString("project.TemplateGlob")
|
||
// 打印获取到的配置值
|
||
fmt.Printf("MySQL Host: %s\n", mysqlHost)
|
||
fmt.Printf("JWT Secret Key: %s\n", jwtSecretKey)
|
||
fmt.Printf("Server Port: %d\n", serverPort)
|
||
fmt.Printf("TemplateGlob: %s\n", templateGlob)
|
||
|
||
globalConfig = &cfg // 保存配置到全局变量
|
||
return &cfg, nil
|
||
}
|
||
|
||
func GetCurrentTheme() string {
|
||
return "default"
|
||
|
||
}
|
||
func SetCurrentTheme(theme string) error {
|
||
return nil
|
||
}
|
||
|
||
// GetJWTSecret 获取 JWT 密钥
|
||
// 移除原有的方法定义(如果存在)
|
||
// func (c *Config) GetJWTSecret() string {
|
||
// 原错误:返回 security.JWTSecret,实际应使用 jwtSecretKey.SecretKey
|
||
// }
|
||
|
||
// 新增包级函数获取 JWT 密钥
|
||
func GetJWTSecret() string {
|
||
if globalConfig == nil {
|
||
//panic("配置未加载,请先调用 LoadConfig")
|
||
}
|
||
return globalConfig.JwtSecretKey.SecretKey
|
||
}
|