package config import ( "fmt" "github.com/spf13/viper" ) // Config 描述 config.yaml 中使用到的应用配置。 // // Database 保存 MySQL 连接参数,Server 保存 HTTP 服务参数。结构体字段名需要与配置文件 // 中的层级保持一致,Viper 会在 InitConfig 中把 YAML 内容反序列化到该结构体。 type Config struct { // Database 是 MySQL 连接配置。 Database struct { User string // 数据库用户名。 Password string // 数据库密码。 Host string // 数据库主机地址。 Port int // 数据库端口。 Dbname string // 数据库名称。 Charset string // 连接字符集,例如 utf8mb4。 Collation string // 排序规则;为空时 GetDSN 会使用 utf8mb4_unicode_ci。 } // Server 是 HTTP 服务配置。 Server struct { Port int // 服务监听端口。 } } // AppConfig 保存进程级全局配置。调用 InitConfig 后才可安全读取。 var AppConfig *Config // InitConfig 从当前目录或 ./config 目录读取 config.yaml,并解析到 AppConfig。 // // 这里使用 panic 暴露配置错误,因为配置缺失或格式错误会导致服务无法正确启动。 func InitConfig() { viper.SetConfigName("config") viper.SetConfigType("yaml") viper.AddConfigPath(".") // 在当前目录查找 config.yaml viper.AddConfigPath("./config") // 兼容多一层目录的情况 if err := viper.ReadInConfig(); err != nil { panic(fmt.Errorf("无法读取配置文件: %w", err)) } if err := viper.Unmarshal(&AppConfig); err != nil { panic(fmt.Errorf("无法解析配置结构体: %w", err)) } } // GetDSN 根据 AppConfig 生成 GORM/MySQL 使用的 DSN 连接字符串。 func GetDSN() string { db := AppConfig.Database collation := db.Collation if collation == "" { collation = "utf8mb4_unicode_ci" } return fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=%s&collation=%s&parseTime=True&loc=Local", db.User, db.Password, db.Host, db.Port, db.Dbname, db.Charset, collation) } // GetServerPort 返回 Gin Run 所需的端口格式,例如 ":8080"。 func GetServerPort() string { return fmt.Sprintf(":%d", AppConfig.Server.Port) }