72 KiB
经验记录
本文件用于记录项目修改过程中的关键问题与解决方案。每条经验使用四段式结构。
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 形状。
2026-05-19-22-59-07 工程分析核心文档被删除状态下的恢复
A. 具体问题
本次开始时工作区中大量 工程分析/ 历史文档处于删除状态,且本地目录不存在;如果直接创建新的短版 经验记录.md 或直接暂存整个目录,可能丢失旧知识库或把无关删除混入本次备份。
B. 产生问题原因
这些删除状态在本次操作前已经存在,且 工程分析/经验记录.md 在 Git 中已有 795 行历史经验。当前需求又要求读取或创建 工程分析/,容易把“恢复核心文档”和“提交所有删除”混为一谈。
C. 解决问题方案
先通过 Git 读取旧 工程整体分析.md、代码编纂工作流.md 和 经验记录.md,确认历史内容;随后只恢复并更新这三个核心文件,新增本次三份时间戳文档和 AGENTS.md,暂存时显式列出本次相关路径,避免提交其他历史删除。
D. 后续如何避免问题
每次发现工作区已有删除或修改时,先区分是否属于本次需求;文档备份 commit 要显式暂存文件路径,不能用 git add .。对 经验记录.md 这类知识库文件,更新前必须确认旧内容仍被保留。
2026-05-19-22-59-07 固化后续代码编纂工作流
A. 具体问题
用户要求后续所有项目修改相关需求都执行固定流程,但仅在对话中说明流程不够稳固,未来进入项目的助手或开发者可能看不到这条约束。
B. 产生问题原因
工作流要求跨越多次会话和多次修改,单靠当前对话记忆不可靠;项目内原有 代码编纂工作流.md 也处于工作区删除状态,需要恢复并更新为当前版本。
C. 解决问题方案
更新 工程分析/代码编纂工作流.md,明确 0 到 7 步、默认不等待二次确认、文档备份提交和重新部署要求;同时新增根目录 AGENTS.md,把后续修改必须读取并执行该工作流作为项目入口约束。
D. 后续如何避免问题
后续任何项目修改前,先读取根目录 AGENTS.md 和 工程分析/代码编纂工作流.md;若用户提出新流程要求,应同步更新这两个入口文档和经验记录,确保流程约束留在仓库中。
2026-05-19-22-59-07 Gitea HTTP 远端缺少可用凭据
A. 具体问题
本次本地文档备份 commit 已完成,但执行 git push origin main 时失败,Git 提示无法读取 http://192.168.31.5:5002 的用户名。
B. 产生问题原因
当前 origin 使用 HTTP Gitea 地址,执行环境没有交互式用户名输入,也没有可用的凭据助手或已保存认证信息。
C. 解决问题方案
保留本地 commit,不在命令行临时拼接账号密码,也不把凭据信息写入仓库或远端 URL。将推送失败原因记录到测试方案和经验记录中,等待用户提供安全的凭据方式后再推送。
D. 后续如何避免问题
需要 Gitea 远端备份前,先确认远端认证方式。优先使用安全的凭据助手、SSH remote 或用户已配置好的 token;不要把账号密码写进 commit、文档、remote URL 或 shell 历史。
2026-05-19-23-47-31 逆向分割映射视图的数据来源边界
A. 具体问题
用户要求右侧二维视图展示由三维 STL 模型逆向推导的分割掩码 Label Map,并与构件层级严格对应;但当前后端尚未提供医学级真实体素化 Label Map 文件。
B. 产生问题原因
现有系统的真实数据能力主要是 DICOM preview、DICOM fusion volume 和 STL preview 三角面抽样,历史版本的右侧区域也已从伪二维 Mask 改为 STL 实体切面。若直接绘制任意彩色区域,会再次变成无来源 Mask。
C. 解决问题方案
右侧新建 VoxelizationMappingView,底层用 DICOM preview 灰度像素作为 Base Layer,上层只根据 STL preview 顶点、当前 Z 切片位置和构件 moduleStyles 投影绘制 Overlay Label Map。每个彩色覆盖区域都来自具体 STL 构件,并复用构件颜色、透明度、显示隐藏和 partId。
D. 后续如何避免问题
在真实体素化服务接入前,所有 Label Map 类可视化必须明确使用 STL 几何或后端生成结果作为来源;不要重新引入无数据来源的演示 Mask。后续若增加医学级体素化,应保留当前 Base/Overlay UI,但将 Overlay 数据源替换为后端真实 Label Map。
2026-05-19-23-47-31 右侧独立切片导航与左侧范围状态分离
A. 具体问题
右侧二维映射视图需要逐层浏览单张 DICOM 切片,而左侧三维融合视图使用的是 DICOM 切片范围和模型切分区间;如果共用同一状态,拖动右侧滑条会破坏左侧融合范围。
B. 产生问题原因
旧工作区已经有 sliceStart/sliceEnd 双端点状态,用于三维 DICOM 范围和 STL clipping plane。右侧新增 Slice Navigator 是单切片校验动作,语义不同。
C. 解决问题方案
新增独立 mappingSlice 状态传入 VoxelizationMappingView,右侧 Slice Navigator 只修改该状态;左侧 sliceStart/sliceEnd 继续驱动三维融合范围和模型切分,两套状态互不覆盖。
D. 后续如何避免问题
新增影像浏览控件前先判断其控制对象是“单切片位置”还是“显示范围/切割范围”。单切片校验使用独立 slice 状态,范围切割使用起止端点状态,避免不同视图之间产生隐式联动。
2026-05-20-00-19-47 右侧映射视图必须复用中部模型位姿
A. 具体问题
右侧“逆向分割映射视图”虽然已经使用 DICOM Base Layer 和 STL Overlay,但 Overlay 计算没有接入中部“模型位姿”状态;用户拖动 X/Y/Z 平移或旋转后,左侧三维视图变化,右侧二维映射仍按旧 STL 原始坐标绘制。
B. 产生问题原因
上一版 VoxelizationMappingView 只接收 moduleStyles、slice 和 STL preview 数据,没有接收 modelPose;drawVoxelOverlayLayer 直接使用 STL 原始顶点和全局 bounds 计算投影,没有先执行与三维场景一致的归一化、旋转、缩放和平移。
C. 解决问题方案
为 VoxelizationMappingView 增加 modelPose 入参,由父组件直接传入中部工具栏的当前位姿;在 Overlay 计算前对 STL 顶点执行 scale -> rotateX -> rotateY -> rotateZ -> translate,再与当前 Z 轴 DICOM 切片平面求交,并使用 requestAnimationFrame 合并高频滑条更新。
D. 后续如何避免问题
凡是右侧二维映射、Mask、Label Map 或导出预览依赖 STL 空间位置时,都必须确认其输入状态包含当前权威位姿;不能让三维视图和二维视图各自维护坐标变换。新增视图前先列出共享状态:位姿、构件样式、切片位置和数据源。
2026-05-20-00-19-47 实体 Mask 填充不能覆盖多构件叠加
A. 具体问题
将截面交线转为实心 Mask 时,如果每个构件直接在主 Overlay canvas 上 putImageData,后一个构件的透明像素会覆盖掉前一个构件,导致多构件同时显示时可能只剩最后绘制的构件。
B. 产生问题原因
Canvas 的 putImageData 是像素替换操作,不是透明合成操作;即使 ImageData 中某些像素 alpha 为 0,也会把目标 canvas 对应位置写成透明,从而擦掉已有 Overlay。
C. 解决问题方案
每个构件先在离屏 canvas 中生成扫描线射线法填充的实心 Mask,再使用 drawImage 以 source-over 合成到主 Overlay canvas;边界描边也在合成后按构件颜色与透明度绘制,保留多构件叠加效果。
D. 后续如何避免问题
多层或多构件 Canvas 叠加时,优先使用离屏画布或单次合并后的 ImageData;只有在明确要替换整张图时才使用主 canvas 的 putImageData。涉及透明叠加的渲染改动,必须检查“前一层是否会被透明像素擦除”。
2026-05-20-00-38-39 多视图 FOV 对齐必须使用同源物理尺度
A. 具体问题
右侧“逆向分割映射视图”此前使用独立归一化 viewExtent 映射 STL 截面,左侧三维融合视图则根据 DICOM 物理尺寸和 baseExtent 计算显示尺寸;两侧视场和缩放来源不同,容易出现同一层切片下解剖结构和 Overlay Mask 大小不一致。
B. 产生问题原因
右侧算法只使用 STL bounds 做归一化,没有读取 DICOM physicalSize、Pixel Spacing 和 slice spacing;同时左侧三维视图过去按当前可见 STL 构件计算 bounds,构件显隐还可能改变左侧模型缩放。
C. 解决问题方案
右侧新增 getPreviewPhysicalSize、getFovCanvasSize 和同源 getModelSceneMetrics,用 DICOM 物理宽高、层厚、总层数和左侧 baseExtent=4.6 推导 dicomWidth/dicomHeight/dicomDepth、slice Z 与 modelBaseScale。左侧三维视图改为始终用全部 STL bounds 建立全局模型尺度,构件显隐只影响 Mesh 是否渲染。
D. 后续如何避免问题
新增任何二维/三维联动视图前,先明确使用哪套物理坐标系和 FOV;DICOM Base Layer、STL Overlay、slice Z 和模型缩放必须从同一组 spacing、physicalSize 与全局 bounds 推导,不能在不同视图中各自定义归一化范围。
2026-05-20-00-38-39 实体 Mask 填充需要补齐内部空洞
A. 具体问题
仅依赖扫描线交点配对填充时,复杂 STL 截面或抽样边界可能产生小孔洞,视觉上仍会像漏隙,不符合“闭合实体区域”Mask 的审查预期。
B. 产生问题原因
Mesh-Plane Intersection 得到的是离散截面线段,浏览器端再进行像素级光栅化;线段精度、重复交点、边界浮点误差和抽样上限都可能让填充区域内部残留透明像素。
C. 解决问题方案
在每个构件的离屏 Mask ImageData 中完成扫描线填充后,从画布四边对透明区域做 flood fill 标记外部背景;任何未被外部连通到的透明像素都视为内部孔洞并填为当前构件颜色,再合成回主 Overlay。
D. 后续如何避免问题
所有实体 Mask 光栅化都应包含“内部孔洞填补”或等价的连通域后处理;验证时不能只看边界是否有线,还要检查内部是否连续饱满。若后续接入后端体素化,也应保留连通域清理策略作为质量检查。
2026-05-20-01-08-38 工具栏空间不足时优先调整栅格比例
A. 具体问题
逆向工作区左侧“影像与模型融合视角”占用桌面端 7 栅格,中部“可视化工具栏”只占 2 栅格,导致三维视图偏大而工具栏过窄,模型位姿和构件层级控制显得拥挤。
B. 产生问题原因
早期布局更偏向三维展示,将主要横向空间给了融合视图;随着中部工具栏承担模型显示、融合显示、切分、位姿和构件层级等操作,2 栅格已经不足以承载密集控件。
C. 解决问题方案
将桌面端三栏比例从 7 / 2 / 3 调整为 6 / 3 / 3,右侧映射视图保持不变,左侧三维视图让出一格给中部工具栏。
D. 后续如何避免问题
新增工具栏控件后,应重新评估三栏空间分配。操作密集型面板不能长期压缩在过窄栅格内;如果中部继续增加控件,应优先考虑分组、折叠或继续调整栅格比例。
2026-05-20-01-08-38 小步长控制需要同步显示精度
A. 具体问题
用户要求模型位姿平移步长改为 0.005,如果只改 slider step,而数值仍按两位小数显示,界面会把部分精细变化四舍五入隐藏。
B. 产生问题原因
旧显示逻辑用 step < 1 ? 2 : 0 固定小数位,适合 0.05 和 1,但不适合 0.005 这种三位小数步长。
C. 解决问题方案
新增 getStepPrecision,根据 step 本身计算显示小数位;平移 X/Y/Z step 改为 0.005 后自动显示三位小数,旋转仍显示整数,缩放仍显示两位小数。
D. 后续如何避免问题
调整任何滑条或步进按钮的 step 时,同步检查数值展示、长按步进和手动输入精度,避免控制精度和显示精度不一致。
2026-05-20-01-38-33 NIfTI 导出必须与 DICOM 体数据同维同距
A. 具体问题
旧的 NII/NII.GZ 导出生成的是固定 64x64x64 演示 Mask,用户在 ITK-SNAP 中打开时无法与真实 DICOM 序列对应,表现为尺度、层数和内容都不可信。
B. 产生问题原因
早期导出接口没有读取真实 DICOM Pixel Data、Pixel Spacing 和 slice spacing,而是直接写入一个合成球体数据;这类演示数据适合验证下载链路,但不能用于医学影像工具复核。
C. 解决问题方案
后端新增真实 NIfTI-1 写入链路:DICOM 原始影像导出为 512x512x300 int16 HU volume,分割影像导出为同维度 uint8 Label Map,并把 spacing 写入 NIfTI header。分割数据复用 STL 构件采样切面、当前位姿变换和扫描线填充逻辑生成,标签值对应构件 partId。
D. 后续如何避免问题
任何影像导出功能都必须先确认维度、spacing、datatype、vox_offset 和真实数据来源。不能用固定尺寸演示数据替代生产导出;新增导出后至少用脚本读取 NIfTI header,并确认体素数和 DICOM 序列一致。
2026-05-20-01-38-33 浏览器下载不应依赖 blob:http 临时地址
A. 具体问题
浏览器控制台出现 blob:http://... was loaded over an insecure connection,用户误以为导出的 NII.GZ 文件本身或服务部署存在安全错误。
B. 产生问题原因
前端先 fetch 后端文件,再用 URL.createObjectURL(blob) 生成临时 blob:http 地址触发下载;在 HTTP 部署环境下,浏览器会对 blob 来源继承非安全上下文并给出警告。
C. 解决问题方案
将 NIfTI、DICOM 压缩包和多文件导出统一改成后端直链附件下载,由 Express 设置 Content-Disposition,前端只创建 <a href="/api/..."> 触发下载,不再生成 blob URL。
D. 后续如何避免问题
面向大文件、医疗影像和压缩包下载时优先使用后端附件直链。如果必须用 blob,应明确浏览器安全提示的影响;生产环境仍应考虑 HTTPS,但不能把 blob 临时地址当作常规下载路径。
2026-05-20-01-38-33 位姿列表需要进入项目状态而不是组件内存
A. 具体问题
用户保存的可视化工具栏位姿在重新进入项目后消失,造成调好的 STL/DICOM 对齐姿态无法继续复核或用于导出。
B. 产生问题原因
旧实现把 savedPoses 放在 ReverseWorkspace 组件本地 state 中,页面重新加载或重新进入项目时只会恢复默认、俯视、侧视三组临时位姿,没有写回后端项目状态。
C. 解决问题方案
为项目状态新增 modelPoses 字段,后端归一化默认位姿并提供 PATCH /api/projects/:projectId/model-poses;前端加载项目时读取 project.modelPoses,保存或重命名位姿时立即写回后端。
D. 后续如何避免问题
凡是用户明确“保存”的可视化参数都应进入项目级持久状态,不能只存在于组件 state。新增保存类交互时同时设计读取、写入、归一化和刷新后的回显验证。
2026-05-20-02-02-37 位姿数字输入必须保留可编辑中间态
A. 具体问题
模型位姿从只读数值改为可编辑数值时,如果直接把 <input type="number"> 完全绑定到 modelPose,用户输入负号、小数点或临时清空内容时会被 React 立即回填旧值,导致难以编辑。
B. 产生问题原因
数值输入存在合法提交值和编辑中间态两层语义;modelPose 只能存储有限数字,而输入框需要短暂容纳空字符串或尚未完整输入的文本。
C. 解决问题方案
新增 poseValueDrafts 保存输入框文本态,并用 focusedPoseInput 控制同步范围。输入内容能解析为数字时立即 clamp 后写入 modelPose;失焦时统一格式化回与 step 匹配的小数位,非法输入则恢复当前位姿值。
D. 后续如何避免问题
任何需要“可编辑数字 + 实时状态”的控件都应区分 draft value 和 committed value。不要把可能为空或临时非法的输入字符串直接写入业务状态,也不要让格式化逻辑打断用户正在输入的字段。
2026-05-20-02-02-37 导入导出的位姿 JSON 要兼容多种入口
A. 具体问题
位姿导出 JSON 包含 activePose、modelPoses 和项目元信息;用户导入时也可能拿到单个 { pose } 或直接 pose 对象。如果导入逻辑只认一种结构,会让“导出后再导入”的闭环不稳定。
B. 产生问题原因
导出文件是侧车数据,不是纯数组;同时调试和人工编辑时常会只保留一个 pose 对象。导入端如果没有 schema 容错,就会把可恢复数据误判为无效。
C. 解决问题方案
导入解析按优先级读取 activePose、pose、直接 pose 对象和 modelPoses[0].pose,并对每个字段使用 poseStepConfig 做 clamp。若包含 modelPoses,则补齐默认/俯视/侧视并通过现有 PATCH /model-poses 持久化。
D. 后续如何避免问题
成对设计导入/导出功能时,应把导出样例作为导入测试用例,同时兼容最小可用对象。导入端必须对字段缺失、字符串数字、越界数值和重复 id 做归一化处理。
2026-05-20-02-15-10 三维方向标识必须来自真实世界矩阵
A. 具体问题
右下角 XYZ 标识原先是静态 SVG,无法随模型旋转位姿和三维融合场景拖拽旋转变化;用户调整模型后,标识仍显示固定方向,容易误导“平移 X/Y/Z 后模型会往哪里移动”的判断。
B. 产生问题原因
旧标识只是界面装饰,没有读取 Three.js 中 fusionRoot 和 modelPoseGroup 的实时变换。模型实际显示方向由场景根节点旋转、模型位姿旋转和相机投影共同决定,静态二维箭头无法表达这个组合结果。
C. 解决问题方案
新增轴向投影辅助函数,在动画循环中读取 modelPoseGroup 的 world position 与 world quaternion,将模型局部 X/Y/Z 方向投影到当前 camera 屏幕空间,再驱动右下角小 SVG 的线段终点。使用投影签名去重,只有方向变化时才更新 React 状态。
D. 后续如何避免问题
凡是三维视图中的方向、法向、切面或平移提示,都应从 Three.js 真实对象矩阵或统一坐标变换链路推导,不能手写静态示意。若该提示会随拖拽视角变化,还必须包含场景根节点和相机投影。
2026-05-20-02-32-47 分割影像与类别元数据必须同包同源
A. 具体问题
用户要求“导出全部 NII.GZ”改成压缩包形式,同时分割影像必须附带不同类别 ID 与名称的对应 JSON,并且分割范围可选所有类别或可见类别。如果 NIfTI 和 JSON 分开下载,或二者使用不同筛选条件,后续在 ITK-SNAP 查看时容易无法追溯标签语义。
B. 产生问题原因
旧前端对多个导出目标采用连续触发多个直链下载,缺少一个原子化导出包;旧分割生成逻辑默认跳过隐藏构件,也没有把实际参与导出的 label/partId/name/fileName/color 等元数据写入侧车文件。
C. 解决问题方案
新增 /api/projects/:projectId/export-bundle,将 DICOM NIfTI、分割 NIfTI、位姿 JSON 和分割 labels JSON 放入同一个 .tar.gz。分割生成函数和 labels JSON 生成函数共用 segmentationScope=visible|all,确保可见/全量筛选逻辑一致;labels JSON 中记录 label、partId、name、categoryName、className、fileName、color、opacity、visible 和 activePose。
D. 后续如何避免问题
任何分割影像导出都应同时考虑语义侧车文件,并保证侧车元数据与实际 mask 标签来自同一批样式和筛选条件。多文件导出优先做成一个后端归档包,避免浏览器多下载顺序、丢文件或元数据错配。
2026-05-20-02-55-11 大面数 STL 导出不能复用预览抽样网格
A. 具体问题
用户在 ITK-SNAP 中查看导出的分割 NIfTI 时,头部 类别仍呈散点或点云状,而原始 头部.stl 是完整实体表面。
B. 产生问题原因
后端 NIfTI 分割生成复用了 createStlPreview(file, 200000) 的预览顶点数组。头部.stl 约有 257 万个三角面,但导出时最多只保留 20 万个抽样面;闭合轮廓被抽稀后,Mesh-Plane Intersection 生成的扫描线交点不连续,实体填充会退化成稀疏点/线。
C. 解决问题方案
保留预览抽样数据仅用于 bounds 和网页显示;NIfTI 导出路径改为逐三角读取完整二进制 STL buffer,对全部网格面执行位姿变换、平面求交和扫描线光栅化。同时后端每个构件、每个 slice 先写入临时二值 mask,再通过四边 flood fill 标记外部区域,将内部未连通孔洞补齐后写入最终 Label Map。
D. 后续如何避免问题
预览数据、抽样数据和医学导出数据必须明确分层。凡是 NIfTI、Mask、Label Map、体素化这类可用于医学工具复核的导出功能,都不得复用用于前端性能优化的抽样网格;验证时必须检查大面数构件的 label 体素数量、slice 覆盖范围和侧视/冠状重建是否连续。
2026-05-20-03-19-25 分割结果保存必须携带位姿与导出上下文
A. 具体问题
用户要求在逆向工作区将当前“逆向分割映射视图”保存至项目库,并在项目库分割结果区域继续导出。如果只保存一个名称或时间,项目库无法复现保存当时的位姿、类别范围和构件样式。
B. 产生问题原因
分割结果不是一个静态按钮状态,而是由模型位姿、构件显隐、颜色、透明度、partId 和分割范围共同决定;这些上下文如果仍散落在组件 state 或只存在当前页面,重新进入项目库后导出的结果可能与保存时不一致。
C. 解决问题方案
项目状态新增 segmentationResults,保存当前结果名称、时间、segmentationScope、模型位姿和构件样式快照;逆向工作区通过后端接口写入项目,项目库分割结果区域读取该记录,并用最新保存结果的位姿作为导出默认输入。导出包新增 stl 目标,将原始 STL 文件放入同一个 tar.gz 中。
D. 后续如何避免问题
凡是“保存至项目库”“保存结果”“复核后导出”类功能,都必须明确保存的是结果本体还是生成结果所需的上下文。医学导出相关记录至少要包含位姿、分割范围、标签样式和生成时间;新增导出目标时也要同步检查逆向工作区和项目库两个入口是否一致。
2026-05-20-11-07-27 软著素材位姿不能成为产品默认最佳参数
A. 具体问题
head-ct-demo-pose-data.json 只是软著和专利撰写时用于展示的素材,不应被产品标注为“最佳位姿”,也不应在用户进入项目时被默认优先加载。
B. 产生问题原因
早前为了演示效果,将示例位姿固化到前后端默认位姿列表,并在逆向工作区加载时优先选择“最佳位姿/位姿2”。这会把文档素材和产品运行时状态混在一起,导致用户误以为该位姿经过业务确认。
C. 解决问题方案
后端移除 best/最佳位姿 默认记录,并在归一化历史数据时过滤旧 best 项;前端移除 headCtBestPose 和默认保存位姿中的最佳项,项目加载时恢复优先选择 default,保留用户手动导入位姿 JSON 的能力。软著材料输出到 新撰写软著文档/,并明确不纳入 Git/Gitea 暂存。
D. 后续如何避免问题
示例素材、专利素材、软著素材只能作为文档或手动导入资源使用,不能命名为“最佳”“推荐”等产品级默认值。今后新增默认位姿或默认参数时,应同时检查前端默认列表、后端状态归一化和项目加载优先级,避免文档素材污染运行时逻辑。
2026-05-20-11-34-57 软著截图自动化要兼顾 WebGL 渲染环境
A. 具体问题
为软著说明书插入真实系统截图时,普通 Chrome Headless 能正常截取登录、概况和项目库界面,但进入逆向工作区后页面空白,导致逆向工作区和导出选项截图不可用。
B. 产生问题原因
逆向工作区包含 Three.js 三维融合视图,普通 headless 环境中 WebGL 上下文创建失败,React 渲染链路被三维视图错误打断,最终截图只得到空白页面。
C. 解决问题方案
截图脚本在进入逆向工作区时改用 Chrome 软件 WebGL 参数,包括 --enable-unsafe-swiftshader、--use-gl=angle 和 --use-angle=swiftshader,等待页面稳定后重新截取逆向工作区与导出面板。生成 Word 时解析 Markdown 图片语法,并将 8 张 PNG 以嵌入媒体的形式写入说明书 .docx。
D. 后续如何避免问题
凡是为含三维场景的页面生成截图或录屏,都应优先验证截图不是空白,并检查浏览器控制台是否有 WebGL 创建失败信息。自动化截图应准备软件渲染兜底;Word 交付前必须用 unzip -l 检查 word/media/ 是否包含预期图片。
2026-05-20-11-51-05 默认医学数据资产入库需要明确体积与二进制属性
A. 具体问题
默认项目依赖 Head_CT_DICOM/ 和 Head_CT_ReConstruct/,但两个目录原先被 .gitignore 排除。新环境只克隆代码时无法直接加载默认演示项目,需要额外复制医学数据资产。
B. 产生问题原因
早期工作流把 DICOM/STL 视为不进入普通文档备份的大型医学源数据,避免无意提交;但当前用户明确要求把默认项目数据作为仓库交付资产,以支持新环境开箱构建。
C. 解决问题方案
移除 .gitignore 中对 Head_CT_DICOM/ 和 Head_CT_ReConstruct/ 的忽略规则,新增 .gitattributes 将 *.dcm 和 *.stl 标记为 binary。提交前统计数据体积和文件数,验证默认项目接口仍返回 DICOM 300 张、STL 9 个构件。
D. 后续如何避免问题
默认演示数据和运行态输出要分开管理:默认项目资产可以入库,但导出文件、状态文件和用户临时数据仍应保持忽略。新增大体积医学数据前必须记录体积、文件数、脱敏/授权假设和远端推送结果;若体积继续增长,应评估 Git LFS 或独立数据包发布。
2026-05-20-12-09-47 软著说明书逐章配图与视频需要同时校验交付格式
A. 具体问题
用户要求软著说明书中每一个 ## X. 章节都配图,并录制系统使用视频,位姿导入必须使用 head-ct-demo-pose-data.json。如果只更新 Markdown 或只生成截图,不重新生成 Word 与视频,就会出现交付材料与源文档不一致的问题。
B. 产生问题原因
软著材料同时存在 Markdown、Word、截图目录和视频目录,多种格式之间没有自动同步机制;逆向工作区还依赖 WebGL 和隐藏文件输入,普通截图流程容易漏掉位姿导入成功状态或生成空白三维画面。
C. 解决问题方案
使用 Chrome 自动化打开系统核心页面并导入 head-ct-demo-pose-data.json,生成 23 张章节截图并插入到说明书 23 个 ## X. 章节下;对 DICOM 信息截图中的患者姓名与编号区域进行遮盖脱敏;使用 ffmpeg 生成 H.264 MP4 系统使用视频;重新生成 1. 软著说明书.docx 并通过 unzip -t 和 word/media 数量检查确认 23 张图片已嵌入。
D. 后续如何避免问题
软著说明书增加、删除或改名章节后,应重新跑“章节数、图片数、图片文件存在、Word 媒体数量、视频信息”五类检查。涉及医学影像信息截图时必须先确认是否存在患者姓名、编号等敏感字段;涉及位姿展示时必须记录所用 JSON 文件,并在截图或视频中保留导入成功状态。
2026-05-20-12-29-06 软著截图应区分完整页面与章节聚焦图
A. 具体问题
用户指出软著说明书中的图片不要截取。上一轮为了让章节主题更聚焦,将部分完整截图裁成局部卡片或面板,导致 Markdown 预览中图片像是只展示了页面片段。
B. 产生问题原因
软著说明书截图既要图文对应,又要保持审查材料中的界面完整性。局部裁剪虽然能突出功能区,但会丢失导航、模块位置和完整操作上下文,不符合用户对“完整截图”的预期。
C. 解决问题方案
重新使用 Chrome 自动化生成 23 张 1680x1050 完整视口截图,仅对 DICOM 信息截图中的患者姓名和患者编号值做遮盖脱敏,不再裁剪功能卡片或局部区域。重新生成 1. 软著说明书.docx,并通过章节图片引用、图片尺寸、Word 图片位置和服务部署检查。
D. 后续如何避免问题
软著截图默认采用完整页面截图;只有用户明确要求“局部图”“放大细节图”时才裁剪。若同一完整页面用于多个章节,校验 Word 时应统计正文图片位置数量,而不能只看 word/media 文件数,因为 Word 会复用相同图片二进制。
2026-05-20-14-19-23 逆向分割结果单结果化需要前后端同时收口
A. 具体问题
用户要求项目库“分割结果”改为“逆向分割结果”,并且只保留一个当前结果,同时逆向工作区退出时询问是否保存、再次进入时读取项目库结果。如果只改前端展示,后端仍保存多条记录,导出和重新进入工作区会继续使用不一致的状态。
B. 产生问题原因
原有设计把 segmentationResults 作为历史列表保存,前端项目库按列表展示,后端导出接口默认使用当前请求参数或项目样式。新的业务语义改成项目级唯一当前结果,涉及保存接口、状态归一化、导出默认参数、工作区加载恢复和视图切换守卫多个链路。
C. 解决问题方案
后端归一化和保存接口均改为只保留最新一条逆向分割结果,并把位姿、构件样式、切片范围、映射切片和显示状态一起保存;导出接口默认读取最新保存结果。前端项目库改为两张结果预览图和统一导出面板;逆向工作区顶部集中保存与导出按钮,保存后显示渐隐提示;主应用视图切换时调用工作区离开守卫,保存失败时阻断退出。
D. 后续如何避免问题
凡是把“历史记录”改为“当前唯一状态”的需求,都要同步检查数据模型、归一化逻辑、保存接口、列表 UI、导出默认参数和重新进入页面的恢复逻辑。提交前用 rg 搜索旧文案和旧入口,避免残留重复下载按钮或旧命名造成用户误解。
2026-05-20-14-53-31 保存提示与管理操作需要区分状态语义
A. 具体问题
用户要求逆向工作区在未修改或刚保存后离开时不再弹出保存确认,同时系统管理工作区的添加、编辑、删除用户按钮必须真正可用,并且不能删除当前登录用户。
B. 产生问题原因
上一轮实现的离开守卫只知道“正在离开逆向工作区”,不知道当前可视化状态是否已经保存,因此无条件弹窗;系统管理页原先只实现了用户列表和重置演示环境,操作按钮没有对应 API 和表单逻辑。
C. 解决问题方案
为逆向工作区建立保存快照,快照覆盖位姿、构件样式、切片范围、映射切片、模型显示、DICOM 融合强度、边界和切分状态;项目加载和保存成功后刷新快照,离开时只有当前快照与保存快照不同才弹确认。后端补齐 /api/users 的新增、编辑和删除接口,删除时拒绝当前登录用户;前端系统管理页改为真实表单和操作流。
D. 后续如何避免问题
凡是“离开前确认保存”类交互,都要先定义脏状态快照,不能只按页面离开事件弹窗。后台管理按钮必须有明确接口、成功/失败反馈和权限边界;至少要覆盖新增、编辑、删除自己、删除其他用户四个验证场景。
2026-05-20-15-20-15 项目库结果视图应复用逆向工作区真实组件
A. 具体问题
用户指出项目库中的“影像与模型融合视角”和“逆向分割映射视图”仍像简化预览,不是逆向工作区里的真实效果;同时编辑用户弹窗字段缺少标签,编辑资料时仍出现密码修改入口,容易误解为保存资料会顺带改密。
B. 产生问题原因
项目库结果页此前为节省加载量,使用了单独的 STL 预览和 DICOM Canvas 组合,导致与逆向工作区的三维融合、二维映射算法和视觉层次不一致。用户管理表单把创建、编辑和改密共用一套输入框,密码字段只通过占位提示表达语义,交互边界不够明确。
C. 解决问题方案
将逆向工作区的 FusionThreeView、VoxelizationMappingView、显示精度和 DICOM 融合强度配置导出给项目库复用;项目库逆向结果页在有保存结果时加载 fusion volume,并直接渲染同款三维融合视图和二维映射视图。用户弹窗改为每个输入框都有字段标签;编辑模式只保留姓名、账号、科室;新增和修改密码模式均要求输入两遍密码并做一致性校验。
D. 后续如何避免问题
凡是用户要求两个页面“效果一致”,优先抽取或导出已有真实组件,不再维护第二套近似 UI。涉及密码、权限、删除等高风险管理操作时,必须把资料编辑和凭据修改拆成不同入口,并通过显式标签、校验和反馈减少误操作。
2026-05-20-15-33-38 医学影像视图控件不要覆盖审查画布
A. 具体问题
用户指出逆向工作区的 Slice Navigator 格式与“DICOM 切片范围”不统一,并且 Overlay Label Map 的构件统计区域会遮挡 DICOM 影像,影响对二维切片和叠加分割结果的审查。
B. 产生问题原因
此前 VoxelizationMappingView 为了紧凑展示,把切片导航放在视图底部,同时将 Overlay 状态和构件列表使用绝对定位压在影像画布底部。该设计在普通预览中节省空间,但在医学影像核验场景中会遮挡 DICOM 主体区域。
C. 解决问题方案
将视图结构调整为“影像画布 + 右侧竖向切片导航 + 下方 Overlay 统计面板”:右侧竖向导航使用独立 mapping-slice-vertical-input,显示当前 DICOM 切片位置和上下层按钮;Overlay 构件列表移到画布下方,不再覆盖 DICOM 影像。
D. 后续如何避免问题
医学影像主画布应优先保持无遮挡,状态、统计、导航控件默认放在画布外侧。若必须悬浮在影像上,只能使用小尺寸状态标识,并在提交前检查是否遮挡解剖结构或分割边界。