diff --git a/tools/mms-mapping/API-getIcdMmsJson.md b/tools/mms-mapping/API-getIcdMmsJson.md deleted file mode 100644 index 682a0f0..0000000 --- a/tools/mms-mapping/API-getIcdMmsJson.md +++ /dev/null @@ -1,371 +0,0 @@ -# getIcdMmsJson 标准 API 调试文档 - -## 1. 文档范围 - -本文档用于说明 `mms-mapping` 模块统一调试接口 `getIcdMmsJson` 的标准调用方式、请求结构、响应规则和联调注意事项。 - -本文档内容以当前源码为准,主要对照以下实现: - -- `tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/controller/MappingController.java` -- `tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/component/MappingRequestConverter.java` -- `tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/component/MappingResponseConverter.java` -- `tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/service/impl/MappingTaskServiceImpl.java` -- `tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/component/MappingGenerationService.java` -- `tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/pojo/param/GenerateMappingFromIcdRequest.java` -- `tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/pojo/vo/MappingTaskResponse.java` - -说明: - -- 本文档仅描述接口契约和调试方式,不改动业务代码。 -- 本次未执行 `mvn` 编译、打包或真实接口联调。 -- 如文档与运行结果冲突,以源码和实际部署配置为准。 - -## 2. 接口基本信息 - -| 项 | 说明 | -| --- | --- | -| 接口名称 | `getIcdMmsJson` | -| 请求方法 | `POST` | -| 请求路径 | `/api/mms-mapping/get-icd-mms-json` | -| Content-Type | `multipart/form-data` | -| 控制器入口 | `MappingController#getIcdMmsJson` | -| 请求组成 | `icdFile` 文件 Part + `request` JSON Part | -| 正常业务响应体 | `MappingTaskResponse` | - -## 3. 接口职责 - -该接口是 `mms-mapping` 模块的统一调试入口,串联以下两个阶段: - -1. 上传 ICD 文件并完成解析,生成 `icdDocument` 和 `indexCandidates` -2. 根据 `request.indexSelection` 判断是否继续生成正式 `mappingJson` - -接口行为分为三种典型结果: - -1. `request.indexSelection` 未传或为空 -返回 `NEED_INDEX_SELECTION`,用于引导前端或调试人员先确认标签与 `lnInst` 的绑定关系。 -2. `request.indexSelection` 已传但校验不通过 -返回 `NEED_INDEX_SELECTION`,同时通过 `problems` 给出不合法原因,要求重新选择。 -3. `request.indexSelection` 校验通过 -返回 `SUCCESS`,输出正式 `mappingJson`,必要时同时落盘并返回 `savedPath`。 - -补充说明: - -- 该接口每次都会重新解析上传的 ICD 文件,因此第二次调试仍然必须重新上传 ICD 文件。 -- 该接口正常进入业务编排后,返回体类型为 `MappingTaskResponse`。 -- 如果异常发生在控制器参数绑定或请求转换阶段,例如文件为空、Part 缺失、JSON Part 解析失败,则由全局异常处理器统一包装为 `HttpResult`,而不是 `MappingTaskResponse`。 - -## 4. 请求规范 - -### 4.1 multipart/form-data Part 说明 - -| Part 名称 | 类型 | 必填 | 说明 | -| --- | --- | --- | --- | -| `icdFile` | File | 是 | ICD 文件,不能为空 | -| `request` | JSON Part | 是 | 生成参数,必须按 `application/json` 发送 | - -说明: - -- `request` Part 不能省略。即使第一次只想拿候选结果,也必须传一个最小 JSON。 -- `request.indexSelection` 可以省略或传空数组,此时接口只返回候选结果,不生成正式映射。 - -### 4.2 request JSON 结构 - -```json -{ - "version": "2026-04-22", - "author": "debug-user", - "saveToDisk": false, - "prettyJson": true, - "outputDir": "D:/temp/mms-output", - "indexSelection": [ - { - "groupKey": "harm", - "groupDesc": "谐波数据", - "bindings": [ - { - "reportName": "brcbStHarm", - "dataSetName": "dsStHarm", - "label": "A相", - "lnInst": "1" - } - ] - } - ] -} -``` - -### 4.3 request 字段说明 - -| 字段 | 类型 | 必填 | 说明 | -| --- | --- | --- | --- | -| `version` | String | 否 | 输出版本号。未传或空白时,后端按当天日期补齐,格式为 `yyyy-MM-dd` | -| `author` | String | 否 | 作者。未传或空白时,回退到配置项 `icd.mapping.default-author`,默认值为 `system` | -| `saveToDisk` | boolean | 否 | 是否将生成结果写入磁盘 | -| `prettyJson` | boolean | 否 | 是否输出格式化 JSON。`true` 为美化 JSON,`false` 为紧凑 JSON | -| `outputDir` | String | 否 | 输出目录。未传或空白时,先回退到配置项 `icd.mapping.default-output-dir`;如果配置也为空,最终落到当前工作目录 | -| `indexSelection` | Array | 否 | 标签与 `lnInst` 的最终绑定关系。未传或为空时,只返回候选结果 | - -### 4.4 indexSelection 字段说明 - -| 字段 | 类型 | 必填 | 说明 | -| --- | --- | --- | --- | -| `groupKey` | String | 是 | 分组唯一键,必须使用第一次响应里返回的原值 | -| `groupDesc` | String | 否 | 分组中文描述,便于调试查看 | -| `bindings` | Array | 是 | 当前业务分组下最终确认的绑定关系列表 | - -### 4.5 bindings 字段说明 - -| 字段 | 类型 | 必填 | 说明 | -| --- | --- | --- | --- | -| `reportName` | String | 是 | 绑定发生在哪个报告上,例如 `brcbStHarm` | -| `dataSetName` | String | 是 | 绑定发生在哪个数据集上,例如 `dsStHarm` | -| `label` | String | 是 | 业务标签,例如 `A相`、`最大值`、`实时数据` | -| `lnInst` | String | 是 | 标签最终绑定到的逻辑节点实例值,例如 `1`、`2`、`3` | - -## 5. 标准调试流程 - -### 5.1 第一次调试:只获取候选结果 - -用途: - -- 上传 ICD 文件 -- 获取 `icdDocument` -- 获取 `indexCandidates` -- 确认每个业务分组下可选的 `reportName`、`dataSetName` 和 `availableLnInstValues` - -调用要求: - -- `request` Part 仍然必须传 -- `request.indexSelection` 可以不传,或传空数组 - -预期结果: - -- `status = NEED_INDEX_SELECTION` -- 响应中返回 `icdDocument` -- 响应中返回 `indexCandidates` - -### 5.2 第二次调试:带索引绑定生成正式结果 - -用途: - -- 根据第一次返回的 `indexCandidates` 组装 `request.indexSelection` -- 再次上传同一个 ICD 文件 -- 生成正式 `mappingJson` - -调用要求: - -- 必须继续上传 `icdFile` -- `groupKey` 必须沿用第一次返回值 -- `reportName`、`dataSetName`、`lnInst` 必须与第一次返回的候选结果匹配 - -预期结果: - -- `status = SUCCESS` -- 响应中返回 `mappingJson` -- 当 `saveToDisk = true` 时,响应中额外返回 `savedPath` - -### 5.3 第二次调试但绑定不合法 - -适用场景: - -- `groupKey` 与候选结果不匹配 -- `reportName` 或 `dataSetName` 不在候选集中 -- `lnInst` 不在 `availableLnInstValues` 内 -- 绑定关系缺失、不完整或结构错误 - -预期结果: - -- `status = NEED_INDEX_SELECTION` -- 响应中仍然返回 `icdDocument` 和 `indexCandidates` -- `problems` 返回具体问题列表,要求重新确认绑定关系 - -## 6. 响应规范 - -### 6.1 正常业务响应体 - -接口正常进入业务编排后,统一返回 `MappingTaskResponse`。该对象使用了 `@JsonInclude(JsonInclude.Include.NON_EMPTY)`,空字段和空集合不会参与序列化。 - -基础字段说明: - -| 字段 | 类型 | 说明 | -| --- | --- | --- | -| `status` | Enum | 本次处理状态,可能为 `SUCCESS`、`NEED_INDEX_SELECTION`、`FAILED` | -| `message` | String | 状态说明或错误提示 | -| `icdDocument` | Object | 需要重新选择索引时返回的 ICD 解析结果 | -| `mappingJson` | String | 正式生成成功后的映射 JSON 文本 | -| `savedPath` | String | 结果已落盘时返回的绝对路径 | -| `indexCandidates` | Array | 待绑定状态下返回的索引候选分组 | -| `problems` | Array | 模板校验、候选分析或绑定校验问题 | - -字段出现规则: - -| 状态 | 必有字段 | 可能出现字段 | -| --- | --- | --- | -| `SUCCESS` | `status`、`message`、`mappingJson` | `savedPath`、`problems` | -| `NEED_INDEX_SELECTION` | `status`、`message`、`icdDocument`、`indexCandidates` | `problems` | -| `FAILED` | `status`、`message` | `problems` | - -### 6.2 NEED_INDEX_SELECTION 响应示例 - -```json -{ - "status": "NEED_INDEX_SELECTION", - "message": "索引配置缺失,请根据候选信息完成标签与数字索引的绑定后重新提交", - "icdDocument": { - "fileName": "demo.icd", - "iedName": "IED1", - "ldInst": "LD0", - "ldPrefix": "LD", - "logicalNodes": [ - { - "lnInst": "1" - } - ] - }, - "indexCandidates": [ - { - "groupKey": "harm", - "groupDesc": "谐波数据", - "reportCount": 1, - "templateLabels": [ - "A相", - "B相", - "C相" - ], - "reports": [ - { - "reportName": "brcbStHarm", - "dataSetName": "dsStHarm", - "reportDesc": "谐波报告", - "availableLnInstValues": [ - "1", - "2", - "3" - ] - } - ] - } - ] -} -``` - -说明: - -- `icdDocument` 实际字段可能比示例更多。 -- 如果本次是“索引配置不合法”而不是“索引配置缺失”,通常还会返回 `problems`。 - -### 6.3 SUCCESS 响应示例 - -```json -{ - "status": "SUCCESS", - "message": "映射生成成功", - "mappingJson": "{\n \"version\": \"2026-04-22\",\n \"author\": \"debug-user\",\n \"ied\": \"IED1\",\n \"ld\": \"LD\",\n \"instList\": []\n}" -} -``` - -说明: - -- `mappingJson` 是字符串字段,字段值本身是一段 JSON 文本。 -- 当 `saveToDisk = true` 时,响应中还会额外返回 `savedPath`。 - -### 6.4 FAILED 响应示例 - -```json -{ - "status": "FAILED", - "message": "映射生成失败:加载 DefaultCfg.txt 失败:默认模板文件不存在:template/DefaultCfg.txt", - "problems": [ - "加载 DefaultCfg.txt 失败:默认模板文件不存在:template/DefaultCfg.txt" - ] -} -``` - -说明: - -- `FAILED` 主要对应服务编排阶段捕获到的运行异常,例如 ICD 解析、模板加载、映射生成、序列化或落盘失败。 -- 并非所有错误都会进入 `FAILED`。如果异常发生在控制器参数绑定或请求转换阶段,会走全局异常处理器,而不是这里的业务响应结构。 - -## 7. 全局异常响应说明 - -以下场景通常不会返回 `MappingTaskResponse`,而是由 `GlobalBusinessExceptionHandler` 统一包装: - -- `icdFile` 缺失或为空 -- `request` Part 缺失 -- `request` Part 的 `Content-Type` 不是 `application/json` -- `multipart/form-data` 结构不合法 -- JSON 反序列化失败或框架参数绑定失败 - -这类异常最终会包装为统一的 `HttpResult` 响应,具体字段结构以全局公共响应定义为准,本文不展开其完整协议,只强调: - -- 不能把这类错误等同理解为 `MappingTaskResponse.status = FAILED` -- 联调时应先区分“业务响应体”与“全局异常包装” - -## 8. 调试示例 - -### 8.1 curl 示例:第一次调用,只获取候选结果 - -```powershell -curl.exe -X POST "http://localhost:8080/api/mms-mapping/get-icd-mms-json" ` - -H "Accept: application/json" ` - -F 'icdFile=@D:/data/demo.icd' ` - -F 'request={"prettyJson":true,"saveToDisk":false};type=application/json' -``` - -### 8.2 curl 示例:第二次调用,带索引绑定直接生成 MMS JSON - -```powershell -curl.exe -X POST "http://localhost:8080/api/mms-mapping/get-icd-mms-json" ` - -H "Accept: application/json" ` - -F 'icdFile=@D:/data/demo.icd' ` - -F 'request={"version":"2026-04-22","author":"debug-user","prettyJson":true,"saveToDisk":false,"indexSelection":[{"groupKey":"harm","groupDesc":"谐波数据","bindings":[{"reportName":"brcbStHarm","dataSetName":"dsStHarm","label":"A相","lnInst":"1"},{"reportName":"brcbStHarm","dataSetName":"dsStHarm","label":"B相","lnInst":"2"},{"reportName":"brcbStHarm","dataSetName":"dsStHarm","label":"C相","lnInst":"3"}]}]};type=application/json' -``` - -## 9. Postman 调试要点 - -1. `Body` 选择 `form-data` -2. `icdFile` 类型选择 `File` -3. `request` 保持文本输入,但该 Part 的 `Content-Type` 必须显式设置为 `application/json` -4. 第一次调试不要省略 `request` Part,只是不传 `indexSelection` -5. 第二次调试时必须继续上传 ICD 文件,并严格按第一次返回的候选结果组装绑定关系 - -## 10. 常见问题 - -### 10.1 为什么第一次调试也必须传 `request` - -因为控制器方法签名使用的是 `@RequestPart("request") GenerateMappingFromIcdRequest request`,该 Part 本身就是必填参数。第一次调试可以只传最小 JSON,但不能完全省略。 - -### 10.2 为什么没有传 `indexSelection`,却没有返回 `FAILED` - -这是接口设计的正常行为。`indexSelection` 缺失或为空时,业务语义不是“接口执行失败”,而是“还需要前端继续确认索引绑定”,因此返回的是 `NEED_INDEX_SELECTION`。 - -### 10.3 `saveToDisk=true` 但没有传 `outputDir`,结果会保存到哪里 - -处理顺序如下: - -1. 先读取请求中的 `outputDir` -2. 如果请求空白,则回退到配置项 `icd.mapping.default-output-dir` -3. 如果配置项也为空,则最终落到当前工作目录 - -### 10.4 `version` 不传时会变成什么 - -后端在正式生成映射文档时,会把空白 `version` 自动补成当天日期,格式为 `yyyy-MM-dd`。 - -### 10.5 `mappingJson` 为什么是字符串,不是嵌套对象 - -因为当前响应结构中 `mappingJson` 定义为 `String`,接口返回的是一段已经序列化好的 JSON 文本,而不是再次展开后的对象结构。 - -### 10.6 什么情况下会返回 `problems` - -`problems` 主要用于承载以下问题: - -- 默认模板校验问题 -- 索引候选分析问题 -- `indexSelection` 绑定校验问题 -- 服务编排阶段捕获到的异常原因 - -## 11. 当前边界 - -- 当前文档仅覆盖 `getIcdMmsJson` 接口,不覆盖 `get-icd` 与 `get-mms-json` 的独立接口文档 -- 当前文档重点描述业务返回体与调试方式,不展开全局 `HttpResult` 的完整协议 -- 示例中的 `icdDocument`、`indexCandidates` 和 `mappingJson` 为结构化示意,实际字段数量与内容以运行结果为准 diff --git a/tools/mms-mapping/README.md b/tools/mms-mapping/README.md index eb4db9c..5f70f25 100644 --- a/tools/mms-mapping/README.md +++ b/tools/mms-mapping/README.md @@ -2,6 +2,11 @@ `mms-mapping` 模块负责解析 ICD 文件并生成 MMS 映射数据。当前统一调试入口为 `getIcdMmsJson`,该接口同时覆盖“先解析 ICD 获取索引候选”和“确认索引后生成正式 MMS JSON”两类场景。 +## 0. 调试文档 + +- `getIcdMmsJson`:`API-getIcdMmsJson.md` +- `buildIndexConfirmData` / `buildIndexSelection`:`API-buildIndexDebug.md` + ## 1. 接口信息 - 路径:`POST /api/mms-mapping/get-icd-mms-json` diff --git a/tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/controller/MappingController.java b/tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/controller/MappingController.java index 725c729..27dd6e6 100644 --- a/tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/controller/MappingController.java +++ b/tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/controller/MappingController.java @@ -2,26 +2,36 @@ package com.njcn.gather.icd.mapping.controller; import com.njcn.common.pojo.annotation.OperateInfo; import com.njcn.common.pojo.enums.common.LogEnum; +import com.njcn.common.pojo.enums.response.CommonResponseEnum; +import com.njcn.common.pojo.response.HttpResult; import com.njcn.common.utils.LogUtil; import com.njcn.gather.icd.mapping.component.IcdToXmlRequestConverter; import com.njcn.gather.icd.mapping.component.IcdToXmlResponseConverter; +import com.njcn.gather.icd.mapping.component.IndexSelectionBuildService; import com.njcn.gather.icd.mapping.component.MappingRequestConverter; import com.njcn.gather.icd.mapping.component.MappingResponseConverter; import com.njcn.gather.icd.mapping.pojo.bo.GenerateMappingResult; import com.njcn.gather.icd.mapping.pojo.bo.IcdToXmlGenerateResult; import com.njcn.gather.icd.mapping.pojo.dto.GenerateFromIcdCommand; import com.njcn.gather.icd.mapping.pojo.dto.IcdToXmlGenerateCommand; +import com.njcn.gather.icd.mapping.pojo.param.BuildIndexSelectionRequest; import com.njcn.gather.icd.mapping.pojo.param.GenerateMappingFromIcdRequest; import com.njcn.gather.icd.mapping.pojo.param.IcdToXmlGenerateRequest; +import com.njcn.gather.icd.mapping.pojo.param.IndexCandidateRequest; import com.njcn.gather.icd.mapping.pojo.param.JsonToXmlRequest; import com.njcn.gather.icd.mapping.pojo.param.SubmitIndexSelectionRequest; import com.njcn.gather.icd.mapping.pojo.vo.IcdToXmlResponse; +import com.njcn.gather.icd.mapping.pojo.vo.IndexConfirmGroupResponse; +import com.njcn.gather.icd.mapping.pojo.vo.IndexSelectionGroupResponse; import com.njcn.gather.icd.mapping.pojo.vo.MappingTaskResponse; import com.njcn.gather.icd.mapping.service.MappingTaskService; import com.njcn.gather.icd.mapping.service.impl.IcdToXmlTaskAppService; import com.njcn.gather.icd.mapping.utils.DateUtils; import com.njcn.web.controller.BaseController; +import com.njcn.web.utils.HttpResultUtil; import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; import io.swagger.annotations.ApiOperation; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -33,6 +43,8 @@ import org.springframework.web.bind.annotation.RequestPart; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; +import java.util.List; + /** * ICD 映射接口入口。 */ @@ -61,11 +73,15 @@ public class MappingController extends BaseController { /** 响应转换器,按接口阶段裁剪最小返回字段。 */ private final IcdToXmlTaskAppService icdToXmlTaskAppService; + /** ICD 结构确认弹窗结果组装服务。 */ + private final IndexSelectionBuildService indexSelectionBuildService; + /** * 上传 ICD 文件,返回候选结果和可编辑的 ICD 解析结果。 */ @OperateInfo(info = LogEnum.BUSINESS_COMMON) @ApiOperation("上传 ICD 文件并生成索引候选") + @ApiImplicitParam(name = "icdFile", value = "ICD 文件", required = true, dataType = "__file", paramType = "form") @PostMapping(value = "/get-icd", consumes = {"multipart/form-data"}) public MappingTaskResponse getICD(@RequestPart("icdFile") MultipartFile icdFile) { String methodDescribe = getMethodDescribe("getICD"); @@ -80,6 +96,7 @@ public class MappingController extends BaseController { */ @OperateInfo(info = LogEnum.BUSINESS_COMMON) @ApiOperation("获取 MMS JSON") + @ApiImplicitParam(name = "request", value = "索引确认后生成 MMS JSON 参数", required = true, dataType = "SubmitIndexSelectionRequest") @PostMapping("/get-mms-json") public MappingTaskResponse getMmsJson(@Validated @RequestBody SubmitIndexSelectionRequest request) { String methodDescribe = getMethodDescribe("getMmsJson"); @@ -95,6 +112,10 @@ public class MappingController extends BaseController { */ @OperateInfo(info = LogEnum.BUSINESS_COMMON) @ApiOperation("上传 ICD 后直接获取 MMS JSON") + @ApiImplicitParams({ + @ApiImplicitParam(name = "icdFile", value = "ICD 文件", required = true, dataType = "__file", paramType = "form"), + @ApiImplicitParam(name = "request", value = "上传 ICD 后直接生成映射参数", required = true, dataType = "GenerateMappingFromIcdRequest", paramType = "form") + }) @PostMapping(value = "/get-icd-mms-json", consumes = {"multipart/form-data"}) public MappingTaskResponse getIcdMmsJson(@RequestPart("icdFile") MultipartFile icdFile, @Validated @RequestPart("request") GenerateMappingFromIcdRequest request) { @@ -107,12 +128,45 @@ public class MappingController extends BaseController { return responseConverter.fromSubmitResult(result); } + /** + * 根据页面回传的 indexCandidates 生成弹窗确认模型。 + */ + @OperateInfo(info = LogEnum.BUSINESS_COMMON) + @ApiOperation("根据 indexCandidates 生成确认数据") + @ApiImplicitParam(name = "indexCandidates", value = "索引候选分组列表", required = true, dataType = "List") + @PostMapping("/build-index-confirm-data") + public HttpResult> buildIndexConfirmData(@RequestBody List indexCandidates) { + String methodDescribe = getMethodDescribe("buildIndexConfirmData"); + LogUtil.njcnDebug(log, "{},开始根据 indexCandidates 生成确认数据,candidateCount={}", + methodDescribe, indexCandidates == null ? 0 : indexCandidates.size()); + List result = indexSelectionBuildService.buildConfirmData(indexCandidates); + return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe); + } + + /** + * 根据前端确认后的结果生成最终 indexSelection。 + */ + @OperateInfo(info = LogEnum.BUSINESS_COMMON) + @ApiOperation("根据确认结果生成 indexSelection") + @ApiImplicitParam(name = "request", value = "根据确认结果生成 indexSelection 参数", required = true, dataType = "BuildIndexSelectionRequest") + @PostMapping("/build-index-selection") + public HttpResult> buildIndexSelection(@RequestBody BuildIndexSelectionRequest request) { + String methodDescribe = getMethodDescribe("buildIndexSelection"); + LogUtil.njcnDebug(log, "{},开始根据确认结果生成 indexSelection,confirmGroupCount={}, confirmedGroupCount={}", + methodDescribe, + request == null || request.getConfirmData() == null ? 0 : request.getConfirmData().size(), + request == null || request.getConfirmedData() == null ? 0 : request.getConfirmedData().size()); + List result = indexSelectionBuildService.buildIndexSelection(request); + return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe); + } + /** * 直接将 MMS JSON 转换为 XML 文件。 * 适用于已经通过 getIcdMmsJson 获得 JSON 后,单独进行 XML 转换的场景。 */ @OperateInfo(info = LogEnum.BUSINESS_COMMON) @ApiOperation("MMS JSON 转 XML") + @ApiImplicitParam(name = "request", value = "MMS JSON 转 XML 参数", required = true, dataType = "JsonToXmlRequest") @PostMapping("/get-xml-from-json") public IcdToXmlResponse getXmlFromJson(@Validated @RequestPart("request") JsonToXmlRequest request) { String methodDescribe = getMethodDescribe("getXmlFromJson"); diff --git a/tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/pojo/param/GenerateMappingFromIcdRequest.java b/tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/pojo/param/GenerateMappingFromIcdRequest.java index 9194dc6..935e841 100644 --- a/tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/pojo/param/GenerateMappingFromIcdRequest.java +++ b/tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/pojo/param/GenerateMappingFromIcdRequest.java @@ -1,38 +1,43 @@ package com.njcn.gather.icd.mapping.pojo.param; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; import lombok.Data; + import java.util.ArrayList; import java.util.List; /** - * 候选接口请求体。 - * - * 当前主要承载输出版本、作者、落盘选项等基础参数。 - * 为兼容旧调用,仍保留 indexSelection 字段,但候选接口本身不依赖该字段。 + * 上传 ICD 后直接生成映射的请求参数。 */ @Data +@ApiModel("上传 ICD 后直接生成映射的请求参数") public class GenerateMappingFromIcdRequest { - /** 输出版本号。为空时后端默认补当天日期。 */ + /** 映射版本号。 */ + @ApiModelProperty("映射版本号,空时默认使用当天日期") private String version; - /** 作者。为空时使用模块默认作者。 */ + /** 映射作者。 */ + @ApiModelProperty("映射作者,空时使用模块默认作者") private String author; - /** 是否保存到磁盘。 */ + /** 是否落盘。 */ + @ApiModelProperty("是否将生成结果落盘保存") private boolean saveToDisk; - /** 是否返回格式化 JSON。 */ + /** 是否格式化 JSON。 */ + @ApiModelProperty("是否返回格式化后的 JSON") private boolean prettyJson; - /** 输出目录。saveToDisk=true 时才会用到。 */ + /** 输出目录。 */ + @ApiModelProperty("输出目录,仅在 saveToDisk=true 时生效") private String outputDir; /** - * 兼容保留的索引选择结果。 - * - * 当前候选接口会直接返回 indexCandidates 和 icdDocument; - * 正式提交时请改用 get-mms-json 接口。 + * 兼容保留的索引绑定结果。 + * 正式提交流程建议改用 get-mms-json 接口。 */ + @ApiModelProperty("兼容保留的索引绑定结果,正式提交建议改用 get-mms-json 接口") private List indexSelection = new ArrayList(); -} \ No newline at end of file +} diff --git a/tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/pojo/param/IndexBindingRequest.java b/tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/pojo/param/IndexBindingRequest.java index 1b288b6..c8d04e5 100644 --- a/tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/pojo/param/IndexBindingRequest.java +++ b/tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/pojo/param/IndexBindingRequest.java @@ -1,24 +1,29 @@ package com.njcn.gather.icd.mapping.pojo.param; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; import lombok.Data; + /** - * 单条索引绑定请求。 - * - * 一条绑定只表达一个最小关系: - * 某个报告 reportName 下,使用某个标签 label 与某个 lnInst 数字做绑定。 + * 单条索引绑定请求项。 */ @Data +@ApiModel("单条索引绑定请求项") public class IndexBindingRequest { - /** 绑定发生在哪个报告上,例如 brcbStHarm。 */ + /** 报告名称。 */ + @ApiModelProperty("报告名称") private String reportName; - /** 绑定发生在哪个数据集上,例如 dsStHarm。 */ + /** 数据集名称。 */ + @ApiModelProperty("数据集名称") private String dataSetName; - /** 业务标签,例如最大值、最小值、实时数据。 */ + /** 模板标签。 */ + @ApiModelProperty("模板标签") private String label; - /** 当前标签最终绑定到的 lnInst 数字,例如 1、2、3。 */ + /** 最终绑定的 lnInst 值。 */ + @ApiModelProperty("最终绑定的 lnInst 值") private String lnInst; -} \ No newline at end of file +} diff --git a/tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/pojo/param/IndexSelectionGroupRequest.java b/tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/pojo/param/IndexSelectionGroupRequest.java index 2020bbe..9f78809 100644 --- a/tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/pojo/param/IndexSelectionGroupRequest.java +++ b/tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/pojo/param/IndexSelectionGroupRequest.java @@ -1,28 +1,28 @@ package com.njcn.gather.icd.mapping.pojo.param; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; import lombok.Data; + import java.util.ArrayList; import java.util.List; /** - * 单个业务分组的索引选择请求。 - * - * 用于回传某个业务分组下,前端最终确认的多条绑定关系。 + * 单个业务分组的索引选择请求参数。 */ @Data +@ApiModel("单个业务分组的索引选择请求参数") public class IndexSelectionGroupRequest { - /** - * 分组唯一键。 - * - * 该值由后端在 NEED_INDEX_SELECTION 场景返回,前端应原样回传, - * 避免仅依赖中文描述做匹配。 - */ + /** 分组唯一键。 */ + @ApiModelProperty("分组唯一键,需原样回传后端返回值") private String groupKey; - /** 分组中文描述,例如“实时数据”“统计数据”。 */ + /** 分组中文描述。 */ + @ApiModelProperty("分组中文描述") private String groupDesc; - /** 当前业务分组下,用户最终确认的绑定关系。 */ + /** 当前分组最终确认的绑定关系。 */ + @ApiModelProperty("当前分组最终确认的绑定关系") private List bindings = new ArrayList(); -} \ No newline at end of file +} diff --git a/tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/pojo/param/JsonToXmlRequest.java b/tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/pojo/param/JsonToXmlRequest.java index 15e80d9..c527f17 100644 --- a/tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/pojo/param/JsonToXmlRequest.java +++ b/tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/pojo/param/JsonToXmlRequest.java @@ -1,25 +1,18 @@ package com.njcn.gather.icd.mapping.pojo.param; -import java.util.ArrayList; -import java.util.List; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; /** - * JSON 转 XML 请求参数。 + * MMS JSON 转 XML 的请求参数。 */ +@ApiModel("MMS JSON 转 XML 的请求参数") public class JsonToXmlRequest { - /** - * MMS 映射 JSON 字符串。 - * 由 getIcdMmsJson 接口返回的 mappingJson 字段提供。 - */ + /** MMS 映射 JSON 字符串。 */ + @ApiModelProperty(value = "MMS 映射 JSON 字符串", required = true) private String mappingJson; - /** - * 索引选择结果(用于重建索引映射配置)。 - * 如果提供了 indexSelection,则会重新构建索引映射; - * 如果为空,则使用默认的索引映射配置。 - */ - - public String getMappingJson() { return mappingJson; } @@ -27,6 +20,4 @@ public class JsonToXmlRequest { public void setMappingJson(String mappingJson) { this.mappingJson = mappingJson; } - - } diff --git a/tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/pojo/param/SubmitIndexSelectionRequest.java b/tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/pojo/param/SubmitIndexSelectionRequest.java index 208fcfd..f35c756 100644 --- a/tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/pojo/param/SubmitIndexSelectionRequest.java +++ b/tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/pojo/param/SubmitIndexSelectionRequest.java @@ -1,37 +1,45 @@ package com.njcn.gather.icd.mapping.pojo.param; -import lombok.Data; import com.njcn.gather.icd.mapping.pojo.bo.icd.IcdDocument; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; import java.util.ArrayList; import java.util.List; /** - * 提交索引绑定并生成映射的请求体。 - * - * 第二个接口不再重复上传 ICD 文件,而是直接接收前端确认或修改后的 ICD 解析结果。 + * 提交索引绑定并生成 MMS JSON 的请求参数。 */ @Data +@ApiModel("提交索引绑定并生成 MMS JSON 的请求参数") public class SubmitIndexSelectionRequest { - /** 前端基于候选接口返回值确认或修改后的 ICD 解析结果。 */ + /** ICD 解析结果。 */ + @ApiModelProperty("ICD 解析结果,通常来自候选接口返回") private IcdDocument icdDocument; - /** 输出版本号。为空时后端默认补当天日期。 */ + /** 映射版本号。 */ + @ApiModelProperty("映射版本号,空时默认使用当天日期") private String version; - /** 作者。为空时使用模块默认作者。 */ + /** 映射作者。 */ + @ApiModelProperty("映射作者,空时使用模块默认作者") private String author; - /** 是否保存到磁盘。 */ + /** 是否落盘。 */ + @ApiModelProperty("是否将生成结果落盘保存") private boolean saveToDisk; - /** 是否返回格式化 JSON。 */ + /** 是否格式化 JSON。 */ + @ApiModelProperty("是否返回格式化后的 JSON") private boolean prettyJson; - /** 输出目录。saveToDisk=true 时才会用到。 */ + /** 输出目录。 */ + @ApiModelProperty("输出目录,仅在 saveToDisk=true 时生效") private String outputDir; /** 用户最终确认的索引绑定关系。 */ + @ApiModelProperty("用户最终确认的索引绑定关系") private List indexSelection = new ArrayList(); -} \ No newline at end of file +} diff --git a/tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/pojo/vo/IcdToXmlResponse.java b/tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/pojo/vo/IcdToXmlResponse.java index 35579c2..180fe0c 100644 --- a/tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/pojo/vo/IcdToXmlResponse.java +++ b/tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/pojo/vo/IcdToXmlResponse.java @@ -1,36 +1,103 @@ package com.njcn.gather.icd.mapping.pojo.vo; - import com.njcn.gather.icd.mapping.pojo.enums.GenerateStatus; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; import java.util.ArrayList; import java.util.List; -// 手动写getter/setter,避免Lombok依赖问题 +/** + * MMS JSON 转 XML 的响应。 + */ +@ApiModel("MMS JSON 转 XML 的响应") public class IcdToXmlResponse { - private GenerateStatus status; - private String message; - private String iedName; - private String ldInst; - private String savedPath; - private MappingDocumentResponse mappingDocument; - private List indexCandidates = new ArrayList(); - private List problems = new ArrayList(); - public GenerateStatus getStatus() { return status; } - public void setStatus(GenerateStatus status) { this.status = status; } - public String getMessage() { return message; } - public void setMessage(String message) { this.message = message; } - public String getIedName() { return iedName; } - public void setIedName(String iedName) { this.iedName = iedName; } - public String getLdInst() { return ldInst; } - public void setLdInst(String ldInst) { this.ldInst = ldInst; } - public String getSavedPath() { return savedPath; } - public void setSavedPath(String savedPath) { this.savedPath = savedPath; } - public MappingDocumentResponse getMappingDocument() { return mappingDocument; } - public void setMappingDocument(MappingDocumentResponse mappingDocument) { this.mappingDocument = mappingDocument; } - public List getIndexCandidates() { return indexCandidates; } - public void setIndexCandidates(List indexCandidates) { this.indexCandidates = indexCandidates; } - public List getProblems() { return problems; } - public void setProblems(List problems) { this.problems = problems; } -} \ No newline at end of file + @ApiModelProperty("本次接口处理状态") + private GenerateStatus status; + + @ApiModelProperty("状态说明或错误提示") + private String message; + + @ApiModelProperty("IED 名称") + private String iedName; + + @ApiModelProperty("逻辑设备实例名") + private String ldInst; + + @ApiModelProperty("落盘后的绝对路径") + private String savedPath; + + @ApiModelProperty("生成后的映射文档摘要") + private MappingDocumentResponse mappingDocument; + + @ApiModelProperty("索引候选分组,存在待确认场景时返回") + private List indexCandidates = new ArrayList(); + + @ApiModelProperty("处理过程中发现的问题列表") + private List problems = new ArrayList(); + + public GenerateStatus getStatus() { + return status; + } + + public void setStatus(GenerateStatus status) { + this.status = status; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public String getIedName() { + return iedName; + } + + public void setIedName(String iedName) { + this.iedName = iedName; + } + + public String getLdInst() { + return ldInst; + } + + public void setLdInst(String ldInst) { + this.ldInst = ldInst; + } + + public String getSavedPath() { + return savedPath; + } + + public void setSavedPath(String savedPath) { + this.savedPath = savedPath; + } + + public MappingDocumentResponse getMappingDocument() { + return mappingDocument; + } + + public void setMappingDocument(MappingDocumentResponse mappingDocument) { + this.mappingDocument = mappingDocument; + } + + public List getIndexCandidates() { + return indexCandidates; + } + + public void setIndexCandidates(List indexCandidates) { + this.indexCandidates = indexCandidates; + } + + public List getProblems() { + return problems; + } + + public void setProblems(List problems) { + this.problems = problems; + } +} diff --git a/tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/pojo/vo/IndexCandidateReportItemResponse.java b/tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/pojo/vo/IndexCandidateReportItemResponse.java index 62c202c..d29c67e 100644 --- a/tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/pojo/vo/IndexCandidateReportItemResponse.java +++ b/tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/pojo/vo/IndexCandidateReportItemResponse.java @@ -1,27 +1,34 @@ package com.njcn.gather.icd.mapping.pojo.vo; -import lombok.Data; import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; import java.util.ArrayList; import java.util.List; /** - * 业务分组下的单个报告候选响应。 + * 索引候选中的单个报告响应项。 */ -@JsonInclude(JsonInclude.Include.NON_EMPTY) @Data +@JsonInclude(JsonInclude.Include.NON_EMPTY) +@ApiModel("索引候选中的单个报告响应项") public class IndexCandidateReportItemResponse { /** 报告名称。 */ + @ApiModelProperty("报告名称") private String reportName; /** 数据集名称。 */ + @ApiModelProperty("数据集名称") private String dataSetName; /** 报告描述。 */ + @ApiModelProperty("报告描述") private String reportDesc; - /** 当前报告可选的 `lnInst` 数值。 */ + /** 当前报告可选的 lnInst 值列表。 */ + @ApiModelProperty("当前报告可选的 lnInst 值列表") private List availableLnInstValues = new ArrayList(); -} \ No newline at end of file +} diff --git a/tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/pojo/vo/IndexCandidateResponse.java b/tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/pojo/vo/IndexCandidateResponse.java index cba1d87..1968b93 100644 --- a/tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/pojo/vo/IndexCandidateResponse.java +++ b/tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/pojo/vo/IndexCandidateResponse.java @@ -1,33 +1,38 @@ package com.njcn.gather.icd.mapping.pojo.vo; -import lombok.Data; import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; import java.util.ArrayList; import java.util.List; /** - * 索引候选响应对象。 - * - * 一个候选对应一个业务分组,分组下可包含多个报告, - * 前端据此完成模板标签与 `lnInst` 的人工绑定。 + * 索引候选分组响应。 */ -@JsonInclude(JsonInclude.Include.NON_EMPTY) @Data +@JsonInclude(JsonInclude.Include.NON_EMPTY) +@ApiModel("索引候选分组响应") public class IndexCandidateResponse { /** 分组唯一键。 */ + @ApiModelProperty("分组唯一键") private String groupKey; /** 分组中文描述。 */ + @ApiModelProperty("分组中文描述") private String groupDesc; - /** 当前分组包含的报告数。 */ + /** 当前分组包含的报告数量。 */ + @ApiModelProperty("当前分组包含的报告数量") private int reportCount; - /** 模板里配置的可选标签。 */ + /** 模板中配置的可选标签。 */ + @ApiModelProperty("模板中配置的可选标签") private List templateLabels = new ArrayList(); /** 当前分组下的报告候选列表。 */ + @ApiModelProperty("当前分组下的报告候选列表") private List reports = new ArrayList(); -} \ No newline at end of file +} diff --git a/tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/pojo/vo/MappingDocumentResponse.java b/tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/pojo/vo/MappingDocumentResponse.java index e486b3e..40a10a0 100644 --- a/tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/pojo/vo/MappingDocumentResponse.java +++ b/tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/pojo/vo/MappingDocumentResponse.java @@ -1,28 +1,37 @@ package com.njcn.gather.icd.mapping.pojo.vo; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; import lombok.Data; + /** * 映射文档摘要响应。 - * - * 用于返回最终映射结果中的关键信息摘要。 */ @Data +@ApiModel("映射文档摘要响应") public class MappingDocumentResponse { + /** 映射文档版本。 */ + @ApiModelProperty("映射文档版本") private String version; /** 映射文档作者。 */ + @ApiModelProperty("映射文档作者") private String author; /** 输出 JSON 中的 IED。 */ + @ApiModelProperty("输出 JSON 中的 IED") private String ied; /** 输出 JSON 中的 LD。 */ + @ApiModelProperty("输出 JSON 中的 LD") private String ld; /** ReportMap 条目数量。 */ + @ApiModelProperty("ReportMap 条目数量") private int reportCount; /** DataSetList 分组数量。 */ + @ApiModelProperty("DataSetList 分组数量") private int dataSetCount; } diff --git a/tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/pojo/vo/MappingTaskResponse.java b/tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/pojo/vo/MappingTaskResponse.java index 2dd238b..bc6003f 100644 --- a/tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/pojo/vo/MappingTaskResponse.java +++ b/tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/pojo/vo/MappingTaskResponse.java @@ -1,39 +1,48 @@ package com.njcn.gather.icd.mapping.pojo.vo; -import lombok.Data; import com.fasterxml.jackson.annotation.JsonInclude; import com.njcn.gather.icd.mapping.pojo.bo.icd.IcdDocument; import com.njcn.gather.icd.mapping.pojo.enums.GenerateStatus; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; import java.util.ArrayList; import java.util.List; /** - * ICD 映射接口统一响应。 - * - * 按接口阶段仅返回当前场景必需字段;空字段和空集合不参与序列化。 + * ICD 映射统一响应。 */ -@JsonInclude(JsonInclude.Include.NON_EMPTY) @Data +@JsonInclude(JsonInclude.Include.NON_EMPTY) +@ApiModel("ICD 映射统一响应") public class MappingTaskResponse { + /** 本次接口处理状态。 */ + @ApiModelProperty("本次接口处理状态") private GenerateStatus status; /** 状态说明或错误提示。 */ + @ApiModelProperty("状态说明或错误提示") private String message; - /** 候选接口或需要重新选择索引时返回的 ICD 解析结果。 */ + /** ICD 解析结果。 */ + @ApiModelProperty("ICD 解析结果,在需要确认索引时返回") private IcdDocument icdDocument; /** 正式生成成功后的完整映射 JSON。 */ + @ApiModelProperty("正式生成成功后的完整映射 JSON") private String mappingJson; - /** 生成文件落盘后的绝对路径。 */ + /** 落盘后的绝对路径。 */ + @ApiModelProperty("落盘后的绝对路径") private String savedPath; /** 待绑定状态下返回的索引候选分组。 */ + @ApiModelProperty("待绑定状态下返回的索引候选分组") private List indexCandidates = new ArrayList(); /** 模板校验、候选分析或绑定校验问题。 */ + @ApiModelProperty("模板校验、候选分析或绑定校验问题") private List problems = new ArrayList(); -} \ No newline at end of file +} diff --git a/tools/mms-mapping/src/test/java/com/njcn/gather/icd/mapping/debug/GetIcdMmsJsonDebugRunner.java b/tools/mms-mapping/src/test/java/com/njcn/gather/icd/mapping/debug/GetIcdMmsJsonDebugRunner.java index 384e65e..7a7fd15 100644 --- a/tools/mms-mapping/src/test/java/com/njcn/gather/icd/mapping/debug/GetIcdMmsJsonDebugRunner.java +++ b/tools/mms-mapping/src/test/java/com/njcn/gather/icd/mapping/debug/GetIcdMmsJsonDebugRunner.java @@ -69,6 +69,7 @@ public class GetIcdMmsJsonDebugRunner { MappingTaskResponse firstResponse = debugNeedIndexSelection(mappingTaskService, responseConverter); printResponse("第一次调试:获取索引候选", firstResponse, objectMapper); + printIndexCandidatesJson(firstResponse, objectMapper); printIndexCandidateSummary(firstResponse); if (!RUN_SECOND_STEP) { @@ -192,6 +193,23 @@ public class GetIcdMmsJsonDebugRunner { } } + /** + * 单独输出 indexCandidates 的 JSON,便于直接复制做第二次调试绑定。 + */ + private static void printIndexCandidatesJson(MappingTaskResponse response, ObjectMapper objectMapper) { + try { + System.out.println(); + System.out.println("===== indexCandidates JSON ====="); + if (response == null) { + System.out.println("null"); + return; + } + System.out.println(objectMapper.writeValueAsString(response.getIndexCandidates())); + } catch (Exception ex) { + throw new IllegalArgumentException("print indexCandidates JSON failed: " + ex.getMessage(), ex); + } + } + private static void printResponse(String title, MappingTaskResponse response, ObjectMapper objectMapper) { try { System.out.println();