重构(前端): 持久化快速命令排序和密码切换

添加持久化排序字段并重新排序快速命令和标签的端点,更新前端以支持手动拖放排序,并为连接和凭据表单添加密码可见性切换。此外,将 SSH 连接测试作为连接列表中的默认操作,并刷新相关模块文档和更改日志。
This commit is contained in:
yinjianm
2026-04-19 02:50:44 +08:00
parent 00d7c6c2f3
commit 8ce007a305
33 changed files with 1996 additions and 975 deletions
+12
View File
@@ -2,6 +2,18 @@
## [Unreleased]
- **[frontend]**: 为快捷指令视图新增分组拖拽排序、组内命令拖拽排序与扁平命令列表拖拽排序,并在拖拽完成后自动切换到手动顺序视图以保持刷新后顺序一致 — by yinjianm
- 方案: [202604190208_quickcommands-drag-reorder](archive/2026-04/202604190208_quickcommands-drag-reorder/)
- **[backend]**: 为快捷指令、快捷指令标签及其关联表补充 `sort_order` 持久化字段,并新增分组重排、全局命令重排和标签内命令重排接口,同时保留既有标签关联顺序 — by yinjianm
- 方案: [202604190208_quickcommands-drag-reorder](archive/2026-04/202604190208_quickcommands-drag-reorder/)
- **[frontend]**: 将连接管理页 SSH 连接卡片的默认操作区调整为“连接 / 测试 / 更多”,并把重复的测试入口从更多菜单移除,减少常用测试操作的额外点击 — by yinjianm
- 方案: [202604190210_connection-card-default-test-button](archive/2026-04/202604190210_connection-card-default-test-button/)
- **[frontend]**: 为连接新增/编辑表单以及登录凭证管理弹窗的直填密码输入补充“小眼睛”显隐切换,默认仍隐藏,仅在本地输入端切换明文核对 — by yinjianm
- 方案: [202604190201_connection-password-visibility-toggle](archive/2026-04/202604190201_connection-password-visibility-toggle/)
- **[workspace-root]**: 为 Docker 镜像发布 workflow 增加按路径检测的动态构建矩阵,仅在共享根文件或对应服务目录变更时构建受影响镜像,手动触发仍保留全量发布能力 - by yinjianm
- 方案: [202604160350_workflow-service-scoped-docker-builds](archive/2026-04/202604160350_workflow-service-scoped-docker-builds/)
@@ -0,0 +1 @@
{"status":"completed","completed":4,"failed":0,"pending":0,"total":4,"done":4,"percent":100,"current":"已完成连接新增/编辑表单与登录凭证管理弹窗的密码显隐切换,并通过前端构建验证","updated_at":"2026-04-19 02:08:00"}
@@ -0,0 +1,121 @@
# 变更提案: connection-password-visibility-toggle
## 元信息
```yaml
类型: 优化
方案类型: implementation
优先级: P2
状态: 已确认
创建: 2026-04-19
```
---
## 1. 需求
### 背景
连接新增/编辑表单以及登录凭证管理弹窗中的密码输入当前只能以掩码形式录入,用户在手工填写时无法即时核对内容是否正确。用户明确要求仅在前端输入端增加“小眼睛”显隐切换,用于检查自己刚输入的密码,而不是让表单默认返回明文或让后端补发已有密码。
### 目标
- 在连接新增/编辑表单的直填密码输入框中增加显隐切换,覆盖 SSH 密码、RDP 密码和 VNC 密码。
- 在登录凭证管理弹窗中增加同样的显隐切换,覆盖 SSH 密码与通用密码输入。
- 保持默认 `password` 掩码行为不变,不改现有提交、测试、保存和后端接口链路。
### 约束条件
```yaml
时间约束: 本轮限定为前端增量改动,不扩展到批量编辑、代理配置或登录页
性能约束: 仅增加本地响应式布尔状态,不引入额外依赖
兼容性约束: 不改变现有表单校验、编辑模式留空保留密码逻辑和已保存凭证模式
业务约束: 不请求后端返回已有明文密码,不改变默认数据返回策略
```
### 验收标准
- [ ] 连接新增/编辑表单的直填密码字段右侧存在可点击的小眼睛按钮,默认隐藏,点击后可切换明文显示。
- [ ] 登录凭证管理弹窗中的密码字段具备相同的显隐切换能力,且不影响原有保存逻辑。
- [ ] 显隐切换仅作用于当前输入框的本地显示状态,不改 API payload 结构,不新增后端接口返回。
- [ ] 前端构建校验通过;若出现与本次无关的既有问题,需在执行记录中明确标注。
---
## 2. 方案
### 技术方案
`AddConnectionFormAuth.vue``LoginCredentialManagementModal.vue` 内分别维护局部的密码可见状态,通过动态切换 input 的 `type``password` / `text`)实现显隐。每个密码输入框右侧内嵌一个次级 icon 按钮,按钮文案走 i18n,点击后只改变当前字段的显示方式,不写入 store、不触发额外请求,也不改变既有表单数据结构。
### 影响范围
```yaml
涉及模块:
- frontend: 连接认证表单与登录凭证管理弹窗的输入交互增强
- frontend-i18n: 显隐密码按钮的中英日文案补充
预计变更文件: 5
```
### 风险评估
| 风险 | 等级 | 应对 |
|------|------|------|
| 眼睛按钮被当成表单提交按钮,导致误触提交 | 中 | 所有切换按钮显式使用 `type="button"` |
| 在现有表单布局中加入尾部按钮后造成输入框样式错位 | 中 | 复用现有边框/背景 token,采用相同高度的绝对定位尾部按钮 |
| 编辑态切换后保留上一次可见状态,影响下一次打开表单体验 | 低 | 在表单重置、取消或切换编辑对象时回收为默认隐藏 |
---
## 3. 技术设计(可选)
N/A。本次不涉及架构、API 或数据模型变更。
---
## 4. 核心场景
> 执行完成后同步到对应模块文档
### 场景: 连接表单核对密码输入
**模块**: frontend
**条件**: 用户在新增连接或编辑连接时使用直填认证来源,并在 SSH / RDP / VNC 密码字段中录入密码。
**行为**: 用户点击密码框右侧的小眼睛按钮,在掩码和明文显示之间切换,以便核对当前输入内容。
**结果**: 用户可以在不改变默认安全策略的前提下确认自己录入的密码是否正确。
### 场景: 登录凭证管理时核对密码输入
**模块**: frontend
**条件**: 用户在登录凭证管理弹窗中新增或编辑密码型凭证。
**行为**: 用户点击密码输入框右侧的小眼睛按钮查看或隐藏当前输入的密码。
**结果**: 用户能够在保存前自检输入内容,同时原有保存和校验逻辑保持不变。
---
## 5. 技术决策
> 本方案涉及的技术决策,归档后成为决策的唯一完整记录
### connection-password-visibility-toggle#D001: 在现有表单内局部实现密码显隐切换
**日期**: 2026-04-19
**状态**: ✅采纳
**背景**: 新增/编辑连接与登录凭证管理都需要密码可见性切换,但两处表单结构和字段命名并不完全一致。
**选项分析**:
| 选项 | 优点 | 缺点 |
|------|------|------|
| A: 抽离公共密码输入组件 | 逻辑集中、后续可复用 | 本轮只是局部交互增强,会引入额外抽象和迁移成本 |
| B: 在两个现有组件中局部实现显隐状态 | 修改范围小,能最大限度保持既有表单行为和样式结构 | 两处按钮结构会有少量重复 |
**决策**: 选择方案 B
**理由**: 本轮目标明确且影响范围小,局部实现能最快落地,并降低对现有认证流程的扰动。
**影响**: 仅影响前端连接表单与登录凭证管理弹窗,不涉及 store、API 和后端数据结构。
---
## 6. 成果设计
### 设计方向
- **美学基调**: 延续现有连接表单的克制型工具化界面,在输入框尾部加入低干扰、可发现的小眼睛操作,不打断原表单阅读节奏。
- **记忆点**: 密码框右侧内嵌的眼睛切换按钮,作为“录入后可即时自检”的明确交互锚点。
- **参考**: 延续项目现有表单 token、边框和 hover/focus 行为,不额外引入新的视觉体系。
### 视觉要素
- **配色**: 继续使用现有 `bg-background``border-border``text-text-secondary``text-foreground``focus:ring-primary` 体系。
- **字体**: 沿用项目现有全局字体与表单字号,不新增展示字体或排版层级。
- **布局**: 输入框保持单行主结构,右侧以内嵌尾部按钮承载显隐操作,避免新增独立行或破坏表单宽度。
- **动效**: 仅保留项目已有 hover/focus 状态反馈,不新增独立动画。
- **氛围**: 不改变当前表单面板氛围,保持与现有认证区和管理弹窗的一致性。
### 技术约束
- **可访问性**: 显隐按钮需提供可读 title/aria-label,确保仅靠图标也能被辅助工具识别。
- **响应式**: 在现有表单宽度下保持按钮内嵌,不引入移动端换行或遮挡输入内容。
@@ -0,0 +1,51 @@
# 任务清单: connection-password-visibility-toggle
> **@status:** completed | 2026-04-19 02:08
```yaml
@feature: connection-password-visibility-toggle
@created: 2026-04-19
@status: completed
@mode: R2
```
## 进度概览
| 完成 | 失败 | 跳过 | 总数 |
|------|------|------|------|
| 4 | 0 | 0 | 4 |
---
## 任务列表
### 1. 前端表单实现
- [√] 1.1 在 `packages/frontend/src/components/AddConnectionFormAuth.vue` 中为直填 SSH / RDP / VNC 密码输入增加本地显隐切换 | depends_on: []
- [√] 1.2 在 `packages/frontend/src/components/LoginCredentialManagementModal.vue` 中为登录凭证密码输入增加同样的显隐切换与重置逻辑 | depends_on: [1.1]
### 2. 文案与验证
- [√] 2.1 在 `packages/frontend/src/locales/zh-CN.json``packages/frontend/src/locales/en-US.json``packages/frontend/src/locales/ja-JP.json` 中补充显隐密码文案 | depends_on: [1.1]
- [√] 2.2 运行 `packages/frontend` 构建校验并记录结果 | depends_on: [1.2, 2.1]
---
## 执行日志
| 时间 | 任务 | 状态 | 备注 |
|------|------|------|------|
| 2026-04-19 02:03 | design | completed | 已创建 implementation 方案包,范围锁定为连接新增/编辑表单与登录凭证管理弹窗的密码显隐切换 |
| 2026-04-19 02:06 | 1.1 | completed | 已为连接表单中的 SSH、RDP、VNC 直填密码输入增加显隐切换按钮与本地显示状态 |
| 2026-04-19 02:07 | 1.2 | completed | 已为登录凭证管理弹窗中的密码输入增加显隐切换,并在表单重置/切换时恢复默认隐藏 |
| 2026-04-19 02:07 | 2.1 | completed | 已补充连接表单显隐密码按钮的中英日文案 |
| 2026-04-19 02:08 | 2.2 | completed | `npm --workspace @nexus-terminal/frontend run build` 通过,仅保留既有 chunk size 警告 |
---
## 执行备注
> 记录执行过程中的重要说明、决策变更、风险提示等
- 仓库中存在历史遗留的未完成方案包 `202603252311_terminal-group-and-broadcast-dedupe`,其备注指向 `ConnectionsView.vue duplicate attribute` 既有验证问题;若本轮构建再次命中,按既有问题记录,不视为本次功能回归。
- 运行态补充验证: 已启动 `vite` 前端并通过 Playwright 访问到 `http://127.0.0.1:4173/login`;但本地 `localhost:3001` 后端未运行,浏览器端出现代理拒绝连接,无法自动进入登录后的连接管理页,因此“点击小眼睛切换明文”仍建议在你的已登录环境手动确认一次。
@@ -0,0 +1 @@
{"status":"completed","completed":8,"failed":0,"pending":0,"total":8,"done":8,"percent":100,"current":"Completed - 快捷指令分组与命令拖拽排序已实现并通过构建验证","updated_at":"2026-04-19 03:12:00"}
@@ -0,0 +1,208 @@
# 变更提案: quickcommands-drag-reorder
## 元信息
```yaml
类型: 新功能
方案类型: implementation
优先级: P1
状态: 已完成
创建: 2026-04-19
完成: 2026-04-19
```
---
## 1. 需求
### 背景
当前快捷指令视图已经支持按标签分组、按名称或最近使用时间浏览命令,并提供双击执行、右键菜单、动态变量与标签编辑等能力,但分组顺序仍然按标签名派生,组内命令顺序也只能依赖计算排序,用户无法把高频分组和常用命令固定在自己习惯的位置。随着工作台内快捷指令数量增加,这会降低定位效率,也和连接树等区域正在逐步支持拖拽重排的交互方向不一致。
### 目标
- 让快捷指令分组支持拖动排序,并在刷新后保持自定义顺序。
- 让快捷指令支持在分组内拖动排序,并在刷新后保持自定义顺序。
- 让关闭标签分组后的扁平列表同样支持拖动排序。
- 在一条命令可绑定多个标签的前提下,明确全局顺序和标签内顺序的持久化语义。
### 约束条件
```yaml
时间约束: 本轮完成前后端联动实现与基础构建验证
性能约束: 不新增依赖,复用仓库已有的 vuedraggable
兼容性约束: 需要兼容现有 SQLite 数据库,通过 migration 为历史数据补齐顺序字段
业务约束: 搜索过滤结果不参与拖拽重排,避免只对局部可见子集排序造成顺序污染
```
### 验收标准
- [ ] 开启标签分组时,已标记分组支持拖动排序,刷新页面后顺序保持不变。
- [ ] 开启标签分组时,组内命令支持拖动排序,刷新页面后顺序保持不变。
- [ ] 关闭标签分组时,扁平命令列表支持拖动排序,刷新页面后顺序保持不变。
- [ ] 多标签命令在不同标签组内可拥有各自的组内顺序,不因编辑命令或补标签而丢失既有顺序。
- [ ] `packages/backend``packages/frontend` 的构建验证通过。
---
## 2. 方案
### 技术方案
本次改动分三层落地。
第一层是数据层,为 `quick_commands``quick_command_tags``quick_command_tag_associations` 三张表分别新增 `sort_order` 字段,并通过 migration 为历史数据回填稳定初始顺序。命令表顺序用于扁平列表与“未标记”分组,标签表顺序用于分组顺序,关联表顺序用于“命令在某个标签组中的局部位置”。
第二层是接口层,在现有快捷指令与快捷指令标签业务域中新增三个重排接口: 标签重排、全局命令重排、标签内命令重排。同时改造现有标签关联写入逻辑,避免编辑命令时通过“先删后插”破坏已有组内顺序。
第三层是前端交互层,在 `QuickCommandsView.vue` 中接入拖拽句柄和持久化回写逻辑,并把命令排序模式扩展为 `manual``name``last_used`。用户完成拖拽后自动切回 `manual` 模式,确保拖拽结果可以立即可见且稳定保留。
### 影响范围
```yaml
涉及模块:
- backend: quick-commands / quick-command-tags / database migration 需要新增顺序字段与重排接口
- frontend: quickCommands.store / quickCommandTags.store / QuickCommandsView 需要支持手动顺序与拖拽持久化
- knowledge-base: 需要同步 frontend/backend 模块文档与 CHANGELOG
预计变更文件: 10-14
```
### 风险评估
| 风险 | 等级 | 应对 |
|------|------|------|
| 多标签命令在多个分组中复用,若仍把组内顺序放在命令表会产生语义冲突 | 高 | 将“标签内顺序”存储到关联表,命令表只承载全局顺序 |
| 历史数据库没有顺序字段,直接读取会导致老数据顺序混乱 | 中 | 通过 migration 补字段并按现有主键或 rowid 回填初始顺序 |
| 搜索过滤结果下拖拽会导致只重排局部子集,用户感知混乱 | 中 | 搜索态禁用拖拽,只允许在完整列表状态下重排 |
| 编辑命令标签时若继续删除并重建关联,会丢失既有组内顺序 | 中 | 改为增量同步标签关联,保留未移除标签的原顺序 |
---
## 3. 技术设计
### 架构设计
```mermaid
flowchart LR
A[QuickCommandsView drag end] --> B[quickCommandsStore / quickCommandTagsStore]
B --> C[reorder APIs]
C --> D[service]
D --> E[repository]
E --> F[(SQLite sort_order fields)]
```
### API设计
#### PUT /api/v1/quick-command-tags/reorder
- **请求**:
```json
{
"tagIds": [3, 1, 5]
}
```
- **响应**:
```json
{
"message": "快捷指令标签顺序已更新"
}
```
#### PUT /api/v1/quick-commands/reorder
- **请求**:
```json
{
"commandIds": [11, 7, 9, 2]
}
```
- **响应**:
```json
{
"message": "快捷指令顺序已更新"
}
```
#### PUT /api/v1/quick-commands/reorder-by-tag
- **请求**:
```json
{
"tagId": 3,
"commandIds": [7, 11, 9]
}
```
- **响应**:
```json
{
"message": "标签内快捷指令顺序已更新"
}
```
### 数据模型
| 字段 | 类型 | 说明 |
|------|------|------|
| `quick_commands.sort_order` | `INTEGER` | 快捷指令的全局手动顺序,供扁平视图与未标记分组使用 |
| `quick_command_tags.sort_order` | `INTEGER` | 快捷指令分组的手动顺序 |
| `quick_command_tag_associations.sort_order` | `INTEGER` | 某条命令在某个标签分组内的手动顺序 |
| `QuickCommandWithTags.tagOrders` | `Record<number, number>` | 返回给前端的“标签 ID -> 组内顺序”映射 |
| `QuickCommandSortByType` | `'manual' | 'name' | 'usage_count' | 'last_used'` | 前端命令列表排序模式 |
---
## 4. 核心场景
### 场景: 调整分组顺序
**模块**: frontend / backend
**条件**: 用户开启快捷指令标签展示,且当前不处于搜索过滤状态。
**行为**: 用户拖动某个已标记分组的标题句柄,前端更新本地拖拽列表并调用标签重排接口。
**结果**: 分组按用户定义的顺序显示,刷新后保持一致,“未标记”分组继续固定在已标记分组之后。
### 场景: 调整标签组内命令顺序
**模块**: frontend / backend
**条件**: 用户在某个标签分组内拖动命令项,且当前不处于搜索过滤状态。
**行为**: 前端将该分组内的命令 ID 顺序提交到标签内重排接口,并自动切换到手动排序模式。
**结果**: 当前分组内的命令顺序立即更新,后续刷新后仍保持该顺序,不影响其它标签组的局部顺序。
### 场景: 调整扁平命令顺序
**模块**: frontend / backend
**条件**: 用户关闭“显示快捷指令标签”设置后浏览扁平列表。
**行为**: 用户拖动命令项,前端提交全局命令重排接口。
**结果**: 扁平列表与“未标记”分组的手动顺序保持一致,仍可切换回名称或最近使用排序查看其它视图。
---
## 5. 技术决策
### quickcommands-drag-reorder#D001: 将“标签内命令顺序”存储在关联表,而不是 quick_commands 主表
**日期**: 2026-04-19
**状态**: 已采纳
**背景**: 一条快捷指令可以绑定多个标签,因此同一条命令可能同时出现在多个分组中。如果组内顺序只存到 `quick_commands` 主表,就无法表达“同一条命令在 A 组和 B 组中的位置不同”。
**选项分析**:
| 选项 | 优点 | 缺点 |
|------|------|------|
| A: 仅在 `quick_commands` 存一个 `sort_order` | 结构简单,接口少 | 无法支持多标签命令在不同分组中的不同顺序 |
| B: 在 `quick_command_tag_associations` 存组内 `sort_order`,命令表保留全局 `sort_order` | 语义完整,能兼容分组视图与扁平视图 | 实现比单表排序稍复杂,需要额外重排接口 |
**决策**: 选择方案 B
**理由**: 这是唯一能同时满足“分组内可排序”和“命令可绑定多个标签”两项约束的方案,同时仍能通过命令表上的全局顺序支持扁平视图。
**影响**: backend, frontend
### quickcommands-drag-reorder#D002: 保留现有名称与最近使用排序,同时新增手动排序模式承接拖拽结果
**日期**: 2026-04-19
**状态**: 已采纳
**背景**: 现有快捷指令视图已经有按名称与最近使用查看命令的需求,直接移除会造成回归;但拖拽排序又必须有一个稳定的“手动顺序”视图承接。
**选项分析**:
| 选项 | 优点 | 缺点 |
|------|------|------|
| A: 用拖拽排序完全替代名称和最近使用排序 | 交互简单 | 会删除已有浏览方式,造成功能回退 |
| B: 增加 `manual` 模式,并在拖拽完成后自动切换到该模式 | 兼容现有浏览模式,同时让拖拽结果立即可见 | 排序状态管理略复杂 |
**决策**: 选择方案 B
**理由**: 能在不删除现有排序入口的前提下,为拖拽排序提供明确而可持久化的展示模式。
**影响**: frontend
---
## 6. 成果设计
### 设计方向
- **美学基调**: 延续现有工作台深色工具面板风格,在不改变整体布局语言的前提下,加入轻量的“可拖动”信号,让快捷指令列表更像可编排控制台而不是静态目录。
- **记忆点**: 分组标题和命令行都带有低干扰的拖拽句柄,拖动时保持现有卡片与高亮体系,仅在当前位置给出明确占位反馈。
- **参考**: 当前 `QuickCommandsView.vue` 的工作台卡片样式,以及连接树拖拽占位反馈的交互方向。
### 视觉要素
- **配色**: 继续复用现有主题变量与 hover/highlight 色,不新增独立色板,只让拖拽句柄在 hover 与拖拽时增强对比。
- **字体**: 沿用当前工作台文本和命令 monospace 字体体系,避免因交互增强引入新的字体层级。
- **布局**: 不改动现有控制栏、分组头和命令项的主体结构,仅在左侧插入窄句柄区域,并在拖拽态显示占位边框。
- **动效**: 复用 `vuedraggable` 的位移动画与现有过渡时间,保证拖放反馈清晰但不过度跳动。
- **氛围**: 保持克制、专业的终端工作台气质,把“可重排”表达为操作强化,而不是视觉重设计。
### 技术约束
- **可访问性**: 拖拽增强不能破坏现有单击选中、双击执行、键盘 `Enter` 执行与右键菜单入口。
- **响应式**: 继续兼容现有紧凑模式与工作台不同宽度场景,句柄区域不能挤占命令文本的主要可读空间。
@@ -0,0 +1,61 @@
# 任务清单: quickcommands-drag-reorder
> **@status:** completed | 2026-04-19 02:49
```yaml
@feature: quickcommands-drag-reorder
@created: 2026-04-19
@status: completed
@mode: R2
```
## 进度概览
| 完成 | 失败 | 跳过 | 总数 |
|------|------|------|------|
| 8 | 0 | 0 | 8 |
---
## 任务列表
### 1. 数据层与迁移
- [√] 1.1 在 `packages/backend/src/database/schema.ts``packages/backend/src/database/migrations.ts` 中为快捷指令、快捷指令标签和标签关联表增加 `sort_order` 字段,并为历史数据回填稳定初始顺序 | depends_on: []
- [√] 1.2 在 `packages/backend/src/quick-commands/quick-commands.repository.ts``packages/backend/src/quick-command-tags/quick-command-tag.repository.ts` 中扩展顺序读取、写入和标签关联保序逻辑 | depends_on: [1.1]
### 2. 后端重排接口
- [√] 2.1 在 `packages/backend/src/quick-commands/` 业务域中新增全局命令重排和标签内命令重排接口 | depends_on: [1.2]
- [√] 2.2 在 `packages/backend/src/quick-command-tags/` 业务域中新增标签分组重排接口,并让新增标签默认追加到末尾 | depends_on: [1.2]
### 3. 前端状态与交互
- [√] 3.1 在 `packages/frontend/src/stores/quickCommands.store.ts` 中新增手动排序模式、顺序元数据解析和命令重排 action | depends_on: [2.1]
- [√] 3.2 在 `packages/frontend/src/stores/quickCommandTags.store.ts` 中支持标签顺序元数据和分组重排 action | depends_on: [2.2]
- [√] 3.3 在 `packages/frontend/src/views/QuickCommandsView.vue` 中接入分组拖拽、组内命令拖拽、扁平列表拖拽与搜索态禁用逻辑 | depends_on: [3.1, 3.2]
### 4. 验证与同步
- [√] 4.1 执行 `npm run build --workspace @nexus-terminal/backend``npm run build --workspace @nexus-terminal/frontend`,验证类型检查和构建通过 | depends_on: [3.3]
- [√] 4.2 同步更新 `.helloagents/modules/frontend.md``.helloagents/modules/backend.md``.helloagents/CHANGELOG.md`,记录本次拖拽排序能力 | depends_on: [4.1]
---
## 执行日志
| 时间 | 任务 | 状态 | 备注 |
|------|------|------|------|
| 2026-04-19 02:08 | DESIGN | completed | 已确认采用“标签顺序 + 全局命令顺序 + 标签内命令顺序”三层持久化方案 |
| 2026-04-19 02:28 | 1.1 / 1.2 | completed | 已为三张快捷指令相关表补齐 `sort_order` 字段,并完成 repository 层顺序读写与标签关联保序改造 |
| 2026-04-19 02:39 | 2.1 / 2.2 | completed | 已补齐快捷指令与快捷指令标签的重排接口和路由,新增标签默认追加到末尾 |
| 2026-04-19 02:58 | 3.1 / 3.2 | completed | 前端 store 已支持 `manual / name / last_used` 排序模式、顺序元数据解析与重排 action |
| 2026-04-19 03:06 | 3.3 | completed | `QuickCommandsView.vue` 已支持分组拖拽、组内命令拖拽、扁平列表拖拽,并在搜索态禁用重排 |
| 2026-04-19 03:09 | 4.1 | completed | `npm run build --workspace @nexus-terminal/backend``npm run build --workspace @nexus-terminal/frontend` 均通过;前端仅保留既有 chunk size warnings |
| 2026-04-19 03:12 | 4.2 | completed | 已同步 frontend/backend 模块文档与 CHANGELOG,记录快捷指令拖拽排序能力 |
---
## 执行备注
> 本次实现对多标签命令采用“关联表局部顺序 + 命令表全局顺序”的双层建模:标签组内拖拽只影响该标签关联顺序,未标记分组和扁平列表拖拽则回写全局命令顺序,从而避免多标签命令在不同分组中的排序语义互相覆盖。
@@ -0,0 +1 @@
{"status":"completed","completed":4,"failed":0,"pending":0,"total":4,"done":4,"percent":100,"current":"连接卡片默认测试按钮调整已完成,待归档方案包","updated_at":"2026-04-19 02:18:00"}
@@ -0,0 +1,108 @@
# 变更提案: connection-card-default-test-button
## 元信息
```yaml
类型: 修复增强
方案类型: implementation
优先级: P2
状态: 已完成
状态说明: SSH 连接卡片默认显示“连接 / 测试 / 更多”,并从更多菜单移除重复测试入口
创建: 2026-04-19
```
---
## 1. 需求
### 背景
连接管理页当前已将连接卡片行内操作收敛为“连接”主按钮和“更多”菜单,但 SSH 连接常用的单连接“测试”仍被藏在更多菜单里。用户当前希望默认直接看到“连接 / 测试 / 更多”三段式操作区,减少进入二级菜单才能测试的额外点击。
### 目标
- 让 SSH 连接卡片默认显示“连接 / 测试 / 更多”三个按钮。
- 复用现有单连接测试状态、文案和禁用逻辑,不新增后端接口或测试链路。
- 保持非 SSH 连接卡片的默认操作区不变,避免把不支持的测试入口暴露出来。
### 约束条件
```yaml
范围约束: 仅调整 packages/frontend/src/views/ConnectionsView.vue 的连接卡片操作区与相关知识库记录
交互约束: “测试”默认显示仅适用于 SSH 连接,RDP/VNC 仍不提供默认测试按钮
实现约束: 必须复用现有 getSingleTestButtonInfo() 与 handleTestSingleConnection() 逻辑
兼容约束: 保持当前 flex-wrap 布局、主题 token 和批量模式下的现有交互行为
```
### 验收标准
- [x] SSH 连接卡片默认操作区显示“连接 / 测试 / 更多”
- [x] SSH 连接的“测试”状态继续显示既有的测试中 spinner、禁用态与 title
- [x] 更多菜单不再重复显示 SSH 的“测试”项,非 SSH 连接的默认按钮区保持现状
- [x] 前端构建通过,连接管理页相关知识库描述已同步
---
## 2. 方案
### 技术方案
`ConnectionsView.vue` 的连接卡片操作区中,将原本只在 SSH 更多菜单里出现的单连接“测试”操作提升到行内按钮区,插入到“连接”和“更多”之间,并继续通过 `getSingleTestButtonInfo()` 复用文本、图标、禁用状态和提示文案,通过 `handleTestSingleConnection()` 复用既有测试执行链路。与此同时,从 SSH 的更多菜单中移除重复的“测试”项,避免同一动作出现两个入口。
### 影响范围
```yaml
涉及模块:
- frontend: ConnectionsView.vue
- frontend: .helloagents/modules/frontend.md
- workspace-root: .helloagents/CHANGELOG.md 与 archive 归档记录
预计变更文件: 5-7
```
### 风险评估
| 风险 | 等级 | 应对 |
|------|------|------|
| 行内按钮增加后在窄宽度卡片上更容易换行 | 低 | 保持现有 `flex flex-wrap` 布局与紧凑按钮尺寸,让小屏自动折行 |
| 若保留菜单里的测试项会导致同一动作重复暴露 | 低 | 将 SSH 更多菜单中的测试入口一并移除,只保留默认按钮 |
| 非 SSH 连接误显示测试入口会造成无效操作认知 | 低 | 明确限定 `conn.type === 'SSH'` 时才显示默认测试按钮 |
---
## 3. 技术设计(可选)
> N/A,本次不涉及架构、接口或数据模型变更。
---
## 4. 核心场景
### 场景: SSH 连接卡片的默认操作区
**模块**: frontend
**条件**: 用户进入连接管理页,列表中存在 SSH 类型连接
**行为**: 每张 SSH 连接卡片默认显示“连接 / 测试 / 更多”三个按钮,点击测试后继续走现有单连接测试逻辑
**结果**: 用户无需进入更多菜单即可直接测试 SSH 连接
### 场景: 非 SSH 连接卡片保持现状
**模块**: frontend
**条件**: 用户进入连接管理页,列表中存在 RDP 或 VNC 类型连接
**行为**: 卡片默认操作区仍保持“连接 / 更多”结构,不显示无效的测试按钮
**结果**: 非 SSH 连接不会暴露不支持的测试入口
---
## 5. 技术决策
> 本方案不涉及新的架构级技术决策;沿用现有连接测试能力与连接管理页设计体系。
---
## 6. 成果设计
### 设计方向
- **美学基调**: 延续当前连接管理页的深色运维控制台风格,通过“一主两辅”的按钮层级表达操作优先级,保持克制而明确的操作密度
- **记忆点**: SSH 连接卡片在行尾固定呈现“连接 / 测试 / 更多”的三按钮条,常用操作一眼可达
- **参考**: 现有 `ConnectionsView.vue` 卡片样式与主题 token 体系
### 视觉要素
- **配色**: 保留主操作按钮 `bg-button` / `text-button-text`,测试与更多按钮继续使用 `bg-background``border-border``hover:bg-border`
- **字体**: 沿用项目现有界面字体体系与 `text-sm` 层级,不引入新的字体表达
- **布局**: 维持右侧按钮区 `flex-wrap`,在主按钮和更多菜单之间插入同级的测试按钮,保证桌面端横排、窄宽度时可自然换行
- **动效**: 延续现有 hover 过渡和测试中 spinner 反馈,不额外引入新动效
- **氛围**: 保持当前卡片式深色面板与边框层次,不改变页面整体视觉基调
### 技术约束
- **可访问性**: 按钮需保留明确文本标签、title 与禁用态视觉反馈
- **响应式**: 不破坏当前 `justify-start xl:justify-end``flex-wrap` 的响应式布局策略
@@ -0,0 +1,50 @@
# 任务清单: connection-card-default-test-button
> **@status:** completed | 2026-04-19 02:18
```yaml
@feature: connection-card-default-test-button
@created: 2026-04-19
@status: completed
@mode: R2
```
## 进度概览
| 完成 | 失败 | 跳过 | 总数 |
|------|------|------|------|
| 4 | 0 | 0 | 4 |
---
## 任务列表
### 1. 方案与范围确认
- [√] 1.1 创建连接卡片默认测试按钮方案包并锁定范围到连接管理页行内操作区 | depends_on: []
### 2. 前端交互调整
- [√] 2.1 将 SSH 连接卡片的“测试”操作提升为默认行内按钮,顺序调整为“连接 / 测试 / 更多” | depends_on: [1.1]
- [√] 2.2 移除 SSH 更多菜单中的重复“测试”入口,并保持非 SSH 连接卡片默认操作区不变 | depends_on: [2.1]
### 3. 验证与同步
- [√] 3.1 运行前端构建并做连接管理页按钮结构验证,同步 frontend 模块文档、CHANGELOG 与归档记录 | depends_on: [2.2]
---
## 执行日志
| 时间 | 任务 | 状态 | 备注 |
|------|------|------|------|
| 2026-04-19 02:10 | 1.1 | 完成 | 创建 implementation 方案包,范围锁定为 SSH 连接卡片默认按钮区调整 |
| 2026-04-19 02:13 | 2.1 | 完成 | 在 `ConnectionsView.vue` 中将 SSH 单连接测试提升为默认行内按钮,位于“连接”和“更多”之间 |
| 2026-04-19 02:14 | 2.2 | 完成 | 删除 SSH 更多菜单中的重复“测试”入口,保留非 SSH 卡片为“连接 / 更多” |
| 2026-04-19 02:18 | 3.1 | 完成 | `npm run build --workspace @nexus-terminal/frontend` 通过;预览环境因缺少后端认证接口仅验证到应用启动与路由守卫重定向 |
---
## 执行备注
> 用户已确认仅 SSH 连接默认显示“测试”按钮,RDP/VNC 保持当前“连接 / 更多”结构。运行态预览可启动,但由于本地预览缺少后端认证接口,`/connections` 会被路由守卫重定向到 `/login`,因此本次对连接卡片交互的最终运行态确认仍需在有登录态的环境中补一次人工目视检查。
+5
View File
@@ -7,6 +7,9 @@
| 时间戳 | 名称 | 类型 | 涉及模块 | 决策 | 结果 |
|--------|------|------|---------|------|------|
| 202604190208 | quickcommands-drag-reorder | - | - | - | ✅完成 |
| 202604190210 | connection-card-default-test-button | implementation | frontend | - | ✅完成 |
| 202604190201 | connection-password-visibility-toggle | - | - | - | ✅完成 |
| 202604160350 | workflow-service-scoped-docker-builds | - | - | - | ✅完成 |
| 202604152323 | status-monitor-reference-layout-parity | implementation | frontend | status-monitor-reference-layout-parity#D001 | ✅完成 |
| 202604152147 | status-monitor-process-manager-modal | - | - | - | ✅完成 |
@@ -56,6 +59,8 @@
## 按月归档
### 2026-04
- [202604190210_connection-card-default-test-button](./2026-04/202604190210_connection-card-default-test-button/) - 将连接管理页 SSH 连接卡片的默认操作区调整为“连接 / 测试 / 更多”,并移除更多菜单中的重复测试入口
- [202604190201_connection-password-visibility-toggle](./2026-04/202604190201_connection-password-visibility-toggle/) - 为连接新增/编辑表单与登录凭证管理弹窗补充密码显隐切换,默认仍隐藏,仅在本地输入端切换明文核对
- [202604152323_status-monitor-reference-layout-parity](./2026-04/202604152323_status-monitor-reference-layout-parity/) - 将右侧状态监控默认视图重排为更贴近参考图的窄屏监控布局,修正顶部信息区与模块内部左右关系
- [202604122248_connections-tag-batch-management](./2026-04/202604122248_connections-tag-batch-management/) - 为连接管理页新增标签批量管理弹窗,并补齐后端批量标签删除策略
- [202604120709_quickcommands-double-click-tooltip](./2026-04/202604120709_quickcommands-double-click-tooltip/) - 将快捷命令列表改为单击选中、双击执行,并在 hover 时显示完整命令
+5
View File
@@ -80,3 +80,8 @@
**条件**: `StatusMonitorService` 为前端工作区持续轮询服务器状态。
**行为**: 当前状态采集链路除 `free``df``/proc/stat``/proc/net/dev` 外,还会补充解析 `memFree``memCached``diskAvailable``diskMountPoint``diskFsType``diskDevice`,并基于 `/proc/diskstats` 计算根设备的磁盘读写速率;CPU 规格信息则会先读取 CPU 型号,再通过 `nproc``getconf _NPROCESSORS_ONLN``grep -c '^processor' /proc/cpuinfo``lscpu` 多级回退获取 `cpuCores`;本轮还新增服务器时区、运行时间和默认进程摘要采集。与此同时,`websocket/connection.ts` 新增 `process:list``process:signal` 消息分发,后端会在当前活动 SSH 会话上下文中执行 `ps``kill` 指令,返回完整进程列表及结束/强制结束结果。
**结果**: 前端默认状态监控可以展示更完整的小屏监控信息,而“查看全部”进程管理 modal 也能沿同一 SSH 会话上下文安全复用进程查询与操作能力。
### 快捷指令顺序持久化
**条件**: 前端快捷指令视图提交分组拖拽、标签内命令拖拽或扁平列表命令拖拽结果。
**行为**: packages/backend/src/database/schema.ts 与 migrations.ts 现在为 quick_commands、quick_command_tags 与 quick_command_tag_associations 三张表补齐 sort_order 字段;quick-commands 业务域新增 /api/v1/quick-commands/reorder 与 /api/v1/quick-commands/reorder-by-tagquick-command-tags 业务域新增 /api/v1/quick-command-tags/reorder。同时标签关联写入从“先删后插”调整为增量同步,保留命令已存在标签关联的原组内顺序,仅为新增关联追加新的末尾顺序。
**结果**: 后端可以稳定表达“标签顺序”“命令全局顺序”和“命令在某个标签组内的局部顺序”三层语义,并保证历史数据库升级后也能直接承接前端拖拽排序能力。
File diff suppressed because one or more lines are too long