将常规毒品鉴定报告的功能从文书系统迁移至送检受理系统
This commit is contained in:
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user