# Batch 2 实施依据:对象/数据集对话框(新建/编辑/导入/导出/插件) 实地研究原系统 `http://tenant.geomative.cn`(项目「香港威立雅」`projectId=1439735554211840`, projectTypeId `1445121423155200`)所得。API 经页面 token replay + 真实 DOM 操作 + fetch 录制捕获。 > 口径:成功码 `code==200`;列表载荷在 `data`(非对象时包成 `data.value`)。 > token 头 `geomativeauthorization`;base `http://tenant.geomative.cn/pop-api`。 ## 一、项目结构(已用于现有功能) `GET /business/projectStruct/queryProjectStruct/{projectId}` → 扁平节点 `[{id,parentId,name,type(1=GS,2=TM),typeName,typeId,confCode,collectTime}]`,根 parentId="0"。 ## 二、编辑 / 新建对象 —— 动态表单(核心,最大工作量) ### 表单 schema 来源(统一端点,编辑弹窗打开时调用) `POST /business/project/getDynamicForm` body `{"typeId": <类型id>, "id": <对象id>, "type": <1=GS|2=TM>, "projectId": }` → 返回结构同 getDetail: ``` { typeId, confCode, name(类型名), description, formList: [ { groupName, values: [ FieldDef... ] } ], // 可多组(对应弹窗内分页签:基本信息/测线布设/数据质量检查...) properties: { : <当前值> } // 编辑预填;新建时为空 } ``` (getGsObjectDetail / tmObject/getDetail 返回同样的 formList/properties,可互为参考。 TM 的 getDetail 还含 dsList / dsClassifyTypeList / gridFieldList。) ### FieldDef 字段定义 ``` confFieldId, fieldUseType(1=核心字段,2=普通), fieldCode(键), fieldName(标签), displayComponentType(控件类型), requiredType(1/2 必填标志——待核实方向), displaySort, fieldDataType(4=字符串,5=日期,6=日期时间...), fieldConfigJsonObject:{fieldChnFormat,fieldRemark,fieldEngFormat}, optionsObject(下拉项;普通字段为 null) ``` ### displayComponentType 已观察样例(需补全映射) TM「常规高密度电阻率法」编辑弹窗实测控件: - 方法名称(只读文本) - 基本信息组:名称/电极数/电极间距/测线长 = **只读文本**(核心字段 fieldUseType=1,编辑时禁用) - 设备 = 下拉(必填) ; 布设日期 = 日期选择(必填) ; 天气 = 下拉(必填) - 布设人/审核人 = 文本(必填) ; 备注 = 文本 GS「测区」formList 含:创建人/创建日期(comp6)/名称(comp1)/创建时间(comp7)/地形地貌(comp8)/岩土性质... → 推测 comp1=单行文本, 6=日期, 7=日期时间, 8=多行文本;**落地前需逐一在原版核实**。 ### 新建 TM 的类型选择 `GET /business/tmObject/queryTmType?projectId=..&gsId=..` → `[{label:"瞬变电磁方法", value:, code:"TEM01"}]` 新建流程:选 GS → queryTmType 选方法类型 → getDynamicForm(typeId,type=2,无id) 取空表单 → 填 → POST。 ### ⚠️ 未捕获(真实壁垒,不可猜) - `POST /business/gsObject`(新建GS body) - `POST /business/tmObject`(新建TM body) - `PUT /business/gsObject` / `PUT /business/tmObject`(更新 body) 实测:点「确定」时必填项为空→前端校验拦截,未发 PUT。要抓须填完必填项保存(会改数据)。 - `PUT /business/dsObject/updateDsObject`(更新DS body) ## 三、删除(已实现 Batch1) `DELETE /business/gsObject/{id}` `DELETE /business/tmObject/{id}` `DELETE /business/dsObject/{id}` ## 四、导入 DS TM 的 getDetail.dsList = 该 TM 可承载的 ds 类型 `[{dsTypeId,nameChn,nameEng,canImport,canExport,...}]`(canImport=true 的可导入)。 `GET /business/dsObject/query/script?dsTypeId=..&tmTypeBaseConfId=..` → 该类型可用导入脚本。 `POST /business/dsObject/checkImport` → 校验脚本所需轨迹/坐标文件是否存在。 `POST /business/dsObject/import`(query 参数已知:aliasName, dsTypeId*, file*, projectId*, scriptCode, scriptParamListJsonStr, structParentConfType*, structParentId*) ⚠️ file 为上传项(multipart);scriptParamListJsonStr 结构未捕获。 ## 五、导出 `POST /business/templateExport/queryExportObject` body `{projectId}` → 可选导出对象树 `[{id,parentId,name,check}]`。 `GET /business/templateExport/queryDataType/{tmTypeBaseConfId}` → 按方法查数据类型。 `POST /business/templateExport/export`(body 未捕获)。 模板列表见 localStorage `template`:templateTypeList[数据管理-数据报告/异常体报告], fileTypeList[WORD/EXCEL], fileTemplateList。 另:数据集详情页「导出」按钮点击未发请求/未弹窗(可能直接下载或需先配模板)——待核实。 ## 六、插件(数据集右键) `GET /business/model/list` → 全局模型目录 `[{id,scriptCode,scriptName,scriptOperationType,formItemList}]` 例:script_ert_inner_inversion「ert反演(默认)」、script_radar_resultant_data_processing「雷达数据处理(默认)」。 ⚠️ "与当前 ds 关联"的过滤逻辑未捕获(model/list 不含 ds 类型关联;各模型用 dsObjectList/{projectId} 声明可接受的数据源)。 `POST /business/model/task/page` → 模型任务分页(用于"数据集任务"面板)。 ## 实施建议顺序 1. 动态表单引擎 `DynamicFormEditor`(Qt):按 formList 渲染 comp1/6/7/8 + 下拉(optionsObject) + 必填校验 + 只读核心字段;编辑用 properties 预填。**先在原版逐一核实 displayComponentType 全集映射。** 2. 编辑对象(最先打通:getDynamicForm 取 schema → 编辑器 → PUT)。**先捕获 PUT body。** 3. 新建 GS / 新建 TM(queryTmType → 空表单 → POST)。**先捕获 POST body。** 4. 导入 DS(dsList 选类型 → query/script → 文件 → checkImport → import)。**先捕获 import 细节。** 5. 导出(queryExportObject 选对象 + 模板 → export)。**先捕获 export body。** 6. 插件子菜单(model/list 列出;调用/关联逻辑待定)。 ## 捕获提交载荷的方法(已在原版页面注入录制器 window.__rec) 在 Playwright 浏览器对原系统执行一次「编辑保存/新建保存/导入/导出」(填完必填项), 即可从 `window.__rec` 读到真实 method+url+body。这是落地步骤 2-5 的前置。