diff --git a/src/main/java/digital/laboratory/platform/entrustment/config/EntrustStateMachineConfig.java b/src/main/java/digital/laboratory/platform/entrustment/config/EntrustStateMachineConfig.java deleted file mode 100644 index c022d59..0000000 --- a/src/main/java/digital/laboratory/platform/entrustment/config/EntrustStateMachineConfig.java +++ /dev/null @@ -1,38 +0,0 @@ -//package digital.laboratory.platform.entrustment.config; -// -//import digital.laboratory.platform.entrustment.enums.EntrustEvent; -//import digital.laboratory.platform.entrustment.enums.EntrustStatusConstants; -//import org.springframework.beans.factory.annotation.Value; -//import org.springframework.context.annotation.Configuration; -//import org.springframework.statemachine.config.EnumStateMachineConfigurerAdapter; -//import org.springframework.statemachine.config.builders.StateMachineStateConfigurer; -// -///** -// * @author ChenJiangBao -// * @version 1.0 -// * @description: 委托状态机配置类 -// * @date 2025/3/14 11:47 -// */ -//@Configuration -//public class EntrustStateMachineConfig extends EnumStateMachineConfigurerAdapter { -// -// @Value("${dlp.entrustment.isApprovalRequired}") -// private boolean isApprovalRequired; // 动态标志判断是否需要审批 -// -// @Override -// public void configure(StateMachineStateConfigurer states) throws Exception { -// states.withStates() -// .initial(EntrustStatusConstants.ENTRUST_STATUS_CREATED) -// .state(EntrustStatusConstants.ENTRUST_STATUS_WAITING_CHECK_CLAIM) -// .state(EntrustStatusConstants.ENTRUST_STATUS_WAITING_CHECK) -// .state(EntrustStatusConstants.ENTRUST_STATUS_WAITING_CONFIRM) -// .state(EntrustStatusConstants.ENTRUST_STATUS_WAITING_DELIVER) -// .state(EntrustStatusConstants.ENTRUST_STATUS_WAITING_ACCEPT) -// .state(EntrustStatusConstants.ENTRUST_STATUS_ACCEPTED) -// .state(EntrustStatusConstants.ENTRUST_STATUS_TEST_FINISH) -// .state(EntrustStatusConstants.ENTRUST_STATUS_COMPLETED) -// .state(EntrustStatusConstants.ENTRUST_STATUS_TERMINATED) -// .state(EntrustStatusConstants.ENTRUST_STATUS_ABORTED) -// .end(EntrustStatusConstants.ENTRUST_STATUS_COMPLETED); -// } -//} diff --git a/src/main/java/digital/laboratory/platform/entrustment/constant/EntrustMarkConstants.java b/src/main/java/digital/laboratory/platform/entrustment/constant/EntrustConstants.java similarity index 92% rename from src/main/java/digital/laboratory/platform/entrustment/constant/EntrustMarkConstants.java rename to src/main/java/digital/laboratory/platform/entrustment/constant/EntrustConstants.java index c7770fa..48b7845 100644 --- a/src/main/java/digital/laboratory/platform/entrustment/constant/EntrustMarkConstants.java +++ b/src/main/java/digital/laboratory/platform/entrustment/constant/EntrustConstants.java @@ -3,7 +3,7 @@ package digital.laboratory.platform.entrustment.constant; /** * 统计的各个中文名称常量接口 */ -public interface EntrustMarkConstants { +public interface EntrustConstants { String CASE_ACCEPT = "案件受理"; @@ -19,6 +19,4 @@ public interface EntrustMarkConstants { Integer LOCAL_SYSTEM = 0; // 本系统数据 Integer THIRD_PARTY_SYSTEM = 1; // 大数据平台同步过来的数据 - - } diff --git a/src/main/java/digital/laboratory/platform/entrustment/controller/ExcelOperationController.java b/src/main/java/digital/laboratory/platform/entrustment/controller/ExcelOperationController.java index 62a4fb6..ee91739 100644 --- a/src/main/java/digital/laboratory/platform/entrustment/controller/ExcelOperationController.java +++ b/src/main/java/digital/laboratory/platform/entrustment/controller/ExcelOperationController.java @@ -25,6 +25,17 @@ public class ExcelOperationController { @Resource private ExcelOperationService excelOperationService; + @ApiOperation("检材信息导入接口") + @PostMapping("/importMaterialInfo") + public R importMaterialInfo(@RequestPart("file") MultipartFile file, @RequestParam("entrustId") String entrustId) { + try { + return excelOperationService.importMaterialInfo(file, entrustId) ? R.ok("检材信息导入成功!") : R.failed("检材信息导入失败!"); + } catch (Exception e) { + e.printStackTrace(); + return R.failed(e.getMessage()); + } + } + @ApiOperation("上传两社人员名单excel文件") @PostMapping("/uploadHairInspect") public R uploadHairInspectExcel(@RequestPart("file") MultipartFile file, @RequestParam("entrustId") String entrustId) { diff --git a/src/main/java/digital/laboratory/platform/entrustment/enums/AnalysisOptionEnums.java b/src/main/java/digital/laboratory/platform/entrustment/enums/AnalysisOptionEnums.java index 09aae07..c3198cd 100644 --- a/src/main/java/digital/laboratory/platform/entrustment/enums/AnalysisOptionEnums.java +++ b/src/main/java/digital/laboratory/platform/entrustment/enums/AnalysisOptionEnums.java @@ -46,4 +46,14 @@ public enum AnalysisOptionEnums { } throw new IllegalArgumentException("No enum constant with code: " + code); } + + // 根据描述获取枚举值 + public static AnalysisOptionEnums fromDesc(String desc) { + for (AnalysisOptionEnums analysisOption : values()) { + if (analysisOption.getChineseName().equals(desc)) { + return analysisOption; + } + } + throw new IllegalArgumentException("No enum constant with description: " + desc); + } } diff --git a/src/main/java/digital/laboratory/platform/entrustment/service/ExcelOperationService.java b/src/main/java/digital/laboratory/platform/entrustment/service/ExcelOperationService.java index 21d459f..5154955 100644 --- a/src/main/java/digital/laboratory/platform/entrustment/service/ExcelOperationService.java +++ b/src/main/java/digital/laboratory/platform/entrustment/service/ExcelOperationService.java @@ -29,4 +29,11 @@ public interface ExcelOperationService { */ void exportByEntrustOrg(Integer year, HttpServletResponse response) throws IOException; + /** + * 导入检材信息 + * @param file + * @param entrustId + * @return + */ + Boolean importMaterialInfo(MultipartFile file, String entrustId) throws Exception; } diff --git a/src/main/java/digital/laboratory/platform/entrustment/service/impl/EntrustmentServiceImpl.java b/src/main/java/digital/laboratory/platform/entrustment/service/impl/EntrustmentServiceImpl.java index 5478fec..3cfc5c8 100644 --- a/src/main/java/digital/laboratory/platform/entrustment/service/impl/EntrustmentServiceImpl.java +++ b/src/main/java/digital/laboratory/platform/entrustment/service/impl/EntrustmentServiceImpl.java @@ -33,7 +33,7 @@ import digital.laboratory.platform.common.feign.RemoteWord2PDFService; import digital.laboratory.platform.common.mybatis.security.service.DLPUser; import digital.laboratory.platform.common.oss.service.OssFile; import digital.laboratory.platform.common.security.util.SecurityUtils; -import digital.laboratory.platform.entrustment.constant.EntrustMarkConstants; +import digital.laboratory.platform.entrustment.constant.EntrustConstants; import digital.laboratory.platform.entrustment.convert.DrugLiteConvert; import digital.laboratory.platform.entrustment.dto.EntrustmentDTO; import digital.laboratory.platform.entrustment.entity.*; @@ -3309,34 +3309,34 @@ public class EntrustmentServiceImpl extends ServiceImpl entrustListMapOrDefault = entrustListMap.getOrDefault( - StrUtil.join("_", EntrustMarkConstants.LOCAL_SYSTEM, EntrustStatusConstants.ENTRUST_STATUS_ACCEPTED.getStatus()), Collections.EMPTY_LIST + StrUtil.join("_", EntrustConstants.LOCAL_SYSTEM, EntrustStatusConstants.ENTRUST_STATUS_ACCEPTED.getStatus()), Collections.EMPTY_LIST ); // o.getAcceptTime().isAfter(LocalDateTime.of(LocalDate.now().withDayOfYear(1), LocalTime.MIN)) 筛选出当年的数据 - markersVOS.add(new MarkersVO(EntrustMarkConstants.CASE_ACCEPT, + markersVOS.add(new MarkersVO(EntrustConstants.CASE_ACCEPT, entrustListMapOrDefault.stream().filter(o -> o.getAcceptTime().isAfter(LocalDateTime.of(LocalDate.now().withDayOfYear(1), LocalTime.MIN)) && EntrustStatusConstants.geAcceptedStatus(o.getStatus()) ).collect(Collectors.toList()).size(), - String.format("已受理 (%s)", EntrustMarkConstants.PUBLIC_SECURITY_BUREAU))); - markersVOS.add(new MarkersVO(EntrustMarkConstants.CASE_ACCEPT, + String.format("已受理 (%s)", EntrustConstants.PUBLIC_SECURITY_BUREAU))); + markersVOS.add(new MarkersVO(EntrustConstants.CASE_ACCEPT, entrustListMap.getOrDefault( - StrUtil.join("_", EntrustMarkConstants.THIRD_PARTY_SYSTEM, EntrustStatusConstants.ENTRUST_STATUS_ACCEPTED.getStatus()), Collections.EMPTY_LIST + StrUtil.join("_", EntrustConstants.THIRD_PARTY_SYSTEM, EntrustStatusConstants.ENTRUST_STATUS_ACCEPTED.getStatus()), Collections.EMPTY_LIST ).size(), "已受理 (大数据平台)")); - markersVOS.add(new MarkersVO(EntrustMarkConstants.CASE_ACCEPT, + markersVOS.add(new MarkersVO(EntrustConstants.CASE_ACCEPT, this.list(Wrappers.lambdaQuery() .ge(Entrustment::getStatus, EntrustStatusConstants.ENTRUST_STATUS_ACCEPTED.getStatus()) .inSql(Entrustment::getId, "SELECT entrust_id FROM b_entrust_material_checkout_result")) @@ -3349,34 +3349,34 @@ public class EntrustmentServiceImpl extends ServiceImpl entrustListMap.getOrDefault(EntrustMarkConstants.LOCAL_SYSTEM + "_" + status, Collections.emptyList()).size()) + .mapToInt(status -> entrustListMap.getOrDefault(EntrustConstants.LOCAL_SYSTEM + "_" + status, Collections.emptyList()).size()) .sum(), - String.format("委托审核(%s)", EntrustMarkConstants.PUBLIC_SECURITY_BUREAU))); - markersVOS.add(new MarkersVO(EntrustMarkConstants.REVIEW_OR_APPROVAL, + String.format("委托审核(%s)", EntrustConstants.PUBLIC_SECURITY_BUREAU))); + markersVOS.add(new MarkersVO(EntrustConstants.REVIEW_OR_APPROVAL, REVIEW_STATUS_GROUP2.stream() - .mapToInt(status -> entrustListMap.getOrDefault(EntrustMarkConstants.LOCAL_SYSTEM + "_" + status, Collections.emptyList()).size()) + .mapToInt(status -> entrustListMap.getOrDefault(EntrustConstants.LOCAL_SYSTEM + "_" + status, Collections.emptyList()).size()) .sum(), - String.format("委托审批(%s)", EntrustMarkConstants.PUBLIC_SECURITY_BUREAU))); - markersVOS.add(new MarkersVO(EntrustMarkConstants.REVIEW_OR_APPROVAL, + String.format("委托审批(%s)", EntrustConstants.PUBLIC_SECURITY_BUREAU))); + markersVOS.add(new MarkersVO(EntrustConstants.REVIEW_OR_APPROVAL, REVIEW_STATUS_GROUP1.stream() - .mapToInt(status -> entrustListMap.getOrDefault(EntrustMarkConstants.THIRD_PARTY_SYSTEM + "_" + status, Collections.emptyList()).size()) + .mapToInt(status -> entrustListMap.getOrDefault(EntrustConstants.THIRD_PARTY_SYSTEM + "_" + status, Collections.emptyList()).size()) .sum(), "委托审核(大数据平台)")); - markersVOS.add(new MarkersVO(EntrustMarkConstants.REVIEW_OR_APPROVAL, + markersVOS.add(new MarkersVO(EntrustConstants.REVIEW_OR_APPROVAL, REVIEW_STATUS_GROUP2.stream() - .mapToInt(status -> entrustListMap.getOrDefault(EntrustMarkConstants.LOCAL_SYSTEM + "_" + status, Collections.emptyList()).size()) + .mapToInt(status -> entrustListMap.getOrDefault(EntrustConstants.LOCAL_SYSTEM + "_" + status, Collections.emptyList()).size()) .sum(), "委托审批(大数据平台)")); - markersVOS.add(new MarkersVO(EntrustMarkConstants.REVIEW_OR_APPROVAL, + markersVOS.add(new MarkersVO(EntrustConstants.REVIEW_OR_APPROVAL, (int) entrustAlterApplyService.count(Wrappers.lambdaQuery() .eq(EntrustAlterApply::getStatus, EntrustAlterApplyStatus.SUBMITTED_WAIT_APPROVE.getStatus())), "委托修改审核")); - markersVOS.add(new MarkersVO(EntrustMarkConstants.SEWAGE_JOB_ACCEPT, statisticsDiffStatusSewageJobDTO.getJobStatusCreatedNum(), "污水任务待发布")); - markersVOS.add(new MarkersVO(EntrustMarkConstants.SEWAGE_JOB_ACCEPT, statisticsDiffStatusSewageJobDTO.getJobStatusClaimNum(), "污水任务已发布")); - markersVOS.add(new MarkersVO(EntrustMarkConstants.SEWAGE_JOB_ACCEPT, statisticsDiffStatusSewageJobDTO.getJobStatusClaimNum(), "污水受理")); - markersVOS.add(new MarkersVO(EntrustMarkConstants.SEWAGE_JOB_ACCEPT, statisticsDiffStatusSewageJobDTO.getSewageTreatmentPlantNum(), "污水厂管理")); + markersVOS.add(new MarkersVO(EntrustConstants.SEWAGE_JOB_ACCEPT, statisticsDiffStatusSewageJobDTO.getJobStatusCreatedNum(), "污水任务待发布")); + markersVOS.add(new MarkersVO(EntrustConstants.SEWAGE_JOB_ACCEPT, statisticsDiffStatusSewageJobDTO.getJobStatusClaimNum(), "污水任务已发布")); + markersVOS.add(new MarkersVO(EntrustConstants.SEWAGE_JOB_ACCEPT, statisticsDiffStatusSewageJobDTO.getJobStatusClaimNum(), "污水受理")); + markersVOS.add(new MarkersVO(EntrustConstants.SEWAGE_JOB_ACCEPT, statisticsDiffStatusSewageJobDTO.getSewageTreatmentPlantNum(), "污水厂管理")); return markersVOS; } diff --git a/src/main/java/digital/laboratory/platform/entrustment/service/impl/ExcelOperationServiceImpl.java b/src/main/java/digital/laboratory/platform/entrustment/service/impl/ExcelOperationServiceImpl.java index 833b146..1c97db1 100644 --- a/src/main/java/digital/laboratory/platform/entrustment/service/impl/ExcelOperationServiceImpl.java +++ b/src/main/java/digital/laboratory/platform/entrustment/service/impl/ExcelOperationServiceImpl.java @@ -1,6 +1,7 @@ package digital.laboratory.platform.entrustment.service.impl; import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.toolkit.IdWorker; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import digital.laboratory.platform.common.core.constant.CommonConstants; @@ -25,6 +26,7 @@ import org.apache.poi.ss.usermodel.*; import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.xssf.streaming.SXSSFWorkbook; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; @@ -40,6 +42,7 @@ import java.time.temporal.ChronoUnit; import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.function.Function; import java.util.stream.Collectors; @@ -86,148 +89,77 @@ public class ExcelOperationServiceImpl implements ExcelOperationService { * @throws Exception 发生异常时抛出 */ @Override + @Transactional(rollbackFor = Exception.class) public Boolean uploadHairInspectExcel(MultipartFile file, String entrustId) throws Exception { - - // 1. 校验委托合法性 + // ---------- 1. 校验委托合法性 ---------- Entrustment entrustment = entrustmentService.getById(entrustId); if (entrustment == null) { - throw new CheckedException(String.format("委托id为 %s 的委托信息不存在!", entrustId)); - } - if (!entrustment.getOldIdentificationResult().equals(EntrustIdentificationSituationType.TWO_AGENCY.getDesc())) { - throw new CheckedException("当前不支持两社人员之外的委托信息进行导入!"); + throw new CheckedException(String.format("委托ID为 %s 的委托信息不存在!", entrustId)); } - // 2. 获取案件与毒品信息 - // 2.1 校验案件信息 - CaseEvent cj = caseEventService.validateCaseInfo(entrustment.getCaseId()); - - // 2.2 获取默认毒品(海洛因) - + if (!EntrustIdentificationSituationType.TWO_AGENCY.getDesc().equals(entrustment.getOldIdentificationResult())) { + throw new CheckedException("当前仅支持‘两社人员’类型的委托信息进行导入!"); + } - // 2.3 获取所有毒品名称映射(便于匹配检测结果) - R> innerGetAllR = remoteCommDrugService.innerGetAll(); - List drugLiteList = innerGetAllR.getData(); - Map drugLiteMap = drugLiteList.stream() - .collect(Collectors.toMap(DrugLite::getName, Function.identity())); + // ---------- 2. 校验案件信息 ---------- + CaseEvent caseEvent = caseEventService.validateCaseInfo(entrustment.getCaseId()); - // 3. 读取Excel内容(从第一行数据开始读取) - int headIndex = 0; - List> data = ExcelUtils.readExcel(file, headIndex); + // ---------- 3. 获取毒品名称映射 ---------- + Map drugMap = getDrugLiteMap(); - // 3.1 获取当前委托下已有检材数,作为orderNo起始编号 - int orderNo = entrustmentIdentificationMaterialService.lambdaQuery() - .eq(EntrustmentIdentificationMaterial::getEntrustmentId, entrustId) - .list().size() + 1; + // ---------- 4. 读取 Excel 数据 ---------- + final int headerRowIndex = 0; + List> excelData = ExcelUtils.readExcel(file, headerRowIndex); + if (CollUtil.isEmpty(excelData)) { + throw new CheckedException("Excel 文件内容为空!"); + } - // 3.2 初始化结果对象集合 - List results = new ArrayList<>(); + // ---------- 5. 处理嫌疑人信息 ---------- + List suspects = excelData.stream() + .map(row -> { + Suspect s = new Suspect(); + s.setName(row.get("姓名")); + s.setIdNumber(row.get("身份证号")); + return s; + }) + .filter(s -> StrUtil.isNotBlank(s.getName())) + .collect(Collectors.toList()); - ArrayList suspects = new ArrayList<>(); - for (Map datum : data) { - Suspect suspect = new Suspect(); - suspect.setName(datum.get("姓名")); - suspect.setIdNumber(datum.get("身份证号")); - suspects.add(suspect); - } if (CollUtil.isNotEmpty(suspects)) { + // 删除旧嫌疑人信息 suspectService.remove(Wrappers.lambdaQuery() .eq(Suspect::getEntrustId, entrustId)); + // 保存新嫌疑人信息 suspectService.addSuspectList(suspects, entrustId); } - List entrustmentIdentificationMaterialList = new ArrayList<>(); - - // 4. 遍历Excel数据行,构建检材与检测结果 - processExcelDataToMaterialEntity(data, entrustment, drugLiteMap, orderNo, cj, entrustmentIdentificationMaterialList); -// entrustMaterialCheckoutResultService.saveBatch(results); - boolean isSave = entrustmentIdentificationMaterialService.saveBatch(entrustmentIdentificationMaterialList); - String entrustReq = entrustmentService.buildEntrustReq(entrustmentIdentificationMaterialList); - entrustment.setEntrustRequirement(entrustReq); - entrustmentService.updateById(entrustment); - // 5. 批量保存检材信息和检测结果 - return isSave; - } - /** - * 处理Excel数据,构建检材对象并设置相关属性 - * @param data Excel数据列表 - * @param entrustment 委托信息对象 - * @param drugLiteMap 毒品名称映射表 - * @param orderNo 检材序号起始值 - * @param cj 案件信息对象 - * @param entrustmentIdentificationMaterialList 检材列表对象集合 - */ - private void processExcelDataToMaterialEntity(List> data, Entrustment entrustment, Map drugLiteMap, int orderNo, CaseEvent cj, List entrustmentIdentificationMaterialList) { - for (Map datum : data) { - // 构建检材对象 - EntrustmentIdentificationMaterial material = new EntrustmentIdentificationMaterial(); - material.setEntrustmentId(entrustment.getId()); - material.setCaseId(entrustment.getCaseId()); - material.setName(datum.get("姓名") + "毛发"); - material.setRemark(datum.get("身份证号")); - - // 解析身份证号 - String idNum = datum.get("身份证号"); - if (idNum != null && idNum.length() == 18) { - material.setBiologyGender(this.getSexByIdNum(idNum)); - material.setMaterialAge(Integer.valueOf(this.getAgeByIdNum(idNum))); - } + // ---------- 6. 构建检材与检测结果 ---------- + Long existingMaterialCount = entrustmentIdentificationMaterialService.lambdaQuery() + .eq(EntrustmentIdentificationMaterial::getEntrustmentId, entrustId) + .count(); + int startOrderNo = Math.toIntExact(existingMaterialCount + 1); - material.setDrawPlace(datum.get("采样单位")); - material.setId(IdWorker.get32UUID().toUpperCase()); + List materialList = processHairExcelDataToMaterialEntity(excelData, entrustment, drugMap, startOrderNo, caseEvent); - // 检测结果解析 - ArrayList matchedDrugs = new ArrayList<>(); - String[] drugs = datum.get("检测结果").split("、"); - if (drugs.length == 0 || (drugs.length == 1 && drugs[0].trim().isEmpty())) { - matchedDrugs.add(drugLiteMap.get("海洛因")); - } else { - for (String drugName : drugs) { - if (drugLiteMap.containsKey(drugName)) { - matchedDrugs.add(drugLiteMap.get(drugName)); - } else { - // 未匹配到任何已知毒品,则调用接口保存 - DrugLite newDrug = new DrugLite(); - newDrug.setId(IdWorker.get32UUID().toUpperCase()); - newDrug.setName(drugName); - R booleanR = remoteCommDrugService.innerSaveDrug(newDrug); - if (booleanR.getCode() == CommonConstants.FAIL) { - throw new CheckedException("新增未知毒品失败!"); - } - // 更新缓存 Map,避免重复插入 - drugLiteMap.put(drugName, newDrug); - matchedDrugs.add(newDrug); - } - } - } - material.setCandidateDrugs(matchedDrugs); - - // 设置检材默认属性 - material.setBiologyType(EntrustBiologyType.HAIR.getDesc()); - material.setType("1"); - material.setTypeName("生物样本"); - material.setQuantity(new BigDecimal(50)); - material.setUnit("mg"); - material.setForm("黑色头发"); - material.setFormName("黑色头发"); - material.setOrderNo(orderNo); - material.setImEntrustNumber(String.valueOf(orderNo)); - orderNo++; - material.setPackComplete(true); - material.setRtSampleQuantity(0); - material.setDrawTime(LocalDateTime.now()); - material.setAnalysisOption(AnalysisOptionEnums.QUALITATIVE.getCode()); + // ---------- 7. 保存检材信息 ---------- + boolean saveSuccess = entrustmentIdentificationMaterialService.saveBatch(materialList); + if (!saveSuccess) { + throw new CheckedException("批量保存检材信息失败!"); + } - entrustmentIdentificationMaterialService.setMaterialIdentificationNo(material, cj); - material.setSample1No(sampleService.getNewSampleNo(material.getImNo(), 1)); + // ---------- 8. 更新委托要求 ---------- + String entrustRequirement = entrustmentService.buildEntrustReq(materialList); + entrustment.setEntrustRequirement(entrustRequirement); + entrustmentService.updateById(entrustment); - entrustmentIdentificationMaterialList.add(material); - } + // ---------- 9. 返回执行结果 ---------- + return true; } /** * 根据当前用户的机构id查询属于这个机构的委托信息 * - * @param year 年份,用于筛选特定年份的委托信息 + * @param year 年份,用于筛选特定年份的委托信息 * @param response */ @Override @@ -238,7 +170,7 @@ public class ExcelOperationServiceImpl implements ExcelOperationService { Wrappers.query() .eq("e.client_org_id", user.getOrgId()) .eq("e.status", EntrustStatusConstants.ENTRUST_STATUS_ACCEPTED.getStatus()) - .likeRight(year != null , "e.accept_time", year) + .likeRight(year != null, "e.accept_time", year) .orderByDesc("e.accept_time") ); @@ -258,7 +190,6 @@ public class ExcelOperationServiceImpl implements ExcelOperationService { Map> materialGroupMap = identificationMaterials.stream().collect(Collectors.groupingBy(EntrustmentIdentificationMaterial::getEntrustmentId)); - // 获取嫌疑人信息并根据委托id分组 Map suspectGroupMap = buildSuspectInfoGroupByEntrustId(entrustmentVOList); @@ -344,14 +275,242 @@ public class ExcelOperationServiceImpl implements ExcelOperationService { // ====== 输出到浏览器 response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); - String filename = user.getOrgName() + "已受理委托信息统计" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")) + ".xlsx"; + String filename = user.getOrgName() + "已受理委托信息统计" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")) + ".xlsx"; response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, StandardCharsets.UTF_8.name())); workbook.write(response.getOutputStream()); workbook.close(); } + /** + * 导入检材信息 + * + * @param file + * @param entrustId + * @return + */ + @Override + public Boolean importMaterialInfo(MultipartFile file, String entrustId) throws Exception { + // ---------- 1. 校验委托合法性 ---------- + Entrustment entrustment = entrustmentService.getById(entrustId); + if (entrustment == null) { + throw new CheckedException(String.format("委托ID为 %s 的委托信息不存在!", entrustId)); + } + + // ---------- 2. 校验案件信息 ---------- + CaseEvent caseEvent = caseEventService.validateCaseInfo(entrustment.getCaseId()); + + // ---------- 3. 获取毒品名称映射 ---------- + Map drugMap = getDrugLiteMap(); + + // ---------- 4. 读取 Excel 数据 ---------- + final int headerRowIndex = 0; + List> excelData = ExcelUtils.readExcel(file, headerRowIndex); + if (CollUtil.isEmpty(excelData)) { + throw new CheckedException("Excel 文件内容为空!"); + } + + + // ---------- 6. 构建检材与检测结果 ---------- + Long existingMaterialCount = entrustmentIdentificationMaterialService.lambdaQuery() + .eq(EntrustmentIdentificationMaterial::getEntrustmentId, entrustId) + .count(); + int startOrderNo = Math.toIntExact(existingMaterialCount + 1); + + List materialList = processExcelDataToMaterialEntity(excelData, entrustment, drugMap, startOrderNo, caseEvent); + + // ---------- 7. 保存检材信息 ---------- + boolean saveSuccess = entrustmentIdentificationMaterialService.saveBatch(materialList); + if (!saveSuccess) { + throw new CheckedException("批量保存检材信息失败!"); + } + + // ---------- 8. 更新委托要求 ---------- + String entrustRequirement = entrustmentService.buildEntrustReq(materialList); + entrustment.setEntrustRequirement(entrustRequirement); + entrustmentService.updateById(entrustment); + + // ---------- 9. 返回执行结果 ---------- + return true; + } + + /** + * 获取毒品清单信息,并转成map + * @return + */ + private Map getDrugLiteMap() { + R> drugResponse = remoteCommDrugService.innerGetAll(); + List drugList = Optional + .ofNullable(drugResponse.getData()) + .orElseThrow( + () -> new CheckedException("获取毒品信息失败!") + ); + Map drugMap = drugList.stream() + .collect(Collectors.toMap(DrugLite::getName, Function.identity())); + return drugMap; + } + + /** + * 处理毛发两社人员Excel数据,构建检材对象并设置相关属性 + * + * @param data Excel数据列表 + * @param entrustment 委托信息对象 + * @param drugLiteMap 毒品名称映射表 + * @param orderNo 检材序号起始值 + * @param cj 案件信息对象 + * @return + */ + private List processHairExcelDataToMaterialEntity(List> data, Entrustment entrustment, Map drugLiteMap, int orderNo, CaseEvent cj) { + List entrustmentIdentificationMaterialList = new ArrayList<>(); + for (Map datum : data) { + // 构建检材对象 + EntrustmentIdentificationMaterial material = new EntrustmentIdentificationMaterial(); + material.setEntrustmentId(entrustment.getId()); + material.setCaseId(entrustment.getCaseId()); + material.setName(datum.get("姓名") + "毛发"); + material.setRemark(datum.get("身份证号")); + + // 解析身份证号 + String idNum = datum.get("身份证号"); + if (idNum != null && idNum.length() == 18) { + material.setBiologyGender(this.getSexByIdNum(idNum)); + material.setMaterialAge(Integer.valueOf(this.getAgeByIdNum(idNum))); + } + + material.setDrawPlace(datum.get("采样单位")); + material.setId(IdWorker.get32UUID().toUpperCase()); + + // 检测结果解析 + String[] drugs = datum.get("检测结果").split("、"); + buildMatchedDrugs(drugLiteMap, material, drugs); + + // 设置检材默认属性 + material.setBiologyType(EntrustBiologyType.HAIR.getDesc()); + material.setType("1"); + material.setTypeName("生物样本"); + material.setQuantity(new BigDecimal(50)); + material.setUnit("mg"); + material.setForm("黑色头发"); + material.setFormName("黑色头发"); + material.setOrderNo(orderNo); + material.setImEntrustNumber(String.valueOf(orderNo)); + orderNo++; + material.setPackComplete(true); + material.setRtSampleQuantity(0); + material.setDrawTime(LocalDateTime.now()); + material.setAnalysisOption(AnalysisOptionEnums.QUALITATIVE.getCode()); + + entrustmentIdentificationMaterialService.setMaterialIdentificationNo(material, cj); + material.setSample1No(sampleService.getNewSampleNo(material.getImNo(), 1)); + + entrustmentIdentificationMaterialList.add(material); + } + return entrustmentIdentificationMaterialList; + } + + /** + * 处理委托检材Excel数据,构建检材对象并设置相关属性 + * + * @param data Excel数据列表 + * @param entrustment 委托信息对象 + * @param drugLiteMap 毒品名称映射表 + * @param orderNo 检材序号起始值 + * @param cj 案件信息对象 + * @return + */ + private List processExcelDataToMaterialEntity(List> data, Entrustment entrustment, Map drugLiteMap, int orderNo, CaseEvent cj) { + List entrustmentIdentificationMaterialList = new ArrayList<>(); + for (Map datum : data) { + // 构建检材对象 + EntrustmentIdentificationMaterial material = new EntrustmentIdentificationMaterial(); + material.setId(IdWorker.get32UUID().toUpperCase()); + material.setEntrustmentId(entrustment.getId()); + material.setCaseId(entrustment.getCaseId()); + material.setName(datum.get("疑似物种类")); + material.setRtSampleQuantity(Integer.valueOf(datum.get("留存样个数"))); + material.setQuantity(new BigDecimal(datum.get("重量/体积"))); + material.setUnit(datum.get("单位")); + String formDesc = datum.get("性状描述"); + material.setForm(formDesc); + material.setFormName(formDesc); + // 提取颜色 + if (StrUtil.isNotBlank(formDesc) && formDesc.contains("色")) { + // 截取“色”之前的部分(包含“色”) + material.setColor(formDesc.substring(0, formDesc.indexOf("色") + 1)); + } + material.setDrawTime(LocalDate.parse(datum.get("提取时间"), DateTimeFormatter.ofPattern("yyyy-MM-dd")).atStartOfDay()); + material.setDrawPlace(datum.get("提取地点")); + + // 检测结果解析 + String[] drugs = datum.get("筛查目标物").split("、"); + buildMatchedDrugs(drugLiteMap, material, drugs); + // 设置委托类型 + material.setType(String.valueOf(entrustment.getEntrustmentType())); + if (entrustment.getEntrustmentType() == 0) { + material.setTypeName("常规毒品"); + } else { + material.setTypeName("生物样本"); + material.setBiologyType(EntrustBiologyType.isExist(formDesc).getDesc()); + } + material.setOrderNo(orderNo); + material.setImEntrustNumber(String.valueOf(orderNo)); + orderNo++; + String packageInfo = datum.get("包装信息"); + if (packageInfo.equals("完整")) { + material.setPackComplete(true); + } else { + material.setPackComplete(false); + } + String age = datum.get("年龄"); + if (StrUtil.isNotBlank(age)) { + material.setMaterialAge(Integer.valueOf(age)); + } + material.setBiologyGender(datum.get("性别")); + material.setAnalysisOption(AnalysisOptionEnums.fromDesc(datum.get("检验项目")).getCode()); + entrustmentIdentificationMaterialService.setMaterialIdentificationNo(material, cj); + material.setSample1No(sampleService.getNewSampleNo(material.getImNo(), 1)); + + entrustmentIdentificationMaterialList.add(material); + } + return entrustmentIdentificationMaterialList; + } + + /** + * 构建匹配筛查目标物毒品列表 + * + * @param drugLiteMap 毒品信息缓存Map + * @param material 委托鉴定检材对象 + * @param drugs 待匹配毒品名称数组 + * @throws CheckedException 抛出检查异常 + */ + private void buildMatchedDrugs(Map drugLiteMap, EntrustmentIdentificationMaterial material,String[] drugs) { + ArrayList matchedDrugs = new ArrayList<>(); + if (drugs.length == 0 || (drugs.length == 1 && drugs[0].trim().isEmpty())) { + matchedDrugs.add(drugLiteMap.get("海洛因")); + } else { + for (String drugName : drugs) { + if (drugLiteMap.containsKey(drugName)) { + matchedDrugs.add(drugLiteMap.get(drugName)); + } else { + // 未匹配到任何已知毒品,则调用接口保存 + DrugLite newDrug = new DrugLite(); + newDrug.setId(IdWorker.get32UUID().toUpperCase()); + newDrug.setName(drugName); + R booleanR = remoteCommDrugService.innerSaveDrug(newDrug); + if (booleanR.getCode() == CommonConstants.FAIL) { + throw new CheckedException("新增未知毒品失败!"); + } + // 更新缓存 Map,避免重复插入 + drugLiteMap.put(drugName, newDrug); + matchedDrugs.add(newDrug); + } + } + } + material.setCandidateDrugs(matchedDrugs); + } + /** * 根据委托id分组,拼接嫌疑人姓名和身份证 + * * @param entrustmentVOList * @return */