// Package config 负责加载和管理应用配置 // 使用 viper 从 YAML 配置文件中读取配置项 package config import ( "fmt" "log" "github.com/spf13/viper" ) // AppConfig 全局配置实例 var AppConfig *Config // Config 应用配置结构体 type Config struct { Server ServerConfig `mapstructure:"server"` Database DatabaseConfig `mapstructure:"database"` JWT JWTConfig `mapstructure:"jwt"` Storage StorageConfig `mapstructure:"storage"` Backup BackupConfig `mapstructure:"backup"` } // BackupConfig 备份工具配置 type BackupConfig struct { // MySQL MysqlDumpPath string `mapstructure:"mysqldump_path"` MysqlPath string `mapstructure:"mysql_path"` // PostgreSQL PgDumpPath string `mapstructure:"pgdump_path"` PsqlPath string `mapstructure:"psql_path"` // SQL Server SqlCmdPath string `mapstructure:"sqlcmd_path"` } // ServerConfig 服务器配置 type ServerConfig struct { Port int `mapstructure:"port"` Mode string `mapstructure:"mode"` // debug / release PublicURL string `mapstructure:"public_url"` // 公网访问地址, 如 http://files.example.com } // DatabaseConfig 数据库配置 type DatabaseConfig struct { Type string `mapstructure:"type"` // 数据库类型: mysql / sqlserver / postgres Host string `mapstructure:"host"` Port int `mapstructure:"port"` Username string `mapstructure:"username"` Password string `mapstructure:"password"` DBName string `mapstructure:"dbname"` } // DSN 返回数据库连接字符串(根据类型生成不同格式) func (d *DatabaseConfig) DSN() string { switch d.Type { case "sqlserver": // SQL Server: sqlserver://user:pass@host:port?database=db名 return fmt.Sprintf("sqlserver://%s:%s@%s:%d?database=%s", d.Username, d.Password, d.Host, d.Port, d.DBName) case "postgres": // PostgreSQL: host=localhost port=5432 user=x password=x dbname=x sslmode=disable return fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s sslmode=disable TimeZone=Asia/Shanghai", d.Host, d.Port, d.Username, d.Password, d.DBName) default: // MySQL: user:pass@tcp(host:port)/dbname?charset=utf8mb4&parseTime=True&loc=Local return fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8mb4&parseTime=True&loc=Local", d.Username, d.Password, d.Host, d.Port, d.DBName) } } // JWTConfig JWT配置 type JWTConfig struct { Secret string `mapstructure:"secret"` Expiration int `mapstructure:"expiration"` // 过期时间(小时) } // StorageConfig 存储配置 type StorageConfig struct { DefaultPolicyID uint `mapstructure:"default_policy_id"` LocalBasePath string `mapstructure:"local_base_path"` CDNHost string `mapstructure:"cdn_host"` // CDN地址, 如 http://localhost:3090 CDNPathPrefix string `mapstructure:"cdn_path_prefix"` // CDN路径前缀, 如 /public } // Load 加载配置文件 // 配置文件搜索路径: ./config.yaml, ./config/config.yaml // 支持环境变量覆盖: SERVER_PORT, SERVER_MODE, DB_HOST, DB_PORT, DB_PASSWORD, DB_NAME 等 func Load() (*Config, error) { viper.SetConfigName("config") viper.SetConfigType("yaml") viper.AddConfigPath(".") viper.AddConfigPath("./config") viper.AddConfigPath("./server") // 设置默认值 setDefaults() // 读取配置文件 if err := viper.ReadInConfig(); err != nil { if _, ok := err.(viper.ConfigFileNotFoundError); !ok { return nil, fmt.Errorf("读取配置文件失败: %w", err) } log.Println("未找到配置文件, 使用默认配置") } // 支持环境变量覆盖(优先级: 环境变量 > 配置文件 > 默认值) viper.SetEnvPrefix("FS") viper.AutomaticEnv() // 环境变量映射 viper.BindEnv("server.port", "FS_SERVER_PORT") viper.BindEnv("server.mode", "FS_SERVER_MODE") viper.BindEnv("server.public_url", "FS_PUBLIC_URL") viper.BindEnv("database.type", "FS_DB_TYPE") viper.BindEnv("database.host", "FS_DB_HOST") viper.BindEnv("database.port", "FS_DB_PORT") viper.BindEnv("database.username", "FS_DB_USER") viper.BindEnv("database.password", "FS_DB_PASSWORD") viper.BindEnv("database.dbname", "FS_DB_NAME") viper.BindEnv("jwt.secret", "FS_JWT_SECRET") AppConfig = &Config{} if err := viper.Unmarshal(AppConfig); err != nil { return nil, fmt.Errorf("解析配置失败: %w", err) } return AppConfig, nil } // setDefaults 设置配置默认值 func setDefaults() { // 服务器默认配置 viper.SetDefault("server.port", 8080) viper.SetDefault("server.mode", "debug") // 数据库默认配置 viper.SetDefault("database.type", "mysql") viper.SetDefault("database.host", "127.0.0.1") viper.SetDefault("database.port", 3306) viper.SetDefault("database.username", "root") viper.SetDefault("database.password", "root") viper.SetDefault("database.dbname", "seeyon_fs") // JWT默认配置 viper.SetDefault("jwt.secret", "seeyon-filesystem-jwt-secret-key-2024") viper.SetDefault("jwt.expiration", 24) // 存储默认配置 viper.SetDefault("storage.default_policy_id", 1) viper.SetDefault("storage.local_base_path", "./data/storage") viper.SetDefault("storage.cdn_host", "") viper.SetDefault("storage.cdn_path_prefix", "/public") }