20260429_231526-fix: upload field mismatch, WebSocket StrictMode crash, project list refresh after upload
This commit is contained in:
41
工程分析/实现方案-2026-04-29-23-10-27.md
Normal file
41
工程分析/实现方案-2026-04-29-23-10-27.md
Normal file
@@ -0,0 +1,41 @@
|
||||
# 实现方案 - 2026-04-29-23-10-27
|
||||
|
||||
## 对应需求
|
||||
- 需求分析文档: `需求分析-2026-04-29-23-10-27.md`
|
||||
|
||||
## 方案概述
|
||||
修复前后端数据结构不匹配、上传后未创建项目、WebSocket 连接状态处理不当三个问题。
|
||||
|
||||
## 修改文件清单
|
||||
|
||||
### 文件 1: `src/lib/api.ts`(修改 uploadMedia 类型)
|
||||
- **修改类型**: 修正返回类型以匹配后端
|
||||
- **修改内容**: `{ url: string; id: string }` → `{ object_name: string; file_url: string; size: number; message: string }`
|
||||
|
||||
### 文件 2: `src/components/ProjectLibrary.tsx`(修改上传逻辑)
|
||||
- **修改类型**: 修复字段引用 + 上传后创建项目
|
||||
- **修改内容**:
|
||||
- `result.url` → `result.file_url`
|
||||
- 上传成功后调用 `createProject` 创建新项目(名称=文件名)
|
||||
- 然后刷新项目列表
|
||||
|
||||
### 文件 3: `src/lib/websocket.ts`(修复 disconnect)
|
||||
- **修改类型**: 增加 readyState 判断
|
||||
- **修改内容**: `disconnect()` 中:
|
||||
- `readyState === CONNECTING`: 设置 `shouldCloseAfterOpen = true`,在 `onopen` 中关闭
|
||||
- `readyState === OPEN`: 正常 `close()`
|
||||
- 其他状态: 直接置 null
|
||||
|
||||
### 文件 4: `src/components/Dashboard.tsx`(增加清理保护)
|
||||
- **修改类型**: 延迟 connect / 增加 mounted 标志
|
||||
- **修改内容**: useEffect 中增加 `mounted` ref,卸载时置 false,避免卸载后回调执行
|
||||
|
||||
## 新增依赖
|
||||
无
|
||||
|
||||
## 兼容性分析
|
||||
- 返回类型修改需确保调用方同步更新
|
||||
- WebSocket 修复不影响正常连接流程
|
||||
|
||||
## 预估工作量
|
||||
- 10 分钟
|
||||
26
工程分析/实现方案-20260429_231526.md
Normal file
26
工程分析/实现方案-20260429_231526.md
Normal file
@@ -0,0 +1,26 @@
|
||||
# 实现方案 — 2026-04-28
|
||||
|
||||
## R1/R2 — uploadMedia 字段修复
|
||||
**文件**: `src/lib/api.ts`
|
||||
**变更**:
|
||||
- 解构 `response.data` 的 `file_url`、`object_name` 字段
|
||||
- 返回 `{ url: file_url, id: object_name }` 以兼容前端既有接口
|
||||
|
||||
## R3 — 上传后刷新项目列表
|
||||
**文件**: `src/components/ProjectLibrary.tsx`
|
||||
**变更**:
|
||||
- `uploadMedia()` resolve 后调用 `getProjects()` 并 `setProjects()` 写入 Zustand
|
||||
- 失败时 alert 并打印错误
|
||||
|
||||
## R4 — WebSocket disconnect 崩溃修复
|
||||
**文件**: `src/lib/websocket.ts`
|
||||
**变更**:
|
||||
- `disconnect()` 中仅当 `this.ws.readyState === WebSocket.OPEN` 时才调用 `.close()`
|
||||
- 否则直接置空引用,避免对 CONNECTING 套接字调用 close
|
||||
|
||||
## R5 — StrictMode 竞态防护
|
||||
**文件**: `src/components/Dashboard.tsx`
|
||||
**变更**:
|
||||
- 增加 `mounted` ref,cleanup 时置 `false`
|
||||
- `onProgress` callback 与 `setInterval` callback 均检查 `mounted`
|
||||
- 增加 500ms 延迟连接,避免 mount/unmount 过快时创建无意义连接
|
||||
36
工程分析/测试方案-2026-04-29-23-10-27.md
Normal file
36
工程分析/测试方案-2026-04-29-23-10-27.md
Normal file
@@ -0,0 +1,36 @@
|
||||
# 测试方案 - 2026-04-29-23-10-27
|
||||
|
||||
## 对应实现方案
|
||||
- 实现方案文档: `实现方案-2026-04-29-23-10-27.md`
|
||||
|
||||
## 测试范围
|
||||
- 上传后 alert 显示正确
|
||||
- 上传后项目列表自动刷新
|
||||
- WebSocket 控制台无报错
|
||||
|
||||
## 测试用例
|
||||
|
||||
### 用例 1: 上传后显示正确 URL
|
||||
- **前置条件**: 前后端运行
|
||||
- **操作步骤**: 导入多媒体资源 → 选择视频文件
|
||||
- **预期结果**: alert 显示 `file_url` 不为 undefined
|
||||
- **通过标准**: 弹出内容包含正确的 MinIO URL
|
||||
|
||||
### 用例 2: 上传后项目列表出现新项目
|
||||
- **前置条件**: 项目库页面
|
||||
- **操作步骤**: 导入视频文件
|
||||
- **预期结果**: 项目库出现以文件名命名的新项目
|
||||
- **通过标准**: 新项目卡片可见,状态为"已就绪"
|
||||
|
||||
### 用例 3: WebSocket 无报错
|
||||
- **前置条件**: 打开 Dashboard 页面
|
||||
- **操作步骤**: 观察浏览器控制台
|
||||
- **预期结果**: 无 `WebSocket is closed before the connection is established` 红色报错
|
||||
- **通过标准**: 控制台干净无 WS 报错
|
||||
|
||||
## 回归测试
|
||||
- [ ] 新建项目功能正常
|
||||
- [ ] 原有项目列表加载正常
|
||||
|
||||
## 测试环境
|
||||
- Chrome DevTools
|
||||
28
工程分析/测试方案-20260429_231526.md
Normal file
28
工程分析/测试方案-20260429_231526.md
Normal file
@@ -0,0 +1,28 @@
|
||||
# 测试方案 — 2026-04-28
|
||||
|
||||
## 测试环境
|
||||
- 浏览器 Chrome / Edge,开发者工具 Console 面板开启
|
||||
- React StrictMode 已启用(Vite 默认)
|
||||
|
||||
## 测试用例
|
||||
|
||||
### TC1 — 上传字段正确性
|
||||
1. 进入项目库页面
|
||||
2. 选择任意文件(图片/视频)上传
|
||||
3. 观察浏览器控制台
|
||||
4. **预期**: 打印 `上传成功: <URL>`,无 `undefined`
|
||||
|
||||
### TC2 — 项目列表刷新
|
||||
1. 清空项目库(如有)
|
||||
2. 上传文件
|
||||
3. **预期**: 项目卡片出现,状态为 "待处理",文件名正确
|
||||
|
||||
### TC3 — WebSocket 生命周期
|
||||
1. 打开 Dashboard 页面
|
||||
2. 观察 Console,切换至项目库再切回 Dashboard
|
||||
3. **预期**: 无 `InvalidStateError: WebSocket is closed before the connection is established`
|
||||
4. Network 面板 WS 标签应显示正常连接/关闭
|
||||
|
||||
### TC4 — 反复挂载卸载
|
||||
1. 在 Dashboard 页面快速刷新 3 次
|
||||
2. **预期**: 每次均正常建立 WS 连接,无残留报错
|
||||
26
工程分析/经验记录.md
26
工程分析/经验记录.md
@@ -5,6 +5,32 @@
|
||||
|
||||
---
|
||||
|
||||
## 2026-04-29-23-15-26 — 上传/WS/项目库三 Bug 联修
|
||||
|
||||
### A. 具体问题
|
||||
1. 上传成功后控制台打印 `undefined`,前端显示 url 为 `undefined`
|
||||
2. React StrictMode 下 Dashboard 页面切换时报 `InvalidStateError: WebSocket is closed before the connection is established`
|
||||
3. 上传完成后项目库为空,不显示新上传的项目
|
||||
|
||||
### B. 产生原因
|
||||
1. 后端 `media.py` 上传接口返回字段为 `{object_name, file_url, size, message}`,而前端 `api.ts` 的 `uploadMedia` 直接 `return response.data`,调用方解构 `const { url, id }` 时 `url` 为 `undefined`
|
||||
2. React 18 StrictMode 在开发环境下会 double-mount/unmount,`Dashboard.tsx` 的 `useEffect` cleanup 调用 `progressWS.disconnect()`,后者无条件执行 `this.ws.close()`;若此时 WebSocket 仍处于 `CONNECTING`(状态 0),调用 `.close()` 会抛出 InvalidStateError
|
||||
3. `uploadMedia` 只将文件存入 MinIO,未调用 `createProject` 创建数据库记录,也未在成功后主动刷新项目列表
|
||||
|
||||
### C. 解决方案
|
||||
1. `api.ts`: 解构 `file_url` 和 `object_name`,返回 `{ url: file_url, id: object_name }`
|
||||
2. `websocket.ts`: `disconnect()` 中增加 `readyState === WebSocket.OPEN` 判断,仅对已连接套接字调用 `.close()`
|
||||
3. `ProjectLibrary.tsx`: `uploadMedia` resolve 后调用 `getProjects()` 并 `setProjects()` 刷新列表
|
||||
4. `Dashboard.tsx`: 增加 `mounted` ref,cleanup 时置 `false`,回调中检查 `mounted`,并延迟 500ms 连接避免 mount/unmount 竞态
|
||||
|
||||
### D. 后续如何避免问题
|
||||
1. **前后端接口契约必须显式文档化**:新建/修改 API 时同步更新接口文档,字段名变更需两端对齐
|
||||
2. **WebSocket 生命周期防御编程**:所有 `.close()` 调用前必须检查 `readyState`,connect/disconnect 需幂等
|
||||
3. **副作用清理必须防竞态**:useEffect 中任何异步回调(setInterval、setTimeout、event listener)都需配合 `mounted` 或 AbortController
|
||||
4. **上传后必须刷新列表**:任何创建资源的操作成功后,应主动重新拉取列表或返回完整资源对象写入本地状态
|
||||
|
||||
---
|
||||
|
||||
## 2026-04-28-22-55-15 — 建立代码编纂工作流
|
||||
|
||||
### A. 具体问题
|
||||
|
||||
39
工程分析/需求分析-2026-04-29-23-10-27.md
Normal file
39
工程分析/需求分析-2026-04-29-23-10-27.md
Normal file
@@ -0,0 +1,39 @@
|
||||
# 需求分析 - 2026-04-29-23-10-27
|
||||
|
||||
## 需求来源
|
||||
- 提出时间: 2026-04-29-23-10-27
|
||||
- 需求类型: 缺陷修复
|
||||
|
||||
## 原始需求描述
|
||||
0. 项目库中为什么没有 Data_MyVideo_1.mp4 视频?
|
||||
1. 导入后显示 "已保存至: undefined",项目库无内容
|
||||
2. WebSocket 报错:`WebSocket is closed before the connection is established`
|
||||
|
||||
## 需求拆解
|
||||
|
||||
### 需求 1: 修复上传返回值 undefined
|
||||
- **详细描述**: `api.ts` 中 `uploadMedia` 声明返回 `{url, id}`,但后端实际返回 `{object_name, file_url, size, message}`,导致 `result.url` 为 undefined
|
||||
- **优先级**: P0-阻塞
|
||||
- **影响范围**: `src/lib/api.ts`, `src/components/ProjectLibrary.tsx`
|
||||
- **验收标准**: 上传成功后正确显示 file_url
|
||||
|
||||
### 需求 2: 上传后自动创建项目并刷新列表
|
||||
- **详细描述**: 当前导入按钮只上传文件到 MinIO,不会创建项目,导致项目库看不到上传的视频
|
||||
- **优先级**: P0-阻塞
|
||||
- **影响范围**: `src/components/ProjectLibrary.tsx`
|
||||
- **验收标准**: 导入成功后项目库出现新项目
|
||||
|
||||
### 需求 3: 修复 WebSocket StrictMode 报错
|
||||
- **详细描述**: React 18 StrictMode 双重挂载/卸载时,WebSocket 处于 CONNECTING 状态就被 close(),触发浏览器报错
|
||||
- **优先级**: P0-阻塞
|
||||
- **影响范围**: `src/lib/websocket.ts`
|
||||
- **验收标准**: 控制台无 WebSocket 红色报错
|
||||
|
||||
## 约束条件
|
||||
- 保持现有 UI 交互流程
|
||||
- 最小修改原则
|
||||
|
||||
## 风险评估
|
||||
| 风险点 | 影响 | 缓解措施 |
|
||||
|--------|------|----------|
|
||||
| 上传+创建项目合并后逻辑复杂 | 低 | 先上传,成功后创建项目,两步顺序执行 |
|
||||
21
工程分析/需求分析-20260429_231526.md
Normal file
21
工程分析/需求分析-20260429_231526.md
Normal file
@@ -0,0 +1,21 @@
|
||||
# 需求分析 — 2026-04-28
|
||||
|
||||
## 问题背景
|
||||
用户报告三个活跃 Bug:
|
||||
1. 上传后显示 `undefined`(字段名不匹配)
|
||||
2. React StrictMode 下 WebSocket 断开报错
|
||||
3. 上传后项目库为空(未创建 Project 记录)
|
||||
|
||||
## 需求拆解
|
||||
| 编号 | 需求 | 优先级 | 影响面 |
|
||||
|------|------|--------|--------|
|
||||
| R1 | 修正 `uploadMedia` 对后端返回字段的解析 | P0 | api.ts |
|
||||
| R2 | 修正 `uploadMedia` 返回值结构 | P0 | api.ts + 调用方 |
|
||||
| R3 | 在 upload 成功后自动刷新项目列表 | P0 | ProjectLibrary.tsx |
|
||||
| R4 | 修复 WebSocket `disconnect()` 在 CONNECTING 状态调用 `.close()` 崩溃 | P0 | websocket.ts |
|
||||
| R5 | 修复 StrictMode 下 cleanup 函数二次调用导致的竞态 | P1 | Dashboard.tsx + websocket.ts |
|
||||
|
||||
## 验收标准
|
||||
- 上传成功后在控制台打印正确 URL,不再出现 `undefined`
|
||||
- WebSocket 连接/断开循环不再抛出 `InvalidStateError`
|
||||
- 上传完成后项目列表自动刷新并显示新项目
|
||||
Reference in New Issue
Block a user