修改送检导入模板

master
杨海航 2 weeks ago
parent 59fc40af97
commit d0bbd4b023
  1. 120
      src/main/java/digital/laboratory/platform/entrustment/service/impl/ExcelOperationServiceImpl.java
  2. 1
      src/main/resources/bootstrap.yml

@ -1,6 +1,7 @@
package digital.laboratory.platform.entrustment.service.impl; package digital.laboratory.platform.entrustment.service.impl;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.IdcardUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.IdWorker; import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
@ -43,6 +44,7 @@ import java.time.temporal.ChronoUnit;
import java.util.*; import java.util.*;
import java.util.function.Function; import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream;
/** /**
* @author ChenJiangBao * @author ChenJiangBao
@ -333,6 +335,7 @@ public class ExcelOperationServiceImpl implements ExcelOperationService {
/** /**
* 获取毒品清单信息并转成map * 获取毒品清单信息并转成map
*
* @return * @return
*/ */
private Map<String, DrugLite> getDrugLiteMap() { private Map<String, DrugLite> getDrugLiteMap() {
@ -423,34 +426,92 @@ public class ExcelOperationServiceImpl implements ExcelOperationService {
CaseEvent cj) { CaseEvent cj) {
List<EntrustmentIdentificationMaterial> entrustmentIdentificationMaterialList = new ArrayList<>(); List<EntrustmentIdentificationMaterial> entrustmentIdentificationMaterialList = new ArrayList<>();
List<String> errorMessages = new ArrayList<>(); // 用于收集错误信息 List<String> errorMessages = new ArrayList<>();
// 预定义合法的单位集合
Set<String> validUnits = Stream.of("g", "mg", "l", "ml").collect(Collectors.toSet());
// 预定义需要校验身份证的鉴定类别
Set<String> idCardRequiredResults = Stream.of("首次鉴定", "补充鉴定", "重新鉴定").collect(Collectors.toSet());
ArrayList<Suspect> suspects = new ArrayList<>();
for (int i = 0; i < data.size(); i++) { for (int i = 0; i < data.size(); i++) {
Map<String, String> datum = data.get(i); Map<String, String> datum = data.get(i);
int rowNum = i + 1; // 实际行号用于报错提示 int rowNum = i + 2;
try { try {
// 1. 基础数据校验 // 1. 基础必填校验
validateField(datum, "疑似物种类", rowNum); validateField(datum, "疑似物种类", rowNum);
validateField(datum, "提取时间", rowNum); validateField(datum, "提取时间", rowNum);
// 2. 单位合法性校验
String unit = datum.get("单位");
if (StrUtil.isBlank(unit) || !validUnits.contains(unit.toLowerCase())) {
throw new IllegalArgumentException("单位[" + unit + "]不合法,只能是 g, mg, l, ml 中的一种");
}
// 3. 身份证号业务校验
// 条件:生物样本(Type=1) 且 属于指定的鉴定结果类别
// 3. 身份证号业务校验及一致性比对
if (entrustment.getEntrustmentType() == 1 && idCardRequiredResults.contains(entrustment.getOldIdentificationResult())) {
String idCard = datum.get("身份证号");
if (StrUtil.isBlank(idCard)) {
throw new IllegalArgumentException("当前鉴定类别下,身份证号不能为空");
}
// 使用 Hutool 的工具类校验身份证合法性(比正则更严谨,会校验最后一位校验码)
if (!IdcardUtil.isValidCard(idCard)) {
throw new IllegalArgumentException("身份证号[" + idCard + "]格式非法");
}
// --- 性别一致性校验 ---
String genderInExcel = datum.get("性别");
if (StrUtil.isNotBlank(genderInExcel)) {
int genderCode = IdcardUtil.getGenderByIdCard(idCard); // 1为男,0为女
String genderFromIdCard = (genderCode == 1) ? "男" : "女";
if (!genderInExcel.equals(genderFromIdCard)) {
throw new IllegalArgumentException("性别[" + genderInExcel + "]与身份证信息(" + genderFromIdCard + ")不一致");
}
}
// --- 年龄一致性校验 ---
String ageStr = datum.get("年龄");
if (StrUtil.isNotBlank(ageStr)) {
int ageInExcel = Integer.parseInt(ageStr);
// 获取身份证对应的年龄(基于当前系统时间计算)
int ageFromIdCard = IdcardUtil.getAgeByIdCard(idCard);
// 考虑到 Excel 录入时可能存在周岁/虚岁或计算日期差异,通常允许 ±1 岁的误差
if (Math.abs(ageInExcel - ageFromIdCard) > 1) {
throw new IllegalArgumentException("年龄[" + ageInExcel + "]与身份证计算结果(" + ageFromIdCard + ")偏差过大");
}
}
}
EntrustmentIdentificationMaterial material = new EntrustmentIdentificationMaterial(); EntrustmentIdentificationMaterial material = new EntrustmentIdentificationMaterial();
// ... (ID, CaseId 等设置保持不变)
material.setId(IdWorker.get32UUID().toUpperCase()); material.setId(IdWorker.get32UUID().toUpperCase());
material.setEntrustmentId(entrustment.getId()); material.setEntrustmentId(entrustment.getId());
material.setCaseId(entrustment.getCaseId()); material.setCaseId(entrustment.getCaseId());
material.setName(datum.get("疑似物种类")); material.setName(datum.get("疑似物种类"));
// 2. 数值转换校验 (防止 Integer.valueOf 报错) // 4. 增强日期解析 (支持 yyyy-MM-dd, yyyy/MM/dd, UTC格式)
material.setDrawTime(flexibleDateParse(datum.get("提取时间"), rowNum));
// 5. 数值转换
material.setRtSampleQuantity(convertToInt(datum.get("留存样个数"), "留存样个数", rowNum)); material.setRtSampleQuantity(convertToInt(datum.get("留存样个数"), "留存样个数", rowNum));
material.setQuantity(convertToBigDecimal(datum.get("重量/体积"), "重量/体积", rowNum)); material.setQuantity(convertToBigDecimal(datum.get("重量/体积"), "重量/体积", rowNum));
material.setUnit(datum.get("单位")); material.setUnit(unit);
// 3. 增强日期解析 (支持 yyyy-MM-dd 和 EEE MMM dd ... 格式) // 6. 身份证号赋值 (如果 datum 中存在则记录)
String drawTimeStr = datum.get("提取时间"); if (datum.containsKey("身份证号")) {
material.setDrawTime(flexibleDateParse(drawTimeStr, rowNum)); Suspect suspect = new Suspect();
suspect.setIdNumber(datum.get("身份证号"));
suspect.setName(datum.get("姓名"));
suspects.add(suspect);
}
// 4. 原有业务逻辑 // ... (后续原有业务逻辑:性状、目标物、年龄、性别等保持不变)
// -------------------------------------------------------
String formDesc = datum.getOrDefault("性状描述", ""); String formDesc = datum.getOrDefault("性状描述", "");
material.setForm(formDesc); material.setForm(formDesc);
material.setFormName(formDesc); material.setFormName(formDesc);
@ -458,11 +519,8 @@ public class ExcelOperationServiceImpl implements ExcelOperationService {
material.setColor(formDesc.substring(0, formDesc.indexOf("色") + 1)); material.setColor(formDesc.substring(0, formDesc.indexOf("色") + 1));
} }
material.setDrawPlace(datum.get("提取地点")); material.setDrawPlace(datum.get("提取地点"));
String[] drugs = datum.getOrDefault("筛查目标物", "").split("、");
String screeningObj = datum.getOrDefault("筛查目标物", "");
String[] drugs = screeningObj.split("、");
buildMatchedDrugs(drugLiteMap, material, drugs); buildMatchedDrugs(drugLiteMap, material, drugs);
material.setType(String.valueOf(entrustment.getEntrustmentType())); material.setType(String.valueOf(entrustment.getEntrustmentType()));
if (entrustment.getEntrustmentType() == 0) { if (entrustment.getEntrustmentType() == 0) {
material.setTypeName("常规毒品"); material.setTypeName("常规毒品");
@ -470,35 +528,29 @@ public class ExcelOperationServiceImpl implements ExcelOperationService {
material.setTypeName("生物样本"); material.setTypeName("生物样本");
material.setBiologyType(EntrustBiologyType.isExist(formDesc).getDesc()); material.setBiologyType(EntrustBiologyType.isExist(formDesc).getDesc());
} }
material.setOrderNo(orderNo); material.setOrderNo(orderNo);
material.setImEntrustNumber(String.valueOf(orderNo)); material.setImEntrustNumber(String.valueOf(orderNo));
orderNo++; orderNo++;
material.setPackComplete("完整".equals(datum.get("包装信息"))); material.setPackComplete("完整".equals(datum.get("包装信息")));
if (StrUtil.isNotBlank(datum.get("年龄"))) { if (StrUtil.isNotBlank(datum.get("年龄"))) {
material.setMaterialAge(convertToInt(datum.get("年龄"), "年龄", rowNum)); material.setMaterialAge(convertToInt(datum.get("年龄"), "年龄", rowNum));
} }
material.setBiologyGender(datum.get("性别")); material.setBiologyGender(datum.get("性别"));
material.setAnalysisOption(AnalysisOptionEnums.fromDesc(datum.get("检验项目")).getCode()); material.setAnalysisOption(AnalysisOptionEnums.fromDesc(datum.get("检验项目")).getCode());
entrustmentIdentificationMaterialService.setMaterialIdentificationNo(material, cj); entrustmentIdentificationMaterialService.setMaterialIdentificationNo(material, cj);
material.setSample1No(sampleService.getNewSampleNo(material.getImNo(), 1)); material.setSample1No(sampleService.getNewSampleNo(material.getImNo(), 1));
entrustmentIdentificationMaterialList.add(material); entrustmentIdentificationMaterialList.add(material);
} catch (Exception e) { } catch (Exception e) {
errorMessages.add("第" + rowNum + "行处理失败: " + e.getMessage()); errorMessages.add("第" + rowNum + "行: " + e.getMessage());
} }
} }
// 5. 如果有错误,抛出异常或返回给前端
if (!errorMessages.isEmpty()) { if (!errorMessages.isEmpty()) {
throw new RuntimeException("Excel导入校验失败:\n" + String.join("\n", errorMessages)); throw new RuntimeException("Excel导入校验失败:\n" + String.join("\n", errorMessages));
} }
suspectService.addSuspectList(suspects, entrustment.getId());
return entrustmentIdentificationMaterialList; return entrustmentIdentificationMaterialList;
} }
@ -564,24 +616,30 @@ public class ExcelOperationServiceImpl implements ExcelOperationService {
} }
private Integer convertToInt(String val, String fieldName, int row) { private Integer convertToInt(String val, String fieldName, int row) {
try { return StrUtil.isBlank(val) ? 0 : Integer.valueOf(val); } try {
catch (Exception e) { throw new IllegalArgumentException(fieldName + "数字格式错误"); } return StrUtil.isBlank(val) ? 0 : Integer.valueOf(val);
} catch (Exception e) {
throw new IllegalArgumentException(fieldName + "数字格式错误");
}
} }
private BigDecimal convertToBigDecimal(String val, String fieldName, int row) { private BigDecimal convertToBigDecimal(String val, String fieldName, int row) {
try { return StrUtil.isBlank(val) ? BigDecimal.ZERO : new BigDecimal(val); } try {
catch (Exception e) { throw new IllegalArgumentException(fieldName + "数值格式错误"); } return StrUtil.isBlank(val) ? BigDecimal.ZERO : new BigDecimal(val);
} catch (Exception e) {
throw new IllegalArgumentException(fieldName + "数值格式错误");
}
} }
/** /**
* 构建匹配筛查目标物毒品列表 * 构建匹配筛查目标物毒品列表
* *
* @param drugLiteMap 毒品信息缓存Map * @param drugLiteMap 毒品信息缓存Map
* @param material 委托鉴定检材对象 * @param material 委托鉴定检材对象
* @param drugs 待匹配毒品名称数组 * @param drugs 待匹配毒品名称数组
* @throws CheckedException 抛出检查异常 * @throws CheckedException 抛出检查异常
*/ */
private void buildMatchedDrugs(Map<String, DrugLite> drugLiteMap, EntrustmentIdentificationMaterial material,String[] drugs) { private void buildMatchedDrugs(Map<String, DrugLite> drugLiteMap, EntrustmentIdentificationMaterial material, String[] drugs) {
ArrayList<DrugLite> matchedDrugs = new ArrayList<>(); ArrayList<DrugLite> matchedDrugs = new ArrayList<>();
if (drugs.length == 0 || (drugs.length == 1 && drugs[0].trim().isEmpty())) { if (drugs.length == 0 || (drugs.length == 1 && drugs[0].trim().isEmpty())) {
matchedDrugs.add(drugLiteMap.get("海洛因")); matchedDrugs.add(drugLiteMap.get("海洛因"));

@ -47,6 +47,7 @@ spring:
max-file-size: 20MB max-file-size: 20MB
# 默认最大请求大小为10M, 总上传的数据大小 # 默认最大请求大小为10M, 总上传的数据大小
max-request-size: 55MB max-request-size: 55MB
location: D:/temp
# 文件上传相关 支持阿里云、华为云、腾讯、minio # 文件上传相关 支持阿里云、华为云、腾讯、minio

Loading…
Cancel
Save