From 6253b901517fa65e3d2b68d25716c46bef45284e Mon Sep 17 00:00:00 2001 From: yinjianm Date: Sun, 19 Apr 2026 21:33:24 +0800 Subject: [PATCH] =?UTF-8?q?feat(frontend):=20=E6=B7=BB=E5=8A=A0=20SSH=20?= =?UTF-8?q?=E7=BB=88=E7=AB=AF=E8=BF=90=E8=A1=8C=E4=B8=AD=E6=A0=87=E8=AE=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 为 SSH 顶部服务器标签和内部终端标签补充 `%` 运行中提示, 并基于发送命令、shell prompt、断连与错误链路派生运行态。 --- .helloagents/CHANGELOG.md | 4 + .../.status.json | 1 + .../proposal.md | 167 ++++++++ .../tasks.md | 55 +++ .helloagents/archive/_index.md | 1 + .helloagents/modules/frontend.md | 2 +- .../src/components/LayoutRenderer.vue | 7 + .../src/components/TerminalTabBar.vue | 15 + .../src/composables/useSshTerminal.ts | 362 ++++++++++-------- packages/frontend/src/locales/en-US.json | 4 +- packages/frontend/src/locales/ja-JP.json | 4 +- packages/frontend/src/locales/zh-CN.json | 4 +- .../stores/session/actions/sessionActions.ts | 2 + .../frontend/src/stores/session/getters.ts | 79 ++-- packages/frontend/src/stores/session/types.ts | 53 +-- 15 files changed, 530 insertions(+), 230 deletions(-) create mode 100644 .helloagents/archive/2026-04/202604192106_terminal-running-indicator/.status.json create mode 100644 .helloagents/archive/2026-04/202604192106_terminal-running-indicator/proposal.md create mode 100644 .helloagents/archive/2026-04/202604192106_terminal-running-indicator/tasks.md diff --git a/.helloagents/CHANGELOG.md b/.helloagents/CHANGELOG.md index 26f9b4c..7151cfd 100644 --- a/.helloagents/CHANGELOG.md +++ b/.helloagents/CHANGELOG.md @@ -2,6 +2,10 @@ ## [Unreleased] +- **[frontend]**: 为 SSH 顶部服务器标签与服务器内终端标签补充 `%` 命令运行中提示,并基于前端发送链路与 shell prompt 输出派生运行态 — by yinjianm + - 方案: [202604192106_terminal-running-indicator](archive/2026-04/202604192106_terminal-running-indicator/) + - 决策: terminal-running-indicator#D001(运行态继续作为前端派生状态实现), terminal-running-indicator#D002(采用发送置位加 prompt 清除的混合检测策略) + - **[frontend]**: 移除状态监控默认 CPU 卡里重复的 `CPU 使用率` 标题,并修正 CPU 摘要区固定高度导致的卡片/按钮截断问题 — by yinjianm - 类型: 快速修改(无方案包) - 文件: packages/frontend/src/components/StatusMonitor.vue:61-88,1035-1100,1565-1580 diff --git a/.helloagents/archive/2026-04/202604192106_terminal-running-indicator/.status.json b/.helloagents/archive/2026-04/202604192106_terminal-running-indicator/.status.json new file mode 100644 index 0000000..4076e17 --- /dev/null +++ b/.helloagents/archive/2026-04/202604192106_terminal-running-indicator/.status.json @@ -0,0 +1 @@ +{"status":"completed","completed":6,"failed":0,"pending":0,"total":6,"done":6,"percent":100,"current":"开发实施、构建验证与知识库同步已完成,待归档","updated_at":"2026-04-19 21:30:56"} diff --git a/.helloagents/archive/2026-04/202604192106_terminal-running-indicator/proposal.md b/.helloagents/archive/2026-04/202604192106_terminal-running-indicator/proposal.md new file mode 100644 index 0000000..cdfb71a --- /dev/null +++ b/.helloagents/archive/2026-04/202604192106_terminal-running-indicator/proposal.md @@ -0,0 +1,167 @@ +# 变更提案: terminal-running-indicator + +## 元信息 +```yaml +类型: 优化 +方案类型: implementation +优先级: P1 +状态: 进行中 +创建: 2026-04-19 +``` + +--- + +## 1. 需求 + +### 背景 +当前工作区顶部的 SSH 服务器标签与终端面板内部的子终端标签,只能表达连接状态和终端数量,无法判断某个终端是否仍在执行命令。用户希望在这两层标签上增加一个轻量的“运行中”标记,优先采用 `%` 这种很接近终端语义的提示,而不是额外堆叠新的大块状态卡片。 + +现有前端状态链路里,`session.store` 会保留连接状态、活动会话和底部命令输入框草稿,但没有后端提供的“命令正在执行”权威字段;因此这次需求需要在不改后端协议的前提下,基于前端已有的“发送命令”和“终端输出”信号推导一个足够稳定的运行态。 + +### 目标 +- 在 SSH 会话发送非空命令后,把对应终端标记为“运行中”。 +- 在终端输出重新出现常见 shell prompt 时,自动清除该终端的“运行中”标记。 +- 顶部服务器级标签在该服务器下任一终端运行时显示 `%` 标记,终端面板内部子标签只给对应终端显示 `%` 标记。 +- 保持现有连接状态圆点、关闭按钮、RDP/VNC 标签行为与后端 WebSocket 协议不变。 + +### 约束条件 +```yaml +时间约束: 本轮只做前端局部增强,保持可直接回滚 +性能约束: 不引入高频全量扫描,仅在发送命令和收到终端输出时做轻量判定 +兼容性约束: RDP/VNC 顶部标签继续沿用现有行为,SSH 多终端模型与 keep-alive 渲染链路不重构 +业务约束: 运行态为前端派生值,不新增后端协议字段;检测不到 prompt 时允许保守依赖兜底清除 +``` + +### 验收标准 +- [ ] SSH 会话通过命令输入框、快捷命令或终端内回车发送非空命令后,对应终端标签出现 `%` 运行中标记。 +- [ ] 同一 SSH 服务器下任一终端处于运行中时,顶部服务器标签同步出现 `%` 标记;运行全部结束后自动消失。 +- [ ] 常见 shell prompt 返回时会清除运行中标记;`Ctrl+C`、断连或再次输入时不会把旧运行态永久残留在标签上。 +- [ ] `npm --workspace @nexus-terminal/frontend run build` 通过,且没有新增模板/类型错误。 + +--- + +## 2. 方案 + +### 技术方案 +继续复用现有 `session.store -> WorkspaceView -> terminalManager/useSshTerminal -> TerminalTabBar/LayoutRenderer` 的前端数据流,不新增后端字段,也不引入新的全局 store。具体分为三层: + +1. 在 SSH `SessionState` 上补充响应式运行态字段与终端行输入缓存。 +2. 在 `WorkspaceView.vue` 的命令发送与终端键入链路里,把“发送非空命令”和“Ctrl+C/回车提交”转成运行态更新。 +3. 在 `useSshTerminal.ts` 的 `ssh:output` 处理链路里,对末尾输出做常见 shell prompt 判定,命中后清除运行态;同时在断连、错误等链路做兜底清理。 + +标签展示层只消费派生好的 `isCommandRunning` 字段: +- `TerminalTabBar.vue` 对 SSH 服务器标签按 `connectionId` 聚合,任一子终端运行时显示 `%`。 +- `LayoutRenderer.vue` 对当前服务器内部终端标签逐个显示 `%`。 + +### 影响范围 +```yaml +涉及模块: + - frontend/session: 为 SSH 会话补充命令运行态与输入缓存字段 + - frontend/workspace: 在发送命令与终端输出链路中维护运行态 + - frontend/ui: 在顶部服务器标签与内部终端标签展示 `%` 提示 + - frontend/i18n: 补充运行中提示文案 +预计变更文件: 7-9 +``` + +### 风险评估 +| 风险 | 等级 | 应对 | +|------|------|------| +| Prompt 正则误判,把普通输出误当成 shell prompt | 中 | 仅对输出末尾的最后非空行做判定,并要求匹配常见提示符结尾形态 | +| 只靠 prompt 检测时,某些交互程序或异常输出不会自动清除运行态 | 中 | 增加 `Ctrl+C`、断连、错误和再次输入时的兜底清除,允许保守回退 | +| 在终端输入链路里新增输入缓存可能影响现有输入转发 | 低 | 缓存只做本地字符串更新,不改变原有 `sendData()` 转发与 `keep-alive` 机制 | + +--- + +## 3. 技术设计 + +### 架构设计 +```mermaid +flowchart TD + A[CommandInputBar or QuickCommands] --> B[WorkspaceView handleSendCommand] + C[Terminal keyboard input] --> D[WorkspaceView handleTerminalInput] + B --> E[session.isCommandRunning = true] + D --> E + E --> F[useSshTerminal handleSshOutput] + F --> G{检测到 shell prompt?} + G -- 是 --> H[session.isCommandRunning = false] + G -- 否 --> I[保持运行态] + E --> J[TerminalTabBar / LayoutRenderer] +``` + +### 数据模型 +| 字段 | 类型 | 说明 | +|------|------|------| +| `isCommandRunning` | `Ref` | 当前 SSH 会话是否处于命令运行中 | +| `terminalInputBuffer` | `Ref` | 终端内当前尚未提交的一行输入缓存,用于回车时判断是否发送了非空命令 | + +--- + +## 4. 核心场景 + +### 场景: 底部命令输入框发送命令后出现运行中标记 +**模块**: frontend +**条件**: 用户已打开某个 SSH 会话,并通过底部命令输入框、快捷命令或历史命令发送非空命令。 +**行为**: `WorkspaceView.vue` 在发送数据给 `terminalManager` 前,将该会话标记为运行中。 +**结果**: 顶部服务器标签和该服务器内部对应终端标签出现 `%` 标记。 + +### 场景: 服务器下有多个终端时聚合显示运行态 +**模块**: frontend +**条件**: 同一 `connectionId` 下存在多个 SSH 终端,且其中至少一个终端仍在执行命令。 +**行为**: `TerminalTabBar.vue` 对当前服务器组内终端的 `isCommandRunning` 做聚合。 +**结果**: 顶部服务器级标签显示 `%`,内部子终端标签只在对应终端上显示 `%`。 + +### 场景: shell prompt 返回后自动清除运行态 +**模块**: frontend +**条件**: 终端收到新的输出块,且末尾出现常见 shell prompt。 +**行为**: `useSshTerminal.ts` 在 `ssh:output` 处理完成后清除运行态。 +**结果**: `%` 标记自动消失,不需要用户手动切换标签或刷新页面。 + +--- + +## 5. 技术决策 + +### terminal-running-indicator#D001: 运行态继续作为前端派生状态实现,而不是扩展后端协议 +**日期**: 2026-04-19 +**状态**: ✅采纳 +**背景**: 这次需求只涉及标签层提示,不要求服务端对命令生命周期建立权威状态机;后端当前也没有现成字段可直接复用。 +**选项分析**: +| 选项 | 优点 | 缺点 | +|------|------|------| +| A: 新增后端 WebSocket 运行态字段 | 语义最权威 | 改动范围扩散到后端协议和前后端联调,超出本轮 UI 增强需求 | +| B: 复用前端发送与输出事件派生命令运行态 | 改动集中在现有前端链路,回滚简单 | 对 prompt 识别准确度有依赖 | +**决策**: 选择方案 B +**理由**: 当前目标是给标签增加“是否还在跑”的轻量感知,不是建设完整任务管理协议。前端派生方案足以满足交互需求,且改动边界与现有架构一致。 +**影响**: 主要影响 `session` 派生状态、`WorkspaceView.vue`、`useSshTerminal.ts` 与两个标签组件。 + +### terminal-running-indicator#D002: 采用“发送非空命令置位 + 常见 prompt 清除 + 中断/断连兜底”的混合检测策略 +**日期**: 2026-04-19 +**状态**: ✅采纳 +**背景**: 单靠“发送命令后一直高亮”会产生残留;单靠输出判定又会遗漏异常结束和交互式输入场景。 +**选项分析**: +| 选项 | 优点 | 缺点 | +|------|------|------| +| A: 只要发送过命令就保持 `%`,直到下次输入再清除 | 实现最简单 | 状态滞后严重,用户很难判断命令是否真的结束 | +| B: 发送非空命令置位,常见 prompt 返回时清除,并用 `Ctrl+C` / 断连 / 新输入兜底 | 贴近真实 shell 行为,误残留更少 | 需要维护输入缓存和轻量 prompt 正则 | +**决策**: 选择方案 B +**理由**: 该策略能在不改后端的前提下最大化接近“命令结束”的真实时机,同时把无法完全识别的 shell 差异控制在可接受范围内。 +**影响**: 需要在 `WorkspaceView.vue` 与 `useSshTerminal.ts` 增加少量运行态同步逻辑。 + +--- + +## 6. 成果设计 + +### 设计方向 +- **美学基调**: 延续现有深色运维工作台,新增提示应是“终端感很强的细小信号”,而不是抢占层级的大号徽标。 +- **记忆点**: 当前正在运行的标签旁边出现一个琥珀色 `%`,让用户一眼联想到 shell prompt 和命令执行现场。 +- **参考**: 现有 `TerminalTabBar` / `LayoutRenderer` 终端标签样式 + 用户明确提出的 `%` 符号偏好。 + +### 视觉要素 +- **配色**: 沿用现有绿色激活态与深色背景,`%` 使用偏琥珀/暖黄的强调色,与连接状态圆点形成层级区分。 +- **字体**: 继续使用项目现有字体体系,不额外引入新字体;`%` 保持和标签文字一致的紧凑终端感。 +- **布局**: `%` 放在服务器数量徽标前或终端标题后,作为紧凑 inline 状态标记,不改变现有关闭按钮区域。 +- **动效**: 不新增复杂动画,仅保留轻量颜色过渡,避免把“运行中”误做成 loading spinner。 +- **氛围**: 保持当前终端工作台的克制风格,让 `%` 像 shell 的即时信号灯,而不是独立组件块。 + +### 技术约束 +- **可访问性**: `%` 标记需带 tooltip/title 文案,避免只靠颜色表达运行态。 +- **响应式**: 移动端和窄宽度下优先保留 `%` 本体,不强依赖长文案。 diff --git a/.helloagents/archive/2026-04/202604192106_terminal-running-indicator/tasks.md b/.helloagents/archive/2026-04/202604192106_terminal-running-indicator/tasks.md new file mode 100644 index 0000000..11c14de --- /dev/null +++ b/.helloagents/archive/2026-04/202604192106_terminal-running-indicator/tasks.md @@ -0,0 +1,55 @@ +# 任务清单: terminal-running-indicator + +> **@status:** completed | 2026-04-19 21:31 + +```yaml +@feature: terminal-running-indicator +@created: 2026-04-19 +@status: completed +@mode: R2 +``` + +## 进度概览 + +| 完成 | 失败 | 跳过 | 总数 | +|------|------|------|------| +| 6 | 0 | 0 | 6 | + +--- + +## 任务列表 + +### 1. 运行态链路补齐 + +- [√] 1.1 在 `packages/frontend/src/stores/session/types.ts` 与 `packages/frontend/src/stores/session/actions/sessionActions.ts` 中为 SSH 会话补充命令运行态与终端输入缓存字段,并完成新会话初始化 | depends_on: [] +- [√] 1.2 在 `packages/frontend/src/stores/session/getters.ts` 与 `packages/frontend/src/composables/useSshTerminal.ts` 中接入“发送非空命令置位、prompt/中断/断连清除”的派生逻辑 | depends_on: [1.1] + +### 2. 标签 UI 展示 + +- [√] 2.1 在 `packages/frontend/src/components/TerminalTabBar.vue` 中为 SSH 顶部服务器标签补充按连接聚合的 `%` 运行中提示 | depends_on: [1.2] +- [√] 2.2 在 `packages/frontend/src/components/LayoutRenderer.vue` 中为当前服务器内部终端标签补充逐终端 `%` 运行中提示 | depends_on: [1.2] +- [√] 2.3 在 `packages/frontend/src/locales/zh-CN.json`、`packages/frontend/src/locales/en-US.json` 与 `packages/frontend/src/locales/ja-JP.json` 中补充运行态 tooltip 文案 | depends_on: [2.1, 2.2] + +### 3. 验证与同步 + +- [√] 3.1 运行 `npm --workspace @nexus-terminal/frontend run build` 验证编译通过,并同步知识库与方案状态 | depends_on: [2.3] + +--- + +## 执行日志 + +| 时间 | 任务 | 状态 | 备注 | +|------|------|------|------| +| 2026-04-19 21:06 | 方案包创建 | 完成 | 已创建 `202604192106_terminal-running-indicator`,按 R2 流程进入开发实施 | +| 2026-04-19 21:19 | 1.1 / 1.2 | 完成 | 已为 SSH 会话补充 `isCommandRunning` 与 `terminalInputBuffer`,并在 `useSshTerminal.ts` 中接入发送置位、prompt/中断/断连清除逻辑 | +| 2026-04-19 21:23 | 2.1 / 2.2 / 2.3 | 完成 | 顶部服务器标签与服务器内终端标签已显示 `%` 运行态提示,并补齐中英日 tooltip 文案 | +| 2026-04-19 21:30 | 3.1 | 完成 | `npm --workspace @nexus-terminal/frontend run build` 通过,并同步 `frontend.md` 与 `CHANGELOG.md` | + +--- + +## 执行备注 + +- 本轮范围限制在 `packages/frontend`,不改 backend WebSocket 协议与 SSH session 模型。 +- 运行态以前端派生值为准,允许在无法识别 prompt 的极少数 shell 场景中退化为“中断/新输入/断连清除”。 +- 顶部服务器标签只做按连接聚合展示,内部终端标签负责表达具体哪一个终端仍在运行。 +- 方案设计时预估会在 `WorkspaceView.vue` 接入运行态,但最终为了覆盖文件管理器等直接调用 `terminalManager.sendData()` 的链路,将输入跟踪统一收口到了 `useSshTerminal.ts`。 diff --git a/.helloagents/archive/_index.md b/.helloagents/archive/_index.md index b9491d7..1dfa513 100644 --- a/.helloagents/archive/_index.md +++ b/.helloagents/archive/_index.md @@ -7,6 +7,7 @@ | 时间戳 | 名称 | 类型 | 涉及模块 | 决策 | 结果 | |--------|------|------|---------|------|------| +| 202604192106 | terminal-running-indicator | - | - | - | ✅完成 | | 202604190520 | status-monitor-cpu-summary-modal | - | - | - | ✅完成 | | 202604190351 | status-monitor-cpu-total-and-per-core | implementation | frontend, backend | status-monitor-cpu-total-and-per-core#D001 | ✅完成 | | 202604190358 | status-monitor-network-vertical-stack | implementation | frontend | - | ✅完成 | diff --git a/.helloagents/modules/frontend.md b/.helloagents/modules/frontend.md index 03342c7..a1c0e98 100644 --- a/.helloagents/modules/frontend.md +++ b/.helloagents/modules/frontend.md @@ -36,7 +36,7 @@ ### 工作区交互 **条件**: 用户进入 `/workspace` 或相关管理页面。 -**行为**: 通过组件、Pinia 与 composable 协同管理终端、文件管理、命令历史、布局配置、主题和状态监控;当前 `/workspace` 默认主布局为“左侧 Workbench、中央终端、右侧状态监控”,其中 Workbench 继续整合快捷指令、命令历史、文件管理和编辑器四个面板,导航入口保持为纯图标按钮,但已调整为位于 `Workbench` 标题区上方的横向 icon rail,四个入口自左向右排列、默认仅显示图标并通过 tooltip 暴露名称,默认激活快捷指令。`CommandInputBar.vue` 当前已将底部命令框升级为支持会话级草稿保留的多行 `textarea`:普通 `Enter` 插入换行,`Ctrl+Shift+Enter` 发送当前命令,输入框会按内容自动增高至约 6 行,超出后在输入框内部滚动,并继续兼容快捷指令/命令历史同步与选中发送逻辑。应用根组件 `App.vue` 现在还新增了全局服务器快捷检索:已登录页面按下 `Ctrl+Shift+F` 会打开 `GlobalConnectionQuickSearch.vue`,通过 `utils/connectionSearch.ts` 对连接名称、主机、用户名、类型和标签做本地模糊排序,并直接复用 `sessionStore.handleConnectRequest()` 触发 SSH 工作区跳转或 RDP / VNC 弹窗连接;该检索弹层现在还会复用 `tags.store.ts` 读取标签名称映射,在结果卡片内补充显示每台服务器的标签 chips,便于快速区分同名或近似主机。快捷指令相关能力目前由 `AddEditQuickCommandForm.vue`、`QuickCommandsView.vue` 与新增的 `utils/quickCommandTemplate.ts` 协同实现:编辑弹窗左侧既可维护自定义 `${变量名}`,也提供 `${{date}}`、`${{time}}`、`${{timestamp}}`、`${{week}}`、`${{uuid}}`、`${{random:8}}`、`${{clipboard}}`、`${{password}}` 等动态变量的一键插入;实际执行时会统一走共享解析器,覆盖编辑弹窗执行、列表直接执行、粘贴到命令输入框和发送到全部服务器等链路,并对未定义变量、无法读取的剪贴板或不可用密码给出非阻断告警。`QuickCommandsView.vue` 内的新增按钮、空状态按钮和列表操作按钮统一复用 `bg-button`、`text-button-text`、`hover:bg-button-hover`、`hover:bg-border` 等主题变量类,避免写死黑白 hover 色值;该视图当前还支持命令项右键菜单,并已修正为实底卡片式上下文菜单,提供立即执行、粘贴到命令输入框(不自动发送)、复制命令、发送到全部服务器、编辑和删除等动作。快捷命令列表的鼠标主交互当前已从“单击立即执行”收紧为“单击仅更新选中态、双击才执行”,从而继续兼容键盘 `Enter` 的选中执行路径并降低误触风险;每条命令项同时会把完整 `command` 文本挂到浏览器原生 tooltip 上,便于在名称或命令被截断时直接 hover 核对完整内容。`Terminal.vue` 现在会跟踪 xterm 相对底部的视口偏移与贴底状态,在终端标签切换、重新激活和 `fit()` 后按原滚动意图恢复;当隐藏标签在后台持续追加日志时,重新激活会基于“距底部偏移”而不是过期的绝对行号恢复 viewport,避免用户继续向下滚动时无法回到底部。组件同时继续在渲染层为带 `xterm-fg-*` class 或内联 `style.color` 的显式前景色字符打标记,让终端文字描边/阴影仅作用于默认前景文本,不覆盖 ANSI 彩色输出;`session.store` 当前会为同一 SSH 连接下的新终端分配递增的 `terminalIndex`。当前顶部 `TerminalTabBar.vue` 已改为服务器级入口:SSH 项只负责在不同服务器之间切换,全局 `+` 继续负责选择其他服务器;同一服务器下的多个终端则下沉到 `LayoutRenderer.vue` 的终端面板内部,以次级标签条承载切换、关闭和新增,从而让“进入服务器后再管理该服务器的多个终端”成为主要交互模型。服务器组头现在除主点击切换外,还额外提供了一个 hover 后出现的 `X` 按钮,点击后会复用既有 `session:close` 事件逐个关闭该 `connectionId` 下的全部终端。当前终端标签右键菜单继续复用 `WorkspaceView.vue` 中转的会话关闭链路,除关闭当前、关闭其他、关闭左右侧外,也支持直接触发“关闭全部”来清空当前工作区中的全部终端标签。连接新增弹窗中的脚本模式则继续由 `useAddConnectionForm.ts` 统一清洗输入:会先剔除空行、Markdown 代码围栏行,再按单引号/双引号感知切分参数,并去掉成对包裹值的外层引号,避免像 `-p '$Moka1998A'` 这样的输入把 `'` 一并保存。`ConnectionsView.vue` 已升级为“左侧范围树 + 顶部搜索工具条 + 右侧结果列表”的双栏管理台,当前左侧进一步支持基于标签名路径分隔符推导的多级标签树、树节点展开状态持久化、分组 scope 恢复,以及树工具栏中的展开全部、收起全部和重置范围控制;近期又补上了独立的左侧树搜索、命中节点及祖先路径过滤、命中链路自动展开、节点计数高亮,以及更接近资源管理器的树头部布局;本轮继续为树节点加入 hover 工具按钮、资源管理器式分隔标题行与拖拽重排占位反馈;右侧结果列表则同时支持顶部排序控件、列头点击排序,并将行内操作整理为“连接”主按钮加“更多”菜单,其中 SSH 连接卡片默认进一步提升为“连接 / 测试 / 更多”三按钮结构,复用既有单连接测试状态,编辑/克隆/删除等次级操作保留在更多菜单中;连接页顶部工具条当前又补上了独立“标签管理”入口,打开 `ManageConnectionTagsModal.vue` 后可按标签名搜索、多选、批量删除标签,并通过显式危险开关决定删除标签时是否连带删除命中的连接;`tags.store.ts` 在该链路里会统一刷新标签与连接缓存,而 `ConnectionsView.vue` 会在当前 scope 指向已删标签或分组时自动回退到 `all`。`FileManager.vue` 当前已进一步收敛为固定 `/` 根节点的单栏资源管理器树,组件加载时会优先拉取 `/` 目录,树中按“目录在前、文件在后”同时显示目录和文件节点,点击目录只展开与聚焦,点击文件则沿用现有工作区文件打开链路;文件右键菜单链路则已补齐图标化菜单结构、危险态删除项、终端子菜单(执行 `cd` 命令到终端 / 新建终端到当前目录)、复制文件名与复制绝对路径等动作,并继续复用现有下载、权限、新建、上传和删除逻辑,同时又新增了独立“上传文件夹”入口:前端会先将本地目录打包为 zip,再复用现有 `sftp:upload` 链路上传,并在上传成功后自动调用远端解压、尝试清理临时压缩包;外部拖拽文件或目录上传时,则会按鼠标当前悬停的目录作为目标路径,其中目录同样走“先压缩再上传”的路径,从而显著降低小文件很多时的扫描与上传耗时;本轮又补上了拖拽上传前的目标路径确认、桌面端右键子菜单点击展开,以及目录删除时“仅删空目录 / 强制递归删除”的显式二选一;当前右键菜单的关闭职责已经收敛到 `FileManagerContextMenu.vue` 组件层处理,`useFileManagerContextMenu.ts` 不再额外注册捕获阶段的全局点击关闭监听,以避免“终端 / 上传 / 压缩”等带子菜单项在展开或点击前被提前关闭;同时 `useSftpActions.ts` 会在删除目录后自动回退当前或待加载的失效路径,避免文件树持续对已删除目录刷出 `No such file`。样式编辑器中的终端文字描边/阴影默认开关也已与新的黑绿终端风格保持默认开启。 +**行为**: 通过组件、Pinia 与 composable 协同管理终端、文件管理、命令历史、布局配置、主题和状态监控;当前 `/workspace` 默认主布局为“左侧 Workbench、中央终端、右侧状态监控”,其中 Workbench 继续整合快捷指令、命令历史、文件管理和编辑器四个面板,导航入口保持为纯图标按钮,但已调整为位于 `Workbench` 标题区上方的横向 icon rail,四个入口自左向右排列、默认仅显示图标并通过 tooltip 暴露名称,默认激活快捷指令。`CommandInputBar.vue` 当前已将底部命令框升级为支持会话级草稿保留的多行 `textarea`:普通 `Enter` 插入换行,`Ctrl+Shift+Enter` 发送当前命令,输入框会按内容自动增高至约 6 行,超出后在输入框内部滚动,并继续兼容快捷指令/命令历史同步与选中发送逻辑。围绕这条发送链路,`session` 派生状态现已补上 `isCommandRunning` 与 `terminalInputBuffer`,用于在发送非空命令后标记运行中,并在收到常见 shell prompt、`Ctrl+C`、断连或错误时清理运行态。应用根组件 `App.vue` 现在还新增了全局服务器快捷检索:已登录页面按下 `Ctrl+Shift+F` 会打开 `GlobalConnectionQuickSearch.vue`,通过 `utils/connectionSearch.ts` 对连接名称、主机、用户名、类型和标签做本地模糊排序,并直接复用 `sessionStore.handleConnectRequest()` 触发 SSH 工作区跳转或 RDP / VNC 弹窗连接;该检索弹层现在还会复用 `tags.store.ts` 读取标签名称映射,在结果卡片内补充显示每台服务器的标签 chips,便于快速区分同名或近似主机。快捷指令相关能力目前由 `AddEditQuickCommandForm.vue`、`QuickCommandsView.vue` 与新增的 `utils/quickCommandTemplate.ts` 协同实现:编辑弹窗左侧既可维护自定义 `${变量名}`,也提供 `${{date}}`、`${{time}}`、`${{timestamp}}`、`${{week}}`、`${{uuid}}`、`${{random:8}}`、`${{clipboard}}`、`${{password}}` 等动态变量的一键插入;实际执行时会统一走共享解析器,覆盖编辑弹窗执行、列表直接执行、粘贴到命令输入框和发送到全部服务器等链路,并对未定义变量、无法读取的剪贴板或不可用密码给出非阻断告警。`QuickCommandsView.vue` 内的新增按钮、空状态按钮和列表操作按钮统一复用 `bg-button`、`text-button-text`、`hover:bg-button-hover`、`hover:bg-border` 等主题变量类,避免写死黑白 hover 色值;该视图当前还支持命令项右键菜单,并已修正为实底卡片式上下文菜单,提供立即执行、粘贴到命令输入框(不自动发送)、复制命令、发送到全部服务器、编辑和删除等动作。快捷命令列表的鼠标主交互当前已从“单击立即执行”收紧为“单击仅更新选中态、双击才执行”,从而继续兼容键盘 `Enter` 的选中执行路径并降低误触风险;每条命令项同时会把完整 `command` 文本挂到浏览器原生 tooltip 上,便于在名称或命令被截断时直接 hover 核对完整内容。`Terminal.vue` 现在会跟踪 xterm 相对底部的视口偏移与贴底状态,在终端标签切换、重新激活和 `fit()` 后按原滚动意图恢复;当隐藏标签在后台持续追加日志时,重新激活会基于“距底部偏移”而不是过期的绝对行号恢复 viewport,避免用户继续向下滚动时无法回到底部。组件同时继续在渲染层为带 `xterm-fg-*` class 或内联 `style.color` 的显式前景色字符打标记,让终端文字描边/阴影仅作用于默认前景文本,不覆盖 ANSI 彩色输出;`session.store` 当前会为同一 SSH 连接下的新终端分配递增的 `terminalIndex`。当前顶部 `TerminalTabBar.vue` 已改为服务器级入口:SSH 项只负责在不同服务器之间切换,全局 `+` 继续负责选择其他服务器;同一服务器下的多个终端则下沉到 `LayoutRenderer.vue` 的终端面板内部,以次级标签条承载切换、关闭和新增,从而让“进入服务器后再管理该服务器的多个终端”成为主要交互模型。服务器组头现在除主点击切换外,还额外提供了一个 hover 后出现的 `X` 按钮,点击后会复用既有 `session:close` 事件逐个关闭该 `connectionId` 下的全部终端;如果该服务器下任一终端仍在执行命令,组头会显示一个琥珀色 `%` 提示。当前服务器内部终端标签同样会在对应终端运行命令时显示 `%`,从而同时暴露“服务器级有活跃命令”和“具体哪个终端仍在运行”两层信号。当前终端标签右键菜单继续复用 `WorkspaceView.vue` 中转的会话关闭链路,除关闭当前、关闭其他、关闭左右侧外,也支持直接触发“关闭全部”来清空当前工作区中的全部终端标签。连接新增弹窗中的脚本模式则继续由 `useAddConnectionForm.ts` 统一清洗输入:会先剔除空行、Markdown 代码围栏行,再按单引号/双引号感知切分参数,并去掉成对包裹值的外层引号,避免像 `-p '$Moka1998A'` 这样的输入把 `'` 一并保存。`ConnectionsView.vue` 已升级为“左侧范围树 + 顶部搜索工具条 + 右侧结果列表”的双栏管理台,当前左侧进一步支持基于标签名路径分隔符推导的多级标签树、树节点展开状态持久化、分组 scope 恢复,以及树工具栏中的展开全部、收起全部和重置范围控制;近期又补上了独立的左侧树搜索、命中节点及祖先路径过滤、命中链路自动展开、节点计数高亮,以及更接近资源管理器的树头部布局;本轮继续为树节点加入 hover 工具按钮、资源管理器式分隔标题行与拖拽重排占位反馈;右侧结果列表则同时支持顶部排序控件、列头点击排序,并将行内操作整理为“连接”主按钮加“更多”菜单,其中 SSH 连接卡片默认进一步提升为“连接 / 测试 / 更多”三按钮结构,复用既有单连接测试状态,编辑/克隆/删除等次级操作保留在更多菜单中;连接页顶部工具条当前又补上了独立“标签管理”入口,打开 `ManageConnectionTagsModal.vue` 后可按标签名搜索、多选、批量删除标签,并通过显式危险开关决定删除标签时是否连带删除命中的连接;`tags.store.ts` 在该链路里会统一刷新标签与连接缓存,而 `ConnectionsView.vue` 会在当前 scope 指向已删标签或分组时自动回退到 `all`。`FileManager.vue` 当前已进一步收敛为固定 `/` 根节点的单栏资源管理器树,组件加载时会优先拉取 `/` 目录,树中按“目录在前、文件在后”同时显示目录和文件节点,点击目录只展开与聚焦,点击文件则沿用现有工作区文件打开链路;文件右键菜单链路则已补齐图标化菜单结构、危险态删除项、终端子菜单(执行 `cd` 命令到终端 / 新建终端到当前目录)、复制文件名与复制绝对路径等动作,并继续复用现有下载、权限、新建、上传和删除逻辑,同时又新增了独立“上传文件夹”入口:前端会先将本地目录打包为 zip,再复用现有 `sftp:upload` 链路上传,并在上传成功后自动调用远端解压、尝试清理临时压缩包;外部拖拽文件或目录上传时,则会按鼠标当前悬停的目录作为目标路径,其中目录同样走“先压缩再上传”的路径,从而显著降低小文件很多时的扫描与上传耗时;本轮又补上了拖拽上传前的目标路径确认、桌面端右键子菜单点击展开,以及目录删除时“仅删空目录 / 强制递归删除”的显式二选一;当前右键菜单的关闭职责已经收敛到 `FileManagerContextMenu.vue` 组件层处理,`useFileManagerContextMenu.ts` 不再额外注册捕获阶段的全局点击关闭监听,以避免“终端 / 上传 / 压缩”等带子菜单项在展开或点击前被提前关闭;同时 `useSftpActions.ts` 会在删除目录后自动回退当前或待加载的失效路径,避免文件树持续对已删除目录刷出 `No such file`。样式编辑器中的终端文字描边/阴影默认开关也已与新的黑绿终端风格保持默认开启。 **结果**: 页面逻辑分散在 `views/`、`components/`、`stores/` 与 `composables/`,其中工作区终端行为和标签交互优先落在 `session.store.ts`、`session/actions/sessionActions.ts`、`session/getters.ts`、`TerminalTabBar.vue`、`WorkspaceView.vue`、`Terminal.vue` 与相关 locale 文件。 ### 仪表盘总览 diff --git a/packages/frontend/src/components/LayoutRenderer.vue b/packages/frontend/src/components/LayoutRenderer.vue index 03419e1..fea01f8 100644 --- a/packages/frontend/src/components/LayoutRenderer.vue +++ b/packages/frontend/src/components/LayoutRenderer.vue @@ -654,6 +654,13 @@ onBeforeUnmount(() => { {{ t('terminalTabBar.terminalBadge', { index: session.terminalIndex }) }} + + % +