diff --git a/docs/superpowers/HANDOFF-vtk-category-view-refactor.md b/docs/superpowers/HANDOFF-vtk-category-view-refactor.md new file mode 100644 index 0000000..23ff476 --- /dev/null +++ b/docs/superpowers/HANDOFF-vtk-category-view-refactor.md @@ -0,0 +1,104 @@ +# 交接: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`)。均已提交(`eceb964`、`ef10c35`)。**无半成品代码**。下一会话方向:**执行 plan**(建议 subagent-driven + 独立 worktree)。 + +## 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)