package config import ( "os" "path/filepath" "strconv" "strings" ) type Config struct { Port string DatabaseURL string CORSOrigins []string // 首次启动时创建的默认管理员 AdminUser string AdminPassword string // Cookie 是否要求 HTTPS(生产环境置 true) SecureCookie bool CookieName string // 附件:文件内容存盘,默认与 SQLite 同目录下的 attachments/ AttachmentDir string // 单个附件上限(字节)。默认 25MB,与常见邮箱附件限额一致 MaxAttachmentBytes int64 // MaxAppearanceBytes 是壁纸图片上限(客户端会先压到 ~2.4MB,这里是兜底)。 MaxAppearanceBytes int64 } var C *Config func Load() *Config { C = &Config{ Port: getEnv("PORT", "8180"), // 空值 = 用内置 SQLite(data/agentmail.db,可用 AGENTMAIL_DATA_DIR 改目录)。 // 想接外部库就给 postgres://…;也接受 sqlite:///path/x.db 与裸路径。 DatabaseURL: getEnv("DATABASE_URL", ""), CORSOrigins: splitEnv("CORS_ORIGINS", []string{ "http://localhost:5173", "http://127.0.0.1:5173", }), AdminUser: strings.ToLower(getEnv("ADMIN_USER", "admin")), AdminPassword: getEnv("ADMIN_PASSWORD", ""), SecureCookie: getEnvBool("SECURE_COOKIE", false), CookieName: getEnv("COOKIE_NAME", "am_session"), AttachmentDir: getEnv("AGENTMAIL_ATTACHMENT_DIR", filepath.Join(getEnv("AGENTMAIL_DATA_DIR", "data"), "attachments")), MaxAttachmentBytes: getEnvInt64("AGENTMAIL_MAX_ATTACHMENT_BYTES", 25<<20), MaxAppearanceBytes: getEnvInt64("AGENTMAIL_MAX_APPEARANCE_BYTES", 4<<20), } return C } func getEnv(key, fallback string) string { if v := os.Getenv(key); v != "" { return v } return fallback } func getEnvBool(key string, fallback bool) bool { if v := os.Getenv(key); v != "" { if b, err := strconv.ParseBool(v); err == nil { return b } } return fallback } func getEnvInt64(key string, fallback int64) int64 { if v := os.Getenv(key); v != "" { if n, err := strconv.ParseInt(v, 10, 64); err == nil && n > 0 { return n } } return fallback } func splitEnv(key string, fallback []string) []string { v := os.Getenv(key) if v == "" { return fallback } parts := strings.Split(v, ",") out := make([]string, 0, len(parts)) for _, p := range parts { if s := strings.TrimSpace(p); s != "" { out = append(out, s) } } if len(out) == 0 { return fallback } return out }