# 交接:VTK 三维分析视图重构(按数据类型分组 + 对象树联动) > 给下一个会话无缝接手。日期 2026-06-24。分支 `feat/vtk-3d-view`。 > 本会话**产出 spec + 实施 plan + openapi 修订,未改业务代码**——下一步是按 plan 执行实现。 > > **速览**:把 VTK 左侧三 tab 重构为「按数据类型大类分组」两 tab;经真实接口实测定分类/字段、opus 子代理评审、客户两轮交互确认后定稿。产出 spec(`specs/2026-06-24-vtk-category-view-refactor-design.md`)+ 实施 plan(`plans/2026-06-24-vtk-category-view-refactor.md`,8 phase/12 task)+ openapi v0.6(`docs/api/vtk-3d-openapi.json`)。 --- ## ⏩ 实施进度(2026-06-24 续会话,Task 1-10 完成) **已完成 Task 1-10(10/12),全部已提交、可编译、逻辑层单测全绿(425 测试,5 个失败均为 PROJ_DATA 环境性、非回归)。剩 Task 11-12(main 接线总成)。** 提交链(在 `a7d558b` docs 之后): ``` a06d9e8 feat(data): createVolume(VoxelGenerateRequest) 重载+fromRequest 派生+请求体打印(mock) # Task10 3af7e44 feat(ui): VtkViewToolbar 画布工具条 + AxesSettingsDialog 坐标轴设置 # Task9 98114a3 feat(ui): CategoryAnalysisTab(QScrollArea 5段)+ColumnDrawer 两tab(旧栏隐藏过渡) # Task8 30e990d feat(ui): CategorySection 类型段组件 + DatasetFieldDictionary 缓存类 # Task7 40646f7 refactor(tree): 评审修复-抽 recomputeAllGsStates 去 nullptr 信号 hack # Task4-6 review 修复 c5b3907 feat(data): DatasetFieldDictionary 解析 arrayType/collectTime 映射+装置字典 # Task6 1978a31 feat(tree): GS 三态状态机(停 AutoTristate)+右键 ds/tm + checkedSourcesChanged # Task4+5(合并) 6b39901 test(data): 补 properties[1] 日期项断言 f00a214 feat(data): VoxelGenerateRequest/SliceGenerateRequest DTO + toJson # Task3 07cf75d feat(app): CategoryConfig 映射表 + splitByCategory # Task2 5a719ca feat(data): DsRow 加 dsTypeCode/properties + parseDsRows 解析 # Task1 ``` **已就绪的新构件(均编译通过)**: - 逻辑层:`DsRow` 扩字段、`splitByCategory`(CategoryConfig 5 段)、`Vtk3dRequests`(Voxel/Slice DTO + toJson + `fromRequest`)、`DatasetFieldDictionary`(parseFieldMapping + 缓存类)、`ObjectTreeSelection`(aggregateGsState/dedupeSources)。 - 对象树:`ObjectTreePanel` GS 三态状态机(停 AutoTristate)+ 右键「选择▸ds/tm」+ `checkedSourcesChanged(QList)` 信号(**与旧 `checkedTmsChanged` 并存**,Task 12 删旧)。 - UI 组件:`CategorySection`(段头装置/日期筛选+段体可勾选树+「+新增三维体」+双击详情)、`CategoryAnalysisTab`(QScrollArea 5 段,setBuckets/section/勾选并集)、`ColumnDrawer` 已改两 tab(三维分析=analysisTab / 二维分析=col2D;**旧 col3D_/colAnalysis_ 仍实例化但 hide()、不入 tab**,保留访问器供 main 过渡)、`VtkViewToolbar`、`AxesSettingsDialog`。 - data:`Api3dRepository::createVolume(VoxelGenerateRequest)` 重载(组装真实请求体+打印+`lastVoxelRequest`),旧 `createVolume(VolumeBuildParams,name)` 保留。 **⚠️ 当前过渡态**:app 可编译运行,但「三维分析」tab 是**空的 CategoryAnalysisTab**(数据接线在 Task 12);旧三维数据集/三维分析功能已隐藏。对象树 GS 三态+右键 ds/tm **已在现 app 生效**(旧 checkedTmsChanged 仍兼容),可立即真实验证(plan Task 4 Step 7 清单)。 **偏离 plan 的决策(已记录理由)**:① Task 4+5 合并一个 commit(plan Task4 右键已引用 Task5 的 emitCheckedSources,循环依赖);② DatasetFieldDictionary 异步拉取下放 main(data 层无网络,类只内存缓存);③ CategorySection 段体先平铺(populateDatasetList),「项目根/GS/TM 容器节点分层」推迟 Task 12 接真实 StructNode;④ createSlice 虚接口未改签名,SliceGenerateRequest 组装并入 Task 12 main 层。 ### 🔧 Task 11+12 待做(main.cpp 接线总成,最高风险,须真实 app 验证) `main.cpp` 1943 行,接线密集。关键现状符号位置: - `:361` `new ColumnDrawer(centerWidget)` —— 需改传 dict(构造已支持第2参 `DatasetFieldDictionary* dict=nullptr`)。 - `:397 refreshAnomalies` / `:448 refreshAnalysis` 闭包用 `drawer->colAnalysis()`。 - `:442 c3 = drawer->col3D()`;`:641` c3 checkedDatasetsChanged→sceneCtrl;`:653` c3 generateVolumeRequested→createVolume;`:898/902` c3 verticalExaggeration。 - `:579/745` createSlice 调用(补 projectId + 组装 SliceGenerateRequest)。 - `:584/623` `colAnalysis()->setItemChecked`;`:666 ca=colAnalysis()`。 - `:1117/1267` 对象树 `checkedTmsChanged` 接线(→改 `checkedSourcesChanged` + confType 分流 `loadRowsAsync(projId, src.id, src.confType, 3, ...)`)。 - `:1134 splitByDimension`→`splitByCategory` + `analysisTab()->setBuckets`;`:1135 col3D/col2D setDatasets`。 - `:1215 clearCentral`。`:1328 drawer->expand()`。 **Task 11 缺口**:`CategoryAnalysisTab`/`CategorySection` 尚无 colAnalysis 的 `setItemChecked`、异常子区 API;三维体段需迁入 Column3DAnalysis 异常控件(参 `src/app/panels/columns/Column3DAnalysis.{hpp,cpp}` + main `:397 refreshAnomalies`)。 **Task 12 要点**(plan §Task12 Step1-8 已详列):① 对象树勾选→confType 分流拉取→splitByCategory→analysisTab setBuckets;② analysisTab checkedDatasetsChanged→并入 checkedProfiles/checkedAnalysis→pushChecked;③ generateVolumeRequested→`VolumeParamsDialog` 扩展(左侧勾选源树·可二次增删 + 右侧「生成位置」下拉=项目内 GS/TM)→组装 `VoxelGenerateRequest`→`createVolume(req)`;④ 工具条 `VtkViewToolbar` 叠加中央 QVTK + AxesSettingsDialog 接坐标轴;⑤ createSlice 补 `nav.currentProjectId()`;⑥ 删旧 checkedTmsChanged/col3D()/colAnalysis()/splitByDimension/Column3D* 引用 + setStructure 传对象树同源 StructNode(容器分层)。**建议新会话以充足上下文做,每步 build + 用户真实验证。** > 下方为初版交接(spec/plan 设计定论,仍有效)。 ## 1. 背景 - 代码库 = 原版 web 系统(`D:\Git\lanbingtech\commercial-admin`,复刻权威)移植的 Qt6 桌面客户端。 - 现状 VTK 视图左侧 `ColumnDrawer` 是三 tab(三维数据集/二维数据集/三维分析),`splitByDimension` 按 `ddCode` 分 3 维度。 - 需求(用户截图设计):把「三维数据集」并入「三维分析」,改成**按数据类型大类分组**(电阻率/视电阻率/瞬变电磁/三维体/切片),每类各自筛选+操作;对象树勾选联动、支持 GS/项目直挂数据;全局视图控制移 VTK 画布工具条。 ## 2. 本会话已完成 1. **摸透现状源码**(ColumnDrawer/Column3D*/DatasetDimension/DatasetListPanel/ObjectTreePanel/RepoTypes/NavDto/Api3dRepository/main.cpp 接线等)。 2. **真实接口实测定关键事实**(用用户给的 token 直连后端,见 §6)——纠正了多个二手猜测。 3. **brainstorming 澄清全部设计决策**(容器布局、分类策略、对象树三态交互、装置类型、生成入口等)。 4. **产出 spec** 并经 **opus 子代理评审 + 据评审修订**(GS 三态停 AutoTristate、properties 两接口形态澄清、帘面勾选链承接等)。 5. **产出实施 plan**(8 phase/12 task,TDD bite-sized,逻辑层完整测试代码、UI 层 build+手动验证)。 6. **客户两轮交互确认**收敛生成三维体交互(见 §3 第 5 条),同步更新 spec/openapi(v0.6)/plan。 7. **openapi 修订**:三维体归属层级 TM → GS/项目根 → 再放开 GS/项目根/TM。 ## 3. 最终设计定论(核心,已写入 spec) 1. **两 tab**:「三维分析」(5 段)+「二维分析」(现 `Column2DDataset` 不动)。 2. **大类分类按 `dsTypeCode`**(不是 ddCode)——电阻率/视电阻率/瞬变电磁三者 ddCode 同为 `dd_inversion_data`,只 dsTypeCode 不同。映射表 `CategoryConfig` 驱动;三维体/切片按 ddCode(`dd_voxel`/`dd_slice`)识别。 3. **对象树联动**: - 非根 GS = **三态复选框**(聚合「GS 自身 ds 开关」+「子 TM 勾选」)+ 右键「选择▸ds/tm」;**必须停用 `Qt::ItemIsAutoTristate`、手动维护三态**(UserRole 存 ds 开关)。 - 项目根 = 无复选框、直挂 ds 固定显示、其下 TM 各自二态勾选。 - 信号 `checkedTmsChanged` → `checkedSourcesChanged(QList)`,按 `structParentConfType`(1=GS/项目, 2=TM) 分流 `loadRowsAsync`。 4. **装置类型/采集时间筛选**:是 ds 结构化属性(`arrayType`/`collectTime`),值在 ds 行 `properties[]`(confFieldId),经 `DatasetFieldDictionary`(按 dsType 拉一次 `dynamicForm` 取 confFieldId↔fieldCode 映射 + 装置 value→中文字典)解析。装置类型只电阻率/视电阻率段有。日期筛选按 collectTime(三维体/切片回退 createTime)。 5. **新增三维体(客户两轮确认定稿)**: - **入口**:数据类型**段头**「+新增三维体」按钮(电阻率/视电阻率/瞬变段),**不在**对象树/容器节点右键。 - **源数据集** = 三维分析中**当前勾选的同类型 ds**(本段类型、可跨 GS)。 - 点击 → `VolumeParamsDialog`:**左侧**树状(按 GS 分组)展示勾选源、**可勾选/取消供确认或二次修改**;**右侧**参数:名称、**生成位置**下拉、插值模型、水平/竖向间距、IDW 幂次、最大影响距离。 - **生成位置(归属)**:默认 = 源同属单 GS→该 GS、源跨 GS→项目根;用户可改为**项目内任意 GS/TM**(`structParentConfType` 1 或 2)。源与归属解耦。 6. **VTK 画布工具条**:全局视图控制(坐标轴/比例/快捷视图/缩放)移到中央 VTK 竖排工具条;设置→`AxesSettingsDialog`(X/Y/深度 显示+min/max);快捷视图按钮文字「前/后/上/下/左/右」;复位=现「适配」。 7. **请求体 DTO**:`createVolume/createSlice` 扩参,内部按 `VoxelGenerateRequest/SliceGenerateRequest` 组装真实请求体结构(仍 mock 存储、假 id),`toJson` 序列化;重构落地即可从 UI 产出给后端联调的真实请求体。 8. **三维体/切片/异常**仍 `Api3dRepository` mock;异常迁入三维体段。 ## 4. 剩余工作 = 执行 plan `plans/2026-06-24-vtk-category-view-refactor.md`,8 phase/12 task,依赖顺序: - **Phase 1-2**(Task 1-3):DsRow 扩展+parseDsRows / CategoryConfig+splitByCategory / 请求体 DTO —— **纯逻辑完整 TDD**。 - **Phase 3-4**(Task 4-6):GS 三态状态机+checkedSourcesChanged / DatasetFieldDictionary —— 逻辑可单测。 - **Phase 5-6**(Task 7-9):CategorySection / CategoryAnalysisTab+ColumnDrawer / VtkViewToolbar+AxesSettingsDialog —— build+手动验证。 - **Phase 7-8**(Task 10-12):Api3d 扩参组装请求体 / 段重组(异常迁三维体段) / main.cpp 接线总成 + 退役 Column3DDataset/Column3DAnalysis。 **建议**:subagent-driven(每 task 新 subagent + task 间两阶段 review)+ 独立 git worktree 隔离。每 task 自带测试/验证+commit;Phase 间「新旧信号并存→Task 12 统一切换删旧」保证每次可编译。 **plan 中 Task 7 段头按钮 + Task 12 `VolumeParamsDialog` 扩展(左侧源列表二次增删 + 生成位置下拉)已按 §3.5 定稿写好。** ## 5. 待确认 / 风险 - **装置类型 value→中文 字典源**(唯一待坐实,不阻塞实现):实测 `arrayType` 原始值(如 `1429468249448449`)**不在**该字段 `optionsObject`(另一套 id `1456095451258368…`)里;`parseDynamicForm:208` 也不翻译;但用户说客户端属性面板显中文。Task 6 先用 optionsObject 建表 + 缺失回退原值。**需用户提供客户端数据集属性面板截图**以定位现有翻译路径(候选:`fieldConfigJsonObject.fieldDataRadius` 指向的全局字典 / `script/arrayTypeList`)。 - **段体容器树建法**(Task 7 核心):段体要呈现「项目根/GS/TM 容器节点→ds」层级,需 main 传 `setStructure`(对象树同源 StructNode)+ ds 的 `structParentId/structParentConfType`(Task 1 已解析)建容器节点。 - 三维体/切片/异常仍 mock;后端就绪后切真实(`I3dSceneRepository` 留缝,见 `HANDOFF-vtk-3d-backend-api.md`)。 ## 6. 关键实测事实 + 接口(直连后端核实) - 后端基址 `http://tenant.geomative.cn/pop-api`;header `geomativeauthorization: Geomative `(token 本会话由用户提供,下会话需重新索取)。 - 样本项目「演示项目(高密度+瞬变)」`1438889436225536`:项目根 GS `1438889436291072` 下直挂 TM(ERT1-8 confCode=ERT、TEM1-15 confCode=TEM01),**无中间 GS 层**(印证「项目根本质是 GS」「TM 可直挂项目根」)。 - **大类 dsTypeCode**:电阻率=`ERT platform inversion data`、视电阻率=`visual resistivity data`、瞬变电磁反演剖面=`DD TRANSIENT ELECTROMAGNETIC INVERSION`(三者 ddCode 同 `dd_inversion_data`)。 - **ds 行 `properties`**(`dsObject/data/page`)= `[{confFieldId,value}]` 数组;**`dynamicForm` 的 `properties`** = `{fieldCode:value}` map(两接口形态不同,勿混)。 - 装置类型字段 `arrayType`、采集时间 `collectTime`(fieldCode);装置枚举 `GET /business/script/arrayTypeList` → `[{itemValue,name}]`(15 项)。 - 层级 `structParentConfType`:1=GS/项目根,2=TM;`loadRowsAsync` 第 3 参即透传它(现状 main.cpp:1142 写死 2)。 - 详情接口 `dsObject/getDetail/{id}`、动态表单 `dsObject/dynamicForm/{id}`(客户端 `loadDatasetFormAsync`→`parseDynamicForm`)。 ## 7. 代码地图 **现状关键文件(重构基础):** | 文件 | 作用 | |---|---| | `src/app/panels/columns/ColumnDrawer.{hpp,cpp}` | 现三 tab 容器(→两 tab) | | `src/app/panels/columns/Column3DDataset/Column3DAnalysis/Column2DDataset` | 三栏现状(前两退役、二维不动) | | `src/app/DatasetDimension.{hpp,cpp}` | splitByDimension(→splitByCategory 替代) | | `src/app/panels/DatasetListPanel.cpp` | populateDatasetList/卡片委托/applyDatasetFilter(复用) | | `src/app/panels/ObjectTreePanel.{hpp,cpp}` | 对象树(GS:123 AutoTristate、:174 itemChanged、:207 右键) | | `src/data/repo/RepoTypes.hpp` | DsRow(扩 dsTypeCode/properties/structParent*) | | `src/data/dto/NavDto.cpp` | parseDsRows:116 / parseDynamicForm:179 | | `src/data/api/Api3dRepository.{hpp,cpp}` | 三维体/切片/异常 mock(createVolume/createSlice 扩参) | | `src/data/repo/VolumeBuildParams.hpp` / `src/core/model/Anomaly.hpp` | 三维体参数 / 异常模型 | | `src/app/main.cpp` | 接线(:388-460 异常/勾选、:1113-1225 对象树→分类分发) | | `src/data/api/ApiProjectRepository.cpp` | loadRowsAsync parentConfType 透传 | **新建(plan §文件结构):** `CategoryConfig.hpp`、`DatasetCategory.{hpp,cpp}`、`Vtk3dRequests.{hpp,cpp}`、`DatasetFieldDictionary.{hpp,cpp}`、`CategorySection.{hpp,cpp}`、`CategoryAnalysisTab.{hpp,cpp}`、`VtkViewToolbar.{hpp,cpp}`、`AxesSettingsDialog.{hpp,cpp}` + 对应 tests。 **契约文档:** `docs/api/vtk-3d-openapi.json`(v0.6-draft)、真实 schema `docs/apis/business_OpenAPI.json`(DsObjectDataVO/DsTypeVO/ArrayTypeVO)。 ## 8. 铁律 / 注意 - **贴源码/实测,别凭印象**:本会话多次因二手猜测("装置类型要后端补字段"、"properties 形态矛盾"、归属层级)被用户/实测纠正——任何字段/语义先去代码或真实接口核实。 - **复用优先**:DatasetListPanel/Api3dRepository/Column2DDataset 复用,不重写。 - **每 task TDD + 可编译 + commit**;不留 TODO 占位。 - 全部回复中文。 ## 9. 相关 - spec:`docs/superpowers/specs/2026-06-24-vtk-category-view-refactor-design.md` - plan:`docs/superpowers/plans/2026-06-24-vtk-category-view-refactor.md` - 后端契约交接:`docs/superpowers/HANDOFF-vtk-3d-backend-api.md`(三维体/切片/异常端点) - 记忆:`vtk-3d-persistence-structure`、`dataset-detail-types-catalog`、`web-3d-view-threetile`、`gpr-volume-design-trio` - 提交:`eceb964`(spec+openapi v0.5)、`ef10c35`(plan + 客户变动 + openapi v0.6)