import { useEffect, useState, useRef } from 'react'; import { Form, Input, Switch, Button, Card, message, Row, Col, theme } from 'antd'; import { proxyApi, type ProxyConfig } from '../api/modules'; import { getErrorMessage } from '../utils/error'; const WS_BASE = `${window.location.protocol === 'https:' ? 'wss' : 'ws'}://${window.location.host}`; export default function ProxyPage() { const { token } = theme.useToken(); const [form] = Form.useForm(); const [loading, setLoading] = useState(false); const [testing, setTesting] = useState(false); const [testingWl, setTestingWl] = useState(false); const [configLoaded, setConfigLoaded] = useState(false); const [logs, setLogs] = useState<{ level: string; message: string }[]>([]); const wsRef = useRef(null); const loadConfig = async () => { try { const data = await proxyApi.get(); form.setFieldsValue({ enabled: data.enabled ?? false, api_url: data.api_url ?? '', http: data.http ?? '', https: data.https ?? '', whitelist_enabled: data.whitelist_enabled ?? false, whitelist_uid: data.whitelist_uid ?? '', whitelist_ukey: data.whitelist_ukey ?? '', }); } catch (e: unknown) { message.error(getErrorMessage(e)); } finally { setConfigLoaded(true); } }; useEffect(() => { loadConfig(); return () => { wsRef.current?.close(); }; }, []); const appendLog = (level: string, msg: string) => { setLogs((prev) => [...prev, { level, message: msg }]); }; const connectWs = (testId: string) => { wsRef.current?.close(); setLogs([]); const ws = new WebSocket(`${WS_BASE}/api/proxy/ws/test/${testId}`); wsRef.current = ws; ws.onmessage = (event) => { const msg = JSON.parse(event.data); if (msg.level === 'heartbeat') return; if (msg.level === 'result') return; appendLog(msg.level, msg.message); }; ws.onclose = () => { wsRef.current = null; setTesting(false); setTestingWl(false); }; }; const handleSave = async () => { setLoading(true); try { const values = await form.validateFields(); await proxyApi.update(values as ProxyConfig); message.success('已保存'); } catch (e: unknown) { message.error(getErrorMessage(e)); } finally { setLoading(false); } }; const handleTestProxy = async () => { setTesting(true); setLogs([]); try { const result = await proxyApi.test(); if (result.test_id) connectWs(result.test_id); } catch (e: unknown) { message.error(getErrorMessage(e)); setTesting(false); } }; const handleTestWhitelist = async () => { setTestingWl(true); setLogs([]); try { const result = await proxyApi.testWhitelist(); if (result.test_id) connectWs(result.test_id); } catch (e: unknown) { message.error(getErrorMessage(e)); setTestingWl(false); } }; const logColors: Record = { error: token.colorError, success: token.colorSuccess, warning: token.colorWarning, info: token.colorText, }; return (

代理配置

{logs.length === 0 ? ( 点击"测试代理"或"测试白名单"查看日志 ) : ( logs.map((log, i) => (
{log.message}
)) )}
); }