7.0 KiB
交接:VTK 三维视图 后端 API 设计(三维体 / 切片 / 异常)
给下一个会话无缝接手用。更新日期 2026-06-24。分支
feat/vtk-3d-view。本会话纯设计 + 产出对接文档,未改业务代码。配套实现交接见HANDOFF-vtk-3d.md。进度速览:澄清了"三维体/切片/异常存为 ds、能否复用存量 ds 接口"的全部疑问,产出后端对接 Swagger
docs/api/vtk-3d-openapi.json(OpenAPI 3.0.3,15 路径/26 schema),已提交9d3b103(未推送)。记忆 vtk-3d-persistence-structure 已同步定论。无半成品。下一会话方向:① 把这份契约交付后端排期;② 后端就绪后做客户端切真实(接口不动,换Api3dRepository实现)。
1. 背景
- 代码库
D:\Git\lanbingtech\geopro= 原版 web 系统移植的 Qt 桌面客户端;原版 web 源码D:\Git\lanbingtech\commercial-admin是复刻权威。 - 三维体/切片/异常的渲染/交互已实现(见另一份 handoff),但持久化全是 mock(
I3dSceneRepository留缝、Api3dRepository内存 map)。 - 本会话起点问题:三维体/切片要存为 ds、异常要挂三维体,现有 ds 接口能否复用? 由此推导出后端要补哪些端点,并产出 Swagger。
2. 本会话已完成
- 摸清存量两套仓储 + 真实端点(见 §6 代码地图)。
- 澄清一系列关键设计点(§3)。
- 产出
docs/api/vtk-3d-openapi.json:三件套后端对接设计稿,JSON 校验通过、无悬空/未用 schema。 - 提交
9d3b103(仅该文件,未推送;按全局设置未加署名)。曾有中间产物docs/api/voxel-slice-openapi.json,迭代后已删并合入 vtk-3d-openapi.json。 - 更新记忆 vtk-3d-persistence-structure,加全部定论 + 文档路径 + commit 号。
3. 设计定论(多轮被用户纠正后收敛,这是核心交付)
-
三维体/切片对后端 = 纯元数据 dsObject
- 增删改查/属性复用存量 dsObject 面:
projectStruct树 /dsObject/data/page列表 /getDetail详情 /dynamicForm属性 /updateDsObject更新 /dsObject/{id}删除。 - 各只加 1 个登记端点(
/dsObject/voxel/generate、/dsObject/slice/generate)——存量"建 ds = 文件 import"对生成类不适用;登记只建记录、不触发后端计算。
- 增删改查/属性复用存量 dsObject 面:
-
体素字节/切面数据全在客户端,后端零数据端点
- 连 GPR 大体(13.6G)体素也不上传、即使落盘也在客户端本地(
ChunkedVolumeStore);后端只持有 dsObject 记录。 - 故无 meta/brick/上传/切片位姿端点(设计途中曾加过,全删)。params/voxel 是否本地落盘是纯客户端策略,后端不感知。
- 连 GPR 大体(13.6G)体素也不上传、即使落盘也在客户端本地(
-
小块结构化数据搭车
attachedParameters- 三维体构建参数(
voxelParams)、切片三点位姿(slicePose)存这里,读走getDetail、写走updateDsObject(与描述deltaContent同机制)。dynamicForm只放给人看的键值属性。
- 三维体构建参数(
-
归属结构:TM → 三维体(dd_voxel) → 切片(dd_slice),异常挂三维体
- 三维体挂在 TM 下(本会话纠正,之前记忆误写"对象/GS")。
structParentConfType=2(TM)。
- 三维体挂在 TM 下(本会话纠正,之前记忆误写"对象/GS")。
-
异常复用整套
/business/exception端点(实体无关,三维体 id 直接塞remarkSourceId)- 异常体(consortium)分组是存量已有(
parseExceptions已解析consortiumId/Name/Type,queryExceptionByTmObjectId按其分组)——非 3D 新增(此前误判已纠正)。 - 3D 仅扩展两处、都在 body/返回字段(不新增端点):①
location加worldPts(三维多边形点)+plane(所在平面),存量是 2Dcoordinate[{x,y}]+经纬/投影坐标;② 截图(R88)。
- 异常体(consortium)分组是存量已有(
4. 剩余工作(按依赖顺序)
后端(阻塞一切,把 vtk-3d-openapi.json 交付排期):
- 注册
dd_voxel/dd_slice两个 dd 类型 + 各自classifyTypecode。 - 实现两个登记端点(
voxel/generate、slice/generate),返回真dsObjectId。 - 为这两类型注册
dynamicForm(属性表单)。 - 扩展异常
locationschema 容纳 3DworldPts+plane并保证往返不丢。 - 加异常
screenshot字段 + 定传输方式。
客户端(后端就绪后;接口 I3dSceneRepository 不动,留缝就是为此):
6. Api3dRepository 内存 map 换成调真实端点。
7. main.cpp:450-451 手动 append 三维体/切片行改成走后端树。
8. 3D 异常路径从 I3dSceneRepository(mock) 切到 IDatasetCommandRepository(真),remarkSourceId=三维体真 id。
5. 待确认问题
classifyTypeList里 dd_voxel/dd_slice 的具体 code(后端定)。location3D 字段精确结构(后端定)。- 截图传输:base64 内联 vs 单独上传(后端定)。
- 未验证风险:原系统
remarkSourceId只挂过 2D dsObject,没挂过三维体 id;listExceptionTypes/getExceptionName挂三维体时是否如预期,需后端整链就绪后实测。
6. 代码地图(本会话查证过的关键文件)
| 文件 | 作用 |
|---|---|
src/data/repo/I3dSceneRepository.hpp |
mock 留缝接口(三维体/切片/异常/任务 CRUD) |
src/data/api/Api3dRepository.{hpp,cpp} |
mock 实现(volumes_/slices_/anomalies_ 内存 map) |
src/data/repo/LocalSample3dRepository.cpp |
本地样本 stub |
src/data/repo/IDatasetCommandRepository.hpp |
真实异常端点 + ds 详情写操作 |
src/data/api/ApiProjectRepository.cpp |
真实 dsObject 面(getDetail/dynamicForm/data/page/delete/update/import/projectStruct) |
src/core/model/Anomaly.hpp |
异常模型(2D: localPts/lonLat/eastNorth;3D: worldPts/plane) |
src/data/repo/VolumeBuildParams.hpp |
三维体构建参数 |
src/data/store/ChunkedVolumeStore.hpp |
GPR 分块体存储(客户端本地落盘) |
src/app/main.cpp |
接线(450-451 合并注入、577/661/745 createSlice/createVolume) |
src/data/dto/NavDto.cpp:374 |
parseExceptions(含 consortium 字段,证实异常体存量已有) |
src/data/dto/DatasetChartDto.cpp |
异常 location/坐标系解析 |
docs/api/vtk-3d-openapi.json |
本会话产出 |
后端响应信封:{code:int, msg:string, data:object|array},code==200 成功,列表/集合放 data.value。
7. 铁律 / 注意
- 贴源码/日志,别凭印象:本会话多次因臆测("装不下"、"异常体是 3D 新增"、自造端点不贴存量)被用户纠正——任何接口字段/语义都先去代码里核实。
- 复用优先于新建:实体无关的契约一律复用存量;只有"生成动作"和"3D 几何/截图"这种存量真装不下的才扩展。
- 全部回复中文。