@@ -636,37 +714,122 @@ export default function ReverseWorkspace({ projectId }: { projectId: string }) {
-
- 分割 Mask
+
+ 可视化工具栏
-
- {mappings.map((mapping, index) => (
-
- ))}
+
+
+
模型显示
+
+ {displayOptions.map((option) => (
+
+ ))}
+
+
-
+
+
+
+
+
+
+
+
+
构件层级
+
{project?.stlFiles?.length ?? 0}
+
+
+ {(project?.stlFiles ?? []).map((fileName, index) => {
+ const style = moduleStyles[fileName] ?? {
+ visible: true,
+ color: moduleColors[index % moduleColors.length],
+ opacity: 0.72,
+ partId: index + 1,
+ };
+ return (
+
+
+
updateModuleStyle(fileName, { color: event.target.value })}
+ className="h-7 w-7 shrink-0 rounded border border-white bg-white p-0.5"
+ title="模型颜色"
+ />
+
+
{fileName.replace(/\.stl$/i, '')}
+
+
+
+
+
+ 透明度
+ updateModuleStyle(fileName, { opacity: Number(event.target.value) })}
+ className="min-w-0 flex-1 accent-blue-600"
+ />
+ {Math.round(style.opacity * 100)}%
+
+
+ );
+ })}
+
+
@@ -675,7 +838,7 @@ export default function ReverseWorkspace({ projectId }: { projectId: string }) {
Metadata
- {`{ project: "${project?.id ?? projectId}", format: "nii.gz" }`}
+ {`{ project: "${project?.id ?? projectId}", display: "${selectedDisplay.label}" }`}
diff --git a/WebSite/src/components/Sidebar.tsx b/WebSite/src/components/Sidebar.tsx
index 756fd8d..5d44640 100644
--- a/WebSite/src/components/Sidebar.tsx
+++ b/WebSite/src/components/Sidebar.tsx
@@ -31,6 +31,7 @@ export default function Sidebar({
const menuItems = [
{ id: ViewType.OVERVIEW, icon: BarChart3, label: '总体概况' },
{ id: ViewType.PROJECTS, icon: FolderRoot, label: '项目库' },
+ { id: ViewType.MODELS, icon: Box, label: '模型库' },
{ id: ViewType.WORKSPACE, icon: Box, label: '逆向工作区' },
{ id: ViewType.SYSTEM, icon: Settings, label: '系统管理工作区' },
];
diff --git a/WebSite/src/types.ts b/WebSite/src/types.ts
index f233845..dab133f 100644
--- a/WebSite/src/types.ts
+++ b/WebSite/src/types.ts
@@ -1,6 +1,7 @@
export enum ViewType {
OVERVIEW = 'overview',
PROJECTS = 'projects',
+ MODELS = 'models',
WORKSPACE = 'workspace',
SYSTEM = 'system',
}
diff --git a/工程分析/实现方案-2026-05-07-18-11-12.md b/工程分析/实现方案-2026-05-07-18-11-12.md
new file mode 100644
index 0000000..ca4cdd7
--- /dev/null
+++ b/工程分析/实现方案-2026-05-07-18-11-12.md
@@ -0,0 +1,83 @@
+# 实现方案 - 2026-05-07-18-11-12
+
+## 修改目标
+
+- 修复项目库构件层级眼睛按钮。
+- 为构件层级增加可编辑 ID。
+- 左侧导航新增 `模型库`。
+- 逆向工作区将 `分割 Mask` 替换为 `可视化工具栏`,并加入模型显示、整体位姿保存/选择、构件层级。
+
+## 涉及路径
+
+- `WebSite/src/types.ts`
+- `WebSite/src/App.tsx`
+- `WebSite/src/components/Sidebar.tsx`
+- `WebSite/src/components/ProjectLibrary.tsx`
+- `WebSite/src/components/ReverseWorkspace.tsx`
+
+## 技术路线
+
+### 1. 左侧新增模型库
+
+- 在 `ViewType` 中新增 `MODELS`。
+- Sidebar 增加 `模型库` 导航项。
+- App 中点击 `模型库` 时复用 `ProjectLibrary`,但通过 `initialViewMode="model"` 默认进入 3D 模型页。
+
+### 2. 项目库构件层级眼睛修复与 ID
+
+- `ModuleStyle` 增加 `partId`。
+- 初始化构件层级时按文件顺序写入 `partId=index+1`。
+- `toggleModuleVisibility()` 明确保留 `partId/color/opacity`,只切换 `visible`。
+- 构件眼睛按钮阻止冒泡,避免父级点击干扰。
+- 每个构件显示 `ID` 输入框,输入值限制为 1 到 255 的整数。
+
+### 3. 逆向工作区可视化工具栏
+
+- 将标题 `分割 Mask` 改为 `可视化工具栏`。
+- 增加模型显示档位:标准、精细、超精细、实体。
+- 增加整体位姿保存/选择:
+ - 默认预设:默认、俯视、侧视。
+ - 用户可保存当前位姿为 `位姿N`。
+ - 选择后更新 `modelPose`。
+- 增加构件层级:
+ - 眼睛显示/隐藏。
+ - 颜色。
+ - 透明度。
+ - ID 1 到 255。
+- 将逆向工作区 Three.js 模型加载逻辑接入构件样式和显示档位。
+
+## 数据流或交互流程
+
+1. 用户进入 `模型库` 或项目库 3D 模型页。
+2. 构件样式状态按 STL 文件初始化。
+3. 用户点击眼睛按钮,前端更新对应构件 `visible`,Three.js 重新加载/渲染可见构件。
+4. 用户修改 ID,前端 clamp 到 1 到 255 并显示。
+5. 用户进入逆向工作区,工具栏显示模型显示、位姿预设、构件层级。
+6. 用户保存或选择整体位姿,融合视角模型位姿更新。
+
+## 兼容性与回滚方案
+
+- `模型库` 复用项目库,不新增后端路由。
+- 构件 ID 仅在前端状态中使用,若后续需要持久化可再扩展后端项目状态。
+- 若逆向工作区工具栏过长,可后续拆成 tabs 或折叠区。
+
+## 预计文件变更
+
+- `types.ts`:新增 ViewType。
+- `Sidebar.tsx`:新增导航项。
+- `App.tsx`:支持模型库视图和 ProjectLibrary 初始 tab。
+- `ProjectLibrary.tsx`:构件 ID、眼睛修复、初始 viewMode 参数。
+- `ReverseWorkspace.tsx`:可视化工具栏与模型样式/位姿预设。
+
+## 人工审核状态
+
+- 本次免二次确认,方案写入后直接执行。
+
+## 执行结果
+
+- 已新增左侧导航 `模型库`,默认进入项目库的 3D 模型页。
+- 已为项目库构件层级增加 `ID` 输入,默认 1 到 N,输入限制为 1 到 255。
+- 已修正项目库构件眼睛按钮切换时保留颜色、透明度、ID 状态。
+- 已将逆向工作区 `分割 Mask` 改为 `可视化工具栏`。
+- 已在可视化工具栏加入模型显示档位、整体位姿保存/选择、构件层级。
+- 已将逆向工作区融合视角的 STL 加载接入构件显示、颜色、透明度和模型显示档位。
diff --git a/工程分析/测试方案-2026-05-07-18-11-12.md b/工程分析/测试方案-2026-05-07-18-11-12.md
new file mode 100644
index 0000000..2f00dbd
--- /dev/null
+++ b/工程分析/测试方案-2026-05-07-18-11-12.md
@@ -0,0 +1,51 @@
+# 测试方案 - 2026-05-07-18-11-12
+
+## 静态检查
+
+1. `git status --short --branch`
+2. `cd WebSite && npm run build`
+3. `cd WebSite && npm run lint`
+
+## 单元或集成测试
+
+当前项目没有独立单元测试体系,本次采用构建、类型检查、API 冒烟和页面运行验证。
+
+## 关键业务场景验证
+
+1. 左侧导航显示 `模型库`。
+2. 点击 `模型库` 默认进入项目库 3D 模型页。
+3. 项目库构件层级:
+ - 点击单个构件眼睛,模型可隐藏/显示。
+ - 顶部眼睛可全隐藏/全显示。
+ - 每个构件显示 `ID`。
+ - ID 可修改为 1 到 255。
+ - ID 修改为 0 时应被限制为 1。
+4. 逆向工作区:
+ - `分割 Mask` 文案变为 `可视化工具栏`。
+ - 工具栏包含模型显示、整体位姿保存/选择、构件层级。
+ - 模型显示档位切换后场景仍可加载。
+ - 保存位姿后可在选择框中切回。
+ - 构件眼睛、颜色、透明度可影响融合视角中的模型显示。
+
+## 医学影像数据相关边界验证
+
+- 本次不修改 DICOM 解析和融合体接口。
+- 回归确认 `/api/projects` 和 `/api/projects/head-ct-demo/dicom-fusion-volume` 可访问。
+
+## 回归风险
+
+- 逆向工作区模型样式状态变化会触发 Three.js 重建,可能带来短暂加载。
+- 左侧新增导航项可能影响当前 header 文案和 activeView 判断。
+- 项目库构件 ID 目前未持久化,刷新页面后回到默认 1 到 N。
+
+## 人工审核状态
+
+- 本次免二次确认。
+
+## 执行记录
+
+- `npm run lint`:通过,实际执行 `tsc --noEmit`。
+- `npm run build`:通过。
+- 重新部署后 `curl -I http://127.0.0.1:4000/`:返回 `HTTP/1.1 200 OK`。
+- `GET /api/projects`:正常返回默认项目,包含 9 个 STL 文件。
+- `GET /api/projects/head-ct-demo/dicom-fusion-volume?start=0&end=10&mode=soft`:正常返回 DICOM 融合体数据。
diff --git a/工程分析/经验记录.md b/工程分析/经验记录.md
index 79316e4..3626c95 100644
--- a/工程分析/经验记录.md
+++ b/工程分析/经验记录.md
@@ -649,3 +649,21 @@ C. 解决问题方案
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 四条路径;逆向工作区的可视化控制应与项目库模型页保持一致,避免用户在两个页面学两套交互。
diff --git a/工程分析/需求分析-2026-05-07-18-11-12.md b/工程分析/需求分析-2026-05-07-18-11-12.md
new file mode 100644
index 0000000..94847e7
--- /dev/null
+++ b/工程分析/需求分析-2026-05-07-18-11-12.md
@@ -0,0 +1,56 @@
+# 需求分析 - 2026-05-07-18-11-12
+
+## 原始需求摘要
+
+用户要求:
+
+1. 修复 `项目库 - 3D模型 - 构件层级` 右侧眼睛按钮不好使的问题。
+2. 左侧导航增加一个功能:`模型库`。
+3. `项目库 - 3D模型 - 构件层级` 中每个层级显示 `ID: XX`,默认从 1 到 N;ID 可修改为 1 到 255 的整数,不能改成 0。
+4. 逆向工作区中 `分割 Mask` 文案改为 `可视化工具栏`。
+5. 在 `可视化工具栏` 中加入模型显示、整体位姿保存和选择、构件层级功能。
+6. 本次需求分析、实现方案、测试方案、执行修改都不需要人工二次确认。
+
+## 业务目标
+
+- 让模型构件显示/隐藏、颜色、透明度和 ID 管理成为稳定可用的可视化控制基础。
+- 将模型相关控制从项目库扩展到逆向工作区,使三维融合视角具备更完整的模型可视化工具栏。
+- 让用户可以保存常用整体位姿并快速切换,降低重复调整成本。
+
+## 输入与输出
+
+输入:
+
+- 用户点击构件层级眼睛按钮。
+- 用户修改构件 ID。
+- 用户在逆向工作区调整模型显示、模型位姿、保存/选择位姿。
+
+输出:
+
+- 构件眼睛按钮能正确隐藏/显示对应 STL。
+- 构件层级显示并可编辑 1 到 255 的 ID。
+- 左侧导航出现 `模型库`,点击后进入项目库的模型页。
+- 逆向工作区中出现 `可视化工具栏`,包含模型显示、整体位姿保存/选择、构件层级。
+
+## 影响范围
+
+- `WebSite/src/types.ts`
+- `WebSite/src/App.tsx`
+- `WebSite/src/components/Sidebar.tsx`
+- `WebSite/src/components/ProjectLibrary.tsx`
+- `WebSite/src/components/ReverseWorkspace.tsx`
+
+## 风险点
+
+- 项目库和逆向工作区各自维护构件状态,若状态结构不一致会导致行为差异。
+- 构件 ID 是前端可视化 ID,不应被误认为已写入 mask 标签或后端分割 ID。
+- 新增 `模型库` 导航若没有正确带入初始 tab,可能和 `项目库` 行为混淆。
+- 逆向工作区可视化工具栏内容较多,需要避免布局过挤。
+
+## 待确认问题
+
+- 本次用户已明确免二次确认,直接执行。
+
+## 人工审核状态
+
+- 本次免二次确认。