package config import ( "log" "os" "strings" "github.com/spf13/viper" ) // Config 应用配置结构 type Config struct { Server ServerConfig `mapstructure:"server"` Database DatabaseConfig `mapstructure:"database"` Redis RedisConfig `mapstructure:"redis"` JWT JWTConfig `mapstructure:"jwt"` Log LogConfig `mapstructure:"log"` WeChat WeChatConfig `mapstructure:"wechat"` WeChatPay WeChatPayConfig `mapstructure:"wechatPay"` Upload UploadConfig `mapstructure:"upload"` } // ServerConfig 服务器配置 type ServerConfig struct { Port int `mapstructure:"port"` Mode string `mapstructure:"mode"` } // DatabaseConfig 数据库配置 type DatabaseConfig struct { Driver string `mapstructure:"driver"` Host string `mapstructure:"host"` Port int `mapstructure:"port"` Username string `mapstructure:"username"` Password string `mapstructure:"password"` DBName string `mapstructure:"dbname"` Charset string `mapstructure:"charset"` ParseTime bool `mapstructure:"parseTime"` Loc string `mapstructure:"loc"` AutoMigrate bool `mapstructure:"autoMigrate"` // 是否自动迁移数据库表 LogLevel string `mapstructure:"logLevel"` // GORM日志级别:silent, error, warn, info } // RedisConfig Redis配置 type RedisConfig struct { Host string `mapstructure:"host"` Port int `mapstructure:"port"` Password string `mapstructure:"password"` DB int `mapstructure:"db"` } // JWTConfig JWT配置 type JWTConfig struct { Secret string `mapstructure:"secret"` Expire int `mapstructure:"expire"` } // LogConfig 日志配置 type LogConfig struct { Level string `mapstructure:"level"` Filename string `mapstructure:"filename"` MaxSize int `mapstructure:"maxSize"` MaxAge int `mapstructure:"maxAge"` MaxBackups int `mapstructure:"maxBackups"` EnableConsole bool `mapstructure:"enableConsole"` // 是否启用控制台输出 EnableFile bool `mapstructure:"enableFile"` // 是否启用文件输出 Format string `mapstructure:"format"` // 日志格式:json 或 text EnableCaller bool `mapstructure:"enableCaller"` // 是否显示调用者信息 EnableOperation bool `mapstructure:"enableOperation"` // 是否启用操作日志 EnablePerf bool `mapstructure:"enablePerf"` // 是否启用性能日志 PerfThreshold int64 `mapstructure:"perfThreshold"` // 性能日志阈值(毫秒) } // WeChatConfig 微信配置 type WeChatConfig struct { AppID string `mapstructure:"appId"` AppSecret string `mapstructure:"appSecret"` } // WeChatPayConfig 微信支付配置 type WeChatPayConfig struct { AppID string `mapstructure:"appId"` // 小程序APPID MchID string `mapstructure:"mchId"` // 商户号 APIv3Key string `mapstructure:"apiV3Key"` // APIv3密钥 CertPath string `mapstructure:"certPath"` // 商户证书路径 KeyPath string `mapstructure:"keyPath"` // 商户私钥路径 SerialNo string `mapstructure:"serialNo"` // 证书序列号 NotifyURL string `mapstructure:"notifyUrl"` // 支付回调地址 RefundNotifyURL string `mapstructure:"refundNotifyUrl"` // 退款回调地址 Environment string `mapstructure:"environment"` // 环境:sandbox 或 production } // UploadConfig 文件上传配置 type UploadConfig struct { MaxImageSize int64 `mapstructure:"maxImageSize"` // 图片最大大小(字节) MaxFileSize int64 `mapstructure:"maxFileSize"` // 文件最大大小(字节) ImageTypes []string `mapstructure:"imageTypes"` // 允许的图片类型 StaticPath string `mapstructure:"staticPath"` // 静态文件路径(本地存储) BaseURL string `mapstructure:"baseUrl"` // 静态文件访问基础URL(本地存储) StorageType string `mapstructure:"storageType"` // 存储类型:local(本地) 或 oss(阿里云OSS) OSS OSSConfig `mapstructure:"oss"` // OSS配置 } // OSSConfig 阿里云OSS配置 type OSSConfig struct { Endpoint string `mapstructure:"endpoint"` // OSS访问域名 AccessKeyID string `mapstructure:"accessKeyId"` // AccessKey ID AccessKeySecret string `mapstructure:"accessKeySecret"` // AccessKey Secret BucketName string `mapstructure:"bucketName"` // Bucket名称 BasePath string `mapstructure:"basePath"` // 文件存储基础路径 Domain string `mapstructure:"domain"` // 自定义域名(可选) } // Load 加载配置 func Load() *Config { // 获取环境变量,默认为development env := getEnvironment() // 根据环境选择配置文件 configName := getConfigName(env) viper.SetConfigName(configName) viper.SetConfigType("yaml") viper.AddConfigPath("./configs") viper.AddConfigPath("../configs") viper.AddConfigPath("../../configs") // 设置默认值 setDefaults() // 启用环境变量支持 viper.AutomaticEnv() viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_")) if err := viper.ReadInConfig(); err != nil { log.Printf("配置文件读取失败: %v, 使用默认配置", err) } else { log.Printf("成功加载配置文件: %s (环境: %s)", viper.ConfigFileUsed(), env) } var config Config if err := viper.Unmarshal(&config); err != nil { log.Fatalf("配置解析失败: %v", err) } // 显示配置信息 logConfigInfo(&config, env) return &config } // logConfigInfo 记录配置信息 func logConfigInfo(config *Config, env string) { log.Printf("=== 配置信息 ===") log.Printf("环境: %s", env) log.Printf("服务器端口: %d", config.Server.Port) log.Printf("服务器模式: %s", config.Server.Mode) log.Printf("数据库: %s@%s:%d/%s", config.Database.Username, config.Database.Host, config.Database.Port, config.Database.DBName) log.Printf("数据库自动迁移: %t", config.Database.AutoMigrate) log.Printf("Redis: %s:%d (DB:%d)", config.Redis.Host, config.Redis.Port, config.Redis.DB) log.Printf("日志级别: %s", config.Log.Level) log.Printf("微信AppID: %s", config.WeChat.AppID) log.Printf("===============") } // getEnvironment 获取当前环境 func getEnvironment() string { env := os.Getenv("GO_ENV") if env == "" { env = os.Getenv("APP_ENV") } if env == "" { env = os.Getenv("ENVIRONMENT") } if env == "" { env = "development" // 默认环境 } return strings.ToLower(env) } // getConfigName 根据环境获取配置文件名 func getConfigName(env string) string { switch env { case "development", "dev": return "config.dev" case "test", "testing": return "config.test" case "production", "prod": return "config.prod" // 生产环境 - 中国区 case "prod-cn", "production-cn": return "config.prod-cn" // 生产环境 - 美国区 case "prod-us", "production-us": return "config.prod-us" // 生产环境 - 欧洲区 case "prod-eu", "production-eu": return "config.prod-eu" default: // 如果环境不匹配,尝试使用默认配置文件 if _, err := os.Stat("./configs/config.yaml"); err == nil { return "config" } // 如果默认配置文件不存在,使用开发环境配置 log.Printf("未知环境 '%s',使用开发环境配置", env) return "config.dev" } } // setDefaults 设置默认配置 func setDefaults() { // 服务器默认配置 viper.SetDefault("server.port", 8080) viper.SetDefault("server.mode", "debug") // 数据库默认配置 viper.SetDefault("database.driver", "mysql") viper.SetDefault("database.host", "localhost") viper.SetDefault("database.port", 3306) viper.SetDefault("database.username", "root") viper.SetDefault("database.password", "") viper.SetDefault("database.dbname", "dianshang") viper.SetDefault("database.charset", "utf8mb4") viper.SetDefault("database.parseTime", true) viper.SetDefault("database.loc", "Local") viper.SetDefault("database.autoMigrate", true) // 默认启用自动迁移 viper.SetDefault("database.logLevel", "warn") // 默认warn级别 // Redis默认配置 viper.SetDefault("redis.host", "localhost") viper.SetDefault("redis.port", 6379) viper.SetDefault("redis.password", "") viper.SetDefault("redis.db", 0) // JWT默认配置 viper.SetDefault("jwt.secret", "your-secret-key") viper.SetDefault("jwt.expire", 7200) // 日志默认配置 viper.SetDefault("log.level", "info") viper.SetDefault("log.filename", "logs/app.log") viper.SetDefault("log.maxSize", 100) viper.SetDefault("log.maxAge", 30) viper.SetDefault("log.maxBackups", 5) viper.SetDefault("log.enableConsole", true) viper.SetDefault("log.enableFile", true) // 文件上传默认配置 viper.SetDefault("upload.maxImageSize", 5*1024*1024) // 5MB viper.SetDefault("upload.maxFileSize", 10*1024*1024) // 10MB viper.SetDefault("upload.imageTypes", []string{".jpg", ".jpeg", ".png", ".gif", ".webp", ".svg"}) viper.SetDefault("upload.staticPath", "./static") viper.SetDefault("upload.baseUrl", "http://localhost:8080") viper.SetDefault("upload.storageType", "local") // 默认使用本地存储 viper.SetDefault("log.format", "json") viper.SetDefault("log.enableCaller", true) viper.SetDefault("log.enableOperation", true) viper.SetDefault("log.enablePerf", true) viper.SetDefault("log.perfThreshold", 1000) // 1秒 // 微信默认配置 viper.SetDefault("wechat.appId", "wx430b70d696b4dbd7") viper.SetDefault("wechat.appSecret", "your-wechat-app-secret") }