package config import ( "log/slog" "os" "sync" "time" ) type Config struct { BaseURL string Semester string TWFID string Recognizer RecognizerConfig } type RecognizerConfig struct { APIURL string APIKey string Model string Timeout time.Duration } var ( cfg *Config cfgOnce sync.Once ) func Load() *Config { cfgOnce.Do(func() { cfg = &Config{ BaseURL: getEnv("JWTS_BASE_URL", "http://jwts.hitwh.edu.cn"), Semester: getEnv("JWTS_SEMESTER", ""), TWFID: getEnv("JWTS_TWFID", ""), Recognizer: RecognizerConfig{ APIURL: getEnv("RECOGNIZER_API_URL", "https://api.littlelan.cn/v1/chat/completions"), APIKey: getEnv("RECOGNIZER_API_KEY", ""), Model: getEnv("RECOGNIZER_MODEL", "qwen3.5-plus"), Timeout: getEnvDuration("RECOGNIZER_TIMEOUT", 120*time.Second), }, } if cfg.Recognizer.APIKey == "" { slog.Warn("RECOGNIZER_API_KEY not set, image recognition will not work") } }) return cfg } func Get() *Config { if cfg == nil { return Load() } return cfg } func getEnv(key, defaultValue string) string { val := os.Getenv(key) if val == "" { return defaultValue } return val } func getEnvDuration(key string, defaultValue time.Duration) time.Duration { val := os.Getenv(key) if val == "" { return defaultValue } if d, err := time.ParseDuration(val); err == nil { return d } return defaultValue } var ( BaseURL = Get().BaseURL Semester = Get().Semester TWFID = Get().TWFID RecognizerAPIURL = Get().Recognizer.APIURL RecognizerAPIKey = Get().Recognizer.APIKey RecognizerModel = Get().Recognizer.Model )