package config import ( "fmt" "github.com/spf13/viper" "github.com/subosito/gotenv" ) // ServerConfig 服务器配置 type ServerConfig struct { Port string `mapstructure:"port"` Environment string `mapstructure:"environment"` } // DatabaseConfig 数据库配置 type DatabaseConfig struct { Driver string `mapstructure:"driver"` SQLite struct { Path string `mapstructure:"path"` } `mapstructure:"sqlite"` Postgres struct { Host string `mapstructure:"host"` Port string `mapstructure:"port"` User string `mapstructure:"user"` Password string `mapstructure:"password"` DBName string `mapstructure:"dbname"` SSLMode string `mapstructure:"sslmode"` } `mapstructure:"postgres"` } // JWTConfig JWT 配置 type JWTConfig struct { Secret string `mapstructure:"secret"` Expire int `mapstructure:"expire"` } // AppConfig 应用程序配置 type AppConfig struct { Server ServerConfig `mapstructure:"server"` Database DatabaseConfig `mapstructure:"database"` JWT JWTConfig `mapstructure:"jwt"` } // 全局配置变量 var appConfig AppConfig // LoadConfig 加载配置 func LoadConfig() { // 使用 gotenv 加载 .env 文件 if err := gotenv.Load(); err != nil { fmt.Printf("警告: 未找到 .env 文件: %v\n", err) } // 配置 Viper 以读取 YAML 配置文件 viper.SetConfigName("config") viper.SetConfigType("yaml") viper.AddConfigPath(".") viper.AddConfigPath("./config") viper.AddConfigPath("../") if err := viper.MergeInConfig(); err != nil { fmt.Printf("警告: 未找到配置文件,使用默认值: %v\n", err) } // 环境变量前缀 viper.SetEnvPrefix("TRACE") viper.AutomaticEnv() // 默认配置 viper.SetDefault("server.port", "3000") viper.SetDefault("server.environment", "development") viper.SetDefault("database.driver", "sqlite") viper.SetDefault("database.sqlite.path", "./data/database.sqlite") viper.SetDefault("database.postgres.host", "localhost") viper.SetDefault("database.postgres.port", "5432") viper.SetDefault("database.postgres.user", "trace") viper.SetDefault("database.postgres.password", "trace123") viper.SetDefault("database.postgres.dbname", "trace") viper.SetDefault("database.postgres.sslmode", "disable") viper.SetDefault("jwt.secret", "your-secret-key-here-change-in-production") viper.SetDefault("jwt.expire", 7200) // 绑定环境变量(支持无前缀的 .env 文件) viper.BindEnv("server.port", "PORT", "TRACE_SERVER_PORT") viper.BindEnv("server.environment", "ENVIRONMENT", "TRACE_SERVER_ENVIRONMENT") viper.BindEnv("jwt.secret", "JWT_SECRET", "TRACE_JWT_SECRET") viper.BindEnv("jwt.expire", "JWT_EXPIRE", "TRACE_JWT_EXPIRE") viper.BindEnv("database.driver", "DATABASE_DRIVER", "TRACE_DATABASE_DRIVER") viper.BindEnv("database.sqlite.path", "DATABASE_PATH", "TRACE_DATABASE_SQLITE_PATH") viper.BindEnv("database.postgres.host", "POSTGRES_HOST", "TRACE_DATABASE_POSTGRES_HOST") viper.BindEnv("database.postgres.port", "POSTGRES_PORT", "TRACE_DATABASE_POSTGRES_PORT") viper.BindEnv("database.postgres.user", "POSTGRES_USER", "TRACE_DATABASE_POSTGRES_USER") viper.BindEnv("database.postgres.password", "POSTGRES_PASSWORD", "TRACE_DATABASE_POSTGRES_PASSWORD") viper.BindEnv("database.postgres.dbname", "POSTGRES_DB", "TRACE_DATABASE_POSTGRES_DBNAME") viper.BindEnv("database.postgres.sslmode", "POSTGRES_SSLMODE", "TRACE_DATABASE_POSTGRES_SSLMODE") // 解析配置 if err := viper.Unmarshal(&appConfig); err != nil { fmt.Printf("配置解析失败: %v\n", err) } // 验证 JWT 密钥 if appConfig.JWT.Secret == "your-secret-key-here-change-in-production" { fmt.Println("警告: 使用默认 JWT 密钥,请在生产环境中设置 JWT_SECRET 环境变量") } // 调试打印 fmt.Printf("加载的配置 - 环境: %s\n", appConfig.Server.Environment) fmt.Printf("加载的配置 - 数据库驱动: %s\n", appConfig.Database.Driver) } // GetAppConfig 获取应用程序配置 func GetAppConfig() *AppConfig { return &appConfig }