修改送检导入模板
This commit is contained in:
+88
-30
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user