From 82fdd7664b25d86625fb47b2e13a62f79e1f221e Mon Sep 17 00:00:00 2001
From: caozehui <2427765068@qq.com>
Date: Tue, 16 Jun 2026 19:25:43 +0800
Subject: [PATCH] =?UTF-8?q?icd=E8=B0=83=E6=95=B4?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
detection/pom.xml | 7 +-
.../icd/controller/PqIcdPathController.java | 62 ++-
.../gather/icd/mapper/PqIcdPathMapper.java | 17 +
.../icd/mapper/mapping/PqIcdPathMapper.xml | 107 ++++-
.../icd/pojo/enums/IcdResponseEnum.java | 27 +-
.../gather/icd/pojo/param/PqIcdPathParam.java | 73 +++-
.../njcn/gather/icd/pojo/po/PqIcdPath.java | 57 ++-
.../gather/icd/service/IPqIcdPathService.java | 27 +-
.../service/impl/PqIcdPathServiceImpl.java | 396 +++++++++++-------
.../service/support/IcdArchiveBuilder.java | 62 +++
.../service/support/IcdPayloadAssembler.java | 90 ++++
.../service/support/IcdPayloadValidator.java | 66 +++
entrance/src/main/resources/application.yml | 3 +
13 files changed, 793 insertions(+), 201 deletions(-)
create mode 100644 detection/src/main/java/com/njcn/gather/icd/service/support/IcdArchiveBuilder.java
create mode 100644 detection/src/main/java/com/njcn/gather/icd/service/support/IcdPayloadAssembler.java
create mode 100644 detection/src/main/java/com/njcn/gather/icd/service/support/IcdPayloadValidator.java
diff --git a/detection/pom.xml b/detection/pom.xml
index 2ee75920..1a346a4d 100644
--- a/detection/pom.xml
+++ b/detection/pom.xml
@@ -145,7 +145,12 @@
activate-tool
1.0.0
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
-
\ No newline at end of file
+
diff --git a/detection/src/main/java/com/njcn/gather/icd/controller/PqIcdPathController.java b/detection/src/main/java/com/njcn/gather/icd/controller/PqIcdPathController.java
index f30566ca..d6a087f4 100644
--- a/detection/src/main/java/com/njcn/gather/icd/controller/PqIcdPathController.java
+++ b/detection/src/main/java/com/njcn/gather/icd/controller/PqIcdPathController.java
@@ -18,12 +18,18 @@ import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
+import org.springframework.core.io.ByteArrayResource;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
+import org.springframework.web.util.UriUtils;
+import javax.validation.Valid;
+import java.nio.charset.StandardCharsets;
import java.util.List;
-
/**
* @author caozehui
* @date 2025-02-10
@@ -38,7 +44,7 @@ public class PqIcdPathController extends BaseController {
@OperateInfo(info = LogEnum.BUSINESS_COMMON)
@GetMapping("/listAll")
- @ApiOperation("获取所有icd")
+ @ApiOperation("获取全部icd")
public HttpResult> listAll() {
String methodDescribe = getMethodDescribe("listAll");
List result = pqIcdPathService.listAll();
@@ -60,7 +66,7 @@ public class PqIcdPathController extends BaseController {
@PostMapping("/add")
@ApiOperation("新增icd")
@ApiImplicitParam(name = "param", value = "icd新增参数", required = true)
- public HttpResult add(PqIcdPathParam param) {
+ public HttpResult add(@Validated PqIcdPathParam.CreateParam param) {
String methodDescribe = getMethodDescribe("add");
LogUtil.njcnDebug(log, "{},新增数据为:{}", methodDescribe, param);
@@ -72,11 +78,27 @@ public class PqIcdPathController extends BaseController {
}
}
+ @OperateInfo(info = LogEnum.BUSINESS_COMMON, operateType = OperateType.ADD)
+ @PostMapping("/external/add")
+ @ApiOperation("外部系统新增icd")
+ @ApiImplicitParam(name = "param", value = "外部系统icd新增参数", required = true)
+ public HttpResult externalAdd(@RequestBody List param) {
+ String methodDescribe = getMethodDescribe("externalAdd");
+ LogUtil.njcnDebug(log, "{},外部新增数据为:{}", methodDescribe, param);
+
+ boolean result = pqIcdPathService.addUpstreamIcd(param);
+ if (result) {
+ return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, true, methodDescribe);
+ } else {
+ return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.FAIL, false, methodDescribe);
+ }
+ }
+
@OperateInfo(info = LogEnum.BUSINESS_COMMON, operateType = OperateType.UPDATE)
@PostMapping("/update")
@ApiOperation("修改icd")
@ApiImplicitParam(name = "param", value = "icd修改参数", required = true)
- public HttpResult update(PqIcdPathParam.UpdateParam param) {
+ public HttpResult update(@Validated PqIcdPathParam.UpdateParam param) {
String methodDescribe = getMethodDescribe("update");
LogUtil.njcnDebug(log, "{},修改数据为:{}", methodDescribe, param);
@@ -88,6 +110,24 @@ public class PqIcdPathController extends BaseController {
}
}
+ @OperateInfo(info = LogEnum.BUSINESS_COMMON)
+ @GetMapping("/standard-list")
+ @ApiOperation("获取标准ICD列表")
+ public HttpResult> standardList() {
+ String methodDescribe = getMethodDescribe("standardList");
+ List result = pqIcdPathService.listStandardIcd();
+ return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
+ }
+
+ @OperateInfo(info = LogEnum.BUSINESS_COMMON)
+ @GetMapping("/getById")
+ @ApiOperation("根据id获取ICD详情")
+ public HttpResult getById(@RequestParam String id) {
+ String methodDescribe = getMethodDescribe("getById");
+ PqIcdPath result = pqIcdPathService.getIcdById(id);
+ return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
+ }
+
@OperateInfo(info = LogEnum.BUSINESS_COMMON, operateType = OperateType.DELETE)
@PostMapping("/delete")
@ApiOperation("删除icd")
@@ -103,5 +143,17 @@ public class PqIcdPathController extends BaseController {
}
}
+ @OperateInfo(info = LogEnum.BUSINESS_COMMON)
+ @GetMapping("/export/{id}")
+ @ApiOperation("导出icd")
+ public ResponseEntity export(@PathVariable String id) {
+ PqIcdPath detail = pqIcdPathService.getIcdById(id);
+ byte[] body = pqIcdPathService.exportIcd(id);
+ String fileName = UriUtils.encode(detail.getName() + ".zip", StandardCharsets.UTF_8);
+ return ResponseEntity.ok()
+ .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename*=UTF-8''" + fileName)
+ .contentType(MediaType.APPLICATION_OCTET_STREAM)
+ .contentLength(body.length)
+ .body(new ByteArrayResource(body));
+ }
}
-
diff --git a/detection/src/main/java/com/njcn/gather/icd/mapper/PqIcdPathMapper.java b/detection/src/main/java/com/njcn/gather/icd/mapper/PqIcdPathMapper.java
index 9072150a..c1616ecd 100644
--- a/detection/src/main/java/com/njcn/gather/icd/mapper/PqIcdPathMapper.java
+++ b/detection/src/main/java/com/njcn/gather/icd/mapper/PqIcdPathMapper.java
@@ -1,9 +1,12 @@
package com.njcn.gather.icd.mapper;
import com.github.yulichang.base.MPJBaseMapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.njcn.gather.icd.pojo.po.PqIcdPath;
import org.apache.ibatis.annotations.Param;
+import java.util.List;
+
/**
* @author caozehui
* @date 2025-02-10
@@ -17,5 +20,19 @@ public interface PqIcdPathMapper extends MPJBaseMapper {
* @return
*/
PqIcdPath selectIcdByDevType(@Param("devTypeId") String devTypeId);
+
+ List selectPageList(Page page, @Param("name") String name);
+
+ List selectStandardList();
+
+ PqIcdPath selectStandardByName(@Param("name") String name);
+
+ List selectByIdsWithoutBlob(@Param("ids") List ids);
+
+ Long countActiveReferencesToStandards(@Param("standardIds") List standardIds);
+
+ PqIcdPath selectDetailById(@Param("id") String id);
+
+ PqIcdPath selectExportById(@Param("id") String id);
}
diff --git a/detection/src/main/java/com/njcn/gather/icd/mapper/mapping/PqIcdPathMapper.xml b/detection/src/main/java/com/njcn/gather/icd/mapper/mapping/PqIcdPathMapper.xml
index ec38e399..759c3a28 100644
--- a/detection/src/main/java/com/njcn/gather/icd/mapper/mapping/PqIcdPathMapper.xml
+++ b/detection/src/main/java/com/njcn/gather/icd/mapper/mapping/PqIcdPathMapper.xml
@@ -4,10 +4,115 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/detection/src/main/java/com/njcn/gather/icd/pojo/enums/IcdResponseEnum.java b/detection/src/main/java/com/njcn/gather/icd/pojo/enums/IcdResponseEnum.java
index 770e853c..ba7ead7a 100644
--- a/detection/src/main/java/com/njcn/gather/icd/pojo/enums/IcdResponseEnum.java
+++ b/detection/src/main/java/com/njcn/gather/icd/pojo/enums/IcdResponseEnum.java
@@ -1,16 +1,37 @@
package com.njcn.gather.icd.pojo.enums;
+import lombok.Getter;
+
/**
* @author caozehui
* @data 2025-11-11
*/
+@Getter
public enum IcdResponseEnum {
FILE_NOT_NULL("A018001", "映射文件不能为空"),
FILE_TYPE_ERROR("A018002", "映射文件类型错误"),
- FILE_SIZE_ERROR("A018003", "映射文件大小超出限制");
+ FILE_SIZE_ERROR("A018003", "映射文件大小超出限制"),
+ ICD_FILE_NOT_NULL("A018004", "ICD原始文件不能为空"),
+ ICD_FILE_TYPE_ERROR("A018005", "ICD原始文件类型错误"),
+ ICD_FILE_READ_ERROR("A018006", "ICD原始文件读取失败"),
+ JSON_FORMAT_ERROR("A018007", "JSON格式错误"),
+ XML_FORMAT_ERROR("A018008", "XML格式错误"),
+ STANDARD_ICD_IN_USE("A018009", "该标准ICD已被非标准ICD引用,禁止删除"),
+ ICD_FILE_NOT_FOUND("A018010", "ICD原始文件不存在"),
+ ICD_EXPORT_FAILED("A018011", "ICD导出失败"),
+ ICD_NOT_FOUND("A018012", "ICD不存在"),
+ RESULT_NOT_NULL("A018013", "结论不能为空"),
+ MSG_NOT_BLANK("A018014", "当结论为否时,描述不能为空"),
+ TYPE_NOT_NULL("A018015", "ICD类型不能为空"),
+ TYPE_VALUE_ERROR("A018016", "ICD类型取值错误"),
+ REFERENCE_ICD_NOT_BLANK("A018017", "非标准ICD必须选择参照标准ICD"),
+ REFERENCE_ICD_INVALID("A018018", "参照标准ICD无效"),
+ GENERATE_FILE("A018019", "文件生成失败"),
+ ICD_TXT_SYNC_FAILED("A018020", "ICD txt文件同步失败"),
+ REFERENCE_STANDARD_ICD_NAME_NOT_FOUND("A018021", "参照标准ICD名称不存在");
- private String code;
- private String message;
+ private final String code;
+ private final String message;
IcdResponseEnum(String code, String message) {
this.code = code;
diff --git a/detection/src/main/java/com/njcn/gather/icd/pojo/param/PqIcdPathParam.java b/detection/src/main/java/com/njcn/gather/icd/pojo/param/PqIcdPathParam.java
index ebcc884f..ef926b85 100644
--- a/detection/src/main/java/com/njcn/gather/icd/pojo/param/PqIcdPathParam.java
+++ b/detection/src/main/java/com/njcn/gather/icd/pojo/param/PqIcdPathParam.java
@@ -17,39 +17,63 @@ import javax.validation.constraints.Pattern;
*/
@Data
public class PqIcdPathParam {
- @ApiModelProperty(value = "名称", required = true)
- @NotBlank(message = DetectionValidMessage.NAME_NOT_BLANK)
- @Pattern(regexp = PatternRegex.ICD_NAME_REGEX, message = DetectionValidMessage.ICD_NAME_FORMAT_ERROR)
- private String name;
-
- @ApiModelProperty(value = "存储路径", required = true)
- @NotBlank(message = DetectionValidMessage.ICD_PATH_NOT_BLANK)
- @Pattern(regexp = PatternRegex.ICD_PATH_REGEX, message = DetectionValidMessage.ICD_PATH_FORMAT_ERROR)
- private String path;
-
- @ApiModelProperty(value = "是否支持电压相角、电流相角指标,0表示否,1表示是", required = true)
+ @ApiModelProperty(value = "angle", required = true)
private Integer angle;
- @ApiModelProperty(value = "角型接线时是否使用相别的指标来进行检测,0表示否,1表示是", required = true)
+ @ApiModelProperty(value = "usePhaseIndex", required = true)
private Integer usePhaseIndex;
- @ApiModelProperty(value = "映射文件", required = true)
- private MultipartFile mappingFile;
+ @ApiModelProperty(value = "jsonStr")
+ private String jsonStr;
+
+ @ApiModelProperty(value = "xmlStr")
+ private String xmlStr;
+
+ @ApiModelProperty(value = "result")
+ private Integer result;
+
+ @ApiModelProperty(value = "msg")
+ private String msg;
+
+ @ApiModelProperty(value = "type")
+ private Integer type;
+
+ @ApiModelProperty(value = "referenceIcdId")
+ private String referenceIcdId;
- /**
- * 分页查询实体
- */
@Data
@EqualsAndHashCode(callSuper = true)
public static class QueryParam extends BaseParam {
- @ApiModelProperty(value = "名称", required = true)
+ @ApiModelProperty(value = "name", required = true)
private String name;
}
+ @Data
+ @EqualsAndHashCode(callSuper = true)
+ public static class CreateParam extends PqIcdPathParam {
+ @ApiModelProperty(value = "icdFile", required = true)
+ private MultipartFile icdFile;
+ }
+
+ @Data
+ @EqualsAndHashCode(callSuper = true)
+ public static class ExternalCreateParam extends PqIcdPathParam {
+ @ApiModelProperty(value = "id", required = true)
+ @NotBlank(message = DetectionValidMessage.ID_NOT_BLANK)
+ @Pattern(regexp = PatternRegex.SYSTEM_ID, message = DetectionValidMessage.ID_FORMAT_ERROR)
+ private String id;
+
+ @ApiModelProperty(value = "name", required = true)
+ @NotBlank(message = DetectionValidMessage.NAME_NOT_BLANK)
+ @Pattern(regexp = PatternRegex.SCRIPT_NAME_REGEX, message = DetectionValidMessage.ICD_NAME_FORMAT_ERROR)
+ private String name;
+
+ @ApiModelProperty(value = "icdFile", required = true)
+ @NotBlank(message = IcdExternalValidMessage.ICD_FILE_NOT_BLANK)
+ private String icdFile;
+
+ }
- /**
- * 更新参数
- */
@Data
@EqualsAndHashCode(callSuper = true)
public static class UpdateParam extends PqIcdPathParam {
@@ -57,5 +81,12 @@ public class PqIcdPathParam {
@NotBlank(message = DetectionValidMessage.ID_NOT_BLANK)
@Pattern(regexp = PatternRegex.SYSTEM_ID, message = DetectionValidMessage.ID_FORMAT_ERROR)
private String id;
+
+ @ApiModelProperty(value = "icdFile")
+ private MultipartFile icdFile;
+ }
+
+ private interface IcdExternalValidMessage {
+ String ICD_FILE_NOT_BLANK = "ICD原始文件不能为空";
}
}
diff --git a/detection/src/main/java/com/njcn/gather/icd/pojo/po/PqIcdPath.java b/detection/src/main/java/com/njcn/gather/icd/pojo/po/PqIcdPath.java
index b59c962d..1e10c615 100644
--- a/detection/src/main/java/com/njcn/gather/icd/pojo/po/PqIcdPath.java
+++ b/detection/src/main/java/com/njcn/gather/icd/pojo/po/PqIcdPath.java
@@ -28,11 +28,6 @@ public class PqIcdPath extends BaseEntity implements Serializable {
*/
private String name;
- /**
- * icd存储地址
- */
- private String path;
-
/**
* 状态:0-删除 1-正常
*/
@@ -46,19 +41,55 @@ public class PqIcdPath extends BaseEntity implements Serializable {
/**
* 角型接线时是否使用相别的指标来进行检测,0表示否,1表示是
*/
+ @TableField("use_phase_index")
private Integer usePhaseIndex;
/**
- * 映射文件路径
+ * 解析后的json字符串
*/
+ @TableField("Json_Str")
+ private String jsonStr;
+
+ /**
+ * 解析后的xml字符串
+ */
+ @TableField("Xml_Str")
+ private String xmlStr;
+
+ /**
+ * ICD原始文件二进制
+ */
+ @TableField("Icd")
+ private byte[] icd;
+
+ /**
+ * 结论
+ */
+ @TableField("Result")
+ private Integer result;
+
+ /**
+ * 结论描述
+ */
+ @TableField("Msg")
+ private String msg;
+
+ /**
+ * ICD类型
+ */
+ @TableField("Type")
+ private Integer type;
+
+ /**
+ * 参照标准ICD
+ */
+ @TableField("Reference_Icd_Id")
+ private String referenceIcdId;
+
@TableField(exist = false)
- private FileVO mappingFile;
+ private String referenceIcdName;
- @Data
- public static class FileVO{
- private String name;
-
- private String url;
- }
+ @TableField(exist = false)
+ private Boolean hasIcdFile;
}
diff --git a/detection/src/main/java/com/njcn/gather/icd/service/IPqIcdPathService.java b/detection/src/main/java/com/njcn/gather/icd/service/IPqIcdPathService.java
index e0272b98..e5f4d5f8 100644
--- a/detection/src/main/java/com/njcn/gather/icd/service/IPqIcdPathService.java
+++ b/detection/src/main/java/com/njcn/gather/icd/service/IPqIcdPathService.java
@@ -28,13 +28,22 @@ public interface IPqIcdPathService extends IService {
*/
Page listIcd(PqIcdPathParam.QueryParam param);
+ /**
+ * 获取所有标准ICD
+ *
+ * @return 标准ICD列表
+ */
+ List listStandardIcd();
+
/**
* 新增Icd
*
* @param param 新增Icd参数
* @return 成功返回true,失败返回false
*/
- boolean addIcd(PqIcdPathParam param);
+ boolean addIcd(PqIcdPathParam.CreateParam param);
+
+ boolean addUpstreamIcd(List param);
/**
* 修改Icd
@@ -52,6 +61,22 @@ public interface IPqIcdPathService extends IService {
*/
boolean deleteIcd(List ids);
+ /**
+ * 根据id获取ICD详情
+ *
+ * @param id ICD id
+ * @return ICD详情
+ */
+ PqIcdPath getIcdById(String id);
+
+ /**
+ * 导出ICD压缩包
+ *
+ * @param id ICD id
+ * @return zip字节数组
+ */
+ byte[] exportIcd(String id);
+
/**
* 根据设备类型id获取Icd
*
diff --git a/detection/src/main/java/com/njcn/gather/icd/service/impl/PqIcdPathServiceImpl.java b/detection/src/main/java/com/njcn/gather/icd/service/impl/PqIcdPathServiceImpl.java
index b66fb5f4..1b6fc628 100644
--- a/detection/src/main/java/com/njcn/gather/icd/service/impl/PqIcdPathServiceImpl.java
+++ b/detection/src/main/java/com/njcn/gather/icd/service/impl/PqIcdPathServiceImpl.java
@@ -1,5 +1,6 @@
package com.njcn.gather.icd.service.impl;
+import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
@@ -12,23 +13,26 @@ import com.njcn.gather.icd.pojo.enums.IcdResponseEnum;
import com.njcn.gather.icd.pojo.param.PqIcdPathParam;
import com.njcn.gather.icd.pojo.po.PqIcdPath;
import com.njcn.gather.icd.service.IPqIcdPathService;
+import com.njcn.gather.icd.service.support.IcdArchiveBuilder;
+import com.njcn.gather.icd.service.support.IcdPayloadAssembler;
import com.njcn.gather.pojo.enums.DetectionResponseEnum;
-import com.njcn.gather.report.pojo.enums.ReportResponseEnum;
import com.njcn.web.factory.PageFactory;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
-import org.springframework.web.multipart.MultipartFile;
-import java.io.BufferedOutputStream;
-import java.io.File;
-import java.io.FileOutputStream;
import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
+import java.nio.file.StandardOpenOption;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
/**
* @author caozehui
@@ -38,174 +42,147 @@ import java.util.List;
@Service
@RequiredArgsConstructor
public class PqIcdPathServiceImpl extends ServiceImpl implements IPqIcdPathService {
+ // 手动录入标准ICD
+ private static final int TYPE_STANDARD = 1;
+ // 手动录入非标准ICD
+ private static final int TYPE_NON_STANDARD = 2;
+ // 上游录入的标准ICD
+ private static final int TYPE_UPSTREAM_STANDARD = 3;
+
+ // 上游录入的非标准ICD
+ private static final int TYPE_UPSTREAM_NON_STANDARD = 4;
+ private static final int RESULT_NO = 0;
+ private static final int RESULT_YES = 1;
+
+ @Value("${icd.txt-dir}")
+ private String icdTxtDir;
+
+ private final IcdPayloadAssembler icdPayloadAssembler;
+ private final IcdArchiveBuilder icdArchiveBuilder;
@Override
public List listAll() {
- return this.lambdaQuery().eq(PqIcdPath::getState, DataStateEnum.ENABLE.getCode()).list();
+ return this.lambdaQuery()
+ .select(PqIcdPath::getId, PqIcdPath::getName, PqIcdPath::getType, PqIcdPath::getReferenceIcdId)
+ .eq(PqIcdPath::getState, DataStateEnum.ENABLE.getCode())
+ .orderByDesc(PqIcdPath::getCreateTime)
+ .list();
+ }
+
+ @Override
+ public List listStandardIcd() {
+ return this.baseMapper.selectStandardList();
}
@Override
public Page listIcd(PqIcdPathParam.QueryParam param) {
- LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
- wrapper.eq(PqIcdPath::getState, DataStateEnum.ENABLE.getCode())
- .like(StrUtil.isNotBlank(param.getName()), PqIcdPath::getName, param.getName())
- .orderByDesc(PqIcdPath::getCreateTime);
- Page page = this.page(new Page<>(PageFactory.getPageNum(param), PageFactory.getPageSize(param)), wrapper);
- String commInstallPath = this.getCommInstallPath();
- page.getRecords().forEach(pqIcdPath -> {
- PqIcdPath.FileVO fileVO = new PqIcdPath.FileVO();
- fileVO.setUrl(commInstallPath + "\\DeviceControl\\Config\\" + pqIcdPath.getName() + ".txt");
- fileVO.setName(pqIcdPath.getName() + ".txt");
- pqIcdPath.setMappingFile(fileVO);
- });
+ Page page = new Page<>(PageFactory.getPageNum(param), PageFactory.getPageSize(param));
+ page.setRecords(this.baseMapper.selectPageList(page, StrUtil.trim(param.getName())));
return page;
}
@Override
@Transactional
- public boolean addIcd(PqIcdPathParam param) {
- param.setName(param.getName().trim());
- this.checkRepeat(param, false);
- PqIcdPath pqIcdPath = new PqIcdPath();
- BeanUtils.copyProperties(param, pqIcdPath);
- pqIcdPath.setState(DataStateEnum.ENABLE.getCode());
-
- String commInstallPath = this.getCommInstallPath();
- System.out.println("commInstallPath = " + commInstallPath);
- long FILE_SIZE_LIMIT = 1 * 1024 * 1024;
- MultipartFile mappingFile = param.getMappingFile();
-
- System.out.println("mappingFile = " + ObjectUtil.isNotNull(mappingFile) + " " + !mappingFile.isEmpty());
- if (ObjectUtil.isNotNull(mappingFile) && !mappingFile.isEmpty()) {
- String mappingFilename = mappingFile.getOriginalFilename();
-
- if (!mappingFilename.endsWith(".txt")) {
- throw new BusinessException(IcdResponseEnum.FILE_TYPE_ERROR);
- }
- if (mappingFile.getSize() > FILE_SIZE_LIMIT) {
- throw new BusinessException(IcdResponseEnum.FILE_SIZE_ERROR);
- }
-
- try {
- // 如果文件存在,则先删除
- String mappingFilePath = commInstallPath + "\\DeviceControl\\Config\\" + mappingFilename;
- System.out.println("mappingFilePath = " + mappingFilePath);
- Path path = Paths.get(mappingFilePath);
- File file = path.toFile();
- if (file.exists()) {
- file.delete();
- }
-
- // 保存文件
- byte[] bytes = mappingFile.getBytes();
- BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(mappingFilePath));
- bufferedOutputStream.write(bytes);
- bufferedOutputStream.flush();
-
- bufferedOutputStream.close();
- System.out.println("File saved successfully");
- } catch (IOException e) {
- throw new BusinessException(ReportResponseEnum.FILE_UPLOAD_FAILED);
- }
- } else {
- System.out.println("mappingFile is null or empty");
- throw new BusinessException(IcdResponseEnum.FILE_NOT_NULL);
+ public boolean addIcd(PqIcdPathParam.CreateParam param) {
+ validateBusinessFields(param, null);
+ PqIcdPath pqIcdPath = icdPayloadAssembler.fromCreate(param);
+ validateReferenceIcd(pqIcdPath.getType(), pqIcdPath.getReferenceIcdId(), null);
+ boolean saved = this.save(pqIcdPath);
+ if (saved) {
+ writeIcdTextFile(resolveIcdTxtDir(), pqIcdPath.getName(), pqIcdPath.getJsonStr());
}
-
- //this.executeRestartCmd(commInstallPath);
-
- return this.save(pqIcdPath);
+ return saved;
}
-// /**
-// * 执行重启通讯服务脚本
-// *
-// * @param commInstallPath
-// */
-// private void executeRestartCmd(String commInstallPath) {
-// // 以管理员身份运行bat脚本
-// String batFilePath = commInstallPath + "\\重启所有服务.bat";
-// try {
-// Runtime.getRuntime().exec(batFilePath);
-// } catch (IOException e) {
-// log.error("重启通讯服务失败", e);
-// }
-// }
-
- private String getCommInstallPath() {
- String workDir = System.getProperty("user.dir");
-// String workDir = "D:\\program\\CN_Gather";
- // 获取映射文件存放文件夹
- String dirPath = workDir + "\\9100";
- int index = workDir.indexOf("\\resources\\extraResources\\java");
- if (index != -1) {
- dirPath = workDir.substring(0, workDir.indexOf("\\resources\\extraResources\\java")) + "\\9100";
+ @Override
+ @Transactional
+ public boolean addUpstreamIcd(List param) {
+ if (CollUtil.isEmpty(param)) {
+ return true;
}
- return dirPath;
+ Set requestStandardIds = collectRequestStandardIds(param);
+ boolean allSaved = true;
+ Path directory = resolveIcdTxtDir();
+ for (PqIcdPathParam.ExternalCreateParam item : param) {
+ validateBusinessFields(item, null);
+ PqIcdPath current = this.baseMapper.selectById(item.getId());
+ PqIcdPath pqIcdPath = icdPayloadAssembler.fromExternalCreate(item, item.getType(), item.getAngle(), item.getUsePhaseIndex());
+ String currentId = current == null ? null : current.getId();
+ String oldName = current == null ? null : current.getName();
+ validateExternalReferenceIcd(pqIcdPath.getType(), pqIcdPath.getReferenceIcdId(), currentId, requestStandardIds);
+ boolean saved = current == null ? this.save(pqIcdPath) : this.updateById(pqIcdPath);
+ if (!saved) {
+ allSaved = false;
+ break;
+ }
+ if (current == null) {
+ writeIcdTextFile(directory, pqIcdPath.getName(), pqIcdPath.getJsonStr());
+ } else {
+ syncUpdatedIcdTextFile(directory, oldName, pqIcdPath.getName(), pqIcdPath.getJsonStr());
+ }
+ }
+ return allSaved;
}
@Override
@Transactional
public boolean updateIcd(PqIcdPathParam.UpdateParam param) {
- param.setName(param.getName().trim());
- this.checkRepeat(param, true);
- PqIcdPath pqIcdPath = new PqIcdPath();
- BeanUtils.copyProperties(param, pqIcdPath);
-
- String commInstallPath = this.getCommInstallPath();
- long FILE_SIZE_LIMIT = 1 * 1024 * 1024;
- MultipartFile mappingFile = param.getMappingFile();
- if (ObjectUtil.isNotNull(mappingFile) && !mappingFile.isEmpty()) {
- String mappingFilename = mappingFile.getOriginalFilename();
-
- if (!mappingFilename.endsWith(".txt")) {
- throw new BusinessException(IcdResponseEnum.FILE_TYPE_ERROR);
- }
- if (mappingFile.getSize() > FILE_SIZE_LIMIT) {
- throw new BusinessException(IcdResponseEnum.FILE_SIZE_ERROR);
- }
-
- try {
- // 如果文件存在,则先删除
- String mappingFilePath = commInstallPath + "\\DeviceControl\\Config\\" + mappingFilename;
- Path path = Paths.get(mappingFilePath);
- File file = path.toFile();
- if (file.exists()) {
- file.delete();
- }
-
- // 保存文件
- byte[] bytes = mappingFile.getBytes();
- BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(mappingFilePath));
- bufferedOutputStream.write(bytes);
- bufferedOutputStream.flush();
-
- bufferedOutputStream.close();
- } catch (IOException e) {
- throw new BusinessException(ReportResponseEnum.FILE_UPLOAD_FAILED);
- }
+ PqIcdPath current = getActiveEntity(param.getId());
+ String oldName = current.getName();
+ validateBusinessFields(param, current.getId());
+ PqIcdPath pqIcdPath = icdPayloadAssembler.merge(current, param);
+ validateReferenceIcd(pqIcdPath.getType(), pqIcdPath.getReferenceIcdId(), current.getId());
+ boolean updated = this.updateById(pqIcdPath);
+ if (updated) {
+ syncUpdatedIcdTextFile(resolveIcdTxtDir(), oldName, pqIcdPath.getName(), pqIcdPath.getJsonStr());
}
-
- //this.executeRestartCmd(commInstallPath);
-
- return this.updateById(pqIcdPath);
+ return updated;
}
@Override
@Transactional
public boolean deleteIcd(List ids) {
- List pqIcdPaths = this.listByIds(ids);
- String commInstallPath = this.getCommInstallPath();
- pqIcdPaths.forEach(pqIcdPath -> {
- String mappingFilePath = commInstallPath + "\\DeviceControl\\Config\\" + pqIcdPath.getName() + ".txt";
- Path path = Paths.get(mappingFilePath);
- File file = path.toFile();
- if (file.exists()) {
- file.delete();
+ if (CollUtil.isEmpty(ids)) {
+ return true;
+ }
+ List pqIcdPaths = this.baseMapper.selectByIdsWithoutBlob(ids);
+ List standardIds = pqIcdPaths.stream()
+ .filter(pqIcdPath -> ObjectUtil.equals(pqIcdPath.getType(), TYPE_STANDARD))
+ .map(PqIcdPath::getId)
+ .collect(Collectors.toList());
+ if (!standardIds.isEmpty()) {
+ Long count = this.baseMapper.countActiveReferencesToStandards(standardIds);
+ if (ObjectUtil.isNotNull(count) && count > 0) {
+ throw new BusinessException(IcdResponseEnum.STANDARD_ICD_IN_USE);
}
- });
+ }
- return this.lambdaUpdate().in(PqIcdPath::getId, ids).set(PqIcdPath::getState, DataStateEnum.DELETED.getCode()).update();
+ boolean deleted = this.lambdaUpdate().in(PqIcdPath::getId, ids).set(PqIcdPath::getState, DataStateEnum.DELETED.getCode()).update();
+ if (deleted) {
+ Path directory = resolveIcdTxtDir();
+ for (PqIcdPath pqIcdPath : pqIcdPaths) {
+ deleteIcdTextFile(directory, pqIcdPath.getName());
+ }
+ }
+ return deleted;
+ }
+
+ @Override
+ public PqIcdPath getIcdById(String id) {
+ PqIcdPath detail = this.baseMapper.selectDetailById(id);
+ if (ObjectUtil.isNull(detail)) {
+ throw new BusinessException(IcdResponseEnum.ICD_NOT_FOUND);
+ }
+ return detail;
+ }
+
+ @Override
+ public byte[] exportIcd(String id) {
+ PqIcdPath detail = this.baseMapper.selectExportById(id);
+ if (ObjectUtil.isNull(detail)) {
+ throw new BusinessException(IcdResponseEnum.ICD_NOT_FOUND);
+ }
+ return icdArchiveBuilder.build(detail);
}
@Override
@@ -213,18 +190,125 @@ public class PqIcdPathServiceImpl extends ServiceImpl wrapper = new LambdaQueryWrapper<>();
- wrapper.eq(PqIcdPath::getName, param.getName())
- .eq(PqIcdPath::getState, DataStateEnum.ENABLE.getCode());
- if (isExcludeSelf) {
- if (param instanceof PqIcdPathParam.UpdateParam) {
- wrapper.ne(PqIcdPath::getId, ((PqIcdPathParam.UpdateParam) param).getId());
- }
+ private void validateBusinessFields(PqIcdPathParam param, String currentId) {
+ if (ObjectUtil.isNull(param.getResult())) {
+ throw new BusinessException(IcdResponseEnum.RESULT_NOT_NULL);
}
- int count = this.count(wrapper);
- if (count > 0) {
- throw new BusinessException(DetectionResponseEnum.ICD_PATH_NAME_REPEAT);
+ if (ObjectUtil.equals(param.getResult(), RESULT_NO) && StrUtil.isBlank(param.getMsg())) {
+ throw new BusinessException(IcdResponseEnum.MSG_NOT_BLANK);
+ }
+ if (ObjectUtil.isNull(param.getType())) {
+ throw new BusinessException(IcdResponseEnum.TYPE_NOT_NULL);
+ }
+ if (!ObjectUtil.equals(param.getType(), TYPE_STANDARD)
+ && !ObjectUtil.equals(param.getType(), TYPE_NON_STANDARD)
+ && !ObjectUtil.equals(param.getType(), TYPE_UPSTREAM_STANDARD)
+ && !ObjectUtil.equals(param.getType(), TYPE_UPSTREAM_NON_STANDARD)) {
+ throw new BusinessException(IcdResponseEnum.TYPE_VALUE_ERROR);
+ }
+ if (requiresReferenceIcd(param.getType()) && StrUtil.isBlank(param.getReferenceIcdId())) {
+ throw new BusinessException(IcdResponseEnum.REFERENCE_ICD_NOT_BLANK);
+ }
+ if (StrUtil.isNotBlank(currentId) && StrUtil.equals(currentId, StrUtil.trim(param.getReferenceIcdId()))) {
+ throw new BusinessException(IcdResponseEnum.REFERENCE_ICD_INVALID);
}
}
+
+ private void validateReferenceIcd(Integer type, String referenceIcdId, String currentId) {
+ if (!requiresReferenceIcd(type)) {
+ return;
+ }
+ if (StrUtil.isNotBlank(currentId) && StrUtil.equals(currentId, referenceIcdId)) {
+ throw new BusinessException(IcdResponseEnum.REFERENCE_ICD_INVALID);
+ }
+ long count = this.lambdaQuery()
+ .eq(PqIcdPath::getId, referenceIcdId)
+ .in(PqIcdPath::getType, TYPE_STANDARD, TYPE_UPSTREAM_STANDARD)
+ .eq(PqIcdPath::getState, DataStateEnum.ENABLE.getCode())
+ .count();
+ if (count <= 0L) {
+ throw new BusinessException(IcdResponseEnum.REFERENCE_ICD_INVALID);
+ }
+ }
+
+ private void validateExternalReferenceIcd(Integer type, String referenceIcdId, String currentId, Set requestStandardIds) {
+ if (!requiresReferenceIcd(type)) {
+ return;
+ }
+ String trimmedReferenceId = StrUtil.trim(referenceIcdId);
+ if (StrUtil.isNotBlank(currentId) && StrUtil.equals(currentId, trimmedReferenceId)) {
+ throw new BusinessException(IcdResponseEnum.REFERENCE_ICD_INVALID);
+ }
+ if (StrUtil.isNotBlank(trimmedReferenceId) && requestStandardIds.contains(trimmedReferenceId)) {
+ return;
+ }
+ validateReferenceIcd(type, trimmedReferenceId, currentId);
+ }
+
+ private Set collectRequestStandardIds(List params) {
+ Set ids = new HashSet<>();
+ for (PqIcdPathParam.ExternalCreateParam param : params) {
+ if (isStandardType(param.getType()) && StrUtil.isNotBlank(param.getId())) {
+ ids.add(StrUtil.trim(param.getId()));
+ }
+ }
+ return ids;
+ }
+
+ private boolean requiresReferenceIcd(Integer type) {
+ return ObjectUtil.equals(type, TYPE_NON_STANDARD) || ObjectUtil.equals(type, TYPE_UPSTREAM_NON_STANDARD);
+ }
+
+ private boolean isStandardType(Integer type) {
+ return ObjectUtil.equals(type, TYPE_STANDARD) || ObjectUtil.equals(type, TYPE_UPSTREAM_STANDARD);
+ }
+
+ private PqIcdPath getActiveEntity(String id) {
+ PqIcdPath current = this.lambdaQuery()
+ .eq(PqIcdPath::getId, id)
+ .eq(PqIcdPath::getState, DataStateEnum.ENABLE.getCode())
+ .one();
+ if (ObjectUtil.isNull(current)) {
+ throw new BusinessException(IcdResponseEnum.ICD_NOT_FOUND);
+ }
+ return current;
+ }
+
+ Path resolveIcdTxtDir() {
+ if (StrUtil.isBlank(icdTxtDir)) {
+ throw new BusinessException(IcdResponseEnum.ICD_TXT_SYNC_FAILED);
+ }
+ return Paths.get(icdTxtDir.trim());
+ }
+
+ void writeIcdTextFile(Path directory, String name, String jsonStr) {
+ try {
+ Files.createDirectories(directory);
+ Files.write(resolveTxtFile(directory, name), StrUtil.nullToDefault(jsonStr, "").getBytes(StandardCharsets.UTF_8),
+ StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.WRITE);
+ } catch (IOException ex) {
+ log.error("sync icd txt file failed, name={}", name, ex);
+ throw new BusinessException(IcdResponseEnum.ICD_TXT_SYNC_FAILED);
+ }
+ }
+
+ void syncUpdatedIcdTextFile(Path directory, String oldName, String newName, String jsonStr) {
+ if (StrUtil.isNotBlank(oldName) && !StrUtil.equals(oldName, newName)) {
+ deleteIcdTextFile(directory, oldName);
+ }
+ writeIcdTextFile(directory, newName, jsonStr);
+ }
+
+ void deleteIcdTextFile(Path directory, String name) {
+ try {
+ Files.deleteIfExists(resolveTxtFile(directory, name));
+ } catch (IOException ex) {
+ log.error("delete icd txt file failed, name={}", name, ex);
+ throw new BusinessException(IcdResponseEnum.ICD_TXT_SYNC_FAILED);
+ }
+ }
+
+ private Path resolveTxtFile(Path directory, String name) {
+ return directory.resolve(name + ".txt");
+ }
}
diff --git a/detection/src/main/java/com/njcn/gather/icd/service/support/IcdArchiveBuilder.java b/detection/src/main/java/com/njcn/gather/icd/service/support/IcdArchiveBuilder.java
new file mode 100644
index 00000000..ee856f63
--- /dev/null
+++ b/detection/src/main/java/com/njcn/gather/icd/service/support/IcdArchiveBuilder.java
@@ -0,0 +1,62 @@
+package com.njcn.gather.icd.service.support;
+
+import com.njcn.common.pojo.exception.BusinessException;
+import com.njcn.gather.icd.pojo.enums.IcdResponseEnum;
+import com.njcn.gather.icd.pojo.po.PqIcdPath;
+import org.springframework.stereotype.Component;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+
+@Component
+public class IcdArchiveBuilder {
+
+ public byte[] build(PqIcdPath item) {
+ if (item == null || item.getIcd() == null || item.getIcd().length == 0) {
+ throw new BusinessException(IcdResponseEnum.ICD_FILE_NOT_FOUND);
+ }
+ try (ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ ZipOutputStream zos = new ZipOutputStream(bos, StandardCharsets.UTF_8)) {
+ writeTextEntry(zos, item.getName() + ".json", item.getJsonStr());
+ writeTextEntry(zos, item.getName() + ".xml", item.getXmlStr());
+ writeBinaryEntry(zos, item.getName() + ".icd", item.getIcd());
+ zos.finish();
+ return bos.toByteArray();
+ } catch (IOException ex) {
+ throw new BusinessException(IcdResponseEnum.ICD_EXPORT_FAILED);
+ }
+ }
+
+ /**
+ * 向ZIP流中写入文本条目
+ *
+ * @param zos ZIP输出流
+ * @param name 条目名称(文件路径)
+ * @param value 文本内容,如果为null则写入空字节数组
+ * @throws IOException 写入异常
+ */
+ private void writeTextEntry(ZipOutputStream zos, String name, String value) throws IOException {
+ // 将文本转换为UTF-8编码的字节数组,null值转换为空数组
+ writeBinaryEntry(zos, name, value == null ? new byte[0] : value.getBytes(StandardCharsets.UTF_8));
+ }
+
+ /**
+ * 向ZIP流中写入二进制条目
+ *
+ * @param zos ZIP输出流
+ * @param name 条目名称(文件路径)
+ * @param data 二进制数据
+ * @throws IOException 写入异常
+ */
+ private void writeBinaryEntry(ZipOutputStream zos, String name, byte[] data) throws IOException {
+ // 创建新的ZIP条目并设置文件名
+ zos.putNextEntry(new ZipEntry(name));
+ // 写入二进制数据
+ zos.write(data);
+ // 关闭当前条目,准备写入下一个条目
+ zos.closeEntry();
+ }
+}
diff --git a/detection/src/main/java/com/njcn/gather/icd/service/support/IcdPayloadAssembler.java b/detection/src/main/java/com/njcn/gather/icd/service/support/IcdPayloadAssembler.java
new file mode 100644
index 00000000..2618353d
--- /dev/null
+++ b/detection/src/main/java/com/njcn/gather/icd/service/support/IcdPayloadAssembler.java
@@ -0,0 +1,90 @@
+package com.njcn.gather.icd.service.support;
+
+import cn.hutool.core.util.StrUtil;
+import com.njcn.common.pojo.enums.common.DataStateEnum;
+import com.njcn.common.pojo.exception.BusinessException;
+import com.njcn.gather.icd.pojo.enums.IcdResponseEnum;
+import com.njcn.gather.icd.pojo.param.PqIcdPathParam;
+import com.njcn.gather.icd.pojo.po.PqIcdPath;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Component;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.IOException;
+
+@Component
+@RequiredArgsConstructor
+public class IcdPayloadAssembler {
+
+ private final IcdPayloadValidator validator;
+
+ public PqIcdPath fromCreate(PqIcdPathParam.CreateParam param) {
+ MultipartFile file = validator.validateIcdFile(param.getIcdFile(), true);
+ validator.validateJson(param.getJsonStr());
+ validator.validateXml(param.getXmlStr());
+
+ PqIcdPath entity = new PqIcdPath();
+ applyCommonFields(entity, param);
+ entity.setName(validator.extractName(file.getOriginalFilename()));
+ entity.setIcd(getBytes(file));
+ entity.setState(DataStateEnum.ENABLE.getCode());
+ return entity;
+ }
+
+ public PqIcdPath fromExternalCreate(PqIcdPathParam.ExternalCreateParam param, int type, int angle, int usePhaseIndex) {
+ byte[] fileBytes = validator.decodeExternalIcdFile(param.getIcdFile());
+ validator.validateJson(param.getJsonStr());
+ validator.validateXml(param.getXmlStr());
+
+ PqIcdPath entity = new PqIcdPath();
+ entity.setId(normalizeNullableText(param.getId()));
+ param.setType(type);
+ param.setAngle(angle);
+ param.setUsePhaseIndex(usePhaseIndex);
+ applyCommonFields(entity, param);
+ entity.setName(normalizeNullableText(param.getName()));
+ entity.setIcd(fileBytes);
+ entity.setState(DataStateEnum.ENABLE.getCode());
+ return entity;
+ }
+
+ public PqIcdPath merge(PqIcdPath current, PqIcdPathParam.UpdateParam param) {
+ MultipartFile file = validator.validateIcdFile(param.getIcdFile(), false);
+ validator.validateJson(param.getJsonStr());
+ validator.validateXml(param.getXmlStr());
+
+ applyCommonFields(current, param);
+ if (file != null && !file.isEmpty()) {
+ current.setName(validator.extractName(file.getOriginalFilename()));
+ current.setIcd(getBytes(file));
+ }
+ return current;
+ }
+
+ private void applyCommonFields(PqIcdPath entity, PqIcdPathParam param) {
+ entity.setAngle(param.getAngle());
+ entity.setUsePhaseIndex(param.getUsePhaseIndex());
+ entity.setJsonStr(param.getJsonStr());
+ entity.setXmlStr(param.getXmlStr());
+ entity.setResult(param.getResult());
+ entity.setMsg(param.getResult() != null && param.getResult() == 1 ? null : normalizeNullableText(param.getMsg()));
+ entity.setType(param.getType());
+ entity.setReferenceIcdId(requiresReferenceIcd(param.getType()) ? normalizeNullableText(param.getReferenceIcdId()) : null);
+ }
+
+ private String normalizeNullableText(String value) {
+ return StrUtil.emptyToNull(StrUtil.trim(value));
+ }
+
+ private boolean requiresReferenceIcd(Integer type) {
+ return type != null && (type == 2 || type == 4);
+ }
+
+ private byte[] getBytes(MultipartFile file) {
+ try {
+ return file.getBytes();
+ } catch (IOException ex) {
+ throw new BusinessException(IcdResponseEnum.ICD_FILE_READ_ERROR);
+ }
+ }
+}
diff --git a/detection/src/main/java/com/njcn/gather/icd/service/support/IcdPayloadValidator.java b/detection/src/main/java/com/njcn/gather/icd/service/support/IcdPayloadValidator.java
new file mode 100644
index 00000000..90e06f69
--- /dev/null
+++ b/detection/src/main/java/com/njcn/gather/icd/service/support/IcdPayloadValidator.java
@@ -0,0 +1,66 @@
+package com.njcn.gather.icd.service.support;
+
+import com.alibaba.fastjson.JSON;
+import com.njcn.common.pojo.exception.BusinessException;
+import com.njcn.gather.icd.pojo.enums.IcdResponseEnum;
+import org.springframework.stereotype.Component;
+import org.springframework.web.multipart.MultipartFile;
+import org.xml.sax.InputSource;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+import java.io.StringReader;
+import java.util.Base64;
+import java.util.Locale;
+
+@Component
+public class IcdPayloadValidator {
+
+ public MultipartFile validateIcdFile(MultipartFile file, boolean required) {
+ if ((file == null || file.isEmpty()) && required) {
+ throw new BusinessException(IcdResponseEnum.ICD_FILE_NOT_NULL);
+ }
+ if (file == null || file.isEmpty()) {
+ return null;
+ }
+ String originalName = file.getOriginalFilename();
+ if (originalName == null || !originalName.toLowerCase(Locale.ROOT).endsWith(".icd")) {
+ throw new BusinessException(IcdResponseEnum.ICD_FILE_TYPE_ERROR);
+ }
+ return file;
+ }
+
+ public String extractName(String originalName) {
+ int suffixIndex = originalName.toLowerCase(Locale.ROOT).lastIndexOf(".icd");
+ return suffixIndex >= 0 ? originalName.substring(0, suffixIndex) : originalName;
+ }
+
+ public byte[] decodeExternalIcdFile(String base64Content) {
+ if (base64Content == null || base64Content.trim().isEmpty()) {
+ throw new BusinessException(IcdResponseEnum.ICD_FILE_NOT_NULL);
+ }
+ try {
+ return Base64.getDecoder().decode(base64Content.trim());
+ } catch (IllegalArgumentException ex) {
+ throw new BusinessException(IcdResponseEnum.ICD_FILE_READ_ERROR);
+ }
+ }
+
+ public void validateJson(String jsonStr) {
+ try {
+ JSON.parse(jsonStr);
+ } catch (Exception ex) {
+ throw new BusinessException(IcdResponseEnum.JSON_FORMAT_ERROR);
+ }
+ }
+
+ public void validateXml(String xmlStr) {
+ try {
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ // 禁用 DOCTYPE 声明
+ factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
+ factory.newDocumentBuilder().parse(new InputSource(new StringReader(xmlStr)));
+ } catch (Exception ex) {
+ throw new BusinessException(IcdResponseEnum.XML_FORMAT_ERROR);
+ }
+ }
+}
diff --git a/entrance/src/main/resources/application.yml b/entrance/src/main/resources/application.yml
index d826bb7b..7e5208f9 100644
--- a/entrance/src/main/resources/application.yml
+++ b/entrance/src/main/resources/application.yml
@@ -109,6 +109,9 @@ qr:
db:
type: mysql
+icd:
+ txt-dir: D:\icd-txt
+
# 比对录波需要的配置,晚点再做优化
# 系统配置