feat(admin): 添加网络代理配置和钱包交易功能
- 在管理面板中集成网络代理配置显示和平台代理设置 - 添加钱包摘要和交易列表API接口及数据管理 - 实现SSE流式响应中的错误处理机制 - 添加全局HTTP代理环境变量配置支持 - 更新平台表单以支持代理模式选择和自定义代理地址 - 集成钱包交易查询过滤和分页功能 - 优化API错误详情解析和显示格式
This commit is contained in:
@@ -0,0 +1,114 @@
|
||||
package netproxy
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
ModeNone = "none"
|
||||
ModeGlobal = "global"
|
||||
ModeCustom = "custom"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
Mode string
|
||||
HTTPProxy string
|
||||
}
|
||||
|
||||
func FromPlatformConfig(values map[string]any) Config {
|
||||
config := Config{
|
||||
Mode: stringFromMap(values, "proxyMode"),
|
||||
HTTPProxy: stringFromMap(values, "httpProxy"),
|
||||
}
|
||||
if nested := recordFromAny(values["networkProxy"]); nested != nil {
|
||||
if mode := stringFromMap(nested, "mode"); mode != "" {
|
||||
config.Mode = mode
|
||||
}
|
||||
if proxy := stringFromMap(nested, "httpProxy"); proxy != "" {
|
||||
config.HTTPProxy = proxy
|
||||
}
|
||||
}
|
||||
return config
|
||||
}
|
||||
|
||||
func Normalize(input Config) (Config, error) {
|
||||
mode, err := normalizeMode(input.Mode)
|
||||
if err != nil {
|
||||
return Config{}, err
|
||||
}
|
||||
config := Config{Mode: mode}
|
||||
if mode != ModeCustom {
|
||||
return config, nil
|
||||
}
|
||||
normalized, _, err := ParseHTTPProxy(input.HTTPProxy)
|
||||
if err != nil {
|
||||
return Config{}, err
|
||||
}
|
||||
config.HTTPProxy = normalized
|
||||
return config, nil
|
||||
}
|
||||
|
||||
func NormalizePlatformConfig(values map[string]any) (map[string]any, error) {
|
||||
next := map[string]any{}
|
||||
for key, value := range values {
|
||||
next[key] = value
|
||||
}
|
||||
config, err := Normalize(FromPlatformConfig(values))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
networkProxy := map[string]any{"mode": config.Mode}
|
||||
if config.Mode == ModeCustom {
|
||||
networkProxy["httpProxy"] = config.HTTPProxy
|
||||
}
|
||||
next["networkProxy"] = networkProxy
|
||||
delete(next, "proxyMode")
|
||||
delete(next, "httpProxy")
|
||||
return next, nil
|
||||
}
|
||||
|
||||
func ParseHTTPProxy(raw string) (string, *url.URL, error) {
|
||||
trimmed := strings.TrimSpace(raw)
|
||||
if trimmed == "" {
|
||||
return "", nil, fmt.Errorf("http proxy is required")
|
||||
}
|
||||
if !strings.Contains(trimmed, "://") {
|
||||
trimmed = "http://" + trimmed
|
||||
}
|
||||
parsed, err := url.Parse(trimmed)
|
||||
if err != nil {
|
||||
return "", nil, fmt.Errorf("invalid http proxy: %w", err)
|
||||
}
|
||||
if parsed.Scheme != "http" && parsed.Scheme != "https" {
|
||||
return "", nil, fmt.Errorf("http proxy scheme must be http or https")
|
||||
}
|
||||
if parsed.Host == "" {
|
||||
return "", nil, fmt.Errorf("http proxy host is required")
|
||||
}
|
||||
return parsed.String(), parsed, nil
|
||||
}
|
||||
|
||||
func normalizeMode(value string) (string, error) {
|
||||
switch strings.ToLower(strings.TrimSpace(value)) {
|
||||
case "", "none", "off", "disabled", "disable":
|
||||
return ModeNone, nil
|
||||
case "global", "system", "env", "environment":
|
||||
return ModeGlobal, nil
|
||||
case "custom":
|
||||
return ModeCustom, nil
|
||||
default:
|
||||
return "", fmt.Errorf("unsupported proxy mode %q", value)
|
||||
}
|
||||
}
|
||||
|
||||
func recordFromAny(value any) map[string]any {
|
||||
record, _ := value.(map[string]any)
|
||||
return record
|
||||
}
|
||||
|
||||
func stringFromMap(values map[string]any, key string) string {
|
||||
value, _ := values[key].(string)
|
||||
return strings.TrimSpace(value)
|
||||
}
|
||||
Reference in New Issue
Block a user