// =========================================== // 多班级版班级管理系统 - Go 后端 // // 开发者: Canglan // 联系方式: admin@sea-studio.top // 版权归属: Sea Network Technology Studio // 许可证: Apache License 2.0 // // 版权所有 © Sea Network Technology Studio // =========================================== package config import ( "fmt" "os" "strconv" "strings" "github.com/joho/godotenv" ) // Config 应用全局配置结构体 type Config struct { // 应用基础配置 AppName string AppEnv string Debug bool AppPort string // MySQL 数据库配置 DBHost string DBPort int DBUser string DBPassword string DBName string DBMaxOpenConns int DBMaxIdleConns int DBConnMaxLife int // 秒 // Redis 配置 RedisHost string RedisPort int RedisPassword string RedisDB int RedisMaxConns int // JWT 配置 JWTSecretKey string JWTAlgorithm string JWTExpireMinutes int JWTIdleTimeoutMinutes int // 系统管理员配置 SuperAdminLoginPath string SuperAdminDefaultUser string SuperAdminDefaultPass string // 日志 LogLevel string LogFile string } // AppConfig 全局配置实例 var AppConfig *Config // Load 加载配置:先尝试加载 .env 文件,然后读取环境变量 func Load() (*Config, error) { // 尝试加载 .env 文件(不存在不报错) _ = godotenv.Load() cfg := &Config{ AppName: getEnv("APP_NAME", "多班级版班级管理系统"), AppEnv: getEnv("APP_ENV", "production"), Debug: getEnvBool("DEBUG", false), AppPort: getEnv("APP_PORT", "56789"), DBHost: getEnv("DB_HOST", "localhost"), DBPort: getEnvInt("DB_PORT", 3306), DBUser: getEnv("DB_USER", "class_admin"), DBPassword: getEnv("DB_PASSWORD", ""), DBName: getEnv("DB_NAME", "classmanagerdb"), DBMaxOpenConns: getEnvInt("DB_MAX_OPEN_CONNS", 25), DBMaxIdleConns: getEnvInt("DB_MAX_IDLE_CONNS", 10), DBConnMaxLife: getEnvInt("DB_CONN_MAX_LIFETIME", 300), RedisHost: getEnv("REDIS_HOST", "localhost"), RedisPort: getEnvInt("REDIS_PORT", 6379), RedisPassword: getEnv("REDIS_PASSWORD", ""), RedisDB: getEnvInt("REDIS_DB", 0), RedisMaxConns: getEnvInt("REDIS_MAX_CONNECTIONS", 500), JWTSecretKey: getEnv("JWT_SECRET_KEY", ""), JWTAlgorithm: getEnv("JWT_ALGORITHM", "HS256"), JWTExpireMinutes: getEnvInt("JWT_EXPIRE_MINUTES", 60), JWTIdleTimeoutMinutes: getEnvInt("JWT_IDLE_TIMEOUT_MINUTES", 10), SuperAdminLoginPath: getEnv("SUPER_ADMIN_LOGIN_PATH", "/super-admin"), SuperAdminDefaultUser: getEnv("SUPER_ADMIN_DEFAULT_USERNAME", "admin"), // 安全警告:默认密码仅用于首次部署初始化,上线前必须在 .env 中修改 SUPER_ADMIN_DEFAULT_PASSWORD。 // EnsureDefaultAdmin 通过 need_change_password=1 强制首次登录改密作为缓解措施。 SuperAdminDefaultPass: getEnv("SUPER_ADMIN_DEFAULT_PASSWORD", "Admin123"), LogLevel: getEnv("LOG_LEVEL", "info"), LogFile: getEnv("LOG_FILE", "logs/app.log"), } // 校验必填项 // 校验必填项 if cfg.JWTSecretKey == "" { return nil, fmt.Errorf("配置 JWT_SECRET_KEY 不能为空") } AppConfig = cfg return cfg, nil } // DSN 返回 MySQL 连接字符串 func (c *Config) DSN() string { return fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8mb4&parseTime=True&loc=Local", c.DBUser, c.DBPassword, c.DBHost, c.DBPort, c.DBName) } // RedisAddr 返回 Redis 地址 func (c *Config) RedisAddr() string { return fmt.Sprintf("%s:%d", c.RedisHost, c.RedisPort) } // IsProduction 判断是否为生产环境 func (c *Config) IsProduction() bool { return c.AppEnv == "production" } // --- 辅助函数 --- func getEnv(key, fallback string) string { if val, ok := os.LookupEnv(key); ok { return val } return fallback } func getEnvInt(key string, fallback int) int { if val, ok := os.LookupEnv(key); ok { if i, err := strconv.Atoi(val); err == nil { return i } } return fallback } func getEnvBool(key string, fallback bool) bool { if val, ok := os.LookupEnv(key); ok { return strings.ToLower(val) == "true" } return fallback }