import { useState, useEffect } from "react"; import { useTranslation } from "react-i18next"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Alert, AlertDescription } from "@/components/ui/alert"; import { Save, Loader2, Info } from "lucide-react"; import { toast } from "sonner"; import { getStreamCheckConfig, saveStreamCheckConfig, type StreamCheckConfig, } from "@/lib/api/connectivity-check"; export function ConnectivityCheckConfigPanel() { const { t } = useTranslation(); const [isLoading, setIsLoading] = useState(true); const [isSaving, setIsSaving] = useState(false); const [error, setError] = useState(null); // 使用字符串状态以支持完全清空数字输入框 const [config, setConfig] = useState({ timeoutSecs: "8", maxRetries: "1", degradedThresholdMs: "6000", }); useEffect(() => { loadConfig(); }, []); async function loadConfig() { try { setIsLoading(true); setError(null); const data = await getStreamCheckConfig(); setConfig({ timeoutSecs: String(data.timeoutSecs), maxRetries: String(data.maxRetries), degradedThresholdMs: String(data.degradedThresholdMs), }); } catch (e) { setError(String(e)); } finally { setIsLoading(false); } } async function handleSave() { // 解析数字,空值使用默认值,0 是有效值 const parseNum = (val: string, defaultVal: number) => { const n = parseInt(val); return isNaN(n) ? defaultVal : n; }; try { setIsSaving(true); const parsed: StreamCheckConfig = { timeoutSecs: parseNum(config.timeoutSecs, 8), maxRetries: parseNum(config.maxRetries, 1), degradedThresholdMs: parseNum(config.degradedThresholdMs, 6000), }; await saveStreamCheckConfig(parsed); toast.success(t("streamCheck.configSaved"), { closeButton: true, }); } catch (e) { toast.error(t("streamCheck.configSaveFailed") + ": " + String(e)); } finally { setIsSaving(false); } } if (isLoading) { return (
); } return (
{error && ( {error} )} {/* 连通检测语义说明:可达 ≠ 配置正确 */} {t("streamCheck.connectivityNote", { defaultValue: "连通检测仅探测供应商地址是否可达,不发送真实模型请求。收到任意响应即视为“可达”——这不代表鉴权或模型配置一定正确。", })} {/* 检查参数配置 */}

{t("streamCheck.checkParams")}

setConfig({ ...config, timeoutSecs: e.target.value }) } />
setConfig({ ...config, maxRetries: e.target.value }) } />
setConfig({ ...config, degradedThresholdMs: e.target.value }) } />
); }