- 在管理面板中集成网络代理配置显示和平台代理设置 - 添加钱包摘要和交易列表API接口及数据管理 - 实现SSE流式响应中的错误处理机制 - 添加全局HTTP代理环境变量配置支持 - 更新平台表单以支持代理模式选择和自定义代理地址 - 集成钱包交易查询过滤和分页功能 - 优化API错误详情解析和显示格式
140 lines
3.9 KiB
Go
140 lines
3.9 KiB
Go
package config
|
|
|
|
import (
|
|
"log/slog"
|
|
"net/url"
|
|
"os"
|
|
"strings"
|
|
)
|
|
|
|
type Config struct {
|
|
AppEnv string
|
|
HTTPAddr string
|
|
DatabaseURL string
|
|
IdentityMode string
|
|
JWTSecret string
|
|
ServerMainBaseURL string
|
|
ServerMainInternalToken string
|
|
TaskProgressCallbackEnabled bool
|
|
TaskProgressCallbackURL string
|
|
TaskProgressCallbackTimeoutMS string
|
|
TaskProgressCallbackMaxAttempts string
|
|
CORSAllowedOrigin string
|
|
GlobalHTTPProxy string
|
|
GlobalHTTPProxySource string
|
|
LogLevel slog.Level
|
|
}
|
|
|
|
func Load() Config {
|
|
globalProxy := LoadGlobalHTTPProxyStatus()
|
|
return Config{
|
|
AppEnv: env("APP_ENV", "development"),
|
|
HTTPAddr: env("HTTP_ADDR", ":8088"),
|
|
DatabaseURL: gatewayDatabaseURL(),
|
|
IdentityMode: env("IDENTITY_MODE", "hybrid"),
|
|
JWTSecret: env("CONFIG_JWT_SECRET", "this is a very secret secret"),
|
|
ServerMainBaseURL: strings.TrimRight(
|
|
env("SERVER_MAIN_BASE_URL", "http://localhost:3000"),
|
|
"/",
|
|
),
|
|
ServerMainInternalToken: env("SERVER_MAIN_INTERNAL_TOKEN", ""),
|
|
TaskProgressCallbackEnabled: env("TASK_PROGRESS_CALLBACK_ENABLED", "true") == "true",
|
|
TaskProgressCallbackURL: env("TASK_PROGRESS_CALLBACK_URL",
|
|
strings.TrimRight(env("SERVER_MAIN_BASE_URL", "http://localhost:3000"), "/")+"/internal/platform/task-progress-callbacks",
|
|
),
|
|
TaskProgressCallbackTimeoutMS: env("TASK_PROGRESS_CALLBACK_TIMEOUT_MS", "5000"),
|
|
TaskProgressCallbackMaxAttempts: env("TASK_PROGRESS_CALLBACK_MAX_ATTEMPTS", "10"),
|
|
CORSAllowedOrigin: env("CORS_ALLOWED_ORIGIN", "http://localhost:5178,http://127.0.0.1:5178"),
|
|
GlobalHTTPProxy: globalProxy.HTTPProxy,
|
|
GlobalHTTPProxySource: globalProxy.Source,
|
|
LogLevel: logLevel(env("LOG_LEVEL", "info")),
|
|
}
|
|
}
|
|
|
|
type GlobalHTTPProxyStatus struct {
|
|
HTTPProxy string
|
|
Source string
|
|
}
|
|
|
|
func LoadGlobalHTTPProxyStatus() GlobalHTTPProxyStatus {
|
|
for _, key := range []string{
|
|
"AI_GATEWAY_GLOBAL_HTTP_PROXY",
|
|
"GLOBAL_HTTP_PROXY",
|
|
"HTTPS_PROXY",
|
|
"https_proxy",
|
|
"HTTP_PROXY",
|
|
"http_proxy",
|
|
"ALL_PROXY",
|
|
"all_proxy",
|
|
} {
|
|
if value := envValue(key); value != "" {
|
|
return GlobalHTTPProxyStatus{HTTPProxy: value, Source: key}
|
|
}
|
|
}
|
|
return GlobalHTTPProxyStatus{}
|
|
}
|
|
|
|
func gatewayDatabaseURL() string {
|
|
if value := envValue("AI_GATEWAY_DATABASE_URL"); value != "" {
|
|
return normalizePostgresURL(value)
|
|
}
|
|
if value := envValue("DATABASE_URL"); value != "" {
|
|
return normalizePostgresURL(value)
|
|
}
|
|
if memoryURL := envValue("MEMORY_DATABASE_URL"); memoryURL != "" {
|
|
return normalizePostgresURL(withDatabase(memoryURL, env("AI_GATEWAY_DATABASE_NAME", "easyai_ai_gateway")))
|
|
}
|
|
return normalizePostgresURL("postgresql://easyai:easyai2025@localhost:5432/easyai_ai_gateway?sslmode=disable")
|
|
}
|
|
|
|
func normalizePostgresURL(raw string) string {
|
|
parsed, err := url.Parse(raw)
|
|
if err != nil {
|
|
return raw
|
|
}
|
|
values := parsed.Query()
|
|
schema := values.Get("schema")
|
|
if schema == "" {
|
|
return raw
|
|
}
|
|
values.Del("schema")
|
|
if values.Get("search_path") == "" {
|
|
values.Set("search_path", schema)
|
|
}
|
|
parsed.RawQuery = values.Encode()
|
|
return parsed.String()
|
|
}
|
|
|
|
func withDatabase(raw string, databaseName string) string {
|
|
parsed, err := url.Parse(raw)
|
|
if err != nil || databaseName == "" {
|
|
return raw
|
|
}
|
|
parsed.Path = "/" + databaseName
|
|
return parsed.String()
|
|
}
|
|
|
|
func envValue(key string) string {
|
|
return strings.TrimSpace(os.Getenv(key))
|
|
}
|
|
|
|
func env(key string, fallback string) string {
|
|
if value := envValue(key); value != "" {
|
|
return value
|
|
}
|
|
return fallback
|
|
}
|
|
|
|
func logLevel(value string) slog.Level {
|
|
switch strings.ToLower(value) {
|
|
case "debug":
|
|
return slog.LevelDebug
|
|
case "warn", "warning":
|
|
return slog.LevelWarn
|
|
case "error":
|
|
return slog.LevelError
|
|
default:
|
|
return slog.LevelInfo
|
|
}
|
|
}
|