package config import ( "fmt" "github.com/spf13/viper" ) type Config struct { App AppConfig `mapstructure:"app"` Log LogConfig `mapstructure:"log"` HTTP HTTPConfig `mapstructure:"http"` Database DatabaseConfig `mapstructure:"database"` Cache CacheConfig `mapstructure:"cache"` } type AppConfig struct { Name string `mapstructure:"name"` Env string `mapstructure:"env"` } type LogConfig struct { Level string `mapstructure:"level"` } type HTTPConfig struct { Host string `mapstructure:"host"` Port int `mapstructure:"port"` } type DatabaseConfig struct { Driver string `mapstructure:"driver"` Host string `mapstructure:"host"` Port int `mapstructure:"port"` User string `mapstructure:"user"` Name string `mapstructure:"name"` Password string `mapstructure:"password"` } type CacheConfig struct { Host string `mapstructure:"host"` Port int `mapstructure:"port"` DB int `mapstructure:"db"` Timeout int `mapstructure:"timeout"` } func Load(path string) (*Config, error) { v := viper.New() // 指定文件,按 .toml 扩展名识别格式 v.SetConfigFile(path) if err := v.ReadInConfig(); err != nil { return nil, fmt.Errorf("读取配置失败: %w", err) } v.AllowEmptyEnv(true) if err := v.BindEnv("database.password", "PG_PASSWORD"); err != nil { return nil, fmt.Errorf("绑定数据库密码环境变量失败: %w", err) } var cfg Config if err := v.Unmarshal(&cfg); err != nil { return nil, fmt.Errorf("解析配置失败: %w", err) } return &cfg, nil }