From d31b0dbc1f95aa83c7a6fa96dfebd5762adecba8 Mon Sep 17 00:00:00 2001 From: Baobhan Sith <80159437+Heavrnl@users.noreply.github.com> Date: Thu, 17 Apr 2025 01:29:34 +0800 Subject: [PATCH] update --- packages/frontend/src/components/Terminal.vue | 14 ++++++--- .../src/composables/useSshTerminal.ts | 31 ++++++++++++++++++- 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/packages/frontend/src/components/Terminal.vue b/packages/frontend/src/components/Terminal.vue index e833764..da8398d 100644 --- a/packages/frontend/src/components/Terminal.vue +++ b/packages/frontend/src/components/Terminal.vue @@ -68,7 +68,7 @@ onMounted(() => { terminal = new Terminal({ cursorBlink: true, fontSize: 14, - fontFamily: 'Consolas, "Courier New", monospace', + fontFamily: 'Consolas, "Courier New", monospace, "Microsoft YaHei", "微软雅黑"', theme: { // 简单主题示例 background: '#1e1e1e', foreground: '#d4d4d4', @@ -76,8 +76,15 @@ onMounted(() => { }, rows: 24, // 初始行数 cols: 80, // 初始列数 + allowTransparency: true, + disableStdin: false, + convertEol: true, + scrollback: 1000, // 减少可滚动历史行数 + scrollOnUserInput: true, // 输入时滚动到底部 ...props.options, // 合并外部传入的选项 }); + + // 注意: 终端数据的解码已在useSshTerminal.ts中进行处理 // 加载插件 fitAddon = new FitAddon(); @@ -215,11 +222,10 @@ defineExpose({ write }); height: 100% !important; } -/* 确保 viewport 填满容器,以便 screen 的 padding 生效 */ +/* 确保 viewport 填满容器,隐藏滚动条 */ .terminal-container :deep(.xterm-viewport) { width: 100% !important; height: 100% !important; - /* 移除可能存在的 overflow: hidden,让 screen 的 padding 可见 */ - overflow: visible !important; + overflow: hidden !important; } diff --git a/packages/frontend/src/composables/useSshTerminal.ts b/packages/frontend/src/composables/useSshTerminal.ts index 39ed018..d399502 100644 --- a/packages/frontend/src/composables/useSshTerminal.ts +++ b/packages/frontend/src/composables/useSshTerminal.ts @@ -73,7 +73,36 @@ export function createSshTerminalManager(sessionId: string, wsDeps: SshTerminalD // 检查是否为 Base64 编码 (需要后端配合发送 encoding 字段) if (message?.encoding === 'base64' && typeof outputData === 'string') { try { - outputData = atob(outputData); // 在浏览器环境中使用 atob + // 使用更安全的Base64解码方式,保证中文字符正确解码 + const base64String = outputData; + // 先用atob获取二进制字符串 + const binaryString = atob(base64String); + // 创建Uint8Array存储二进制数据 + const bytes = new Uint8Array(binaryString.length); + for (let i = 0; i < binaryString.length; i++) { + bytes[i] = binaryString.charCodeAt(i); + } + // 使用TextDecoder确保UTF-8正确解码 + outputData = new TextDecoder('utf-8').decode(bytes); + + // 如果输出仍然包含乱码字符,尝试其他编码 + if (outputData.includes('�')) { + console.warn(`[会话 ${sessionId}][SSH终端模块] UTF-8解码后仍有乱码,尝试其他编码...`); + // 尝试不同的编码 + const encodings = ['gbk', 'gb18030', 'big5', 'iso-8859-1']; + for (const encoding of encodings) { + try { + const decoded = new TextDecoder(encoding).decode(bytes); + if (!decoded.includes('�')) { + outputData = decoded; + console.log(`[会话 ${sessionId}][SSH终端模块] 成功使用${encoding}解码`); + break; + } + } catch (encErr) { + // 忽略不支持的编码错误 + } + } + } } catch (e) { console.error(`[会话 ${sessionId}][SSH终端模块] Base64 解码失败:`, e, '原始数据:', message.payload); outputData = `\r\n[解码错误: ${e}]\r\n`; // 在终端显示解码错误