796 lines
38 KiB
Markdown
796 lines
38 KiB
Markdown
# 经验记录
|
||
|
||
本文件用于记录项目修改过程中的关键问题与解决方案。每条经验使用四段式结构。
|
||
|
||
## 2026-05-04-02-38-48 建立代码编纂工作流
|
||
|
||
A. 具体问题
|
||
|
||
当前项目尚无统一的需求分析、实现方案、测试方案、经验沉淀和备份提交流程,后续修改容易缺少可追溯记录。
|
||
|
||
B. 产生问题原因
|
||
|
||
项目仍处于早期建设阶段,已有前端工程和医学影像数据资产,但尚未建立工程治理文档与固定执行规范。
|
||
|
||
C. 解决问题方案
|
||
|
||
创建 `工程分析/` 目录,新增工程整体分析、代码编纂工作流、本次需求分析、实现方案、测试方案和经验记录文档。后续项目修改必须先写文档,并在实现方案和测试方案阶段等待用户二次人工审核确认。
|
||
|
||
D. 后续如何避免问题
|
||
|
||
每次项目修改前先记录时间戳并阅读 `工程分析/工程整体分析.md` 与 `工程分析/经验记录.md`。修改前写入需求、实现和测试文档,确认后再执行,完成后追加经验记录并提交 Gitea 备份。
|
||
|
||
## 2026-05-04-02-38-48 Gitea 推送后的本地凭据清理
|
||
|
||
A. 具体问题
|
||
|
||
使用带账号信息的一次性推送地址完成 Gitea push 后,本地 `branch.main.remote` 曾记录为带账号信息的 URL。
|
||
|
||
B. 产生问题原因
|
||
|
||
`git push -u <url> main` 会把该 `<url>` 记录为当前分支上游,而不是只使用已配置的 `origin` 名称。
|
||
|
||
C. 解决问题方案
|
||
|
||
将 `origin` 保持为不含账号信息的仓库地址,并把 `branch.main.remote` 改回 `origin`、`branch.main.merge` 改为 `refs/heads/main`。
|
||
|
||
D. 后续如何避免问题
|
||
|
||
后续推送时优先使用已配置好的 `origin`。如果必须临时带认证信息推送,推送后立即检查 `git config --get-regexp 'branch\\.main|remote\\.origin'`,确保本地配置中没有保存账号密码。
|
||
|
||
## 2026-05-04-02-38-48 开发服务端口占用
|
||
|
||
A. 具体问题
|
||
|
||
本项目默认 Vite 端口 `3000` 已被 `/home/wkmgc/Desktop/Seg_Server` 的 node 服务占用,无法直接作为本项目部署端口。
|
||
|
||
B. 产生问题原因
|
||
|
||
同一机器上已有其他项目服务监听 `0.0.0.0:3000`。
|
||
|
||
C. 解决问题方案
|
||
|
||
不停止既有服务,改用 `3001` 端口启动当前项目的 Vite 服务,并通过 `curl -I http://127.0.0.1:3001/` 验证返回 `HTTP/1.1 200 OK`。
|
||
|
||
D. 后续如何避免问题
|
||
|
||
部署前先使用 `ss -ltnp` 检查目标端口。如果默认端口被占用,优先选择相邻可用端口并在测试方案执行结果中记录实际访问地址。
|
||
|
||
## 2026-05-04-02-38-48 后台部署进程托管
|
||
|
||
A. 具体问题
|
||
|
||
使用普通 `nohup` 后台启动 Vite 时进程会静默退出,无法稳定保留服务。
|
||
|
||
B. 产生问题原因
|
||
|
||
当前命令执行环境会回收普通后台子进程,导致 `nohup` 方式没有形成稳定部署。
|
||
|
||
C. 解决问题方案
|
||
|
||
使用 `tmux new-session -d -s revoxelseg-dicom` 托管 Vite 服务,使开发服务脱离当前命令执行会话独立运行。
|
||
|
||
D. 后续如何避免问题
|
||
|
||
需要保留长时间运行的开发服务时,优先使用 `tmux` 会话托管,并用 `tmux capture-pane -pt <session>` 查看启动日志,用 `curl` 验证 HTTP 响应。
|
||
|
||
## 2026-05-04-03-08-20 附件 logo 落盘与静态资源引用
|
||
|
||
A. 具体问题
|
||
|
||
用户要求将 title 图标、登录页 logo 和左上角 logo 都替换为对话中提供的图片,需要把附件图片变为前端可稳定访问的静态资源。
|
||
|
||
B. 产生问题原因
|
||
|
||
前端组件不能直接引用对话附件,必须先将图片保存到项目静态资源目录,再通过固定 URL 引用。
|
||
|
||
C. 解决问题方案
|
||
|
||
确认 `/tmp/logo_check.png` 与用户提供的 logo 一致后,将其复制到 `WebSite/public/logo.png`。`index.html` favicon、登录页和侧边栏统一通过 `/logo.png` 引用。
|
||
|
||
D. 后续如何避免问题
|
||
|
||
后续涉及用户上传图片替换项目资源时,先在本地确认附件是否已落盘;优先放入 `WebSite/public/` 并使用根路径引用,避免组件间重复存放资源。
|
||
|
||
## 2026-05-04-03-08-20 指定端口重新部署
|
||
|
||
A. 具体问题
|
||
|
||
用户要求将项目部署到 `http://192.168.3.11:4000/`,需要从原先 `3001` 端口切换到 `4000`。
|
||
|
||
B. 产生问题原因
|
||
|
||
项目早前使用 `tmux` 会话 `revoxelseg-dicom` 托管在 `3001`,本次需求指定了新的访问端口。
|
||
|
||
C. 解决问题方案
|
||
|
||
先检查 `4000` 端口是否空闲,然后关闭旧 `revoxelseg-dicom` 会话,使用同名 `tmux` 会话启动 Vite:`node ./node_modules/vite/bin/vite.js --host 0.0.0.0 --port 4000 --strictPort`。随后用本机地址和内网地址分别验证 HTTP 200。
|
||
|
||
D. 后续如何避免问题
|
||
|
||
每次调整部署端口前先检查端口占用和现有 `tmux` 会话;部署后同时验证 `127.0.0.1` 与目标内网 IP,并把实际访问地址写入测试方案执行结果。
|
||
|
||
## 2026-05-04-03-21-40 从纯前端演示升级为前后端协调系统
|
||
|
||
A. 具体问题
|
||
|
||
原系统登录、项目列表、用户列表、出厂重置和导出都是前端静态假数据,不同浏览器之间无法共享状态。
|
||
|
||
B. 产生问题原因
|
||
|
||
项目初始形态是 Vite/React 前端演示,没有后端 API、共享状态存储和统一部署入口。
|
||
|
||
C. 解决问题方案
|
||
|
||
新增 Express 后端 `server.ts`,用同一 `4000` 端口服务 API 和前端页面。后端通过 `WebSite/data/state.json` 维护演示状态,前端通过 `/api/session` 轮询同步登录状态,并将项目、用户、概况、重置和导出功能全部接入 API。
|
||
|
||
D. 后续如何避免问题
|
||
|
||
新增跨浏览器共享功能时,默认先判断状态是否必须由后端维护;涉及多浏览器一致性的功能不要放在组件静态数组或浏览器本地状态中。
|
||
|
||
## 2026-05-04-03-21-40 默认医学数据项目载入
|
||
|
||
A. 具体问题
|
||
|
||
项目列表需要默认载入 `Head_CT_DICOM` 和 `Head_CT_ReConstruct`,恢复演示环境出厂设置后也必须恢复这两个默认数据目录。
|
||
|
||
B. 产生问题原因
|
||
|
||
旧项目列表使用硬编码医疗项目示例,和当前仓库中的 DICOM/STL 数据资产没有建立关系。
|
||
|
||
C. 解决问题方案
|
||
|
||
后端启动和读取状态时扫描 `Head_CT_DICOM` 的 `.dcm` 数量与 `Head_CT_ReConstruct` 的 `.stl` 文件列表,生成默认项目 `head-ct-demo`。`POST /api/demo/reset` 使用同一逻辑重建默认项目。
|
||
|
||
D. 后续如何避免问题
|
||
|
||
演示数据入口统一放在后端默认项目构建函数中,避免多个页面分别硬编码 DICOM/STL 路径或数量。
|
||
|
||
## 2026-05-04-03-21-40 NIfTI 导出闭环
|
||
|
||
A. 具体问题
|
||
|
||
逆向工作区需要最终生成 `nii` 或 `nii.gz` 格式的分割 mask,而旧界面只有导出按钮,没有后端文件生成能力。
|
||
|
||
B. 产生问题原因
|
||
|
||
项目尚未实现真实 STL 到 DICOM 空间的体素化算法,也没有文件导出 API。
|
||
|
||
C. 解决问题方案
|
||
|
||
新增 `POST /api/projects/:projectId/export-mask`,后端生成 NIfTI-1 单文件 mask,并按请求输出 `.nii` 或 `.nii.gz`。`.nii.gz` 使用 Node `zlib.gzipSync` 压缩,并通过 `Content-Disposition` 触发下载。
|
||
|
||
D. 后续如何避免问题
|
||
|
||
导出类功能需要先定义后端接口、文件格式和校验命令。后续实现真实体素化时,可替换当前演示 mask 生成函数,但保留 API 和下载流程。
|
||
|
||
## 2026-05-04-03-21-40 Vite 中间件 HMR 端口冲突
|
||
|
||
A. 具体问题
|
||
|
||
Express + Vite 中间件启动时,默认 HMR WebSocket 端口 `24678` 被其他服务占用,日志出现端口冲突。
|
||
|
||
B. 产生问题原因
|
||
|
||
同一机器同时运行多个 Vite 服务,默认 HMR 端口可能重复。
|
||
|
||
C. 解决问题方案
|
||
|
||
在 `createViteServer` 中指定 `server.hmr.port = 24679`,使本项目后端服务使用独立 HMR 端口。
|
||
|
||
D. 后续如何避免问题
|
||
|
||
多项目并行部署时,除了业务端口外,也检查 Vite HMR 端口;发现冲突时为每个项目分配独立 HMR 端口。
|
||
|
||
## 2026-05-04-03-50-07 概况统计语义误导
|
||
|
||
A. 具体问题
|
||
|
||
项目总数只有 1 时,“已处理项目总数”也显示 1,容易让用户误解为系统已经完成真实处理。
|
||
|
||
B. 产生问题原因
|
||
|
||
旧统计把 `status === completed` 直接当作已处理项目,而默认演示项目为了表示数据可用被标记为 `completed`。
|
||
|
||
C. 解决问题方案
|
||
|
||
将概况卡片语义改为“已导出 Mask 项目”,后端按 `exportedMaskCount > 0` 统计;默认项目初始为 0,只有实际触发 mask 导出后才计入。
|
||
|
||
D. 后续如何避免问题
|
||
|
||
统计卡片必须反映明确业务事件,不要把演示数据可用状态和处理完成状态混在一起。
|
||
|
||
## 2026-05-04-03-50-07 DICOM 预览解析
|
||
|
||
A. 具体问题
|
||
|
||
项目库 DICOM 影像页看不到真实影像,只显示占位图形。
|
||
|
||
B. 产生问题原因
|
||
|
||
前端没有读取 DICOM 像素数据,后端也没有提供切片预览 API。
|
||
|
||
C. 解决问题方案
|
||
|
||
新增 `GET /api/projects/:projectId/dicom-preview`,后端解析当前 Little Endian DICOM 的 Rows、Columns、Window、Rescale 和 Pixel Data,返回 base64 灰度像素,前端用 canvas 绘制真实切片。
|
||
|
||
D. 后续如何避免问题
|
||
|
||
医学影像可视化应优先验证真实像素是否进入浏览器。后续扩展更多 DICOM 传输语法时,应把解析器替换为成熟 DICOM 库或 Python 预处理服务。
|
||
|
||
## 2026-05-04-03-50-07 STL 模型真实渲染
|
||
|
||
A. 具体问题
|
||
|
||
项目库 3D 模型页显示的是占位立方体,不是 `Head_CT_ReConstruct` 中的真实 STL。
|
||
|
||
B. 产生问题原因
|
||
|
||
前端没有 STLLoader,后端也没有安全暴露 STL 文件。
|
||
|
||
C. 解决问题方案
|
||
|
||
新增 `GET /api/projects/:projectId/models/:fileName`,仅允许读取项目 STL 列表中的文件;前端使用 Three.js `STLLoader`、`Bounds` 和 `Center` 加载并自动居中显示模型。
|
||
|
||
D. 后续如何避免问题
|
||
|
||
三维模型视图必须加载真实模型文件,不能长期使用占位几何体;后端文件服务要限制文件名和项目白名单,避免任意路径读取。
|
||
|
||
## 2026-05-04-03-50-07 Recharts 容器尺寸警告
|
||
|
||
A. 具体问题
|
||
|
||
控制台出现 Recharts 警告:图表宽高为 `-1`,需要检查容器尺寸。
|
||
|
||
B. 产生问题原因
|
||
|
||
图表在布局尚未稳定时渲染,`ResponsiveContainer` 从父容器拿到异常宽高。
|
||
|
||
C. 解决问题方案
|
||
|
||
为图表外层设置 `min-w-0`、固定高度和 `min-h`,并在 chartData 存在后再渲染 `ResponsiveContainer`,高度使用明确数值 `300`。
|
||
|
||
D. 后续如何避免问题
|
||
|
||
使用 Recharts 时保证父容器有稳定尺寸;在异步数据未到达前不要提前渲染响应式图表。
|
||
|
||
## 2026-05-04-03-50-07 Python 环境引入边界
|
||
|
||
A. 具体问题
|
||
|
||
用户提出如果需要 Python 可新建 conda 环境,但本次需求可以在现有 Node/React/Three.js 技术栈中完成。
|
||
|
||
B. 产生问题原因
|
||
|
||
DICOM/STL/Mask 功能既可以由前端演示链路实现,也可能进入 Python 医学影像算法链路,需要判断当前阶段是否真的需要 Python。
|
||
|
||
C. 解决问题方案
|
||
|
||
本次不创建 conda 环境,避免增加不必要复杂度;README 中说明当前构建方式和后续真实体素化阶段的 conda 环境建议。
|
||
|
||
D. 后续如何避免问题
|
||
|
||
只有当需要真实 DICOM 空间解析、STL 体素填充、NIfTI 精确写入或批处理算法时,再引入 Python/conda,并把环境文件纳入项目文档。
|
||
|
||
## 2026-05-04-04-12-34 DICOM 三方向预览
|
||
|
||
A. 具体问题
|
||
|
||
项目库 DICOM 影像只能看横断面,且右侧切片控制显示为 `NAV` 和 `#0`,不符合医学影像浏览习惯。
|
||
|
||
B. 产生问题原因
|
||
|
||
旧前端只把 DICOM 序列当成单一轴向切片数组浏览,后端 DICOM preview API 只返回单张横断面。
|
||
|
||
C. 解决问题方案
|
||
|
||
后端 DICOM preview API 增加 `plane=axial|sagittal|coronal` 参数。横断面读取单张 DICOM,矢状面和冠状面从 DICOM 序列逐张采样重建灰度平面。前端增加方向切换,并把右侧控制改为 `第 n / 总数` 的切片语义。
|
||
|
||
D. 后续如何避免问题
|
||
|
||
医学影像浏览控件应按方向、当前切片和总切片数表达,不使用模糊的导航标签;多方向重建后续可加入缓存或 Python 预处理优化性能。
|
||
|
||
## 2026-05-04-04-12-34 STL 多模型样式控制
|
||
|
||
A. 具体问题
|
||
|
||
3D 模型视图只显示单个 STL,右侧状态点无实际意义,用户需要不同 STL 有独立颜色和透明度,并由整体眼睛统一控制显示。
|
||
|
||
B. 产生问题原因
|
||
|
||
旧实现把 STL 列表当成选择器,只加载当前选中的一个模型;侧栏状态点只是装饰,没有绑定模型材质。
|
||
|
||
C. 解决问题方案
|
||
|
||
前端为每个 STL 建立 `visible`、`color`、`opacity` 状态,同时加载所有可见 STL;每个模型材质绑定对应颜色和透明度,右侧整体眼睛统一切换所有 STL 可见性,删除无意义状态点。
|
||
|
||
D. 后续如何避免问题
|
||
|
||
三维列表中的视觉控件必须和真实渲染状态绑定;颜色、透明度、可见性等控件不应只是静态装饰。
|
||
|
||
## 2026-05-04-04-12-34 项目管理交互
|
||
|
||
A. 具体问题
|
||
|
||
创建项目输入框常驻在项目列表中占空间;项目编辑需要手动保存按钮;项目缺少删除入口和二次确认。
|
||
|
||
B. 产生问题原因
|
||
|
||
项目管理功能初版偏向快速可用,没有区分高频浏览和低频管理操作。
|
||
|
||
C. 解决问题方案
|
||
|
||
创建项目改为点击 `+` 后弹窗输入;项目名编辑改为失焦或回车自动保存;项目右侧增加删除按钮,点击后必须在确认弹窗中再次确认。
|
||
|
||
D. 后续如何避免问题
|
||
|
||
列表页面应减少常驻表单噪声;破坏性操作必须二次确认;轻量编辑可采用失焦保存,但需要避免空名称提交。
|
||
|
||
## 2026-05-04-04-58-36 项目列表按钮布局
|
||
|
||
A. 具体问题
|
||
|
||
项目列表标题旁的 `+` 创建按钮和侧栏收缩按钮靠得太近,视觉上发生重叠。
|
||
|
||
B. 产生问题原因
|
||
|
||
两个操作都放在项目列表标题区右侧,且侧栏宽度固定,未给低频收缩操作独立位置。
|
||
|
||
C. 解决问题方案
|
||
|
||
保留 `+` 在标题区,收缩按钮移动到项目列表侧栏中线外侧,并调整容器为 `overflow-visible`,避免按钮被卡片裁剪。
|
||
|
||
D. 后续如何避免问题
|
||
|
||
同一区域的高频操作和布局控制应分区放置;绝对定位按钮如果超出容器,要同步检查父容器裁剪策略。
|
||
|
||
## 2026-05-04-04-58-36 DICOM 三方向缓存与显示模式
|
||
|
||
A. 具体问题
|
||
|
||
矢状面和冠状面切换后图像变化慢或不明显,且 DICOM 只能用单一窗宽窗位显示。
|
||
|
||
B. 产生问题原因
|
||
|
||
每次重建非横断面都要重新读取 DICOM 序列,前后端没有把显示模式作为预览参数,也没有复用已解析的体数据。
|
||
|
||
C. 解决问题方案
|
||
|
||
后端按显示模式缓存 DICOM 体数据和预览结果,API 增加 `mode=default|bone|soft|contrast`;前端切换方向时重置到对应方向中间层,并提供显示模式分段按钮。
|
||
|
||
D. 后续如何避免问题
|
||
|
||
DICOM 多平面重建应优先设计缓存键和窗宽窗位参数;后续接入真实医学影像库时继续保留 plane、slice、mode 的稳定 API 契约。
|
||
|
||
## 2026-05-04-04-58-36 STL 大文件预览
|
||
|
||
A. 具体问题
|
||
|
||
3D 模型页容易空白,直接加载 9 个原始 STL 总量约 240MB,浏览器解析慢且缺少可靠进度反馈。
|
||
|
||
B. 产生问题原因
|
||
|
||
前端承担了原始 STL 解析和渲染的全部工作,大体积二进制模型会阻塞交互并放大 WebGL 环境差异。
|
||
|
||
C. 解决问题方案
|
||
|
||
后端新增 STL 二进制采样预览 API,只返回抽样三角面顶点;前端用原生 Three.js 按采样顶点生成 BufferGeometry,并显示加载进度。WebGL 不可用时改用二维 canvas 投影预览兜底。
|
||
|
||
D. 后续如何避免问题
|
||
|
||
大模型浏览应区分“预览网格”和“原始精度文件”;列表/项目库优先加载轻量预览,进入精修或导出阶段再读取完整 STL。
|
||
|
||
## 2026-05-04-04-58-36 逆向工作区项目上下文与融合视图
|
||
|
||
A. 具体问题
|
||
|
||
逆向工作区没有明确显示当前项目,融合视图没有展示 DICOM 与 STL 归一化中心对齐的效果。
|
||
|
||
B. 产生问题原因
|
||
|
||
工作区初版更多是流程面板,缺少从项目库传入项目后继续呈现项目上下文和影像/模型叠加结果的状态。
|
||
|
||
C. 解决问题方案
|
||
|
||
工作区进入后读取当前项目详情,顶部显示项目名、DICOM 数量、STL 数量和路径;融合视图加载 DICOM 软组织窗切片,并叠加中心对齐的模型轮廓、十字参考线和切片滑块。
|
||
|
||
D. 后续如何避免问题
|
||
|
||
跨页面工作流必须在目标页面重新显示当前操作对象;医学影像配准类视图至少应具备影像层、模型层、对齐标识和当前切片控制。
|
||
|
||
## 2026-05-04-05-20-16 DICOM 三平面预览与下载
|
||
|
||
A. 具体问题
|
||
|
||
DICOM 切片长按不能连续移动,三平面不能旋转,矢状面/冠状面存在大量黑边导致主体像只显示一半,同时缺少当前 PNG 和整套 DICOM 压缩包下载。
|
||
|
||
B. 产生问题原因
|
||
|
||
前端切片控制只有原生 range 输入,缺少连续步进逻辑;canvas 绘制没有旋转参数;后端重建平面直接输出完整矩阵,没有对非黑内容边界做裁切;下载链路只覆盖了分割 Mask。
|
||
|
||
C. 解决问题方案
|
||
|
||
前端新增上下箭头长按定时步进、左/右 90 度旋转和与显示一致的 PNG 导出;后端 DICOM 文件按自然文件名排序,对重建平面做内容裁切并做轻量边缘增强;新增 `dicom-archive` 接口生成 `tar.gz` 压缩包。
|
||
|
||
D. 后续如何避免问题
|
||
|
||
医学影像预览的显示状态应统一由平面、切片、窗宽窗位、旋转角度组成;下载当前视图时复用同一套 canvas 绘制逻辑,避免屏幕显示和导出结果不一致。
|
||
|
||
## 2026-05-04-05-20-16 3D 模型加载完成但画布空白
|
||
|
||
A. 具体问题
|
||
|
||
项目库 3D 模型页提示加载完成,但用户界面仍可能看不到模型。
|
||
|
||
B. 产生问题原因
|
||
|
||
STL 抽样顶点仍保留原始模型坐标,先给 group 位置减中心再缩放时,模型可能被缩放后的坐标体系推离相机视野;WebGL 不可用时二维兜底 canvas 尺寸也依赖容器测量,可能拿到过小尺寸。
|
||
|
||
C. 解决问题方案
|
||
|
||
模型加载完成后先计算整体包围盒,将中心偏移直接平移到每个 mesh 的 geometry 顶点,再统一缩放 group 和设置相机;二维兜底 canvas 在容器尺寸不可用时使用父容器尺寸或默认尺寸,保证兜底预览可见。
|
||
|
||
D. 后续如何避免问题
|
||
|
||
三维预览应在模型坐标归一化后再设置相机;验证时要覆盖 WebGL 正常路径和 WebGL 不可用兜底路径,并做 canvas 尺寸和非背景像素检查。
|
||
|
||
## 2026-05-04-05-20-16 逆向工作区路径信息噪声
|
||
|
||
A. 具体问题
|
||
|
||
逆向工作区标题中显示 `Head_CT_DICOM ↔ Head_CT_ReConstruct`,对用户当前操作帮助不大。
|
||
|
||
B. 产生问题原因
|
||
|
||
早期为了证明项目数据源接入,将数据目录路径直接放进了页面副标题。
|
||
|
||
C. 解决问题方案
|
||
|
||
副标题改为只显示当前项目名称;DICOM 数量和 STL 数量保留在上下文标签中。
|
||
|
||
D. 后续如何避免问题
|
||
|
||
工作区首屏应优先显示“当前正在处理哪个项目”和“下一步操作”,底层路径只在诊断、详情或设置区域出现。
|
||
|
||
## 2026-05-04-05-41-22 STL 实体化程度与位姿控制
|
||
|
||
A. 具体问题
|
||
|
||
3D 模型虽然可以显示,但抽样三角面过少时视觉上偏稀疏,用户希望更接近白色实体 STL 拼装效果,并且能够手动调整整体模型位姿。
|
||
|
||
B. 产生问题原因
|
||
|
||
项目库为了避免大体积 STL 造成浏览器卡顿,使用固定低抽样量预览;同时模型 group 只有自动旋转,没有暴露旋转、平移、缩放等用户控制。
|
||
|
||
C. 解决问题方案
|
||
|
||
新增“预览/标准/精细”实体化程度,后端 STL preview 抽样上限提升到 `36000`;前端新增白色实体模式、自动旋转开关、旋转 X/Y/Z、平移 X/Y/Z、缩放和重置位姿控制,所有位姿变换作用在整体 group 上。
|
||
|
||
D. 后续如何避免问题
|
||
|
||
大模型预览应提供性能档位,而不是在“速度”和“实体感”之间固定取舍;位姿控制必须作用于整体模型容器,避免破坏各 STL 构件的相对拼装关系。
|
||
|
||
## 2026-05-04-05-41-22 DICOM 长按切片反馈
|
||
|
||
A. 具体问题
|
||
|
||
长按切片上下箭头时,编号会变化,但用户希望图像也有连续变化的运动感。
|
||
|
||
B. 产生问题原因
|
||
|
||
前端连续修改 `sliceIndex` 后依赖异步 API 返回更新图像,缺少请求乱序保护和切片切换中的视觉反馈。
|
||
|
||
C. 解决问题方案
|
||
|
||
将长按步进间隔缩短到 `95ms`,为 DICOM preview 请求加入递增序号,只允许最新请求更新画面;切片切换时给 canvas 容器增加轻微缩放、亮度和状态提示。
|
||
|
||
D. 后续如何避免问题
|
||
|
||
连续浏览医学影像时,必须同时处理“状态连续变化”“图像异步返回”和“旧请求覆盖新请求”三个问题;前端应保留上一帧并提供明确切换反馈。
|
||
|
||
## 2026-05-04-05-41-22 逆向工作区标题去重
|
||
|
||
A. 具体问题
|
||
|
||
逆向工作区同时出现全局标题和页面内标题,也重复显示“当前项目”。
|
||
|
||
B. 产生问题原因
|
||
|
||
页面局部标题和全局 header 没有统一职责,项目上下文既出现在副标题,也出现在标签行。
|
||
|
||
C. 解决问题方案
|
||
|
||
保留全局 header 的“逆向工作区”,删除页面内重复标题和副标题;保留并放大当前项目、DICOM 数量、STL 数量标签。
|
||
|
||
D. 后续如何避免问题
|
||
|
||
页面级标题应由全局导航或内容区二选一承担;当前对象信息只保留在最醒目的单一位置,减少重复文本造成的噪声。
|
||
|
||
## 2026-05-04-05-56-34 DICOM 多平面物理比例
|
||
|
||
A. 具体问题
|
||
|
||
矢状面和冠状面只按像素矩阵重建,没有考虑切片间距与单张图像内像素间距,导致图像观感过扁。
|
||
|
||
B. 产生问题原因
|
||
|
||
后端重建平面时直接使用 `切片数 x 行/列数` 作为输出尺寸,默认把切片方向和像素方向当成等距网格。
|
||
|
||
C. 解决问题方案
|
||
|
||
解析 `PixelSpacing`、`SliceThickness`、`SpacingBetweenSlices` 和 `ImagePositionPatient`;优先用相邻 `ImagePositionPatient` 距离估计真实切片间距,并按 `sliceSpacing` 与像素间距做最近邻重采样,返回 spacing 与 physicalSize。
|
||
|
||
D. 后续如何避免问题
|
||
|
||
医学影像任意重建平面都必须带着物理 spacing 计算,不应只看像素数量;当 DICOM tag 缺失时要明确 fallback 来源。
|
||
|
||
## 2026-05-04-05-56-34 DICOM 信息面板
|
||
|
||
A. 具体问题
|
||
|
||
前端缺少 DICOM 详细信息查询,用户无法看到像素间距、切片间距等判断空间比例的关键信息。
|
||
|
||
B. 产生问题原因
|
||
|
||
原有 API 只服务于灰度预览,没有暴露 DICOM 元数据和序列级空间统计。
|
||
|
||
C. 解决问题方案
|
||
|
||
新增 `GET /api/projects/:projectId/dicom-info`,返回患者、检查、序列、图像矩阵、窗宽窗位、spacing、物理尺寸和首尾切片位置;前端增加“信息”按钮和 DICOM 详细信息弹窗。
|
||
|
||
D. 后续如何避免问题
|
||
|
||
影像显示功能旁应提供可审计的元数据入口,特别是任何影响几何比例、配准和导出的空间参数。
|
||
|
||
## 2026-05-04-05-56-34 3D 模型交互控制简化
|
||
|
||
A. 具体问题
|
||
|
||
3D 模型页存在不需要的白色实体模式和自动旋转,同时缺少更高细节档位;鼠标拖拽、滚轮等画布操作不能同步到右侧位姿控件。
|
||
|
||
B. 产生问题原因
|
||
|
||
前一版位姿控制主要依赖右侧滑块,画布本身只负责渲染;显示开关也偏演示型,没有完全贴近用户的实际浏览习惯。
|
||
|
||
C. 解决问题方案
|
||
|
||
移除白色实体和自动旋转;新增“超精细”档,后端 STL 抽样上限提升到 `72000`;画布监听左键旋转、右键或 Shift 平移、滚轮缩放,并回写整体位姿 state。
|
||
|
||
D. 后续如何避免问题
|
||
|
||
三维浏览默认应遵循常见交互习惯,UI 控件与鼠标操作必须共享同一份状态;演示型开关要及时剔除,避免干扰核心工作流。
|
||
|
||
## 2026-05-07-16-20-46 3D 默认位姿
|
||
|
||
A. 具体问题
|
||
|
||
网页端 3D 模型默认位姿看起来不像用户参考图中的正常位姿,打开后更像斜向观察。
|
||
|
||
B. 产生问题原因
|
||
|
||
默认 Three.js 相机使用 `(4.5, 3.5, 5)` 斜向等距视角,而用户期望的是接近俯视/轴向的标准视角。
|
||
|
||
C. 解决问题方案
|
||
|
||
将默认相机改为俯视方向:`camera.up=(0,1,0)`、`camera.position=(0,0,6)`、`lookAt(0,0,0)`;保留默认位姿滑块为旋转 0、平移 0、缩放 1,重置位姿也回到同一基准。
|
||
|
||
D. 后续如何避免问题
|
||
|
||
默认位姿应该由相机预设和模型位姿共同定义;如果用户提供标准视图截图,应优先匹配相机视角,再决定是否需要固定模型 Z 轴校正。
|
||
|
||
## 2026-05-07-16-35-52 3D 位姿重置与旋转中心
|
||
|
||
A. 具体问题
|
||
|
||
整体位姿只有一个重置按钮,无法分别恢复旋转和平移缩放;同时用户感觉模型旋转中心不在模型正中间,缺少右下角 XYZ 方位参考。
|
||
|
||
B. 产生问题原因
|
||
|
||
前端位姿状态虽包含旋转、平移和缩放,但重置操作仍使用单一 `defaultModelPose`;Three.js 预览也使用单 group 同时承载旋转、平移和缩放,层级职责不够清晰;画布缺少固定的方位提示。
|
||
|
||
C. 解决问题方案
|
||
|
||
抽出统一的位姿 clamp 方法;新增 `重置旋转位姿` 与 `重置平移缩放位姿`;旋转项增加 ±90° 快捷按钮,平移和缩放增加正负方向快捷步进;Three.js 渲染拆为 `poseGroup` 负责平移、`pivotGroup` 负责围绕整体包围盒中心旋转和缩放;右下角增加 X/Y/Z 方位与旋转角度 overlay。
|
||
|
||
D. 后续如何避免问题
|
||
|
||
三维位姿控制应按旋转、平移、缩放分开管理;模型加载后必须先基于所有 STL 的整体包围盒做中心化,再把旋转和缩放应用到中心 pivot 上;涉及交互状态时,滑块、按钮和鼠标操作必须共享同一份 clamp 逻辑。
|
||
|
||
## 2026-05-07-16-53-23 STL 抽样中心漂移与动态坐标轴
|
||
|
||
A. 具体问题
|
||
|
||
用户旋转模型后切换 `预览/标准/精细/超精细`,模型位置会明显偏移;鼠标拖拽旋转时也感觉旋转中心没有落在模型内部;右下角坐标轴不随旋转位姿变化。
|
||
|
||
B. 产生问题原因
|
||
|
||
前端用当前抽样出来的 STL 顶点计算整体包围盒,不同细节档位的抽样集合不同,导致中心点和缩放基准随档位变化;右下角坐标轴是固定 HTML/CSS 图形,没有基于当前旋转矩阵更新。
|
||
|
||
C. 解决问题方案
|
||
|
||
后端 STL preview 在遍历完整二进制 STL 时同步计算全量 `bounds`,前端加载时使用所有可见 STL 的全量包围盒合成稳定中心和尺寸,再把抽样 geometry 平移到该中心;右下角坐标轴改为 SVG,根据 `rotateX/Y/Z` 生成 Three.js 旋转矩阵并投影 X/Y/Z 三轴。
|
||
|
||
D. 后续如何避免问题
|
||
|
||
任何用于配准、视角稳定、旋转中心的几何参数都必须来自全量模型或稳定元数据,不能来自随性能档位变化的抽样数据;坐标系、状态文字和模型实际位姿应共用同一份 pose 状态。
|
||
|
||
## 2026-05-07-17-05-43 模型显示实体档位
|
||
|
||
A. 具体问题
|
||
|
||
用户不再需要低质量 `预览` 档位,希望在 `模型显示` 中增加更接近 STL 实体面片的 `实体` 档位。
|
||
|
||
B. 产生问题原因
|
||
|
||
原有档位以性能抽样为主,最高 `超精细` 仍受后端 `72000` 三角面上限约束,且材质继续使用用户设置的半透明度,视觉上仍偏点状或半透明预览。
|
||
|
||
C. 解决问题方案
|
||
|
||
前端删除 `预览` 档位,新增 `实体` 档位并设置更高请求上限 `200000`;后端 STL preview clamp 同步提升到 `200000`;实体档位下将材质不透明度下限提高到 `0.94`,在保留构件颜色的同时增强实体感。
|
||
|
||
D. 后续如何避免问题
|
||
|
||
模型显示档位应明确区分“性能抽样”和“实体查看”;若新增高质量档位,需要同步检查前端请求 limit、后端 clamp、材质表现和浏览器性能边界。
|
||
|
||
## 2026-05-07-17-28-34 逆向工作区三维融合视角
|
||
|
||
A. 具体问题
|
||
|
||
逆向工作区原来的 `影像与模型融合视角` 只是二维 DICOM 图片和示意轮廓叠加,不能表现 DICOM 体数据、切片范围、STL 模型同场景融合,也不能让 DICOM 和模型作为整体旋转观察。
|
||
|
||
B. 产生问题原因
|
||
|
||
早期实现更偏演示界面,没有后端接口提供一段 DICOM 体数据纹理;前端也没有 Three.js 融合场景,只是在二维 canvas 上放置静态标注层。
|
||
|
||
C. 解决问题方案
|
||
|
||
新增 `dicom-fusion-volume` 后端接口,按起止切片返回最多 64 张、最大 256 像素边长的轴向 CT 纹理和 spacing/physicalSize;前端逆向工作区新增 Three.js 融合场景,将 DICOM 渲染为黑色长方体和切片纹理,将 STL preview 模型加载到同一场景,并提供切片范围与模型位姿控件。
|
||
|
||
D. 后续如何避免问题
|
||
|
||
融合、配准、体素化相关视图应优先使用三维数据结构,而不是二维示意图;DICOM 体数据接口必须限制切片数量和纹理尺寸,保证浏览器交互稳定;模型相对 DICOM 的调整和整体场景观察要分开管理。
|
||
|
||
## 2026-05-07-18-11-12 构件层级状态与可视化工具栏
|
||
|
||
A. 具体问题
|
||
|
||
项目库构件层级的单个眼睛按钮表现不稳定;构件缺少可编辑的 1 到 255 ID;逆向工作区仍显示 `分割 Mask`,缺少模型显示、位姿保存/选择和构件层级等可视化控制。
|
||
|
||
B. 产生问题原因
|
||
|
||
构件样式状态只记录 visible/color/opacity,部分更新路径会用默认值重建对象,容易丢失扩展字段;逆向工作区三维融合视角初版只加载模型,没有把项目库中的模型显示和构件层级控制模式迁移过来。
|
||
|
||
C. 解决问题方案
|
||
|
||
扩展构件样式状态为 visible/color/opacity/partId,所有更新都保留既有字段;项目库和逆向工作区均使用 1 到 255 的 ID clamp;新增 `模型库` 复用项目库并默认进入模型页;逆向工作区将中间栏改为 `可视化工具栏`,加入模型显示档位、位姿保存/选择和构件层级,并把这些状态传入 Three.js 模型加载逻辑。
|
||
|
||
D. 后续如何避免问题
|
||
|
||
构件层级状态应作为统一结构在不同页面复用;任何新增构件字段都要检查初始化、单项更新、全局更新和默认 fallback 四条路径;逆向工作区的可视化控制应与项目库模型页保持一致,避免用户在两个页面学两套交互。
|
||
|
||
## 2026-05-07-18-42-53 构件 ID 跨页面联动
|
||
|
||
A. 具体问题
|
||
|
||
项目库 3D 模型和逆向工作区可视化工具栏都能修改构件 ID,但两边原先分别维护本地状态,无法保证 ID、显示隐藏、颜色和透明度一致。
|
||
|
||
B. 产生问题原因
|
||
|
||
构件样式属于项目级配置,但旧实现只保存在 React 组件 state 中,页面切换或不同浏览器访问时不会自动共享。
|
||
|
||
C. 解决问题方案
|
||
|
||
在项目数据中新增 `moduleStyles` 字段,并新增 `PATCH /api/projects/:projectId/module-styles` 接口。项目库和逆向工作区都读写同一后端状态,服务端统一补齐默认值并将 `partId` 限制在 `1~255`。
|
||
|
||
D. 后续如何避免问题
|
||
|
||
凡是需要跨页面、跨浏览器一致的配置项,优先放入后端项目状态;前端可以保留本地 state 提升响应速度,但必须通过 API 持久化并从项目数据恢复。
|
||
|
||
## 2026-05-08-01-19-42 融合视角缓存、边界与切割控制
|
||
|
||
A. 具体问题
|
||
|
||
融合视角在切片范围变化时需要反复请求 DICOM 体数据;模型旋转中心带有模型偏移,极端旋转后容易看起来脱离 DICOM;同时缺少 DICOM/模型边界、透明度档位和沿 DICOM 帧切割模型的操作入口。
|
||
|
||
B. 产生问题原因
|
||
|
||
前一版融合视图以单次加载为主,没有前端缓存点位;模型居中后又把模型组整体设置了 Z 偏移,使旋转 pivot 不完全等同于 DICOM 体中心;三维辅助元素只显示了 DICOM 边线,没有完整的模型边界和切割平面。
|
||
|
||
C. 解决问题方案
|
||
|
||
在前端使用 `Map` 按项目、模式和切片终点缓存 `DicomFusionVolume`;DICOM 切片范围增加五个预存点位和一键预存;Three.js 中将模型旋转组保持在 DICOM 原点,把模型自身偏移放入子节点;增加 DICOM 边界、模型边界、DICOM 透明度三档、切割帧滑条和 clipping plane 切割面。
|
||
|
||
D. 后续如何避免问题
|
||
|
||
涉及 DICOM 与 STL 配准的旋转、缩放、切割操作,应优先明确坐标系和 pivot 来源,默认以 DICOM 体中心为基准;高频切片请求应先设计缓存键和预取策略,避免 UI 操作直接触发重复网络与纹理构建。
|
||
|
||
## 2026-05-08-01-53-07 DICOM 范围变化不改变空间基准
|
||
|
||
A. 具体问题
|
||
|
||
DICOM 切片范围变化后,融合视图中的 DICOM 体深度和帧分布会随范围重新计算,导致模型看起来被自动居中或改变了和 DICOM 的原始配准位置;切分开启后也缺少在 DICOM 帧上直观看到 Mask 的反馈。
|
||
|
||
B. 产生问题原因
|
||
|
||
后端 `dicom-fusion-volume` 使用当前 `start/end` 的范围长度计算 `physicalSize.depth`;前端又把当前返回的帧均匀铺满整个 DICOM box,而不是按原始 DICOM index 放回完整序列位置。
|
||
|
||
C. 解决问题方案
|
||
|
||
后端 physical depth 改为完整序列深度;前端 DICOM slice plane 的 Z 位置改用 `volume.indices[index] / (total - 1)` 映射到完整 DICOM box;切片范围改为 `sliceStart/sliceEnd` 双端点,默认最高切片;切割开启时额外渲染切割帧 DICOM texture,并叠加橙色 Mask 轮廓。
|
||
|
||
D. 后续如何避免问题
|
||
|
||
所有配准相关可视化都必须区分“显示范围”和“空间基准”:显示范围可以变化,但 DICOM 物理尺寸、模型缩放基准和坐标原点不能跟着变化;任何切割或 Mask 预览都要明确只是辅助显示,不能修改原始 DICOM/STL 位姿。
|
||
|
||
## 2026-05-08-03-03-52 项目定位错误导致控件未修复
|
||
|
||
A. 具体问题
|
||
|
||
用户要求将“DICOM 切片范围”的起点、终点合并为一个范围条,但页面仍显示两个上下排列的进度条。
|
||
|
||
B. 产生问题原因
|
||
|
||
前一次处理时依据当前工作目录误改了 `Head_CT_Morph`,而用户截图中的真实页面来自 `ReVoxelSeg_DICOM/WebSite/src/components/ReverseWorkspace.tsx`。没有先用截图中的页面文案和 DOM 片段全局定位真实渲染文件,导致改动没有作用到用户看到的程序。
|
||
|
||
C. 解决问题方案
|
||
|
||
在 `/home/wkmgc/Desktop` 范围内搜索 `DICOM 切片范围` 和 `三维融合场景已就绪`,定位到正确项目 `ReVoxelSeg_DICOM`。将 `ReverseWorkspace.tsx` 中两个独立 `range` 替换为单条自绘轨道叠加两个端点的范围控件,并在 `index.css` 中隐藏原生 range 轨道、保留可拖动 thumb。
|
||
|
||
D. 后续如何避免问题
|
||
|
||
收到 UI 截图或 DOM 片段时,先用页面可见文案、class 片段和组件文本在所有相关项目目录中定位真实源码,再修改代码。若当前仓库内找不到截图中的文本,必须立即扩大搜索范围并向用户说明实际项目位置,不能默认当前工作目录就是目标项目。
|
||
|
||
## 2026-05-08-03-13-20 模型切分必须由 DICOM 范围统一驱动
|
||
|
||
A. 具体问题
|
||
|
||
逆向工作区初始 DICOM 范围只落在最后一张;模型切分还有独立“帧”滑块,与 DICOM 切片范围割裂;切分开启后额外生成 `CUT MASK` 伪贴图,容易误导用户以为是真实语义分割结果。
|
||
|
||
B. 产生问题原因
|
||
|
||
前一版把“DICOM 显示范围”和“模型切割帧”设计成两套状态,并为了给切割反馈绘制了演示性质的二维 mask 纹理,没有把切分严格绑定到 DICOM 起点和终点双帧。
|
||
|
||
C. 解决问题方案
|
||
|
||
删除 `cutSlice` 状态和模型切分帧滑块,项目加载时将 `sliceStart` 初始化为 `0`、`sliceEnd` 初始化为最大帧;`FusionThreeView` 改接收 `cutStart/cutEnd`,根据 DICOM 物理深度映射为两张 clipping plane,模型切分启用后只保留两帧之间的中间模型区域;删除 `createCutMaskTexture` 和 `CUT MASK` 贴图调用。
|
||
|
||
D. 后续如何避免问题
|
||
|
||
所有模型切分、分割预览、Mask 展示都必须明确数据来源。没有真实体素化或真实语义分割结果时,不应使用伪造 mask 图像;同一业务动作只保留一套权威控制状态,模型切分应默认由 DICOM 切片范围驱动。
|
||
|
||
## 2026-05-08-03-23-51 重复入口与辅助显示清理
|
||
|
||
A. 具体问题
|
||
|
||
系统同时提供“项目库”和“模型库”两个入口,实际模型库只是复用项目库的模型页,信息架构重复;逆向工作区的 DICOM 范围说明和五点预存按钮已经不必要;模型切分启用后出现红色辅助平面,干扰观察。
|
||
|
||
B. 产生问题原因
|
||
|
||
早期为了快速进入模型页新增了独立 `MODELS` 路由和侧边栏入口;DICOM 范围控件在调试缓存阶段加入了预存点位;模型切分为了强调切割位置渲染了半透明平面,但用户当前更需要干净的真实裁切效果。
|
||
|
||
C. 解决问题方案
|
||
|
||
删除 `ViewType.MODELS`、侧边栏“模型库”和 `App.tsx` 中对应分支,保留“项目库”统一承载 DICOM、模型、Mask 视图;删除 DICOM 范围说明、五点预存状态和按钮,保留 `fusionVolumeCacheRef` 对实际加载范围的缓存;删除切分辅助平面 Mesh,只保留两张 clipping plane 裁切模型。
|
||
|
||
D. 后续如何避免问题
|
||
|
||
新增导航入口前先判断是否是独立业务对象和独立工作流,避免用多个入口指向同一组件状态;辅助视觉元素应在用户确认有价值后保留,医学三维视图中默认少放装饰或调试平面,避免遮挡真实数据。
|
||
|
||
## 2026-05-08-03-35-22 Mask 展示改为真实 STL 切面
|
||
|
||
A. 具体问题
|
||
|
||
逆向工作区右侧 `Mask 展示` 仍然是二维彩色示意图,并且底部存在“导出进度”栏;用户希望看到切割后的 STL 实体切面。
|
||
|
||
B. 产生问题原因
|
||
|
||
旧 `Mask 展示` 是早期演示 UI,没有接入真实 STL 模型,也没有复用 DICOM 范围切割逻辑;导出进度栏展示的是导出状态文本,不是用户当前关注的切面实体结果。
|
||
|
||
C. 解决问题方案
|
||
|
||
新增 `CutSectionPreview` Three.js 组件,复用当前项目 STL preview、构件颜色/隐藏状态、模型位姿和 DICOM 切片范围;启用模型切分时使用两张 clipping plane 保留中间区域,并以实体材质展示裁切后的 STL。删除旧二维 Mask 示意结构和底部“导出进度”栏。
|
||
|
||
D. 后续如何避免问题
|
||
|
||
右侧结果展示区域应优先呈现真实数据或真实处理结果,避免使用占位式示意图长期冒充结果;如果尚未生成真实语义分割 Mask,应明确展示当前可验证的 STL 切面实体,而不是伪造 Mask 形状。
|