Files

222 lines
6.0 KiB
Go

package config
import (
"os"
"strconv"
"time"
)
// Config holds all configuration for the application
type Config struct {
// Server configuration
ServerPort string
Environment string
// MySQL Database configuration
DBHost string
DBPort string
DBUser string
DBPassword string
DBName string
DBCharset string
// Data directory
DataDir string
// Redis configuration
RedisAddr string
RedisPassword string
RedisDB int
// YunAPI configuration (exchange rates)
YunAPIURL string
YunAPIKey string
SyncInterval time.Duration
CacheExpiration time.Duration
MaxRetries int
// JWT configuration
JWTSecret string
JWTAccessExpiry time.Duration
JWTRefreshExpiry time.Duration
// GitHub OAuth configuration
GitHubClientID string
GitHubClientSecret string
GitHubRedirectURL string
FrontendURL string
// Gitee OAuth configuration
GiteeClientID string
GiteeClientSecret string
GiteeRedirectURL string
// AI configuration (OpenAI compatible)
OpenAIAPIKey string
OpenAIBaseURL string
WhisperModel string
ChatModel string
AISessionTimeout time.Duration
// Image upload configuration
ImageUploadDir string
MaxImageSize int64
AllowedImageTypes string
MaxImagesPerTx int
// Task Queue configuration
MQWorkerCount int
MQPollInterval time.Duration
// Aliyun SMS configuration
AliyunAccessKeyID string
AliyunAccessKeySecret string
AliyunSignName string
AliyunTemplateCode string
// SMTP Configuration (Email)
SMTPHost string
SMTPPort int
SMTPUser string
SMTPPassword string
SMTPFrom string
}
// Load loads configuration from environment variables
func Load() *Config {
cfg := &Config{
// Server
ServerPort: getEnv("SERVER_PORT", "2612"),
Environment: getEnv("ENVIRONMENT", "development"),
// Data directory
DataDir: getEnv("DATA_DIR", "./data"),
// MySQL Database
DBHost: getEnv("DB_HOST", ""),
DBPort: getEnv("DB_PORT", "3306"),
DBUser: getEnv("DB_USER", ""),
DBPassword: getEnv("DB_PASSWORD", ""),
DBName: getEnv("DB_NAME", ""),
DBCharset: getEnv("DB_CHARSET", "utf8mb4"),
// Redis
RedisAddr: getEnv("REDIS_ADDR", ""),
RedisPassword: getEnv("REDIS_PASSWORD", ""),
RedisDB: getEnvInt("REDIS_DB", 0),
// YunAPI (exchange rates)
YunAPIURL: getEnv("YUNAPI_URL", ""),
YunAPIKey: getEnv("YUNAPI_KEY", ""),
SyncInterval: getEnvDuration("SYNC_INTERVAL", 10*time.Minute),
CacheExpiration: getEnvDuration("CACHE_EXPIRATION", 10*time.Minute),
MaxRetries: getEnvInt("MAX_RETRIES", 3),
// JWT
JWTSecret: getEnv("JWT_SECRET", ""),
JWTAccessExpiry: getEnvDuration("JWT_ACCESS_EXPIRY", 15*time.Minute),
JWTRefreshExpiry: getEnvDuration("JWT_REFRESH_EXPIRY", 168*time.Hour), // 7 days
// GitHub OAuth
GitHubClientID: getEnv("GITHUB_CLIENT_ID", ""),
GitHubClientSecret: getEnv("GITHUB_CLIENT_SECRET", ""),
GitHubRedirectURL: getEnv("GITHUB_REDIRECT_URL", ""),
FrontendURL: getEnv("FRONTEND_URL", "http://localhost:2613"),
// Gitee OAuth
GiteeClientID: getEnv("GITEE_CLIENT_ID", ""),
GiteeClientSecret: getEnv("GITEE_CLIENT_SECRET", ""),
GiteeRedirectURL: getEnv("GITEE_REDIRECT_URL", ""),
// AI (OpenAI compatible)
OpenAIAPIKey: getEnv("OPENAI_API_KEY", ""),
OpenAIBaseURL: getEnv("OPENAI_BASE_URL", ""),
WhisperModel: getEnv("WHISPER_MODEL", "whisper-1"),
ChatModel: getEnv("CHAT_MODEL", "gpt-3.5-turbo"),
AISessionTimeout: getEnvDuration("AI_SESSION_TIMEOUT", 30*time.Minute),
// Image upload
ImageUploadDir: getEnv("IMAGE_UPLOAD_DIR", "./uploads/images"),
MaxImageSize: getEnvInt64("MAX_IMAGE_SIZE", 10*1024*1024), // 10MB
AllowedImageTypes: getEnv("ALLOWED_IMAGE_TYPES", "image/jpeg,image/png,image/heic"),
MaxImagesPerTx: getEnvInt("MAX_IMAGES_PER_TX", 9),
// Task Queue
MQWorkerCount: getEnvInt("MQ_WORKER_COUNT", 2),
MQPollInterval: getEnvDuration("MQ_POLL_INTERVAL", 5*time.Second),
// Aliyun SMS
AliyunAccessKeyID: getEnv("ALIYUN_ACCESS_KEY_ID", ""),
AliyunAccessKeySecret: getEnv("ALIYUN_ACCESS_KEY_SECRET", ""),
AliyunSignName: getEnv("ALIYUN_SIGN_NAME", ""),
AliyunTemplateCode: getEnv("ALIYUN_TEMPLATE_CODE", ""),
// SMTP
SMTPHost: getEnv("SMTP_HOST", ""),
SMTPPort: getEnvInt("SMTP_PORT", 587),
SMTPUser: getEnv("SMTP_USER", ""),
SMTPPassword: getEnv("SMTP_PASSWORD", ""),
SMTPFrom: getEnv("SMTP_FROM", ""),
}
// Ensure data directory exists
if cfg.DataDir != "" {
_ = os.MkdirAll(cfg.DataDir, 0755)
}
// Ensure image upload directory exists
if cfg.ImageUploadDir != "" {
_ = os.MkdirAll(cfg.ImageUploadDir, 0755)
}
return cfg
}
// IsDevelopment returns true if running in development mode
func (c *Config) IsDevelopment() bool {
return c.Environment == "development"
}
// IsProduction returns true if running in production mode
func (c *Config) IsProduction() bool {
return c.Environment == "production"
}
// getEnv gets an environment variable or returns a default value
func getEnv(key, defaultValue string) string {
if value := os.Getenv(key); value != "" {
return value
}
return defaultValue
}
// getEnvInt gets an environment variable as int or returns a default value
func getEnvInt(key string, defaultValue int) int {
if value := os.Getenv(key); value != "" {
if intValue, err := strconv.Atoi(value); err == nil {
return intValue
}
}
return defaultValue
}
// getEnvInt64 gets an environment variable as int64 or returns a default value
func getEnvInt64(key string, defaultValue int64) int64 {
if value := os.Getenv(key); value != "" {
if intValue, err := strconv.ParseInt(value, 10, 64); err == nil {
return intValue
}
}
return defaultValue
}
// getEnvDuration gets an environment variable as duration or returns a default value
func getEnvDuration(key string, defaultValue time.Duration) time.Duration {
if value := os.Getenv(key); value != "" {
if duration, err := time.ParseDuration(value); err == nil {
return duration
}
}
return defaultValue
}