feat(admin): 添加网络代理配置和钱包交易功能

- 在管理面板中集成网络代理配置显示和平台代理设置
- 添加钱包摘要和交易列表API接口及数据管理
- 实现SSE流式响应中的错误处理机制
- 添加全局HTTP代理环境变量配置支持
- 更新平台表单以支持代理模式选择和自定义代理地址
- 集成钱包交易查询过滤和分页功能
- 优化API错误详情解析和显示格式
This commit is contained in:
2026-05-11 23:02:10 +08:00
parent c992f1de60
commit f550c0acd5
30 changed files with 1455 additions and 76 deletions
+23 -9
View File
@@ -4,7 +4,6 @@ import (
"context"
"errors"
"log/slog"
"net/http"
"strings"
"time"
@@ -15,10 +14,11 @@ import (
)
type Service struct {
cfg config.Config
store *store.Store
logger *slog.Logger
clients map[string]clients.Client
cfg config.Config
store *store.Store
logger *slog.Logger
clients map[string]clients.Client
httpClients *httpClientCache
}
type Result struct {
@@ -27,17 +27,18 @@ type Result struct {
}
func New(cfg config.Config, db *store.Store, logger *slog.Logger) *Service {
httpClient := &http.Client{Timeout: 120 * time.Second}
httpClients := newHTTPClientCache()
return &Service{
cfg: cfg,
store: db,
logger: logger,
clients: map[string]clients.Client{
"openai": clients.OpenAIClient{HTTPClient: httpClient},
"gemini": clients.GeminiClient{HTTPClient: httpClient},
"volces": clients.VolcesClient{HTTPClient: httpClient},
"openai": clients.OpenAIClient{HTTPClient: httpClients.none},
"gemini": clients.GeminiClient{HTTPClient: httpClients.none},
"volces": clients.VolcesClient{HTTPClient: httpClients.none},
"simulation": clients.SimulationClient{},
},
httpClients: httpClients,
}
}
@@ -200,6 +201,18 @@ func (s *Service) runCandidate(ctx context.Context, task store.GatewayTask, user
}
defer s.store.RecordClientRelease(context.WithoutCancel(ctx), candidate.ClientID, "")
requestHTTPClient, err := s.httpClientForCandidate(candidate, simulated)
if err != nil {
_ = s.store.FinishTaskAttempt(ctx, store.FinishTaskAttemptInput{
AttemptID: attemptID,
Status: "failed",
Retryable: false,
Metrics: mergeMetrics(attemptMetrics(candidate, attemptNo, simulated), map[string]any{"error": err.Error(), "retryable": false}),
ErrorCode: clients.ErrorCode(err),
ErrorMessage: err.Error(),
})
return clients.Response{}, err
}
client := s.clientFor(candidate, simulated)
callStartedAt := time.Now()
response, err := client.Run(ctx, clients.Request{
@@ -208,6 +221,7 @@ func (s *Service) runCandidate(ctx context.Context, task store.GatewayTask, user
Model: task.Model,
Body: body,
Candidate: candidate,
HTTPClient: requestHTTPClient,
Stream: boolFromMap(body, "stream"),
StreamDelta: onDelta,
})