Files
Airwallex/config/config.go
zqq61 faba565c66 feat: Go 重写后端,替换 Python FastAPI
用 Go (Gin + GORM + SQLite) 重写整个后端:
- 单二进制部署,不依赖 Python/pip/SDK
- net/http 原生客户端,无 Cloudflare TLS 指纹问题
- 多阶段 Dockerfile:Node 构建前端 + Go 构建后端 + Alpine 运行
- 内存占用从 ~95MB 降至 ~3MB
- 完整保留所有 API 路由、JWT 认证、API Key 权限、审计日志
2026-03-16 02:11:48 +08:00

75 lines
1.6 KiB
Go

package config
import (
"crypto/rand"
"encoding/hex"
"log"
"os"
"strconv"
"github.com/joho/godotenv"
)
type Config struct {
AdminUsername string
AdminPassword string
SecretKey string
JWTExpireMinutes int
DatabaseURL string
Port string
}
var Cfg Config
func Load() {
// Load .env file from multiple locations (ignore errors if not found)
_ = godotenv.Load()
_ = godotenv.Load("backend/.env")
dbURL := getEnv("DATABASE_URL", "data/airwallex.db")
// Strip sqlite:/// prefix if present (Python SQLAlchemy format)
for _, prefix := range []string{"sqlite:///./", "sqlite:///", "sqlite://"} {
if len(dbURL) > len(prefix) && dbURL[:len(prefix)] == prefix {
dbURL = dbURL[len(prefix):]
break
}
}
Cfg = Config{
AdminUsername: getEnv("ADMIN_USERNAME", "admin"),
AdminPassword: getEnv("ADMIN_PASSWORD", "admin123"),
SecretKey: getEnv("SECRET_KEY", generateRandomKey(32)),
JWTExpireMinutes: getEnvInt("JWT_EXPIRE_MINUTES", 480),
DatabaseURL: dbURL,
Port: getEnv("PORT", "8000"),
}
}
func getEnv(key, fallback string) string {
if val, ok := os.LookupEnv(key); ok {
return val
}
return fallback
}
func getEnvInt(key string, fallback int) int {
val, ok := os.LookupEnv(key)
if !ok {
return fallback
}
n, err := strconv.Atoi(val)
if err != nil {
log.Printf("warning: invalid integer for %s: %s, using default %d", key, val, fallback)
return fallback
}
return n
}
func generateRandomKey(length int) string {
b := make([]byte, length)
if _, err := rand.Read(b); err != nil {
log.Fatalf("failed to generate random key: %v", err)
}
return hex.EncodeToString(b)
}