diff --git a/frontend/src/pages/Resource/Server/List/components/SSHTerminalContent.tsx b/frontend/src/pages/Resource/Server/List/components/SSHTerminalContent.tsx index 84f50b45..237a3bfd 100644 --- a/frontend/src/pages/Resource/Server/List/components/SSHTerminalContent.tsx +++ b/frontend/src/pages/Resource/Server/List/components/SSHTerminalContent.tsx @@ -44,7 +44,7 @@ type ConnectionStatus = 'connecting' | 'connected' | 'reconnecting' | 'disconnec interface WebSocketMessage { type: 'output' | 'input' | 'status' | 'error'; - data: string; + data: string | { response: { type: string; data: string } }; // 支持字符串或 response 包装格式 timestamp?: number; metadata?: Record | null; } @@ -213,11 +213,34 @@ export const SSHTerminalContent: React.FC = ({ if (wsRef.current?.readyState === WebSocket.OPEN) { wsRef.current.send(JSON.stringify({ type: 'input', - data: data, + data: { + request: { + type: 'input', + command: data, + } + } })); } }); + // 监听终端尺寸变化 + terminal.onResize((size) => { + console.log('📐 终端尺寸变化:', size); + if (wsRef.current?.readyState === WebSocket.OPEN) { + wsRef.current.send(JSON.stringify({ + type: 'resize', + data: { + request: { + type: 'resize', + rows: size.rows, + cols: size.cols, + } + } + })); + console.log('📤 已发送尺寸调整消息:', size); + } + }); + // 延迟连接 setTimeout(() => { connectWebSocket(); @@ -254,6 +277,22 @@ export const SSHTerminalContent: React.FC = ({ ws.onopen = () => { console.log('🔗 WebSocket已连接:', wsUrl); console.log('📺 Terminal实例存在:', !!terminalInstanceRef.current); + + // 发送初始终端尺寸 + if (terminalInstanceRef.current) { + const terminal = terminalInstanceRef.current; + ws.send(JSON.stringify({ + type: 'resize', + data: { + request: { + type: 'resize', + rows: terminal.rows, + cols: terminal.cols, + } + } + })); + console.log('📤 已发送初始终端尺寸:', { rows: terminal.rows, cols: terminal.cols }); + } }; ws.onmessage = (event) => { @@ -262,28 +301,33 @@ export const SSHTerminalContent: React.FC = ({ const msg: WebSocketMessage = JSON.parse(event.data); console.log('📦 解析后的消息:', msg); + // 提取实际数据:处理后端 response 包装格式 + const actualData = typeof msg.data === 'string' + ? msg.data + : msg.data?.response?.data || ''; + switch (msg.type) { case 'output': - console.log('📝 输出数据:', msg.data?.substring(0, 100)); + console.log('📝 输出数据:', actualData?.substring(0, 100)); console.log('📺 Terminal实例:', !!terminalInstanceRef.current); - if (msg.data && terminalInstanceRef.current) { - terminalInstanceRef.current.write(msg.data); + if (actualData && terminalInstanceRef.current) { + terminalInstanceRef.current.write(actualData); console.log('✅ 数据已写入终端'); } else { - console.warn('⚠️ 无法写入终端:', { hasData: !!msg.data, hasTerminal: !!terminalInstanceRef.current }); + console.warn('⚠️ 无法写入终端:', { hasData: !!actualData, hasTerminal: !!terminalInstanceRef.current }); } break; case 'error': - console.error('❌ SSH错误:', msg.data); - terminalInstanceRef.current?.writeln(`\r\n\x1b[31m错误: ${msg.data}\x1b[0m\r\n`); - message.error(msg.data || '连接错误'); + console.error('❌ SSH错误:', actualData); + terminalInstanceRef.current?.writeln(`\r\n\x1b[31m错误: ${actualData}\x1b[0m\r\n`); + message.error(actualData || '连接错误'); break; case 'status': - console.log('📊 状态变化:', msg.data); - setConnectionStatus(msg.data as ConnectionStatus); - if (msg.data === 'connected') { + console.log('📊 状态变化:', actualData); + setConnectionStatus(actualData as ConnectionStatus); + if (actualData === 'connected') { // 显示审计警告 terminalInstanceRef.current?.writeln('\r\n\x1b[33m┌─────────────────────────────────────────────────────────────\x1b[0m'); terminalInstanceRef.current?.writeln('\x1b[33m│ ⚠️ 链宇技术有限公司 - 安全提示\x1b[0m'); diff --git a/frontend/src/pages/Resource/Server/List/index.tsx b/frontend/src/pages/Resource/Server/List/index.tsx index 7fbffc6d..796272d8 100644 --- a/frontend/src/pages/Resource/Server/List/index.tsx +++ b/frontend/src/pages/Resource/Server/List/index.tsx @@ -168,18 +168,16 @@ const ServerList: React.FC = () => { setTestingServerId(server.id); try { const result = await testServerConnection(server.id); - // 后端返回 { success: true, data: true/false } - // data 为 true 表示连接成功, false 表示连接失败 - if (result === true) { + if (result.connected) { toast({ title: '连接成功', - description: '服务器连接正常', + description: `${result.hostname} - ${result.osVersion} (响应时间: ${result.responseTime}ms)`, }); } else { toast({ variant: 'destructive', title: '连接失败', - description: '无法连接到服务器', + description: result.errorMessage || '无法连接到服务器', }); } } catch (error: any) { diff --git a/frontend/src/pages/Resource/Server/List/service.ts b/frontend/src/pages/Resource/Server/List/service.ts index d67a3473..a35f2aaa 100644 --- a/frontend/src/pages/Resource/Server/List/service.ts +++ b/frontend/src/pages/Resource/Server/List/service.ts @@ -5,6 +5,7 @@ import type { ServerCategoryRequest, ServerResponse, ServerRequest, + ServerConnectionTestResult, } from './types'; import type { ServerFormValues } from './schema'; import type { Page } from '@/types/base'; @@ -111,8 +112,8 @@ export const batchDeleteServers = (ids: number[]) => /** * 测试服务器连接 - * 返回 true 表示连接成功, false 表示连接失败 + * 返回连接测试结果,包含连接状态和服务器信息 */ export const testServerConnection = (id: number) => - request.post(`${SERVER_URL}/${id}/test-connection`); + request.post(`${SERVER_URL}/${id}/test-connection`); diff --git a/frontend/src/pages/Resource/Server/List/types.ts b/frontend/src/pages/Resource/Server/List/types.ts index 893aab9a..ff1e4586 100644 --- a/frontend/src/pages/Resource/Server/List/types.ts +++ b/frontend/src/pages/Resource/Server/List/types.ts @@ -224,3 +224,27 @@ export const AuthTypeLabels: Record