fix(frontend): 修复文件管理器删除与上传稳定性
补齐文件管理器右键子菜单点击展开,新增拖拽上传目标确认, 并在上传完成后自动刷新当前可见目录 目录删除改为区分仅删空目录与强制递归删除,删除后自动回退 失效路径,避免文件树持续报 No such file 同步后端 sftp:rmdir 的 recursive 分支,并将关于页与版本检查 默认仓库链接切换到 Micah123321/nexus-terminal
This commit is contained in:
+124
@@ -0,0 +1,124 @@
|
||||
# 变更提案: file-manager-root-sibling-bootstrap
|
||||
|
||||
## 元信息
|
||||
```yaml
|
||||
类型: 修复
|
||||
方案类型: implementation
|
||||
优先级: P1
|
||||
状态: 已完成
|
||||
创建: 2026-03-26
|
||||
完成: 2026-03-26
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 1. 需求
|
||||
|
||||
### 背景
|
||||
工作台文件区近期已调整为固定 `/` 根节点树,但用户反馈在新开终端连接后,`/` 展开时仍只显示 `root`,没有补齐 `/` 下其它同级目录。结合现场代码,文件区启动时会同时涉及 `/` 根目录预加载和当前工作目录(如 `/root`)加载,这可能导致 `/` 的目录响应被当作过时请求忽略,从而树里只保留当前路径链路。
|
||||
|
||||
### 目标
|
||||
- 保持当前工作目录(如 `/root`)仍是当前操作目录。
|
||||
- 在新会话初始化后,`/` 展开时补齐 `/` 下其它同级目录,而不只显示 `root`。
|
||||
- 避免为了补树而把当前目录错误切回 `/`。
|
||||
|
||||
### 约束条件
|
||||
```yaml
|
||||
范围约束: 优先限制在 FileManager.vue / useSftpActions.ts,避免牵涉后端接口
|
||||
交互约束: 当前工作目录保持不变,文件树补全属于后台树状态修正
|
||||
兼容约束: 已有目录展开、路径输入、右键菜单和上传能力不回退
|
||||
风险约束: 不应把所有过时 readdir 响应都重新接受,只修正根目录初始化场景
|
||||
```
|
||||
|
||||
### 验收标准
|
||||
- [ ] 新开终端连接后,`/` 根节点展开能显示 `root` 外的同级目录
|
||||
- [ ] 当前操作目录仍保持在实际工作目录(如 `/root`),不会因补树自动跳回 `/`
|
||||
- [ ] 前端构建通过
|
||||
|
||||
---
|
||||
|
||||
## 2. 方案
|
||||
|
||||
### 技术方案
|
||||
在 `useSftpActions.ts` 的 `readdir` 成功处理里,为 `/` 根目录引入一次性“后台树补全”容忍逻辑:若 `/` 的响应因为当前路径请求更晚而变成 stale,但根树尚未加载,则仍允许把 `/` 的子节点合并进 `fileTree`,同时不改 `currentPath`、`isLoading` 和当前请求指针。这样既保留 `/root` 作为当前工作目录,又能把 `/` 下的一级同级目录补齐到树中。
|
||||
|
||||
### 影响范围
|
||||
```yaml
|
||||
涉及模块:
|
||||
- frontend: `packages/frontend/src/composables/useSftpActions.ts`
|
||||
预计变更文件: 1-3
|
||||
```
|
||||
|
||||
### 风险评估
|
||||
| 风险 | 等级 | 应对 |
|
||||
|------|------|------|
|
||||
| 误把真正过时的目录响应写回树,造成状态回退 | 中 | 仅对 `path === '/'` 且根树尚未加载的初始化场景放行 |
|
||||
| 根树补全后 currentPath 被错误覆盖为 `/` | 中 | stale 根响应只合并树,不更新 currentPath / isLoading |
|
||||
| 修复逻辑不足以覆盖其它层级目录的竞态 | 低 | 本轮只解决用户明确报告的 `/` 同级目录缺失问题 |
|
||||
|
||||
---
|
||||
|
||||
## 3. 技术设计(可选)
|
||||
|
||||
### 架构设计
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A[loadDirectory('/')] --> B[readdir success for '/']
|
||||
C[loadDirectory('/root')] --> D[readdir success for '/root']
|
||||
B --> E[background root tree bootstrap]
|
||||
D --> F[currentPath stays /root]
|
||||
```
|
||||
|
||||
### 数据模型
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `loadingRequestId` | `string \| null` | 当前前台加载请求 ID |
|
||||
| `fileTree.childrenLoaded` | `boolean` | `/` 根节点是否已完成首轮树加载 |
|
||||
| `currentPathRef` | `Ref<string>` | 当前操作目录,不应被 stale 根响应覆盖 |
|
||||
|
||||
---
|
||||
|
||||
## 4. 核心场景
|
||||
|
||||
### 场景: 新会话进入 `/root`,同时补齐 `/` 的一级兄弟目录
|
||||
**模块**: frontend
|
||||
**条件**: 新终端连接建立后,文件区需要同时知道当前工作目录和 `/` 根树。
|
||||
**行为**: `/root` 继续作为当前工作目录加载;若 `/` 的目录响应稍后到达且根树尚未完成初始化,仍允许把 `/` 的一级目录合并进树,但不改变当前目录。
|
||||
**结果**: 用户在树里能看到 `/` 下多个同级目录,同时右上方当前路径仍维持在 `/root`。
|
||||
|
||||
---
|
||||
|
||||
## 5. 技术决策
|
||||
|
||||
### file-manager-root-sibling-bootstrap#D001: 仅对 stale 的 `/` 根目录响应做树补全放行,而不是全面接收所有 stale readdir 响应
|
||||
**日期**: 2026-03-26
|
||||
**状态**: ✅采纳
|
||||
**背景**: 用户问题集中在新会话下 `/` 根树只剩当前路径链路;广义接收所有 stale 响应会带来状态回退风险。
|
||||
**选项分析**:
|
||||
| 选项 | 优点 | 缺点 |
|
||||
|------|------|------|
|
||||
| A: 只对 `/` 且根树未加载的 stale 响应放行 | 改动最小,直接覆盖当前缺陷,风险可控 | 只修复根目录初始化场景 |
|
||||
| B: 接收所有 stale readdir 响应并更新树 | 可能覆盖更多竞态 | 容易把旧目录状态写回,风险高 |
|
||||
**决策**: 选择方案A
|
||||
**理由**: 这次是已知初始化竞态,不需要把整个目录加载协议重写。先做可验证、可控的定点修复更稳妥。
|
||||
**影响**: frontend
|
||||
|
||||
---
|
||||
|
||||
## 6. 成果设计
|
||||
|
||||
### 设计方向
|
||||
- **美学基调**: N/A
|
||||
- **记忆点**: N/A
|
||||
- **参考**: 用户提供的新终端文件树截图
|
||||
|
||||
### 视觉要素
|
||||
- **配色**: N/A
|
||||
- **字体**: N/A
|
||||
- **布局**: N/A
|
||||
- **动效**: N/A
|
||||
- **氛围**: N/A
|
||||
|
||||
### 技术约束
|
||||
- **可访问性**: N/A
|
||||
- **响应式**: N/A
|
||||
Reference in New Issue
Block a user