parent
a741c5ab04
commit
da71a8ba41
@ -0,0 +1,33 @@ |
|||||||
|
package digital.laboratory.platform.entrustment.enums; |
||||||
|
|
||||||
|
import lombok.Getter; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author ChenJiangBao |
||||||
|
* @version 1.0 |
||||||
|
* @description: 委托信息导出excel表头枚举 |
||||||
|
* @date 2025/7/14 10:47 |
||||||
|
*/ |
||||||
|
@Getter |
||||||
|
public enum EntrustExportHeaderEnum { |
||||||
|
CASE_NAME("caseName", "案件名称"), |
||||||
|
CASE_BRIEF("caseBrief", "案情简要"), |
||||||
|
HAPPEN_TIME("happenTime", "案发时间"), |
||||||
|
SUSPECT_INFO("suspectInfo", "嫌疑人信息"), |
||||||
|
CLIENT_ORG_NAME("clientOrgName", "委托单位"), |
||||||
|
ENTRUST_TIME("entrustmentTime", "送检时间"), |
||||||
|
ACCEPT_NO("acceptNo", "受理编号"), |
||||||
|
ACCEPT_TIME("acceptTime", "受理时间"), |
||||||
|
ENTRUST_REQUIREMENT("entrustRequirement", "鉴定要求"), |
||||||
|
MATERIAL_CHARACTER("materialCharacterDesc", "性状描述"), |
||||||
|
MATERIAL_COUNT("materialCount", "检材数量"), |
||||||
|
MATERIAL_RESULT("materialResult", "检材检测结果"); |
||||||
|
|
||||||
|
private final String field; // 字段名,用于匹配数据
|
||||||
|
private final String header; // Excel列名,用于显示
|
||||||
|
|
||||||
|
EntrustExportHeaderEnum(String field, String header) { |
||||||
|
this.field = field; |
||||||
|
this.header = header; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,393 @@ |
|||||||
|
package digital.laboratory.platform.entrustment.service.impl; |
||||||
|
|
||||||
|
import cn.hutool.core.collection.CollUtil; |
||||||
|
import com.baomidou.mybatisplus.core.toolkit.IdWorker; |
||||||
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
||||||
|
import digital.laboratory.platform.common.core.exception.CheckedException; |
||||||
|
import digital.laboratory.platform.common.core.util.R; |
||||||
|
import digital.laboratory.platform.common.mybatis.security.service.DLPUser; |
||||||
|
import digital.laboratory.platform.common.security.util.SecurityUtils; |
||||||
|
import digital.laboratory.platform.entrustment.entity.*; |
||||||
|
import digital.laboratory.platform.entrustment.enums.AnalysisOptionEnums; |
||||||
|
import digital.laboratory.platform.entrustment.enums.EntrustExportHeaderEnum; |
||||||
|
import digital.laboratory.platform.entrustment.enums.EntrustIdentificationSituationType; |
||||||
|
import digital.laboratory.platform.entrustment.enums.EntrustStatusConstants; |
||||||
|
import digital.laboratory.platform.entrustment.mapper.EntrustmentMapper; |
||||||
|
import digital.laboratory.platform.entrustment.service.*; |
||||||
|
import digital.laboratory.platform.entrustment.utils.ExcelUtils; |
||||||
|
import digital.laboratory.platform.entrustment.vo.EntrustmentVO; |
||||||
|
import digital.laboratory.platform.sys.entity.DrugLite; |
||||||
|
import digital.laboratory.platform.sys.enums.entrust.EntrustBiologyType; |
||||||
|
import digital.laboratory.platform.sys.feign.RemoteCommDrugService; |
||||||
|
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.web.multipart.MultipartFile; |
||||||
|
|
||||||
|
import javax.annotation.Resource; |
||||||
|
import javax.servlet.http.HttpServletResponse; |
||||||
|
import java.io.IOException; |
||||||
|
import java.math.BigDecimal; |
||||||
|
import java.net.URLEncoder; |
||||||
|
import java.nio.charset.StandardCharsets; |
||||||
|
import java.time.LocalDate; |
||||||
|
import java.time.LocalDateTime; |
||||||
|
import java.time.format.DateTimeFormatter; |
||||||
|
import java.time.temporal.ChronoUnit; |
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Map; |
||||||
|
import java.util.function.Function; |
||||||
|
import java.util.stream.Collectors; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author ChenJiangBao |
||||||
|
* @version 1.0 |
||||||
|
* @description: excel上传服务层接口 实现类 |
||||||
|
* @date 2025/4/16 11:55 |
||||||
|
*/ |
||||||
|
@Service |
||||||
|
public class ExcelOperationServiceImpl implements ExcelOperationService { |
||||||
|
|
||||||
|
@Resource |
||||||
|
private SampleService sampleService; |
||||||
|
|
||||||
|
@Resource |
||||||
|
private CaseEventService caseEventService; |
||||||
|
|
||||||
|
@Resource |
||||||
|
private EntrustmentService entrustmentService; |
||||||
|
|
||||||
|
@Resource |
||||||
|
private EntrustmentMapper entrustmentMapper; |
||||||
|
|
||||||
|
@Resource |
||||||
|
private EntrustmentIdentificationMaterialService entrustmentIdentificationMaterialService; |
||||||
|
|
||||||
|
@Resource |
||||||
|
private EntrustMaterialCheckoutResultService entrustMaterialCheckoutResultService; |
||||||
|
|
||||||
|
@Resource |
||||||
|
private RemoteCommDrugService remoteCommDrugService; |
||||||
|
|
||||||
|
@Resource |
||||||
|
private SuspectService suspectService; |
||||||
|
|
||||||
|
/** |
||||||
|
* 上传两社人员名单Excel文件,并自动生成检材与检测结果数据 |
||||||
|
* |
||||||
|
* @param file Excel文件(包含人员信息) |
||||||
|
* @param entrustId 委托ID |
||||||
|
* @return 是否成功导入 |
||||||
|
* @throws Exception 发生异常时抛出 |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public Boolean uploadHairInspectExcel(MultipartFile file, String entrustId) throws Exception { |
||||||
|
|
||||||
|
// 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("当前不支持两社人员之外的委托信息进行导入!"); |
||||||
|
} |
||||||
|
|
||||||
|
// 2. 获取案件与毒品信息
|
||||||
|
// 2.1 校验案件信息
|
||||||
|
CaseEvent cj = caseEventService.validateCaseInfo(entrustment.getCaseId()); |
||||||
|
|
||||||
|
// 2.2 获取默认毒品(海洛因)
|
||||||
|
|
||||||
|
|
||||||
|
// 2.3 获取所有毒品名称映射(便于匹配检测结果)
|
||||||
|
R<List<DrugLite>> innerGetAllR = remoteCommDrugService.innerGetAll(); |
||||||
|
List<DrugLite> drugLiteList = innerGetAllR.getData(); |
||||||
|
Map<String, DrugLite> drugLiteMap = drugLiteList.stream() |
||||||
|
.collect(Collectors.toMap(DrugLite::getName, Function.identity())); |
||||||
|
|
||||||
|
// 3. 读取Excel内容(从第一行数据开始读取)
|
||||||
|
int headIndex = 1; |
||||||
|
List<Map<String, String>> data = ExcelUtils.readExcel(file, headIndex); |
||||||
|
|
||||||
|
// 3.1 获取当前委托下已有检材数,作为orderNo起始编号
|
||||||
|
int orderNo = entrustmentIdentificationMaterialService.lambdaQuery() |
||||||
|
.eq(EntrustmentIdentificationMaterial::getEntrustmentId, entrustId) |
||||||
|
.list().size() + 1; |
||||||
|
|
||||||
|
// 3.2 初始化结果对象集合
|
||||||
|
List<EntrustMaterialCheckoutResult> results = new ArrayList<>(); |
||||||
|
|
||||||
|
ArrayList<Suspect> suspects = new ArrayList<>(); |
||||||
|
for (Map<String, String> datum : data) { |
||||||
|
Suspect suspect = new Suspect(); |
||||||
|
suspect.setName(datum.get("姓名")); |
||||||
|
suspect.setIdNumber(datum.get("身份证号")); |
||||||
|
suspects.add(suspect); |
||||||
|
} |
||||||
|
if (CollUtil.isNotEmpty(suspects)) { |
||||||
|
suspectService.remove(Wrappers.<Suspect>lambdaQuery() |
||||||
|
.eq(Suspect::getEntrustId, entrustId)); |
||||||
|
suspectService.addSuspectList(suspects, entrustId); |
||||||
|
} |
||||||
|
List<EntrustmentIdentificationMaterial> entrustmentIdentificationMaterialList = new ArrayList<>(); |
||||||
|
|
||||||
|
// 4. 遍历Excel数据行,构建检材与检测结果
|
||||||
|
for (Map<String, String> 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()); |
||||||
|
|
||||||
|
// 检测结果解析
|
||||||
|
ArrayList<DrugLite> matchedDrugs = new ArrayList<>(); |
||||||
|
String[] drugs = datum.get("检测结果").split("、"); |
||||||
|
if (drugs.length == 0 || (drugs.length == 1 && drugs[0].trim().isEmpty())) { |
||||||
|
matchedDrugs.add(drugLiteMap.get("海洛因")); |
||||||
|
} else { |
||||||
|
boolean matched = false; |
||||||
|
for (String drugName : drugs) { |
||||||
|
if (drugLiteMap.containsKey(drugName)) { |
||||||
|
matchedDrugs.add(drugLiteMap.get(drugName)); |
||||||
|
matched = true; |
||||||
|
} |
||||||
|
} |
||||||
|
if (!matched) { |
||||||
|
matchedDrugs.add(drugLiteMap.get("海洛因")); |
||||||
|
} |
||||||
|
} |
||||||
|
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()); |
||||||
|
|
||||||
|
entrustmentIdentificationMaterialService.setMaterialIdentificationNo(material, cj); |
||||||
|
material.setSample1No(sampleService.getNewSampleNo(material.getImNo(), 1)); |
||||||
|
|
||||||
|
entrustmentIdentificationMaterialList.add(material); |
||||||
|
} |
||||||
|
// entrustMaterialCheckoutResultService.saveBatch(results);
|
||||||
|
boolean isSave = entrustmentIdentificationMaterialService.saveBatch(entrustmentIdentificationMaterialList); |
||||||
|
String entrustReq = entrustmentService.buildEntrustReq(entrustmentIdentificationMaterialList); |
||||||
|
entrustment.setEntrustRequirement(entrustReq); |
||||||
|
entrustmentService.updateById(entrustment); |
||||||
|
// 5. 批量保存检材信息和检测结果
|
||||||
|
return isSave; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 根据当前用户的机构id查询属于这个机构的委托信息 |
||||||
|
* |
||||||
|
* @param year 年份,用于筛选特定年份的委托信息 |
||||||
|
* @param response |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public void exportByEntrustOrg(Integer year, HttpServletResponse response) throws IOException { |
||||||
|
DLPUser user = SecurityUtils.getUser(); |
||||||
|
// 查询委托单位是当前用户机构id的委托信息
|
||||||
|
List<EntrustmentVO> entrustmentVOList = entrustmentMapper.getEntrustmentVOList( |
||||||
|
Wrappers.<Entrustment>query() |
||||||
|
.eq("e.client_org_id", user.getOrgId()) |
||||||
|
.eq("e.status", EntrustStatusConstants.ENTRUST_STATUS_ACCEPTED.getStatus()) |
||||||
|
.likeRight(year != null , "e.accept_time", year) |
||||||
|
.orderByDesc("e.accept_time") |
||||||
|
); |
||||||
|
|
||||||
|
if (CollUtil.isEmpty(entrustmentVOList)) { |
||||||
|
throw new CheckedException(String.format("当前用户机构 [%s] 无委托信息!", user.getOrgName())); |
||||||
|
} |
||||||
|
|
||||||
|
// 获取检材信息
|
||||||
|
List<EntrustmentIdentificationMaterial> identificationMaterials = entrustmentIdentificationMaterialService.list( |
||||||
|
Wrappers.<EntrustmentIdentificationMaterial>lambdaQuery() |
||||||
|
.in(EntrustmentIdentificationMaterial::getEntrustmentId, |
||||||
|
entrustmentVOList.stream().map(EntrustmentVO::getId).collect(Collectors.toList())) |
||||||
|
); |
||||||
|
|
||||||
|
// 分组
|
||||||
|
Map<String, List<EntrustmentIdentificationMaterial>> materialGroupMap = identificationMaterials.stream().collect(Collectors.groupingBy(EntrustmentIdentificationMaterial::getEntrustmentId)); |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 获取嫌疑人信息并根据委托id分组
|
||||||
|
Map<String, String> suspectGroupMap = buildSuspectInfoGroupByEntrustId(entrustmentVOList); |
||||||
|
|
||||||
|
SXSSFWorkbook workbook = new SXSSFWorkbook(); |
||||||
|
Sheet sheet = workbook.createSheet(user.getOrgName() + "已受理委托信息统计"); |
||||||
|
|
||||||
|
// ====== 合并第一行单元格 (0,0) 到 (0, 列数-1)
|
||||||
|
List<EntrustExportHeaderEnum> headers = CollUtil.newArrayList(EntrustExportHeaderEnum.values()); |
||||||
|
sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, headers.size() - 1)); |
||||||
|
|
||||||
|
// ====== 设置标题行内容
|
||||||
|
Row titleRow = sheet.createRow(0); |
||||||
|
Cell titleCell = titleRow.createCell(0); |
||||||
|
titleCell.setCellValue(user.getOrgName() + "已受理委托信息统计"); |
||||||
|
|
||||||
|
// 可选:设置样式(加粗、居中)
|
||||||
|
CellStyle titleStyle = workbook.createCellStyle(); |
||||||
|
Font font = workbook.createFont(); |
||||||
|
font.setBold(true); |
||||||
|
font.setFontHeightInPoints((short) 14); |
||||||
|
titleStyle.setFont(font); |
||||||
|
titleStyle.setAlignment(HorizontalAlignment.CENTER); |
||||||
|
titleCell.setCellStyle(titleStyle); |
||||||
|
|
||||||
|
// ====== 第二行为表头
|
||||||
|
Row headerRow = sheet.createRow(1); |
||||||
|
for (int i = 0; i < headers.size(); i++) { |
||||||
|
headerRow.createCell(i).setCellValue(headers.get(i).getHeader()); |
||||||
|
// // 设置自动长度
|
||||||
|
// sheet.autoSizeColumn(i);
|
||||||
|
} |
||||||
|
|
||||||
|
// ====== 第三行开始写入数据
|
||||||
|
for (int i = 0; i < entrustmentVOList.size(); i++) { |
||||||
|
EntrustmentVO vo = entrustmentVOList.get(i); |
||||||
|
Row row = sheet.createRow(i + 2); |
||||||
|
|
||||||
|
for (int j = 0; j < headers.size(); j++) { |
||||||
|
EntrustExportHeaderEnum header = headers.get(j); |
||||||
|
Cell cell = row.createCell(j); |
||||||
|
|
||||||
|
switch (header) { |
||||||
|
case CASE_NAME: |
||||||
|
cell.setCellValue(vo.getCaseName()); |
||||||
|
break; |
||||||
|
case CASE_BRIEF: |
||||||
|
cell.setCellValue(vo.getCaseBrief()); |
||||||
|
break; |
||||||
|
case HAPPEN_TIME: |
||||||
|
cell.setCellValue(vo.getHappenTime()); |
||||||
|
break; |
||||||
|
case SUSPECT_INFO: |
||||||
|
cell.setCellValue(suspectGroupMap.get(vo.getId())); |
||||||
|
break; |
||||||
|
case CLIENT_ORG_NAME: |
||||||
|
cell.setCellValue(vo.getClientOrgName()); |
||||||
|
break; |
||||||
|
case ENTRUST_TIME: |
||||||
|
cell.setCellValue(vo.getEntrustmentTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"))); |
||||||
|
break; |
||||||
|
case ACCEPT_NO: |
||||||
|
cell.setCellValue(vo.getAcceptNo()); |
||||||
|
break; |
||||||
|
case ACCEPT_TIME: |
||||||
|
cell.setCellValue(vo.getAcceptTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"))); |
||||||
|
break; |
||||||
|
case ENTRUST_REQUIREMENT: |
||||||
|
cell.setCellValue(vo.getEntrustRequirement()); |
||||||
|
break; |
||||||
|
case MATERIAL_CHARACTER: |
||||||
|
cell.setCellValue(entrustMaterialCheckoutResultService.buildMaterialCharacterDesc(materialGroupMap.get(vo.getId()))); |
||||||
|
break; |
||||||
|
case MATERIAL_COUNT: |
||||||
|
cell.setCellValue(vo.getIdentificationMaterialCount()); |
||||||
|
break; |
||||||
|
case MATERIAL_RESULT: |
||||||
|
cell.setCellValue(entrustMaterialCheckoutResultService.buildEntrustMaterialCheckoutResultStr(vo.getId())); |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
// ====== 输出到浏览器
|
||||||
|
// response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
||||||
|
// 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(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 根据委托id分组,拼接嫌疑人姓名和身份证 |
||||||
|
* @param entrustmentVOList |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
private Map<String, String> buildSuspectInfoGroupByEntrustId(List<EntrustmentVO> entrustmentVOList) { |
||||||
|
List<Suspect> suspectList = suspectService.list( |
||||||
|
Wrappers.<Suspect>lambdaQuery() |
||||||
|
.in(Suspect::getEntrustId, |
||||||
|
entrustmentVOList.stream().map(EntrustmentVO::getId).collect(Collectors.toList())) |
||||||
|
); |
||||||
|
|
||||||
|
// 分组
|
||||||
|
Map<String, String> suspectGroupMap = suspectList |
||||||
|
.stream() |
||||||
|
.collect( |
||||||
|
Collectors.groupingBy( // 按照entrustId分组
|
||||||
|
Suspect::getEntrustId, |
||||||
|
Collectors.collectingAndThen( // 收集器:将分组后的列表转换为字符串, 拼接嫌疑人姓名和身份证
|
||||||
|
Collectors.toList(), |
||||||
|
groupList -> groupList |
||||||
|
.stream() |
||||||
|
.map(item -> String.format("%s : %s", item.getName(), item.getIdNumber())) |
||||||
|
.collect(Collectors.joining("、")) |
||||||
|
) |
||||||
|
) |
||||||
|
); |
||||||
|
return suspectGroupMap; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public String getSexByIdNum(String idNumber) { |
||||||
|
// 去除空格并转换为大写
|
||||||
|
idNumber = idNumber.trim().toUpperCase(); |
||||||
|
|
||||||
|
// 校验身份证长度
|
||||||
|
if (idNumber.length() == 18) { |
||||||
|
try { |
||||||
|
// 提取性别
|
||||||
|
int genderCode = Integer.parseInt(idNumber.substring(16, 17)); |
||||||
|
return genderCode % 2 == 0 ? "女" : "男"; |
||||||
|
} catch (Exception e) { |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
return ""; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public String getAgeByIdNum(String idNumber) { |
||||||
|
if (idNumber.length() == 18) { |
||||||
|
try { |
||||||
|
// 提取出生日期并计算年龄
|
||||||
|
String birthDateStr = idNumber.substring(6, 14); |
||||||
|
LocalDate birthDate = LocalDate.parse(birthDateStr, DateTimeFormatter.BASIC_ISO_DATE); |
||||||
|
LocalDate currentDate = LocalDate.now(); |
||||||
|
long age = ChronoUnit.YEARS.between(birthDate, currentDate); |
||||||
|
return String.valueOf(age); |
||||||
|
|
||||||
|
} catch (Exception e) { |
||||||
|
} |
||||||
|
} |
||||||
|
return ""; |
||||||
|
} |
||||||
|
} |
@ -1,230 +0,0 @@ |
|||||||
package digital.laboratory.platform.entrustment.service.impl; |
|
||||||
|
|
||||||
import cn.hutool.core.collection.CollUtil; |
|
||||||
import com.alibaba.fastjson.JSON; |
|
||||||
import com.baomidou.mybatisplus.core.toolkit.IdWorker; |
|
||||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
|
||||||
import digital.laboratory.platform.common.core.exception.CheckedException; |
|
||||||
import digital.laboratory.platform.common.core.util.R; |
|
||||||
import digital.laboratory.platform.entrustment.entity.*; |
|
||||||
import digital.laboratory.platform.entrustment.enums.AnalysisOptionEnums; |
|
||||||
import digital.laboratory.platform.entrustment.enums.EntrustIdentificationSituationType; |
|
||||||
import digital.laboratory.platform.entrustment.service.*; |
|
||||||
import digital.laboratory.platform.entrustment.utils.ExcelUtils; |
|
||||||
import digital.laboratory.platform.sys.entity.DrugLite; |
|
||||||
import digital.laboratory.platform.sys.enums.entrust.EntrustBiologyType; |
|
||||||
import digital.laboratory.platform.sys.feign.RemoteCommDrugService; |
|
||||||
import org.springframework.stereotype.Service; |
|
||||||
import org.springframework.web.multipart.MultipartFile; |
|
||||||
|
|
||||||
import javax.annotation.Resource; |
|
||||||
import java.math.BigDecimal; |
|
||||||
import java.time.LocalDate; |
|
||||||
import java.time.LocalDateTime; |
|
||||||
import java.time.format.DateTimeFormatter; |
|
||||||
import java.time.temporal.ChronoUnit; |
|
||||||
import java.util.ArrayList; |
|
||||||
import java.util.List; |
|
||||||
import java.util.Map; |
|
||||||
import java.util.function.Function; |
|
||||||
import java.util.stream.Collectors; |
|
||||||
|
|
||||||
/** |
|
||||||
* @author ChenJiangBao |
|
||||||
* @version 1.0 |
|
||||||
* @description: excel上传服务层接口 实现类 |
|
||||||
* @date 2025/4/16 11:55 |
|
||||||
*/ |
|
||||||
@Service |
|
||||||
public class ExcelUploadServiceImpl implements ExcelUploadService { |
|
||||||
|
|
||||||
@Resource |
|
||||||
private SampleService sampleService; |
|
||||||
|
|
||||||
@Resource |
|
||||||
private CaseEventService caseEventService; |
|
||||||
|
|
||||||
@Resource |
|
||||||
private EntrustmentService entrustmentService; |
|
||||||
|
|
||||||
@Resource |
|
||||||
private EntrustmentIdentificationMaterialService entrustmentIdentificationMaterialService; |
|
||||||
|
|
||||||
@Resource |
|
||||||
private RemoteCommDrugService remoteCommDrugService; |
|
||||||
|
|
||||||
@Resource |
|
||||||
private EntrustMaterialCheckoutResultService entrustMaterialCheckoutResultService; |
|
||||||
|
|
||||||
@Resource |
|
||||||
private SuspectService suspectService; |
|
||||||
|
|
||||||
/** |
|
||||||
* 上传两社人员名单Excel文件,并自动生成检材与检测结果数据 |
|
||||||
* |
|
||||||
* @param file Excel文件(包含人员信息) |
|
||||||
* @param entrustId 委托ID |
|
||||||
* @return 是否成功导入 |
|
||||||
* @throws Exception 发生异常时抛出 |
|
||||||
*/ |
|
||||||
@Override |
|
||||||
public Boolean uploadHairInspectExcel(MultipartFile file, String entrustId) throws Exception { |
|
||||||
|
|
||||||
// 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("当前不支持两社人员之外的委托信息进行导入!"); |
|
||||||
} |
|
||||||
|
|
||||||
// 2. 获取案件与毒品信息
|
|
||||||
// 2.1 校验案件信息
|
|
||||||
CaseEvent cj = caseEventService.validateCaseInfo(entrustment.getCaseId()); |
|
||||||
|
|
||||||
// 2.2 获取默认毒品(海洛因)
|
|
||||||
|
|
||||||
|
|
||||||
// 2.3 获取所有毒品名称映射(便于匹配检测结果)
|
|
||||||
R<List<DrugLite>> innerGetAllR = remoteCommDrugService.innerGetAll(); |
|
||||||
List<DrugLite> drugLiteList = innerGetAllR.getData(); |
|
||||||
Map<String, DrugLite> drugLiteMap = drugLiteList.stream() |
|
||||||
.collect(Collectors.toMap(DrugLite::getName, Function.identity())); |
|
||||||
|
|
||||||
// 3. 读取Excel内容(从第一行数据开始读取)
|
|
||||||
int headIndex = 1; |
|
||||||
List<Map<String, String>> data = ExcelUtils.readExcel(file, headIndex); |
|
||||||
|
|
||||||
// 3.1 获取当前委托下已有检材数,作为orderNo起始编号
|
|
||||||
int orderNo = entrustmentIdentificationMaterialService.lambdaQuery() |
|
||||||
.eq(EntrustmentIdentificationMaterial::getEntrustmentId, entrustId) |
|
||||||
.list().size() + 1; |
|
||||||
|
|
||||||
// 3.2 初始化结果对象集合
|
|
||||||
List<EntrustMaterialCheckoutResult> results = new ArrayList<>(); |
|
||||||
|
|
||||||
ArrayList<Suspect> suspects = new ArrayList<>(); |
|
||||||
for (Map<String, String> datum : data) { |
|
||||||
Suspect suspect = new Suspect(); |
|
||||||
suspect.setName(datum.get("姓名")); |
|
||||||
suspect.setIdNumber(datum.get("身份证号")); |
|
||||||
suspects.add(suspect); |
|
||||||
} |
|
||||||
if (CollUtil.isNotEmpty(suspects)){ |
|
||||||
suspectService.remove(Wrappers.<Suspect>lambdaQuery() |
|
||||||
.eq(Suspect::getEntrustId, entrustId)); |
|
||||||
suspectService.addSuspectList(suspects, entrustId); |
|
||||||
} |
|
||||||
List<EntrustmentIdentificationMaterial> entrustmentIdentificationMaterialList = new ArrayList<>(); |
|
||||||
|
|
||||||
// 4. 遍历Excel数据行,构建检材与检测结果
|
|
||||||
for (Map<String, String> 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()); |
|
||||||
|
|
||||||
// 检测结果解析
|
|
||||||
ArrayList<DrugLite> matchedDrugs = new ArrayList<>(); |
|
||||||
String[] drugs = datum.get("检测结果").split("、"); |
|
||||||
if (drugs.length == 0 || (drugs.length == 1 && drugs[0].trim().isEmpty())){ |
|
||||||
matchedDrugs.add(drugLiteMap.get("海洛因")); |
|
||||||
}else { |
|
||||||
boolean matched = false; |
|
||||||
for (String drugName : drugs) { |
|
||||||
if (drugLiteMap.containsKey(drugName)) { |
|
||||||
matchedDrugs.add(drugLiteMap.get(drugName)); |
|
||||||
matched = true; |
|
||||||
} |
|
||||||
} |
|
||||||
if (!matched) { |
|
||||||
matchedDrugs.add(drugLiteMap.get("海洛因")); |
|
||||||
} |
|
||||||
} |
|
||||||
material.setCandidateDrugs(matchedDrugs); |
|
||||||
// if (!matchedDrugs.isEmpty()) {
|
|
||||||
// EntrustMaterialCheckoutResult result = new EntrustMaterialCheckoutResult();
|
|
||||||
// result.setId(material.getId());
|
|
||||||
// result.setQualitativeResult(JSON.toJSONString(matchedDrugs));
|
|
||||||
// result.setEntrustId(entrustId);
|
|
||||||
// results.add(result);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// 设置检材默认属性
|
|
||||||
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); |
|
||||||
} |
|
||||||
// entrustMaterialCheckoutResultService.saveBatch(results);
|
|
||||||
boolean isSave = entrustmentIdentificationMaterialService.saveBatch(entrustmentIdentificationMaterialList); |
|
||||||
String entrustReq = entrustmentService.buildEntrustReq(entrustmentIdentificationMaterialList); |
|
||||||
entrustment.setEntrustRequirement(entrustReq); |
|
||||||
entrustmentService.updateById(entrustment); |
|
||||||
// 5. 批量保存检材信息和检测结果
|
|
||||||
return isSave; |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
public String getSexByIdNum(String idNumber) { |
|
||||||
// 去除空格并转换为大写
|
|
||||||
idNumber = idNumber.trim().toUpperCase(); |
|
||||||
|
|
||||||
// 校验身份证长度
|
|
||||||
if (idNumber.length() == 18) { |
|
||||||
try { |
|
||||||
// 提取性别
|
|
||||||
int genderCode = Integer.parseInt(idNumber.substring(16, 17)); |
|
||||||
return genderCode % 2 == 0 ? "女" : "男"; |
|
||||||
} catch (Exception e) { |
|
||||||
|
|
||||||
} |
|
||||||
} |
|
||||||
return ""; |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
public String getAgeByIdNum(String idNumber) { |
|
||||||
if (idNumber.length() == 18) { |
|
||||||
try { |
|
||||||
// 提取出生日期并计算年龄
|
|
||||||
String birthDateStr = idNumber.substring(6, 14); |
|
||||||
LocalDate birthDate = LocalDate.parse(birthDateStr, DateTimeFormatter.BASIC_ISO_DATE); |
|
||||||
LocalDate currentDate = LocalDate.now(); |
|
||||||
long age = ChronoUnit.YEARS.between(birthDate, currentDate); |
|
||||||
return String.valueOf(age); |
|
||||||
|
|
||||||
} catch (Exception e) { |
|
||||||
} |
|
||||||
} |
|
||||||
return ""; |
|
||||||
} |
|
||||||
} |
|
Loading…
Reference in new issue