package config import ( "fmt" "os" "strconv" "strings" "time" _ "github.com/joho/godotenv/autoload" ) var Cfg *Config // Config 结构体存储应用配置 type Config struct { // 服务器配置 Port int ReadTimeout time.Duration WriteTimeout time.Duration // PassKey配置 AppName string // 依赖方(Relying Party)显示名称 RPID string // 依赖方ID(通常为域名) RPOrigins []string // 依赖方源(URL) WebAuthnTimeout time.Duration ChallengeExpiration time.Duration // 数据库配置 DB_Type string DSN string DBMaxOpenConns int DBMaxIdleConns int // DBHost string // DBPort int // DBUser string // DBPassword string // DBName string // 缓存配置 RedisHost string RedisPort int RedisPassword string RedisDB int // 日志配置 LogLevel string LogPath string // 其他应用特定配置 AllowRegister bool UnlimitedQuota bool DefaultActive bool UsageWorker int UsageChanSize int TaskTimeInterval int } func init() { // 加载配置 cfg, err := LoadConfig() if err != nil { panic(fmt.Sprintf("加载配置失败: %v", err)) } Cfg = cfg } // LoadConfig 从环境变量加载配置 func LoadConfig() (*Config, error) { cfg := &Config{ AppName: "OpenTeam", RPID: "localhost", // 域名 RPOrigins: []string{"https://localhost:5173"}, // 默认值设置 Port: 80, ReadTimeout: 10 * time.Second, WriteTimeout: 10 * time.Second, LogLevel: "info", LogPath: "./logs/", DB_Type: "sqlite", DSN: "", DBMaxOpenConns: 10, DBMaxIdleConns: 5, RedisDB: 0, // 系统设置 AllowRegister: false, UnlimitedQuota: true, DefaultActive: true, UsageWorker: 1, UsageChanSize: 1000, TaskTimeInterval: 60, } // PassKey配置 if appName := os.Getenv("APP_NAME"); appName != "" { cfg.AppName = appName } if domain := os.Getenv("RPID"); domain != "" { cfg.RPID = domain } if origin := os.Getenv("RPORIGINS"); origin != "" { var rpos []string list := strings.Split(origin, ",") for _, l := range list { trimmedl := strings.TrimSpace(l) if trimmedl != "" { rpos = append(rpos, trimmedl) } } cfg.RPOrigins = rpos } // 服务器配置 if port := os.Getenv("PORT"); port != "" { if p, err := strconv.Atoi(port); err == nil { cfg.Port = p } else { return nil, fmt.Errorf("PORT: %s", port) } } if timeout := os.Getenv("READ_TIMEOUT"); timeout != "" { if t, err := strconv.Atoi(timeout); err == nil { cfg.ReadTimeout = time.Duration(t) * time.Second } else { return nil, fmt.Errorf("无效的READ_TIMEOUT: %s", timeout) } } if timeout := os.Getenv("WRITE_TIMEOUT"); timeout != "" { if t, err := strconv.Atoi(timeout); err == nil { cfg.WriteTimeout = time.Duration(t) * time.Second } else { return nil, fmt.Errorf("无效的WRITE_TIMEOUT: %s", timeout) } } // 数据库配置 if dbType := os.Getenv("DB_TYPE"); dbType != "" { cfg.DB_Type = dbType } else { cfg.DB_Type = "sqlite" } if dsn := os.Getenv("DB_DSN"); dsn != "" { cfg.DSN = dsn } if conns := os.Getenv("DB_MAX_OPEN_CONNS"); conns != "" { if c, err := strconv.Atoi(conns); err == nil { cfg.DBMaxOpenConns = c } else { return nil, fmt.Errorf("无效的DB_MAX_OPEN_CONNS: %s", conns) } } if conns := os.Getenv("DB_MAX_IDLE_CONNS"); conns != "" { if c, err := strconv.Atoi(conns); err == nil { cfg.DBMaxIdleConns = c } else { return nil, fmt.Errorf("无效的DB_MAX_IDLE_CONNS: %s", conns) } } // Redis配置 if host := os.Getenv("REDIS_HOST"); host != "" { cfg.RedisHost = host } if port := os.Getenv("REDIS_PORT"); port != "" { if p, err := strconv.Atoi(port); err == nil { cfg.RedisPort = p } else { return nil, fmt.Errorf("无效的REDIS_PORT: %s", port) } } if password := os.Getenv("REDIS_PASSWORD"); password != "" { cfg.RedisPassword = password } if db := os.Getenv("REDIS_DB"); db != "" { if d, err := strconv.Atoi(db); err == nil { cfg.RedisDB = d } else { return nil, fmt.Errorf("无效的REDIS_DB: %s", db) } } // 日志配置 if level := os.Getenv("LOG_LEVEL"); level != "" { cfg.LogLevel = level } if path := os.Getenv("LOG_PATH"); path != "" { cfg.LogPath = path } // 功能标志 if allowRegister := os.Getenv("ALLOW_REGISTER"); allowRegister != "" { if b, err := strconv.ParseBool(allowRegister); err == nil { cfg.AllowRegister = b } } if unlimitedQuota := os.Getenv("UNLIMITED_QUOTA"); unlimitedQuota != "" { if b, err := strconv.ParseBool(unlimitedQuota); err == nil { cfg.UnlimitedQuota = b } } if defaultActive := os.Getenv("DEFAULT_ACTIVE"); defaultActive != "" { if b, err := strconv.ParseBool(defaultActive); err == nil { cfg.DefaultActive = b } } if worker := os.Getenv("USAGE_WORKER"); worker != "" { if w, err := strconv.Atoi(worker); err == nil { cfg.UsageWorker = w } } if size := os.Getenv("USAGE_CHAN_SIZE"); size != "" { if s, err := strconv.Atoi(size); err == nil { cfg.UsageChanSize = s } } if interval := os.Getenv("TASK_TIME_INTERVAL"); interval != "" { if i, err := strconv.Atoi(interval); err == nil { cfg.TaskTimeInterval = i } } return cfg, nil }