Files
ai_dianshang/server/internal/config/config.go

255 lines
9.1 KiB
Go
Raw Normal View History

2025-11-17 14:11:46 +08:00
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")
}