diff --git a/steady/check-square/src/test/java/com/njcn/gather/steady/checksquare/service/impl/SteadyChecksquareServiceImplTest.java b/steady/check-square/src/test/java/com/njcn/gather/steady/checksquare/service/impl/SteadyChecksquareServiceImplTest.java index 4ba231b..44a349c 100644 --- a/steady/check-square/src/test/java/com/njcn/gather/steady/checksquare/service/impl/SteadyChecksquareServiceImplTest.java +++ b/steady/check-square/src/test/java/com/njcn/gather/steady/checksquare/service/impl/SteadyChecksquareServiceImplTest.java @@ -1,6 +1,8 @@ package com.njcn.gather.steady.checksquare.service.impl; import com.fasterxml.jackson.databind.ObjectMapper; +import com.baomidou.mybatisplus.core.toolkit.support.SFunction; +import com.baomidou.mybatisplus.core.metadata.TableInfoHelper; import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.njcn.gather.steady.checksquare.component.SteadyChecksquareCalculator; @@ -32,8 +34,11 @@ import com.njcn.gather.tool.adddata.component.AddDataTimeSlotCalculator; import com.njcn.gather.tool.addledger.pojo.vo.AddLedgerLinePathVO; import com.njcn.gather.tool.addledger.service.AddLedgerService; import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.mockito.ArgumentCaptor; +import org.apache.ibatis.builder.MapperBuilderAssistant; +import org.apache.ibatis.session.Configuration; import org.springframework.transaction.annotation.Transactional; import java.lang.reflect.Method; @@ -58,6 +63,14 @@ import static org.mockito.Mockito.when; * 鏁版嵁鏍¢獙鏈嶅姟娴嬭瘯銆? */ class SteadyChecksquareServiceImplTest { + @BeforeAll + static void initMybatisPlusTableInfo() { + MapperBuilderAssistant assistant = new MapperBuilderAssistant(new Configuration(), ""); + TableInfoHelper.initTableInfo(assistant, SteadyChecksquareTaskPO.class); + TableInfoHelper.initTableInfo(assistant, SteadyChecksquareItemPO.class); + TableInfoHelper.initTableInfo(assistant, SteadyChecksquareDetailPO.class); + } + @Test void shouldNotOpenTransactionAroundCreateCalculation() throws Exception { Method createMethod = SteadyChecksquareServiceImpl.class.getMethod("create", SteadyChecksquareQueryParam.class); @@ -72,7 +85,7 @@ class SteadyChecksquareServiceImplTest { LambdaQueryChainWrapper taskQuery = mock(LambdaQueryChainWrapper.class); when(taskService.lambdaQuery()).thenReturn(taskQuery); when(taskQuery.eq(any(), any())).thenReturn(taskQuery); - when(taskQuery.orderByDesc(any())).thenReturn(taskQuery); + when(taskQuery.orderByDesc(any(SFunction.class))).thenReturn(taskQuery); when(taskQuery.list()).thenReturn(Collections.emptyList()); SteadyChecksquareServiceImpl service = new SteadyChecksquareServiceImpl(new SteadyTrendIndicatorCatalog(), mock(SteadyChecksquareInfluxQueryComponent.class), new SteadyChecksquareCalculator(), @@ -110,7 +123,7 @@ class SteadyChecksquareServiceImplTest { LambdaQueryChainWrapper taskQuery = mock(LambdaQueryChainWrapper.class); when(taskService.lambdaQuery()).thenReturn(taskQuery); when(taskQuery.eq(any(), any())).thenReturn(taskQuery); - when(taskQuery.orderByDesc(any())).thenReturn(taskQuery); + when(taskQuery.orderByDesc(any(SFunction.class))).thenReturn(taskQuery); when(taskQuery.list()).thenReturn(Collections.emptyList()); SteadyChecksquareServiceImpl service = new SteadyChecksquareServiceImpl(new SteadyTrendIndicatorCatalog(), influxQueryComponent, new SteadyChecksquareCalculator(), @@ -165,7 +178,7 @@ class SteadyChecksquareServiceImplTest { task.setState(1); when(taskService.lambdaQuery()).thenReturn(taskQuery); when(taskQuery.eq(any(), any())).thenReturn(taskQuery); - when(taskQuery.orderByDesc(any())).thenReturn(taskQuery); + when(taskQuery.orderByDesc(any(SFunction.class))).thenReturn(taskQuery); when(taskQuery.list()).thenReturn(Collections.singletonList(task)); SteadyChecksquareServiceImpl service = new SteadyChecksquareServiceImpl(new SteadyTrendIndicatorCatalog(), mock(SteadyChecksquareInfluxQueryComponent.class), new SteadyChecksquareCalculator(), @@ -200,7 +213,7 @@ class SteadyChecksquareServiceImplTest { LambdaQueryChainWrapper taskQuery = mock(LambdaQueryChainWrapper.class); when(taskService.lambdaQuery()).thenReturn(taskQuery); when(taskQuery.eq(any(), any())).thenReturn(taskQuery); - when(taskQuery.orderByDesc(any())).thenReturn(taskQuery); + when(taskQuery.orderByDesc(any(SFunction.class))).thenReturn(taskQuery); when(taskQuery.list()).thenReturn(Collections.emptyList()); SteadyChecksquareServiceImpl service = new SteadyChecksquareServiceImpl(new SteadyTrendIndicatorCatalog(), influxQueryComponent, new SteadyChecksquareCalculator(), @@ -660,7 +673,7 @@ class SteadyChecksquareServiceImplTest { SteadyChecksquareItemVO item = new SteadyChecksquareItemVO(); item.setItemKey("line-001|V_RMS"); item.setIndicatorCode("V_RMS"); - item.setIndicatorName("鐩哥數鍘嬫湁鏁堝€?); + item.setIndicatorName("鐩哥數鍘嬫湁鏁堝€?"); item.setIntervalMinutes(1); item.setHasData(true); item.setExpectedPointCount(2); diff --git a/tools/device-types/src/main/java/com/njcn/gather/device/types/mapper/mapping/CsDevTypeMapper.xml b/tools/device-types/src/main/java/com/njcn/gather/device/types/mapper/mapping/CsDevTypeMapper.xml index e2e78ae..e62e029 100644 --- a/tools/device-types/src/main/java/com/njcn/gather/device/types/mapper/mapping/CsDevTypeMapper.xml +++ b/tools/device-types/src/main/java/com/njcn/gather/device/types/mapper/mapping/CsDevTypeMapper.xml @@ -3,8 +3,28 @@ "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> + + + + + + + + + + + + + + + + + + + resultMap="CsIcdPathVOResultMap"> SELECT ID AS id, Name AS name, diff --git a/tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/pojo/param/IcdCheckResultSaveParam.java b/tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/pojo/param/IcdCheckResultSaveParam.java index b2e3a9c..fa7dadd 100644 --- a/tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/pojo/param/IcdCheckResultSaveParam.java +++ b/tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/pojo/param/IcdCheckResultSaveParam.java @@ -1,5 +1,8 @@ package com.njcn.gather.icd.mapping.pojo.param; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.databind.JsonNode; +import com.njcn.gather.icd.mapping.pojo.bo.icd.IcdDocument; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; @@ -20,6 +23,13 @@ public class IcdCheckResultSaveParam { @ApiModelProperty("校验结论:0-否,1-是") private Integer result; - @ApiModelProperty("校验结论描述") - private String msg; + @ApiModelProperty("校验结论详情JSON") + private JsonNode msg; + + @ApiModelProperty("getICD返回的icdDocument原始解析记录") + private IcdDocument icdDocument; + + @ApiModelProperty("ICD文件二进制内容,仅 multipart 保存时由后端填充") + @JsonIgnore + private byte[] icdContent; } diff --git a/tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/pojo/po/CsIcdPathPO.java b/tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/pojo/po/CsIcdPathPO.java index df70ac9..c8c2a80 100644 --- a/tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/pojo/po/CsIcdPathPO.java +++ b/tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/pojo/po/CsIcdPathPO.java @@ -3,6 +3,8 @@ package com.njcn.gather.icd.mapping.pojo.po; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.databind.JsonNode; +import com.njcn.gather.icd.mapping.typehandler.JsonNodeTypeHandler; import lombok.Data; import java.io.Serializable; @@ -12,7 +14,7 @@ import java.time.LocalDateTime; * ICD 存储记录。 */ @Data -@TableName("cs_icd_path") +@TableName(value = "cs_icd_path", autoResultMap = true) public class CsIcdPathPO implements Serializable { private static final long serialVersionUID = 1L; @@ -26,7 +28,7 @@ public class CsIcdPathPO implements Serializable { @TableField("Path") private String path; - @TableField("Icd_Content") + @TableField("Icd") private byte[] icdContent; @TableField("Angle") @@ -59,8 +61,8 @@ public class CsIcdPathPO implements Serializable { @TableField("Result") private Integer result; - @TableField("Msg") - private String msg; + @TableField(value = "Msg", typeHandler = JsonNodeTypeHandler.class) + private JsonNode msg; @TableField("Type") private Integer type; diff --git a/tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/pojo/vo/CsIcdPathVO.java b/tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/pojo/vo/CsIcdPathVO.java index b27cebc..042234f 100644 --- a/tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/pojo/vo/CsIcdPathVO.java +++ b/tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/pojo/vo/CsIcdPathVO.java @@ -1,5 +1,6 @@ package com.njcn.gather.icd.mapping.pojo.vo; +import com.fasterxml.jackson.databind.JsonNode; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; @@ -40,8 +41,8 @@ public class CsIcdPathVO { @ApiModelProperty("校验结论,0-否,1-是") private Integer result; - @ApiModelProperty("校验结论描述") - private String msg; + @ApiModelProperty("校验结论详情JSON") + private JsonNode msg; @ApiModelProperty("ICD类型,1-标准ICD") private Integer type; diff --git a/tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/service/impl/CsIcdPathServiceImpl.java b/tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/service/impl/CsIcdPathServiceImpl.java index 44306df..9f2af1e 100644 --- a/tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/service/impl/CsIcdPathServiceImpl.java +++ b/tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/service/impl/CsIcdPathServiceImpl.java @@ -2,6 +2,8 @@ package com.njcn.gather.icd.mapping.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; import com.njcn.gather.icd.mapping.mapper.CsIcdPathMapper; import com.njcn.gather.icd.mapping.pojo.param.CsIcdPathParam; import com.njcn.gather.icd.mapping.pojo.param.IcdCheckResultSaveParam; @@ -32,6 +34,8 @@ public class CsIcdPathServiceImpl implements CsIcdPathService { private final CsIcdPathMapper csIcdPathMapper; + private final ObjectMapper objectMapper = new ObjectMapper(); + @Override public List listIcdPaths(CsIcdPathParam.ListParam param) { CsIcdPathParam.ListParam checkedParam = param == null ? new CsIcdPathParam.ListParam() : param; @@ -116,13 +120,26 @@ public class CsIcdPathServiceImpl implements CsIcdPathService { icdPath.setJsonStr(trimToNull(param.getMappingJson())); icdPath.setXmlStr(trimToNull(param.getXml())); icdPath.setResult(normalizeResult(param.getResult())); - icdPath.setMsg(trimToNull(param.getMsg())); + icdPath.setMsg(param.getMsg()); icdPath.setReferenceIcdId(referenceIcd.getId()); + if (param.getIcdDocument() != null) { + icdPath.setIcdContent(serializeIcdDocument(param)); + } else if (param.getIcdContent() != null && param.getIcdContent().length > 0) { + icdPath.setIcdContent(param.getIcdContent()); + } icdPath.setUpdateBy(currentUserId()); icdPath.setUpdateTime(LocalDateTime.now()); return csIcdPathMapper.updateById(icdPath) > 0; } + private byte[] serializeIcdDocument(IcdCheckResultSaveParam param) { + try { + return objectMapper.writeValueAsBytes(param.getIcdDocument()); + } catch (JsonProcessingException ex) { + throw new IllegalArgumentException("ICD解析记录序列化失败:" + ex.getMessage(), ex); + } + } + private CsIcdPathPO buildIcdPath(CsIcdPathParam param) { CsIcdPathPO icdPath = new CsIcdPathPO(); icdPath.setName(requireText(param.getName(), "ICD名称不能为空")); diff --git a/tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/typehandler/JsonNodeTypeHandler.java b/tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/typehandler/JsonNodeTypeHandler.java new file mode 100644 index 0000000..c97e63a --- /dev/null +++ b/tools/mms-mapping/src/main/java/com/njcn/gather/icd/mapping/typehandler/JsonNodeTypeHandler.java @@ -0,0 +1,51 @@ +package com.njcn.gather.icd.mapping.typehandler; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.ibatis.type.BaseTypeHandler; +import org.apache.ibatis.type.JdbcType; + +import java.sql.CallableStatement; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; + +/** + * 将数据库 JSON 字段映射为 Jackson JsonNode,便于接口直接返回结构化失败原因。 + */ +public class JsonNodeTypeHandler extends BaseTypeHandler { + + private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + + @Override + public void setNonNullParameter(PreparedStatement ps, int i, JsonNode parameter, JdbcType jdbcType) + throws SQLException { + ps.setString(i, parameter.toString()); + } + + @Override + public JsonNode getNullableResult(ResultSet rs, String columnName) throws SQLException { + return parse(rs.getString(columnName)); + } + + @Override + public JsonNode getNullableResult(ResultSet rs, int columnIndex) throws SQLException { + return parse(rs.getString(columnIndex)); + } + + @Override + public JsonNode getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { + return parse(cs.getString(columnIndex)); + } + + private JsonNode parse(String value) throws SQLException { + if (value == null || value.trim().isEmpty()) { + return null; + } + try { + return OBJECT_MAPPER.readTree(value); + } catch (Exception ex) { + throw new SQLException("解析JSON字段失败", ex); + } + } +} diff --git a/tools/mms-mapping/src/test/java/com/njcn/gather/icd/mapping/component/IcdConsistencyCheckServiceTest.java b/tools/mms-mapping/src/test/java/com/njcn/gather/icd/mapping/component/IcdConsistencyCheckServiceTest.java index 3efcd4a..a00ecb5 100644 --- a/tools/mms-mapping/src/test/java/com/njcn/gather/icd/mapping/component/IcdConsistencyCheckServiceTest.java +++ b/tools/mms-mapping/src/test/java/com/njcn/gather/icd/mapping/component/IcdConsistencyCheckServiceTest.java @@ -18,7 +18,7 @@ class IcdConsistencyCheckServiceTest { Path tempDir; @Test - void checkShouldReturnMismatchIssuesAndCorrectedJsonWithoutSavedPath() throws Exception { + void checkShouldReturnMismatchIssuesWithoutAutoCorrectingConsistencyDiffs() throws Exception { IcdConsistencyCheckRequest request = new IcdConsistencyCheckRequest(); request.setStandardJson(buildStandardJson()); request.setCheckedJson(buildCheckedJson()); @@ -31,13 +31,38 @@ class IcdConsistencyCheckServiceTest { Assertions.assertEquals("不符合", response.getMessage()); Assertions.assertFalse(response.getIssues().isEmpty()); Assertions.assertTrue(response.getIssuesJson().contains("ReportMap")); - Assertions.assertTrue(response.getCorrectedJson().contains("\"unit\" : \"s\"")); - Assertions.assertTrue(response.getCorrectedJson().contains("\"reportCount\" : 2")); - Assertions.assertTrue(response.getCorrectedJson().contains("\"start\" : 1")); - Assertions.assertTrue(response.getCorrectedJson().contains("\"end\" : 4")); + Assertions.assertNull(response.getCorrectedJson()); Assertions.assertTrue(Files.list(tempDir).findAny().isPresent()); } + @Test + void checkShouldOnlyReturnCorrectedJsonForRtFreSelfMappingRule() { + IcdConsistencyCheckRequest request = new IcdConsistencyCheckRequest(); + request.setStandardJson(buildRtFreStandardJson()); + request.setCheckedJson(buildRtFreCheckedJson()); + + IcdConsistencyCheckResponse response = service.check(request); + + Assertions.assertEquals(0, response.getResult()); + Assertions.assertTrue(response.getCorrectedJson().contains("\"rptID\" : \"demoRtFre\"")); + Assertions.assertTrue(response.getCorrectedJson().contains("\"FlickerFlag\" : \"1\"")); + Assertions.assertTrue(response.getCorrectedJson().contains("\"reportCount\" : 0")); + Assertions.assertTrue(response.getCorrectedJson().contains("\"reportCount\" : 1")); + } + + @Test + void checkShouldReportEmptySdiListAsTypeListProblem() { + IcdConsistencyCheckRequest request = new IcdConsistencyCheckRequest(); + request.setStandardJson(buildStandardJson()); + request.setCheckedJson(buildEmptySdiListJson()); + + IcdConsistencyCheckResponse response = service.check(request); + + Assertions.assertEquals(0, response.getResult()); + Assertions.assertTrue(response.getIssuesJson().contains("typeList 不能为空:统计数据 / A相 / 频率")); + Assertions.assertFalse(response.getIssuesJson().contains("sdiList 不能为空")); + } + @Test void checkShouldReturnPassWhenCheckedJsonMatchesStandardJson() { IcdConsistencyCheckRequest request = new IcdConsistencyCheckRequest(); @@ -94,6 +119,69 @@ class IcdConsistencyCheckServiceTest { "}"; } + private String buildRtFreStandardJson() { + return "{\n" + + " \"IED\":\"IED1\",\n" + + " \"LD\":\"LD0\",\n" + + " \"DataType\":\"1\",\n" + + " \"unit\":\"s\",\n" + + " \"ReportMap\":[\n" + + " {\"desc\":\"统计数据\",\"reportCount\":1,\"rptID\":\"rpt-stat\",\"name\":\"brcbStat\",\"buffered\":\"BR\",\"inst\":\"01\",\"FlickerFlag\":\"0\",\"Select\":\"all\",\"TrgOps\":\"dchg\"},\n" + + " {\"desc\":\"波动闪变\",\"reportCount\":1,\"rptID\":\"rpt-flk\",\"name\":\"brcbFlk\",\"buffered\":\"BR\",\"inst\":\"02\",\"FlickerFlag\":\"0\",\"Select\":\"all\",\"TrgOps\":\"dchg\"},\n" + + " {\"desc\":\"实时数据\",\"reportCount\":0,\"rptID\":\"demoRtFre\",\"name\":\"brcbRt\",\"buffered\":\"RP\",\"inst\":\"03\",\"FlickerFlag\":\"1\",\"Select\":\"all\",\"TrgOps\":\"dchg\"},\n" + + " {\"desc\":\"暂态事件\",\"reportCount\":1,\"rptID\":\"rpt-tran\",\"name\":\"brcbTran\",\"buffered\":\"BR\",\"inst\":\"04\",\"FlickerFlag\":\"0\",\"Select\":\"all\",\"TrgOps\":\"dchg\"}\n" + + " ],\n" + + " \"DataSetList\":[\n" + + buildDataSet("MMXU", "统计数据", "1", "A相", "Hz", "频率", 1, 4, "Hz") + ",\n" + + buildDataSet("MSQI", "实时数据", "1", "A相", "A", "电流", 1, 2, "A") + ",\n" + + buildDataSet("MHAI", "谐波数据", "1", "A相", "Har", "谐波", 1, 2, "%") + ",\n" + + buildDataSet("MFLK", "波动闪变", "1", "A相", "Flk", "闪变", 1, 2, "pu") + "\n" + + " ]\n" + + "}"; + } + + private String buildRtFreCheckedJson() { + return "{\n" + + " \"IED\":\"IED1\",\n" + + " \"LD\":\"LD0\",\n" + + " \"DataType\":\"1\",\n" + + " \"unit\":\"s\",\n" + + " \"ReportMap\":[\n" + + " {\"desc\":\"统计数据\",\"reportCount\":2,\"rptID\":\"rpt-stat\",\"name\":\"brcbStat\",\"buffered\":\"BR\",\"inst\":\"01\",\"FlickerFlag\":\"0\",\"Select\":\"all\",\"TrgOps\":\"dchg\"},\n" + + " {\"desc\":\"波动闪变\",\"reportCount\":1,\"rptID\":\"rpt-flk\",\"name\":\"brcbFlk\",\"buffered\":\"BR\",\"inst\":\"02\",\"FlickerFlag\":\"0\",\"Select\":\"all\",\"TrgOps\":\"dchg\"},\n" + + " {\"desc\":\"实时数据\",\"reportCount\":1,\"rptID\":\"demoRtFre\",\"name\":\"brcbRt\",\"buffered\":\"RP\",\"inst\":\"03\",\"FlickerFlag\":\"0\",\"Select\":\"all\",\"TrgOps\":\"dchg\"},\n" + + " {\"desc\":\"暂态事件\",\"reportCount\":1,\"rptID\":\"rpt-tran\",\"name\":\"brcbTran\",\"buffered\":\"BR\",\"inst\":\"04\",\"FlickerFlag\":\"0\",\"Select\":\"all\",\"TrgOps\":\"dchg\"}\n" + + " ],\n" + + " \"DataSetList\":[\n" + + buildDataSet("MMXU", "统计数据", "1", "A相", "Hz", "频率", 1, 4, "Hz") + ",\n" + + buildDataSet("MSQI", "实时数据", "1", "A相", "A", "电流", 1, 2, "A") + ",\n" + + buildDataSet("MHAI", "谐波数据", "1", "A相", "Har", "谐波", 1, 2, "%") + ",\n" + + buildDataSet("MFLK", "波动闪变", "1", "A相", "Flk", "闪变", 1, 2, "pu") + "\n" + + " ]\n" + + "}"; + } + + private String buildEmptySdiListJson() { + return "{\n" + + " \"IED\":\"IED1\",\n" + + " \"LD\":\"LD0\",\n" + + " \"DataType\":\"1\",\n" + + " \"unit\":\"s\",\n" + + " \"ReportMap\":[\n" + + " {\"desc\":\"统计数据\",\"reportCount\":2,\"rptID\":\"rpt-stat\",\"name\":\"brcbStat\",\"buffered\":\"BR\",\"inst\":\"01\",\"FlickerFlag\":\"0\",\"Select\":\"all\",\"TrgOps\":\"dchg\"},\n" + + " {\"desc\":\"波动闪变\",\"reportCount\":1,\"rptID\":\"rpt-flk\",\"name\":\"brcbFlk\",\"buffered\":\"BR\",\"inst\":\"02\",\"FlickerFlag\":\"0\",\"Select\":\"all\",\"TrgOps\":\"dchg\"},\n" + + " {\"desc\":\"实时数据\",\"reportCount\":1,\"rptID\":\"rpt-rt\",\"name\":\"brcbRt\",\"buffered\":\"RP\",\"inst\":\"03\",\"FlickerFlag\":\"0\",\"Select\":\"all\",\"TrgOps\":\"dchg\"},\n" + + " {\"desc\":\"暂态事件\",\"reportCount\":1,\"rptID\":\"rpt-tran\",\"name\":\"brcbTran\",\"buffered\":\"BR\",\"inst\":\"04\",\"FlickerFlag\":\"0\",\"Select\":\"all\",\"TrgOps\":\"dchg\"}\n" + + " ],\n" + + " \"DataSetList\":[\n" + + buildDataSetWithoutSdiList("MMXU", "统计数据", "1", "A相", "Hz", "频率") + ",\n" + + buildDataSet("MSQI", "实时数据", "1", "A相", "A", "电流", 1, 2, "A") + ",\n" + + buildDataSet("MHAI", "谐波数据", "1", "A相", "Har", "谐波", 1, 2, "%") + ",\n" + + buildDataSet("MFLK", "波动闪变", "1", "A相", "Flk", "闪变", 1, 2, "pu") + "\n" + + " ]\n" + + "}"; + } + private String buildDataSet(String lnClass, String groupDesc, String inst, String instDesc, String doiName, String doiDesc, int start, int end, String unit) { return " {\"desc\":\"" + groupDesc + "\",\"lnClass\":\"" + lnClass + "\",\"instList\":[{\"inst\":\"" + inst + @@ -101,4 +189,11 @@ class IcdConsistencyCheckServiceTest { "\",\"start\":" + start + ",\"end\":" + end + ",\"unit\":\"" + unit + "\",\"coefficient\":1.0,\"baseflag\":1,\"basecount\":1,\"icdcout\":10,\"sdiList\":[{\"name\":\"mag\",\"desc\":\"幅值\",\"typeList\":[{\"name\":\"f\",\"desc\":\"浮点\"}]}]}]}]}"; } + + private String buildDataSetWithoutSdiList(String lnClass, String groupDesc, String inst, String instDesc, + String doiName, String doiDesc) { + return " {\"desc\":\"" + groupDesc + "\",\"lnClass\":\"" + lnClass + "\",\"instList\":[{\"inst\":\"" + inst + + "\",\"desc\":\"" + instDesc + "\",\"doiList\":[{\"name\":\"" + doiName + "\",\"desc\":\"" + doiDesc + + "\",\"start\":1,\"end\":4,\"unit\":\"Hz\",\"coefficient\":1.0,\"baseflag\":1,\"basecount\":1,\"icdcout\":10,\"sdiList\":[]}]}]}"; + } } diff --git a/tools/mms-mapping/src/test/java/com/njcn/gather/icd/mapping/service/impl/CsIcdPathServiceImplTest.java b/tools/mms-mapping/src/test/java/com/njcn/gather/icd/mapping/service/impl/CsIcdPathServiceImplTest.java index 903a07c..83aa585 100644 --- a/tools/mms-mapping/src/test/java/com/njcn/gather/icd/mapping/service/impl/CsIcdPathServiceImplTest.java +++ b/tools/mms-mapping/src/test/java/com/njcn/gather/icd/mapping/service/impl/CsIcdPathServiceImplTest.java @@ -1,9 +1,12 @@ package com.njcn.gather.icd.mapping.service.impl; import com.njcn.gather.icd.mapping.mapper.CsIcdPathMapper; +import com.njcn.gather.icd.mapping.pojo.bo.icd.IcdDocument; import com.njcn.gather.icd.mapping.pojo.param.CsIcdPathParam; import com.njcn.gather.icd.mapping.pojo.param.IcdCheckResultSaveParam; import com.njcn.gather.icd.mapping.pojo.po.CsIcdPathPO; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.mockito.ArgumentCaptor; @@ -19,9 +22,21 @@ import static org.mockito.Mockito.when; class CsIcdPathServiceImplTest { + private final ObjectMapper objectMapper = new ObjectMapper(); private final CsIcdPathMapper csIcdPathMapper = mock(CsIcdPathMapper.class); private final CsIcdPathServiceImpl service = new CsIcdPathServiceImpl(csIcdPathMapper); + @Test + void checkResultParamShouldIgnoreIcdContentFromJson() throws Exception { + String requestJson = "{\"mappingJson\":\"{}\",\"result\":1,\"icdContent\":\"\"}"; + + IcdCheckResultSaveParam param = objectMapper.readValue(requestJson, IcdCheckResultSaveParam.class); + + Assertions.assertEquals("{}", param.getMappingJson()); + Assertions.assertEquals(1, param.getResult()); + Assertions.assertNull(param.getIcdContent()); + } + @Test void listIcdPathsShouldTrimKeywordBeforeQuery() { CsIcdPathParam.ListParam param = new CsIcdPathParam.ListParam(); @@ -152,7 +167,8 @@ class CsIcdPathServiceImplTest { param.setMappingJson("{}"); param.setXml(""); param.setResult(1); - param.setMsg("通过"); + JsonNode msg = objectMapper.createObjectNode().put("summary", "通过"); + param.setMsg(msg); boolean result = service.saveIcdCheckResult("icd-001", param); @@ -161,6 +177,62 @@ class CsIcdPathServiceImplTest { Assertions.assertTrue(result); Assertions.assertEquals("reference-icd", captor.getValue().getReferenceIcdId()); Assertions.assertEquals(1, captor.getValue().getResult()); + Assertions.assertEquals("通过", captor.getValue().getMsg().get("summary").asText()); + } + + @Test + void saveIcdCheckResultShouldSaveIcdBinaryContentWhenProvided() { + CsIcdPathPO referenceIcd = new CsIcdPathPO(); + referenceIcd.setId("reference-icd"); + when(csIcdPathMapper.selectList(any())).thenReturn(Collections.singletonList(referenceIcd)); + + CsIcdPathPO icdPath = new CsIcdPathPO(); + icdPath.setId("icd-001"); + icdPath.setState(1); + when(csIcdPathMapper.selectById(eq("icd-001"))).thenReturn(icdPath); + when(csIcdPathMapper.updateById(any(CsIcdPathPO.class))).thenReturn(1); + + byte[] fileContent = "".getBytes(); + IcdCheckResultSaveParam param = new IcdCheckResultSaveParam(); + param.setMappingJson("{}"); + param.setResult(1); + param.setIcdContent(fileContent); + + boolean result = service.saveIcdCheckResult("icd-001", param); + + ArgumentCaptor captor = ArgumentCaptor.forClass(CsIcdPathPO.class); + verify(csIcdPathMapper).updateById(captor.capture()); + Assertions.assertTrue(result); + Assertions.assertArrayEquals(fileContent, captor.getValue().getIcdContent()); + } + + @Test + void saveIcdCheckResultShouldSaveIcdDocumentJsonContentWhenProvided() throws Exception { + CsIcdPathPO referenceIcd = new CsIcdPathPO(); + referenceIcd.setId("reference-icd"); + when(csIcdPathMapper.selectList(any())).thenReturn(Collections.singletonList(referenceIcd)); + + CsIcdPathPO icdPath = new CsIcdPathPO(); + icdPath.setId("icd-001"); + icdPath.setState(1); + when(csIcdPathMapper.selectById(eq("icd-001"))).thenReturn(icdPath); + when(csIcdPathMapper.updateById(any(CsIcdPathPO.class))).thenReturn(1); + + IcdDocument icdDocument = new IcdDocument(); + icdDocument.setFileName("checked.icd"); + icdDocument.setIedName("IED1"); + icdDocument.setLdInst("LD0"); + IcdCheckResultSaveParam param = new IcdCheckResultSaveParam(); + param.setMappingJson("{}"); + param.setResult(1); + param.setIcdDocument(icdDocument); + + boolean result = service.saveIcdCheckResult("icd-001", param); + + ArgumentCaptor captor = ArgumentCaptor.forClass(CsIcdPathPO.class); + verify(csIcdPathMapper).updateById(captor.capture()); + Assertions.assertTrue(result); + Assertions.assertArrayEquals(objectMapper.writeValueAsBytes(icdDocument), captor.getValue().getIcdContent()); } private CsIcdPathParam buildParam(String name) {