package config import ( "fmt" "strings" "github.com/spf13/viper" ) const envPrefix = "JUNHONG" func Load() (*Config, error) { v := viper.New() embeddedReader, err := getEmbeddedConfig() if err != nil { return nil, fmt.Errorf("读取嵌入配置失败: %w", err) } v.SetConfigType("yaml") if err := v.ReadConfig(embeddedReader); err != nil { return nil, fmt.Errorf("解析嵌入配置失败: %w", err) } v.SetEnvPrefix(envPrefix) v.SetEnvKeyReplacer(strings.NewReplacer(".", "_")) v.AutomaticEnv() bindEnvVariables(v) cfg := &Config{} if err := v.Unmarshal(cfg); err != nil { return nil, fmt.Errorf("反序列化配置失败: %w", err) } if err := cfg.ValidateRequired(); err != nil { return nil, err } if err := cfg.Validate(); err != nil { return nil, err } globalConfig.Store(cfg) return cfg, nil } func bindEnvVariables(v *viper.Viper) { bindings := []string{ "server.address", "server.read_timeout", "server.write_timeout", "server.shutdown_timeout", "server.prefork", "database.host", "database.port", "database.user", "database.password", "database.dbname", "database.sslmode", "database.max_open_conns", "database.max_idle_conns", "database.conn_max_lifetime", "redis.address", "redis.port", "redis.password", "redis.db", "redis.pool_size", "redis.min_idle_conns", "redis.dial_timeout", "redis.read_timeout", "redis.write_timeout", "storage.provider", "storage.temp_dir", "storage.s3.endpoint", "storage.s3.region", "storage.s3.bucket", "storage.s3.access_key_id", "storage.s3.secret_access_key", "storage.s3.use_ssl", "storage.s3.path_style", "storage.presign.upload_expires", "storage.presign.download_expires", "logging.level", "logging.development", "logging.app_log.filename", "logging.app_log.max_size", "logging.app_log.max_backups", "logging.app_log.max_age", "logging.app_log.compress", "logging.access_log.filename", "logging.access_log.max_size", "logging.access_log.max_backups", "logging.access_log.max_age", "logging.access_log.compress", "queue.concurrency", "queue.retry_max", "queue.timeout", "jwt.secret_key", "jwt.token_duration", "jwt.access_token_ttl", "jwt.refresh_token_ttl", "middleware.enable_rate_limiter", "middleware.rate_limiter.max", "middleware.rate_limiter.expiration", "middleware.rate_limiter.storage", "sms.gateway_url", "sms.username", "sms.password", "sms.signature", "sms.timeout", "default_admin.username", "default_admin.password", "default_admin.phone", } for _, key := range bindings { _ = v.BindEnv(key) } }