/* @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 } 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) return &cfg, nil } func GetCurrentTheme() string { return "default" } func SetCurrentTheme(theme string) { } // GetJWTSecret 获取 JWT 密钥 func (c *Config) GetJWTSecret() string { //return c.JWT.Secret return c.Security.JWTSecret }