import { useState, useEffect, useRef } from "react"; import { useTranslation } from "react-i18next"; import { FormLabel } from "@/components/ui/form"; import { Input } from "@/components/ui/input"; import { Zap, AlertTriangle, Server, Unplug } from "lucide-react"; import { proxyApi, type UrlPreview } from "@/lib/api/proxy"; type AppType = "claude" | "codex" | "gemini"; interface EndpointFieldProps { id: string; label: string; value: string; onChange: (value: string) => void; placeholder: string; hint?: string; showManageButton?: boolean; onManageClick?: () => void; manageButtonLabel?: string; // 应用类型和 API 格式 appType?: AppType; apiFormat?: string; // 是否显示请求地址预览 showUrlPreview?: boolean; } export function EndpointField({ id, label, value, onChange, placeholder, hint, showManageButton = true, onManageClick, manageButtonLabel, appType, apiFormat, showUrlPreview = true, }: EndpointFieldProps) { const { t } = useTranslation(); const [urlPreview, setUrlPreview] = useState(null); const lastRequestIdRef = useRef(0); const defaultManageLabel = t("providerForm.manageAndTest", { defaultValue: "管理和测速", }); // 调用后端 API 获取 URL 预览 useEffect(() => { if (!value || !appType || !showUrlPreview) { // 标记当前所有已发出的请求为过期,避免旧请求回写 lastRequestIdRef.current += 1; setUrlPreview(null); return; } // 防抖:延迟 300ms 后请求 const timer = setTimeout(async () => { const requestId = ++lastRequestIdRef.current; try { const preview = await proxyApi.buildUrlPreview( appType, value, apiFormat, ); if (requestId !== lastRequestIdRef.current) return; setUrlPreview(preview); } catch (error) { console.error("Failed to build URL preview:", error); if (requestId !== lastRequestIdRef.current) return; setUrlPreview(null); } }, 300); return () => clearTimeout(timer); }, [value, appType, apiFormat, showUrlPreview]); return (
{label} {showManageButton && onManageClick && ( )}
onChange(e.target.value)} placeholder={placeholder} autoComplete="off" /> {/* 请求地址预览 */} {showUrlPreview && urlPreview && (
{/* CLI 直连请求地址 */}

{t("providerForm.directRequestUrl", { defaultValue: "CLI 直连请求地址:", })}

{urlPreview.direct_url}

{t("providerForm.directRequestUrlDesc", { defaultValue: "CLI 直连模式下的实际请求地址", })}

{/* CCS 代理请求地址 */}

{t("providerForm.proxyRequestUrl", { defaultValue: "CCS 代理请求地址:", })}

{urlPreview.proxy_url}

{t("providerForm.proxyRequestUrlDesc", { defaultValue: "CCS 智能拼接后转发到上游的地址", })}

)} {/* 全链接警告 */} {urlPreview?.is_full_url && (

{t("providerForm.fullUrlWarningTitle", { defaultValue: "检测到完整 API 路径", })}

{t("providerForm.fullUrlWarning", { defaultValue: "填写了包含 API 路径的完整地址,此配置仅在代理模式下生效。直连模式下请只填写基础地址。", })}

)} {hint ? (

{hint}

) : null}
); }