diff --git a/backend/internal/api/codex_proxy.go b/backend/internal/api/codex_proxy.go index 9534f1f..f03954d 100644 --- a/backend/internal/api/codex_proxy.go +++ b/backend/internal/api/codex_proxy.go @@ -2,11 +2,13 @@ package api import ( "encoding/json" + "fmt" "net/http" "strconv" "strings" "codex-pool/internal/database" + "codex-pool/internal/logger" "codex-pool/internal/proxyutil" ) @@ -83,10 +85,12 @@ func addCodexProxy(w http.ResponseWriter, r *http.Request) { count, err := database.Instance.AddCodexProxies(validProxies) if err != nil { + logger.Error(fmt.Sprintf("批量添加代理失败: %v", err), "", "proxy-pool") Error(w, http.StatusInternalServerError, "批量添加代理失败: "+err.Error()) return } + logger.Success(fmt.Sprintf("批量添加代理: %d/%d 个成功", count, len(validProxies)), "", "proxy-pool") Success(w, map[string]interface{}{ "added": count, "total": len(validProxies), @@ -109,13 +113,16 @@ func addCodexProxy(w http.ResponseWriter, r *http.Request) { id, err := database.Instance.AddCodexProxy(proxyURL, req.Description) if err != nil { if strings.Contains(err.Error(), "UNIQUE constraint failed") { + logger.Warning(fmt.Sprintf("代理已存在: %s", getProxyDisplay(proxyURL)), "", "proxy-pool") Error(w, http.StatusConflict, "代理地址已存在") return } + logger.Error(fmt.Sprintf("添加代理失败: %v", err), "", "proxy-pool") Error(w, http.StatusInternalServerError, "添加代理失败: "+err.Error()) return } + logger.Success(fmt.Sprintf("添加代理: %s (ID: %d)", getProxyDisplay(proxyURL), id), "", "proxy-pool") Success(w, map[string]interface{}{ "id": id, "message": "添加成功", @@ -130,9 +137,11 @@ func deleteCodexProxy(w http.ResponseWriter, r *http.Request) { if r.URL.Query().Get("all") == "true" { err := database.Instance.ClearCodexProxies() if err != nil { + logger.Error(fmt.Sprintf("清空代理池失败: %v", err), "", "proxy-pool") Error(w, http.StatusInternalServerError, "清空代理失败: "+err.Error()) return } + logger.Success("已清空所有代理", "", "proxy-pool") Success(w, map[string]string{"message": "已清空所有代理"}) return } @@ -147,10 +156,12 @@ func deleteCodexProxy(w http.ResponseWriter, r *http.Request) { } if err := database.Instance.DeleteCodexProxy(id); err != nil { + logger.Error(fmt.Sprintf("删除代理失败 (ID: %d): %v", id, err), "", "proxy-pool") Error(w, http.StatusInternalServerError, "删除代理失败: "+err.Error()) return } + logger.Info(fmt.Sprintf("删除代理 (ID: %d)", id), "", "proxy-pool") Success(w, map[string]string{"message": "删除成功"}) } @@ -169,10 +180,12 @@ func toggleCodexProxy(w http.ResponseWriter, r *http.Request) { } if err := database.Instance.ToggleCodexProxy(id); err != nil { + logger.Error(fmt.Sprintf("切换代理状态失败 (ID: %d): %v", id, err), "", "proxy-pool") Error(w, http.StatusInternalServerError, "切换代理状态失败: "+err.Error()) return } + logger.Info(fmt.Sprintf("切换代理状态 (ID: %d)", id), "", "proxy-pool") Success(w, map[string]string{"message": "状态已切换"}) } @@ -210,11 +223,14 @@ func testCodexProxy(w http.ResponseWriter, r *http.Request) { return } - // 执行测试 (异步执行以防前端超时,但用户想要同步结果,所以这里同步执行) - // 因为是在管理后台点击,15s 超时是可以接受的 + proxyDisplay := getProxyDisplay(targetProxy.ProxyURL) + logger.Status(fmt.Sprintf("测试代理中: %s", proxyDisplay), "", "proxy-pool") + + // 执行测试 result, err := proxyutil.TestProxy(targetProxy.ProxyURL) if err != nil { database.Instance.UpdateCodexProxyTestResult(id, "", false) + logger.Error(fmt.Sprintf("测试代理失败: %s - %v", proxyDisplay, err), "", "proxy-pool") Error(w, http.StatusInternalServerError, "测试过程出错: "+err.Error()) return } @@ -226,5 +242,11 @@ func testCodexProxy(w http.ResponseWriter, r *http.Request) { return } + if result.Success { + logger.Success(fmt.Sprintf("测试代理成功: %s -> %s (%s)", proxyDisplay, result.IP, result.Location), "", "proxy-pool") + } else { + logger.Error(fmt.Sprintf("测试代理失败: %s - %s", proxyDisplay, result.Error), "", "proxy-pool") + } + Success(w, result) } diff --git a/frontend/src/components/layout/Sidebar.tsx b/frontend/src/components/layout/Sidebar.tsx index 82ed79d..e11c3ae 100644 --- a/frontend/src/components/layout/Sidebar.tsx +++ b/frontend/src/components/layout/Sidebar.tsx @@ -46,7 +46,7 @@ const navItems: NavItem[] = [ { to: '/config', icon: Cog, label: '配置概览' }, { to: '/config/s2a', icon: Server, label: 'S2A 配置' }, { to: '/config/email', icon: Mail, label: '邮箱配置' }, - { to: '/config/codex-proxy', icon: Globe, label: '代理池' }, + { to: '/config/codex-proxy', icon: Globe, label: 'CodexAuth代理池' }, ] }, ]