255 lines
9.1 KiB
Go
255 lines
9.1 KiB
Go
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"
|
||
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")
|
||
} |