/* @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 }