将常规毒品鉴定报告的功能从文书系统迁移至送检受理系统

master
杨海航 1 week ago
parent cd74639604
commit ecf37974a4
  1. 252
      src/main/java/digital/laboratory/platform/entrustment/service/impl/EntrustMaterialCheckoutResultServiceImpl.java

@ -3,6 +3,7 @@ package digital.laboratory.platform.entrustment.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
@ -32,18 +33,20 @@ import digital.laboratory.platform.entrustment.vo.DetectionRateVO;
import digital.laboratory.platform.entrustment.vo.EntrustMaterialCheckoutResultVO;
import digital.laboratory.platform.entrustment.vo.EntrustmentIdentificationMaterialVO;
import digital.laboratory.platform.entrustment.vo.SuspectDetectionVO;
import digital.laboratory.platform.othersys.utils.HttpsUtils;
import digital.laboratory.platform.sys.entity.Area;
import digital.laboratory.platform.sys.entity.DrugLite;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.*;
import org.springframework.beans.BeanUtils;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import springfox.documentation.spring.web.json.Json;
import org.springframework.web.client.RestClientException;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
@ -67,6 +70,7 @@ import java.util.stream.Collectors;
* @createDate 2024-12-30 16:16:25
*/
@Service
@Slf4j
public class EntrustMaterialCheckoutResultServiceImpl extends ServiceImpl<EntrustMaterialCheckoutResultMapper, EntrustMaterialCheckoutResult>
implements EntrustMaterialCheckoutResultService {
@ -1122,10 +1126,16 @@ public class EntrustMaterialCheckoutResultServiceImpl extends ServiceImpl<Entrus
.map(r -> buildResultVO(r, materialMap))
.sorted(Comparator.comparingInt(EntrustMaterialCheckoutResultVO::getOrderNo))
.collect(Collectors.toList());
boolean push = pushToDatabase(suspects, resultVOS, entrustment, caseEvent, user);
if (entrustment.getEntrustmentType() == 0) {
push = this.pushQualitativeReportData(entrustment, user);
}
if (push) {
entrustment.setPlatformFlag(true);
entrustmentService.updateById(entrustment);
}
// 数据推送至目标数据库
return pushToDatabase(suspects, resultVOS, entrustment, caseEvent, user);
return push;
}
private EntrustMaterialCheckoutResultVO buildResultVO(EntrustMaterialCheckoutResult result, Map<String, EntrustmentIdentificationMaterial> materialMap) {
@ -1241,12 +1251,239 @@ public class EntrustMaterialCheckoutResultServiceImpl extends ServiceImpl<Entrus
return false;
}
entrustment.setPlatformFlag(true);
entrustmentService.updateById(entrustment);
return true;
}
public boolean pushQualitativeReportData(Entrustment entrust, DLPUser dlpUser) {
JSONObject jsonObject = this.buildQualitativeReportJsonPayload(entrust, dlpUser);
log.info("推送定性报告数据, 受理编号: {}, 请求数据: {}", entrust.getAcceptNo(), jsonObject);
try {
ResponseEntity<String> response = exchangeRemoteApi(jsonObject, "http://83.3.9.45/thirdparty/report-generate/dingXingReport/v1");
if (response.getStatusCode().is2xxSuccessful() && response.getBody().contains("\"status\":200")) {
log.info("推送定性报告数据成功, 受理编号: {}, 响应: {}", entrust.getAcceptNo(), response.getBody());
return true;
} else {
log.warn("推送定性报告数据失败, 受理编号: {}, 状态码: {}, 响应: {}",
entrust.getAcceptNo(), response.getStatusCode(), response.getBody());
return false;
}
} catch (RestClientException e) {
log.error("推送定性报告数据到 LabsCare 失败, 受理编号: {}", entrust.getAcceptNo(), e);
return false;
}
}
/**
* 通过POST请求与远程API进行交互
*
* @param jsonObject 包含请求数据的JSONObject对象
* @param url 远程API的URL
* @return ResponseEntity<String> 包含远程API响应数据的ResponseEntity对象
*/
private ResponseEntity<String> exchangeRemoteApi(JSONObject jsonObject, String url) {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON); // 设置为 application/json
HttpEntity<JSONObject> requestEntity = new HttpEntity<>(jsonObject, headers);
ResponseEntity<String> response = HttpsUtils
.genRestTemplate()
.exchange(
url,
HttpMethod.POST,
requestEntity,
String.class
);
return response;
}
/**
* 构建推送定性报告的json数据
*
* @param entrust 委托信息
* @return
*/
private JSONObject buildQualitativeReportJsonPayload(Entrustment entrust, DLPUser dlpUser) {
List<EntrustmentIdentificationMaterial> materialList = entrustmentIdentificationMaterialService.lambdaQuery()
.eq(EntrustmentIdentificationMaterial::getEntrustmentId, entrust.getId())
.list();
CaseEvent caseEvent = caseEventService.getById(entrust.getCaseId());
String[] splitAcceptNo = entrust.getAcceptNo().split("-");
// 封装推送定性报告数据
JSONObject jsonObject = new JSONObject();
jsonObject.set("jcxz", buildMaterialCharacterDesc(materialList)); // 检材性状描述
jsonObject.set("jiandingwenshuhao", String.format("[%s]%s号", splitAcceptNo[0], splitAcceptNo[1])); // 鉴定文书号
jsonObject.set("jdyq", entrust.getEntrustRequirement()); // 鉴定要求
jsonObject.set("jyaq", caseEvent.getCaseBrief()); // 简要案情
jsonObject.set("jyy1qm", dlpUser.getName()); // 检测人
jsonObject.set("jyyr2qm", dlpUser.getName()); // 检测人
jsonObject.set("jyy1zc", "#NULL#"); // 检验人1专业技术资格或职称
jsonObject.set("jyy2zc", "#NULL#"); // 检验人2专业技术资格或职称
jsonObject.set("qfrq", "#NULL#");
jsonObject.set("qrcode", "#NULL#"); // 二维码地址
jsonObject.set("sjr1List", CollUtil.newArrayList(entrust.getDeliverer1Name(), entrust.getDeliverer2Name())); // 送检人
jsonObject.set("slrq", entrust.getAcceptTime().format(DateTimeFormatter.ofPattern("yyyy年MM月dd日")));
jsonObject.set("wtdw", entrust.getClientOrgName()); // 委托单位
jsonObject.set("zrqm", "#NULL#"); // 授权签字人
jsonObject.set("zrzc", "#NULL#"); // 授权签字人专业技术资格或职称
// 定性检验报告样品 检测信息
JSONObject inspectDataInfo = new JSONObject();
inspectDataInfo.set("dxff", "《疑似毒品中 2-氟苯丙胺等 388种麻醉药品和精神药品的定性检验 气相色谱-质谱法》(JD/Y JY01.07-2024)");
inspectDataInfo.set("jysj", entrust.getAcceptTime().format(DateTimeFormatter.ofPattern("yyyy年MM月dd日")));
inspectDataInfo.set("outStr", this.buildResultStr(entrust.getId()));
cn.hutool.json.JSONArray gauging = new cn.hutool.json.JSONArray();
gauging.add(inspectDataInfo);
// 定性检验报告样品信息
JSONObject sampleJson = new JSONObject();
sampleJson.put("gauging", gauging);
cn.hutool.json.JSONArray sampleArrayJSON = new cn.hutool.json.JSONArray();
sampleArrayJSON.add(sampleJson);
jsonObject.set("sample", sampleArrayJSON);
return jsonObject;
}
public String buildResultStr(String entrustId) {
List<EntrustMaterialCheckoutResult> list = this.lambdaQuery()
.eq(EntrustMaterialCheckoutResult::getEntrustId, entrustId)
.isNotNull(EntrustMaterialCheckoutResult::getQualitativeResult)
.list();
Set<String> idList = list.stream()
.map(EntrustMaterialCheckoutResult::getId)
.collect(Collectors.toSet());
Map<String, EntrustMaterialCheckoutResult> resultMap = list.stream()
.collect(Collectors.toMap(EntrustMaterialCheckoutResult::getId, Function.identity()));
List<EntrustmentIdentificationMaterial> materialList = entrustmentIdentificationMaterialService.lambdaQuery()
.in(EntrustmentIdentificationMaterial::getId, idList)
.list();
materialList.sort(Comparator.comparing(sample -> extractTailNumber(sample.getAcceptNo())));
// drugName -> List<orderNo>
Map<String, List<Integer>> drugToOrderNos = new HashMap<>();
for (EntrustmentIdentificationMaterial material : materialList) {
List<DrugLite> drugLites = DrugLiteConvert.getDrugLites(resultMap.get(material.getId()).getQualitativeResult());
Integer orderNo = material.getOrderNo();
for (DrugLite drug : drugLites) {
drugToOrderNos
.computeIfAbsent(drug.getName(), k -> new ArrayList<>())
.add(orderNo);
}
}
// 按每个药品对应的最小 orderNo 进行排序,确保先输出最小号的药品
List<Map.Entry<String, List<Integer>>> entries = new ArrayList<>(drugToOrderNos.entrySet());
entries.sort(Comparator.comparingInt(e -> Collections.min(e.getValue())));
StringBuilder sb = new StringBuilder();
for (Map.Entry<String, List<Integer>> entry : entries) {
String drugName = entry.getKey();
List<Integer> orderNos = entry.getValue();
Collections.sort(orderNos);
sb.append("从");
if (isConsecutive(orderNos) && orderNos.size() >= 2) {
sb.append(orderNos.get(0)).append("号和").append(orderNos.get(orderNos.size() - 1)).append("号检材中");
} else {
sb.append(orderNos.stream()
.map(no -> no + "号检材")
.collect(Collectors.joining("、")))
.append("中");
}
sb.append("检出").append(drugName).append(",");
}
// 去掉最后一个逗号,添加句号
if (sb.length() > 0 && sb.charAt(sb.length() - 1) == ',') {
sb.setCharAt(sb.length() - 1, '。');
}
return sb.toString();
}
private boolean isConsecutive(List<Integer> list) {
for (int i = 1; i < list.size(); i++) {
if (list.get(i) - list.get(i - 1) != 1) {
return false;
}
}
return true;
}
public String buildMaterialCharacterDesc(List<EntrustmentIdentificationMaterial> materialList) {
if (CollUtil.isEmpty(materialList)) {
return StrUtil.EMPTY;
}
// 按尾号排序(提取编号尾号进行比较)
materialList.sort(Comparator.comparing(sample -> extractTailNumber(sample.getAcceptNo())));
List<String> descriptions = new ArrayList<>();
int start = -1, prev = -1;
String prevForm = null;
List<String> mergedOrderNos = new ArrayList<>();
// 遍历排序后的检材编号,合并相邻且性状相同的编号
for (EntrustmentIdentificationMaterial material : materialList) {
int current = extractTailNumber(material.getAcceptNo()); // 提取尾号
String form = material.getForm();
if (start == -1) { // 初始化
start = prev = current;
prevForm = form;
} else if (current == prev + 1 && form.equals(prevForm)) {
// 只有连续尾号 + 相同性状才能合并
prev = current;
} else {
// 遇到新性状或不连续尾号,存储前一段描述
mergedOrderNos.add(formatRange(start, prev) + "检材为" + prevForm);
start = prev = current;
prevForm = form;
}
}
// 处理最后一组数据
mergedOrderNos.add(formatRange(start, prev) + "检材为" + prevForm);
// **如果只有一个检材,省略编号**
if (mergedOrderNos.size() == 1 && materialList.size() == 1) {
return "检材为" + prevForm + "。";
}
return String.join(";", mergedOrderNos) + "。";
}
/**
* 生成编号范围的字符串
*
* @param start 起始编号
* @param end 结束编号
* @return 生成的范围字符串例如 "1号至3号" "5号"
*/
private String formatRange(int start, int end) {
return (start == end) ? start + "号" : start + "号至" + end + "号";
}
/**
* 提取检材编号的尾号即最后一个 `-` 之后的数值
*
* @param orderNo 检材编号格式2025-89-13
* @return 尾号示例返回 13
*/
private int extractTailNumber(String orderNo) {
String[] parts = orderNo.split("-");
return (parts.length > 0) ? Integer.parseInt(parts[parts.length - 1]) : 0;
}
/**
* 推送嫌疑人毒检结果任务
*
@ -1827,7 +2064,6 @@ public class EntrustMaterialCheckoutResultServiceImpl extends ServiceImpl<Entrus
}
}
}

Loading…
Cancel
Save