2026-05-21-00-05-04 导入进度与压缩包支持
This commit is contained in:
57
工程分析/实现方案-2026-05-21-00-05-04.md
Normal file
57
工程分析/实现方案-2026-05-21-00-05-04.md
Normal file
@@ -0,0 +1,57 @@
|
||||
# 实现方案-2026-05-21-00-05-04
|
||||
|
||||
## 实现方案文档路径
|
||||
|
||||
`工程分析/实现方案-2026-05-21-00-05-04.md`
|
||||
|
||||
## 修改目标
|
||||
|
||||
- 项目库导入 DICOM/STL 时显示上传进度、文件数量和体积。
|
||||
- 将项目资产导入从 base64 JSON 改为 multipart 表单上传,降低浏览器内存占用。
|
||||
- 后端接收普通文件和压缩包,并在服务端展开 ZIP/TAR/TAR.GZ/TGZ/GZ。
|
||||
- 导入完成后继续刷新项目状态、清理缓存、保留覆盖确认逻辑。
|
||||
- 对 3D 模型导入崩溃原因给出技术修复:避免 `Promise.all(fileToBase64)` 和巨型 JSON body。
|
||||
|
||||
## 涉及路径
|
||||
|
||||
- `WebSite/src/lib/api.ts`
|
||||
- `WebSite/src/components/ProjectLibrary.tsx`
|
||||
- `WebSite/server.ts`
|
||||
- `WebSite/package.json`
|
||||
- `WebSite/package-lock.json`
|
||||
- `工程分析/经验记录.md`
|
||||
|
||||
## 技术路线
|
||||
|
||||
1. 引入 `multer` 接收 multipart 文件,使用内存上传缓冲后统一写入项目资产目录。
|
||||
2. 引入 `adm-zip` 解压 ZIP;TAR/TAR.GZ/TGZ 使用 Node `zlib` 与简单 tar header 解析;单文件 GZ 解压为原文件。
|
||||
3. 后端新增导入文件展开函数,统一过滤 DICOM/STL 目标扩展名,并防止路径穿越。
|
||||
4. 前端新增 `uploadProjectAssets`,使用 `XMLHttpRequest.upload.onprogress` 返回上传百分比。
|
||||
5. 项目库增加导入进度状态和紧凑进度条,上传完成后显示服务器解析/解压阶段。
|
||||
6. 文件选择器 accept 增加 `.zip,.tar,.tar.gz,.tgz,.gz`。
|
||||
|
||||
## 执行步骤
|
||||
|
||||
1. 写入需求、实现、测试方案。
|
||||
2. 安装 multipart 和 zip 解析依赖。
|
||||
3. 修改后端导入接口,兼容新的 multipart 上传。
|
||||
4. 修改前端 API 封装和项目库导入 UI。
|
||||
5. 执行 `npm run lint`、`npm run build`。
|
||||
6. 验证健康检查、首页响应和示例项目状态。
|
||||
7. 追加经验记录,提交推送 Gitea,重新部署服务。
|
||||
|
||||
## 兼容性与回滚方案
|
||||
|
||||
- 若 multipart 上传出现问题,可临时保留 JSON body 解析分支作为兼容回退。
|
||||
- 若压缩包解析失败,应返回明确错误,不写入半成品项目状态。
|
||||
- 如新增依赖不可用,可回退为仅支持普通文件和 TAR.GZ,ZIP 支持后续补齐。
|
||||
|
||||
## 预计文件变更
|
||||
|
||||
- 前端 API 1 个、项目库组件 1 个、后端服务 1 个、依赖清单 2 个、工程分析文档 4 个。
|
||||
|
||||
## 提交与部署策略
|
||||
|
||||
- 只暂存本次相关代码和工程分析文档。
|
||||
- commit message 包含 `2026-05-21-00-05-04` 与“导入进度与压缩包支持”。
|
||||
- 重新构建并使用 `tmux` 会话 `revoxelseg-dicom` 运行 4000 服务。
|
||||
58
工程分析/测试方案-2026-05-21-00-05-04.md
Normal file
58
工程分析/测试方案-2026-05-21-00-05-04.md
Normal file
@@ -0,0 +1,58 @@
|
||||
# 测试方案-2026-05-21-00-05-04
|
||||
|
||||
## 测试方案文档路径
|
||||
|
||||
`工程分析/测试方案-2026-05-21-00-05-04.md`
|
||||
|
||||
## 静态检查
|
||||
|
||||
- 执行 `cd WebSite && npm run lint`,确认 TypeScript 类型检查通过。
|
||||
- 使用 `rg` 检查旧的 `fileToBase64` 和 JSON 导入链路是否已移除或不再用于项目资产导入。
|
||||
|
||||
执行结果:`npm run lint` 已通过;项目库导入已不再使用 `fileToBase64` 或 `Promise.all(files.map(...base64))`。
|
||||
|
||||
## 构建检查
|
||||
|
||||
- 执行 `cd WebSite && npm run build`,确认生产构建通过。
|
||||
|
||||
执行结果:`npm run build` 已通过;Vite 仅提示既有 chunk 体积超过 500 kB。
|
||||
|
||||
## 关键业务场景验证
|
||||
|
||||
- 项目库 DICOM 影像导入时显示文件数、上传百分比和进度条。
|
||||
- 项目库 3D 模型导入时显示文件数、上传百分比和进度条。
|
||||
- 上传完成到服务端解压/解析期间显示“服务器处理中”状态。
|
||||
- 已有 DICOM/STL 时仍先弹出覆盖提醒。
|
||||
- 文件选择器允许普通 DICOM/STL,也允许 `.zip`、`.tar`、`.tar.gz`、`.tgz`、`.gz`。
|
||||
|
||||
## 医学影像数据相关边界验证
|
||||
|
||||
- 导入 ZIP 中的 STL 文件后,项目 `modelCount` 和 `stlFiles` 更新。
|
||||
- 导入 ZIP/TAR.GZ 中的 DICOM 文件后,项目 `dicomCount` 更新,并生成 DICOM 信息缓存。
|
||||
- 压缩包中无关文件不会进入项目资产目录。
|
||||
- 路径穿越条目不会写出上传目标目录。
|
||||
- 导入后清理 DICOM/STL/Fusion 缓存,避免旧预览残留。
|
||||
|
||||
执行结果:使用临时项目上传包含 `会厌.stl` 的 ZIP,接口返回 `modelCount: 1`、`stlFiles: ["会厌.stl"]`;验证后已删除临时项目和临时上传目录。
|
||||
|
||||
## 部署验证
|
||||
|
||||
- 重启 `tmux` 会话 `revoxelseg-dicom`。
|
||||
- 验证:
|
||||
- `curl http://127.0.0.1:4000/api/health`
|
||||
- `curl -I http://127.0.0.1:4000/`
|
||||
- `curl http://127.0.0.1:4000/api/projects` 中默认项目仍为 DICOM 300、STL 9。
|
||||
|
||||
执行结果:服务已用新代码临时重启并通过 `/api/health`、首页响应验证;当前运行态中默认项目已被用户导入过肝脏 STL,因此最终不以 STL 9 作为强制断言,恢复演示环境仍可回到默认数据。
|
||||
|
||||
## Git/Gitea 备份验证
|
||||
|
||||
- `git status --short` 确认暂存范围不包含无关历史删除或软著材料。
|
||||
- commit message 包含 `2026-05-21-00-05-04`。
|
||||
- 推送到 Gitea `main` 成功。
|
||||
|
||||
## 风险与回归关注点
|
||||
|
||||
- 大文件上传进度是上传阶段进度,不代表服务端解压完全结束。
|
||||
- `multer` 内存缓存仍会占用服务端内存,后续如需超大数据集,应改为磁盘临时文件流式处理。
|
||||
- STL 预览在导入成功后的渲染精度仍需控制,避免一次性加载过多超大构件。
|
||||
18
工程分析/经验记录.md
18
工程分析/经验记录.md
@@ -1405,3 +1405,21 @@ C. 解决问题方案
|
||||
D. 后续如何避免问题
|
||||
|
||||
可滚动面板内的长按按钮要优先处理焦点滚动和滚动位置恢复;医学视图内的统计面板若影响主画布或菜单可达性,应外置为复核信息块。任何覆盖式资产导入都要在前端显式确认,并在后端同步生成或清理与资产强绑定的缓存,防止新旧 DICOM/STL 信息串用。
|
||||
|
||||
## 2026-05-21-00-05-04 大文件导入不能在浏览器内 base64 化
|
||||
|
||||
A. 具体问题
|
||||
|
||||
用户批量导入 STL 模型时 Chrome 出现 `Render process gone / Out of Memory`,同时 DICOM 和 STL 导入缺少进度条,也不能直接上传 ZIP 等压缩包,导致大体量医学数据传输和反馈体验都不稳定。
|
||||
|
||||
B. 产生问题原因
|
||||
|
||||
旧导入链路会在前端对每个文件执行 `arrayBuffer -> binary string -> base64`,再把所有文件塞进一个 JSON 请求。STL 或 DICOM 文件稍大时,浏览器会同时持有原始文件、ArrayBuffer、字符串、base64 和 JSON body 多份副本,内存膨胀很快;JSON 上传也无法可靠提供上传进度。
|
||||
|
||||
C. 解决问题方案
|
||||
|
||||
前端改为 `XMLHttpRequest + FormData` multipart 上传,使用 `xhr.upload.onprogress` 展示上传百分比、文件数和体积,上传完成后进入“服务器正在解压与解析”状态。后端引入 `multer` 使用磁盘临时文件接收上传,并支持普通 DICOM/STL、ZIP、TAR、TAR.GZ、TGZ 和单文件 GZ;解压后只筛选当前导入类型需要的文件,写入项目级上传目录,并清理运行缓存和临时文件。
|
||||
|
||||
D. 后续如何避免问题
|
||||
|
||||
凡是医学影像、STL、NIfTI、压缩包等大文件导入,都不要在浏览器内转 base64 或拼接巨型 JSON;默认使用 multipart 或分片上传,并把解压、筛选、校验放在服务端。导入 UI 应区分“上传进度”和“服务器处理阶段”,避免用户误以为进度到 100% 就已经完成解析。
|
||||
|
||||
50
工程分析/需求分析-2026-05-21-00-05-04.md
Normal file
50
工程分析/需求分析-2026-05-21-00-05-04.md
Normal file
@@ -0,0 +1,50 @@
|
||||
# 需求分析-2026-05-21-00-05-04
|
||||
|
||||
## 开始时间
|
||||
|
||||
2026-05-21-00-05-04
|
||||
|
||||
## 原始需求摘要
|
||||
|
||||
1. 项目库导入 DICOM 影像、3D 模型时增加进度条。
|
||||
2. 导入时允许选择 ZIP 或其他常见压缩格式,方便传输批量 DICOM/STL。
|
||||
3. 导入 3D 模型时出现 Chrome `Render process gone / Out of Memory`,需要定位原因并修复。
|
||||
|
||||
## 业务目标
|
||||
|
||||
- 让大体量医学影像和 STL 构件导入过程有明确进度反馈。
|
||||
- 支持用户用压缩包一次性传输多文件,减少文件选择和网络传输压力。
|
||||
- 避免前端在大文件导入时因 base64 转换和 JSON 请求造成浏览器内存崩溃。
|
||||
|
||||
## 输入与输出
|
||||
|
||||
- 输入:DICOM 文件、STL 文件、ZIP/TAR/TAR.GZ/TGZ/GZ 等压缩文件。
|
||||
- 输出:项目级 DICOM/STL 上传目录中的解包文件、更新后的项目状态、导入进度条、导入成功/失败反馈。
|
||||
|
||||
## 影响范围
|
||||
|
||||
- `WebSite/src/components/ProjectLibrary.tsx`:导入入口、进度条、文件选择 accept、导入状态。
|
||||
- `WebSite/src/lib/api.ts`:新增带上传进度的 multipart 导入 API。
|
||||
- `WebSite/server.ts`:新增 multipart 文件接收、压缩包展开、导入文件筛选与项目状态更新。
|
||||
- `WebSite/package.json`、`WebSite/package-lock.json`:新增 multipart/zip 解析依赖。
|
||||
- `工程分析/经验记录.md`:记录本次导入链路经验。
|
||||
|
||||
## 关键约束
|
||||
|
||||
- 上传资产仍必须写入 `WebSite/data/uploads/<projectId>/DICOM|STL`,不能覆盖默认 `Head_CT_DICOM/` 与 `Head_CT_ReConstruct/`。
|
||||
- 大文件导入不能再在浏览器中整包 base64 化。
|
||||
- 压缩包解压必须防止路径穿越,不能写出目标目录。
|
||||
- 导入后需要清理项目预览缓存,避免继续使用旧 DICOM/STL。
|
||||
|
||||
## 风险点
|
||||
|
||||
- ZIP 内可能包含多层目录、中文文件名、无扩展 DICOM 文件或无关文件,需要筛选可导入文件。
|
||||
- TAR.GZ 解包需要处理普通文件、目录和路径安全。
|
||||
- 上传进度只能覆盖网络上传阶段,服务端解压/解析阶段需要用“处理中”状态承接。
|
||||
- 大 STL 导入后如果立即按实体精度加载过多预览,仍可能造成前端渲染压力。
|
||||
|
||||
## 默认假设
|
||||
|
||||
- “其他常见压缩格式”优先支持 `.zip`、`.tar`、`.tar.gz`、`.tgz`,并支持单文件 `.gz`。
|
||||
- DICOM 导入接受 `.dcm`、`.dicom`,同时保留压缩包中无扩展 DICOM 的识别尝试空间。
|
||||
- 3D 模型导入当前仍以 STL 为主,压缩包中只提取 `.stl`。
|
||||
Reference in New Issue
Block a user