From ecf37974a4550721fa34548ea160dc232237c325 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=B5=B7=E8=88=AA?= <11918452+yang-haihang@user.noreply.gitee.com> Date: Mon, 16 Jun 2025 16:29:22 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B0=86=E5=B8=B8=E8=A7=84=E6=AF=92=E5=93=81?= =?UTF-8?q?=E9=89=B4=E5=AE=9A=E6=8A=A5=E5=91=8A=E7=9A=84=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E4=BB=8E=E6=96=87=E4=B9=A6=E7=B3=BB=E7=BB=9F=E8=BF=81=E7=A7=BB?= =?UTF-8?q?=E8=87=B3=E9=80=81=E6=A3=80=E5=8F=97=E7=90=86=E7=B3=BB=E7=BB=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...rustMaterialCheckoutResultServiceImpl.java | 252 +++++++++++++++++- 1 file changed, 244 insertions(+), 8 deletions(-) diff --git a/src/main/java/digital/laboratory/platform/entrustment/service/impl/EntrustMaterialCheckoutResultServiceImpl.java b/src/main/java/digital/laboratory/platform/entrustment/service/impl/EntrustMaterialCheckoutResultServiceImpl.java index 15e6697..4194fb1 100644 --- a/src/main/java/digital/laboratory/platform/entrustment/service/impl/EntrustMaterialCheckoutResultServiceImpl.java +++ b/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 implements EntrustMaterialCheckoutResultService { @@ -1122,10 +1126,16 @@ public class EntrustMaterialCheckoutResultServiceImpl extends ServiceImpl 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 materialMap) { @@ -1241,12 +1251,239 @@ public class EntrustMaterialCheckoutResultServiceImpl extends ServiceImpl 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 包含远程API响应数据的ResponseEntity对象 + */ + private ResponseEntity exchangeRemoteApi(JSONObject jsonObject, String url) { + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); // 设置为 application/json + HttpEntity requestEntity = new HttpEntity<>(jsonObject, headers); + ResponseEntity response = HttpsUtils + .genRestTemplate() + .exchange( + url, + HttpMethod.POST, + requestEntity, + String.class + ); + return response; + } + + /** + * 构建推送定性报告的json数据 + * + * @param entrust 委托信息 + * @return + */ + private JSONObject buildQualitativeReportJsonPayload(Entrustment entrust, DLPUser dlpUser) { + + List 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 list = this.lambdaQuery() + .eq(EntrustMaterialCheckoutResult::getEntrustId, entrustId) + .isNotNull(EntrustMaterialCheckoutResult::getQualitativeResult) + .list(); + + Set idList = list.stream() + .map(EntrustMaterialCheckoutResult::getId) + .collect(Collectors.toSet()); + + Map resultMap = list.stream() + .collect(Collectors.toMap(EntrustMaterialCheckoutResult::getId, Function.identity())); + + List materialList = entrustmentIdentificationMaterialService.lambdaQuery() + .in(EntrustmentIdentificationMaterial::getId, idList) + .list(); + + materialList.sort(Comparator.comparing(sample -> extractTailNumber(sample.getAcceptNo()))); + + // drugName -> List + Map> drugToOrderNos = new HashMap<>(); + + for (EntrustmentIdentificationMaterial material : materialList) { + List 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>> entries = new ArrayList<>(drugToOrderNos.entrySet()); + entries.sort(Comparator.comparingInt(e -> Collections.min(e.getValue()))); + + StringBuilder sb = new StringBuilder(); + for (Map.Entry> entry : entries) { + String drugName = entry.getKey(); + List 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 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 materialList) { + if (CollUtil.isEmpty(materialList)) { + return StrUtil.EMPTY; + } + + // 按尾号排序(提取编号尾号进行比较) + materialList.sort(Comparator.comparing(sample -> extractTailNumber(sample.getAcceptNo()))); + + List descriptions = new ArrayList<>(); + int start = -1, prev = -1; + String prevForm = null; + List 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