diff --git a/src/main/java/digital/laboratory/platform/entrustment/config/properties/ApiPathProperties.java b/src/main/java/digital/laboratory/platform/entrustment/config/properties/ApiPathProperties.java index 93ca979..576f431 100644 --- a/src/main/java/digital/laboratory/platform/entrustment/config/properties/ApiPathProperties.java +++ b/src/main/java/digital/laboratory/platform/entrustment/config/properties/ApiPathProperties.java @@ -4,14 +4,48 @@ import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; +/** + * 贵阳禁毒-情报平台推送数据配置 + */ @Component -@ConfigurationProperties(prefix = "countrydrugsystem.apipath") -@Data +@ConfigurationProperties(prefix = "gyjd.labscare.api") public class ApiPathProperties { - private String tokenPath; - private String taskListPath; - private String receivePath; - private String closePath; - private String rejectPath; - private String returnPath; + /** + * api的ip + */ + private String host; + + /** + * 委托书推送的接口 + */ + private String entrustLetter; + + /** + * 确认书推送接口 + */ + private String confirmLetter; + + public String getHost() { + return host; + } + + public void setHost(String host) { + this.host = host; + } + + public String getEntrustLetter() { + return host + entrustLetter; + } + + public void setEntrustLetter(String entrustLetter) { + this.entrustLetter = entrustLetter; + } + + public String getConfirmLetter() { + return host + confirmLetter; + } + + public void setConfirmLetter(String confirmLetter) { + this.confirmLetter = confirmLetter; + } } diff --git a/src/main/java/digital/laboratory/platform/entrustment/constant/DateTimeFormatterConstants.java b/src/main/java/digital/laboratory/platform/entrustment/constant/DateTimeFormatterConstants.java new file mode 100644 index 0000000..69837be --- /dev/null +++ b/src/main/java/digital/laboratory/platform/entrustment/constant/DateTimeFormatterConstants.java @@ -0,0 +1,17 @@ +package digital.laboratory.platform.entrustment.constant; + +/** + * 实际类型的格式化常量 + */ +public interface DateTimeFormatterConstants { + + String yyyy年MM月dd日 = "yyyy年MM月dd日"; + + String yyyy年MM月dd日_HH时mm分ss秒 = "yyyy年MM月dd日 HH时mm分ss秒"; + + String yyyy_MM_dd = "yyyy-MM-dd"; + + String yyyy_MM_dd_HH_mm_ss = "yyyy-MM-dd HH:mm:ss"; + + +} diff --git a/src/main/java/digital/laboratory/platform/entrustment/event/PushDataToLabsCareEvent.java b/src/main/java/digital/laboratory/platform/entrustment/event/PushDataToLabsCareEvent.java new file mode 100644 index 0000000..111ca8a --- /dev/null +++ b/src/main/java/digital/laboratory/platform/entrustment/event/PushDataToLabsCareEvent.java @@ -0,0 +1,37 @@ +package digital.laboratory.platform.entrustment.event; + +import lombok.Getter; +import org.springframework.context.ApplicationEvent; + +import java.time.Clock; + +/** + * 推送数据到LabsCare 数据平台上的spring 事件 + */ +@Getter +public class PushDataToLabsCareEvent extends ApplicationEvent { + + /** + * 委托id + */ + private final String entrustId; + + /** + * 推送的数据类型, 1 鉴定委托书数据 | 2 鉴定事项确认书数据 + */ + private final Integer pushType; + + public PushDataToLabsCareEvent(Object source, String entrustId, Integer pushType) { + super(source); + this.entrustId = entrustId; + this.pushType = pushType; + } + + public PushDataToLabsCareEvent(Object source, Clock clock, String entrustId, Integer pushType) { + super(source, clock); + this.entrustId = entrustId; + this.pushType = pushType; + } + + +} diff --git a/src/main/java/digital/laboratory/platform/entrustment/listener/PushDataToLabsCareEventListener.java b/src/main/java/digital/laboratory/platform/entrustment/listener/PushDataToLabsCareEventListener.java new file mode 100644 index 0000000..fd38eb0 --- /dev/null +++ b/src/main/java/digital/laboratory/platform/entrustment/listener/PushDataToLabsCareEventListener.java @@ -0,0 +1,256 @@ +package digital.laboratory.platform.entrustment.listener; + +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONObject; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import digital.laboratory.platform.entrustment.config.GlobalThreadPool; +import digital.laboratory.platform.entrustment.config.properties.ApiPathProperties; +import digital.laboratory.platform.entrustment.entity.EntrustmentIdentificationMaterial; +import digital.laboratory.platform.entrustment.event.PushDataToLabsCareEvent; +import digital.laboratory.platform.entrustment.service.CommonFeignService; +import digital.laboratory.platform.entrustment.service.EntrustmentIdentificationMaterialService; +import digital.laboratory.platform.entrustment.service.EntrustmentService; +import digital.laboratory.platform.entrustment.vo.EntrustmentVO; +import digital.laboratory.platform.entrustment.vo.MaterialListForBookVo; +import digital.laboratory.platform.othersys.utils.HttpsUtils; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.ApplicationListener; +import org.springframework.http.*; +import org.springframework.stereotype.Component; +import org.springframework.web.client.RestClientException; + +import javax.annotation.Resource; +import java.time.format.DateTimeFormatter; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Collectors; + +/** + * 监听有关推送数据到LabsCare 平台的事件, 采用异步 + */ +@Slf4j +@Component +public class PushDataToLabsCareEventListener implements ApplicationListener { + + @Resource + private ApiPathProperties apiPathProperties; + + @Resource + private EntrustmentService entrustmentService; + + @Resource + private CommonFeignService commonFeignService; + + @Resource + private EntrustmentIdentificationMaterialService entrustmentIdentificationMaterialService; + + private DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日"); + + /** + * 处理委托数据推送事件 + * + * @param event 委托数据推送事件对象 + */ + @Override + public void onApplicationEvent(PushDataToLabsCareEvent event) { + CompletableFuture.supplyAsync(() -> { + // 获取委托信息 + EntrustmentVO entrustVO = entrustmentService.getEntrustmentVOById(event.getEntrustId()); + if (entrustVO == null) { + log.warn("未找到委托信息, entrustId={}", event.getEntrustId()); + return null; + } + return entrustVO; + }, GlobalThreadPool.getInstance()).thenAcceptAsync(entrustVO -> { + if (entrustVO == null) return; // 提前返回,避免后续报错 + + // 处理不同的推送类型 + switch (event.getPushType()) { + case 1: // 推送委托书数据 + try { + Map dataMap = entrustmentService.buildEntrustLetterDataMap(entrustVO); + pushEntrustLetterData(entrustVO, dataMap); + } catch (IllegalAccessException e) { + log.error("委托编号 {} 的鉴定委托书数据推送失败!", entrustVO.getEntrustmentNo(), e); + } + break; + case 2: // 推送鉴定事项确认书数据 + try { + pushItemConfirmLetterData(entrustVO); + } catch (Exception e) { + log.error("受理编号 {} 的鉴定事项确认书数据推送失败!", entrustVO.getAcceptNo(), e); + } + break; + default: + log.warn("未知的推送类型: {}", event.getPushType()); + break; + } + }, GlobalThreadPool.getInstance()).exceptionally(e -> { + log.error("推送数据到 LabsCare 失败", e); + return null; + }); + } + + /** + * 推送鉴定事项确认书数据 + * + * @param entrustVO 委托vo + */ + private void pushItemConfirmLetterData(EntrustmentVO entrustVO) { + JSONObject jsonObject = buildItemConfirmLetterJsonPayload(entrustVO); + + try { + ResponseEntity response = exchangeRemoteApi(jsonObject, apiPathProperties.getConfirmLetter()); + + if (response.getStatusCode().is2xxSuccessful() && response.getBody().contains("\"status\":200")) { + log.info("推送鉴定事项确认书数据成功, 受理编号: {}, 响应: {}", entrustVO.getAcceptNo(), response.getBody()); + } else { + log.warn("推送鉴定事项确认书数据失败, 受理编号: {}, 状态码: {}, 响应: {}", + entrustVO.getAcceptNo(), response.getStatusCode(), response.getBody()); + } + } catch (RestClientException e) { + log.error("推送鉴定事项确认书数据到 LabsCare 失败, 受理编号: {}", entrustVO.getAcceptNo(), e); + } + } + + /** + * 构建鉴定事项确认书的JSON负载 + * + * @param entrustVO 委托单VO对象,包含构建JSON负载所需的数据 + * @return 包含鉴定事项确认书数据的JSONObject对象 + */ + private JSONObject buildItemConfirmLetterJsonPayload(EntrustmentVO entrustVO) { + JSONObject jsonObject = new JSONObject(); + jsonObject.set("ajmc", entrustVO.getCaseName()); // 案件名称 + jsonObject.set("dwfzr", StrUtil.join("、", entrustVO.getDeliverer1Name(), entrustVO.getDeliverer2Name())); // 送检人签名 + // 检材处理要求,这里的值是直接复制了确认书里的值 + jsonObject.set("jcclyq", "以上检材均按照《办理毒品犯罪案件毒品提取、扣押、称量、取样和送检程序若干问题的规定》、《贵阳市公安局关于进一步规范毒品取样、保管及送检程序的通知》要求的提取部位和提取方法进行取样。"); + jsonObject.set("jdjbrqm", ""); /// 鉴定机构经办人签字 ,我们系统是单位自己打印出来,线下自己手签 + jsonObject.set("jdyq", entrustVO.getEntrustRequirement()); // 鉴定要求 + jsonObject.set("jyaq", entrustVO.getCaseBrief()); // 简要案情 + jsonObject.set("lqrqm", ""); // 领取人签名 + jsonObject.set("sjr1", entrustVO.getDeliverer1Name()); // 送检人1姓名 + jsonObject.set("sjr2", entrustVO.getDeliverer2Name()); // 送检人2姓名 + jsonObject.set("sjr1dh", entrustVO.getDeliverer1Phone()); // 送检人电话 + jsonObject.set("sjr2dh", entrustVO.getDeliverer2Phone()); + jsonObject.set("sjr1zjh", StrUtil.join(":", entrustVO.getDeliverer1Cert(), entrustVO.getDeliverer1Id())); // 送检人证件和号码 + jsonObject.set("sjr2zjh", StrUtil.join(":", entrustVO.getDeliverer2Cert(), entrustVO.getDeliverer2Id())); + jsonObject.set("sjr1zw", entrustVO.getDeliverer1Position()); // 送检人职务 + jsonObject.set("sjr2zw", entrustVO.getDeliverer2Position()); + jsonObject.set("slbh", entrustVO.getAcceptNo()); + jsonObject.set("slrq", entrustVO.getAcceptTime().format(formatter)); + jsonObject.set("slr", commonFeignService.remoteGetUserById(entrustVO.getAcceptUser()).getName()); + jsonObject.set("slrqm", ""); // 鉴定机构受理人签字 + jsonObject.set("type", ""); + jsonObject.set("wtbh", entrustVO.getAcceptNo()); // 委托书编号 + jsonObject.set("wtdw", entrustVO.getClientOrgName()); + jsonObject.set("wtsj", entrustVO.getEntrustmentTime().format(formatter)); + List materialList = entrustmentIdentificationMaterialService.list(Wrappers.lambdaQuery() + .eq(EntrustmentIdentificationMaterial::getEntrustmentId, entrustVO.getId())); + List materialBookVoList = entrustmentService.getMaterialBookVoList(materialList); + List table = materialBookVoList.stream().map(materialBookVo -> { + JSONObject materialBookVoJson = new JSONObject(); + materialBookVoJson.set("baozhuang", materialBookVo.isPackComplete() ? "是" : "否"); + materialBookVoJson.set("bh", materialBookVo.getOrderNo()); + materialBookVoJson.set("yswzl", materialBookVo.getMaterialName()); + materialBookVoJson.set("bz", materialBookVo.getRemark()); + materialBookVoJson.set("lcygs", materialBookVo.getRtSampleQuantity()); + materialBookVoJson.set("sl", materialBookVo.getTotalSampleDes()); + materialBookVoJson.set("xzms", materialBookVo.getFormName()); + return materialBookVoJson; + }).collect(Collectors.toList()); + jsonObject.put("table", table); + return jsonObject; + } + + + /** + * 推送委托函数据 + * + * @param entrustVO + * @param dataMap 待推送的数据映射 + */ + private void pushEntrustLetterData(EntrustmentVO entrustVO, Map dataMap) { + JSONObject jsonObject = buildEntrustLetterJsonPayload(entrustVO, dataMap); + + try { + ResponseEntity response = exchangeRemoteApi(jsonObject, apiPathProperties.getEntrustLetter()); + + if (response.getStatusCode().is2xxSuccessful() && response.getBody().contains("\"status\":200")) { + log.info("推送鉴定委托书数据成功, 委托编号: {}, 响应: {}", entrustVO.getEntrustmentNo(), response.getBody()); + } else { + log.warn("推送鉴定委托书数据失败, 委托编号: {}, 状态码: {}, 响应: {}", + entrustVO.getEntrustmentNo(), response.getStatusCode(), response.getBody()); + } + } catch (RestClientException e) { + log.error("推送鉴定委托书数据到 LabsCare 失败, 委托编号: {}", entrustVO.getEntrustmentNo(), e); + } + } + + + /** + * 构建委托函的JSON负载 + * + * @param entrustVO 委托VO对象 + * @param dataMap 数据映射 + * @return 构建好的JSON对象 + */ + private JSONObject buildEntrustLetterJsonPayload(EntrustmentVO entrustVO, Map dataMap) { + JSONObject jsonObject = new JSONObject(); + jsonObject.set("afsj", entrustVO.getHappenTime()); + jsonObject.set("ajmc", entrustVO.getCaseName()); + jsonObject.set("jyaq", entrustVO.getCaseBrief()); + jsonObject.set("sjr1", entrustVO.getDeliverer1Name()); + jsonObject.set("sjr2", entrustVO.getDeliverer2Name()); + jsonObject.set("sjr1dh", entrustVO.getDeliverer1Phone()); + jsonObject.set("sjr2dh", entrustVO.getDeliverer2Phone()); + jsonObject.set("slrq", entrustVO.getAcceptTime().format(formatter)); + jsonObject.set("wtdw", entrustVO.getClientOrgName()); + jsonObject.set("wtsj", entrustVO.getEntrustmentTime().format(formatter)); + jsonObject.set("yjdqk", entrustVO.getOldIdentificationResult()); + + // 组装材料信息 + List materialList = (List) dataMap.get("materialList"); + AtomicInteger index = new AtomicInteger(1); + List table = materialList.stream().map(material -> { + JSONObject materialJson = new JSONObject(); + materialJson.set("bzsfwz", material.getPackComplete() ? "是" : "否"); + materialJson.set("jyjdyq", material.getDrugsValue() + material.getAnalysisOptionValue()); + materialJson.set("lcygs", material.getRtSampleQuantity()); + materialJson.set("projectName", index.getAndIncrement()); + materialJson.set("tqdd", material.getDrawPlace()); + materialJson.set("tqsj", material.getDrawTime().format(formatter)); + materialJson.set("xzms", material.getFormName()); + materialJson.set("yswzl", material.getName()); + materialJson.set("zltj", material.getQuantity() + material.getUnit()); + return materialJson; + }).collect(Collectors.toList()); + + jsonObject.set("table", table); + return jsonObject; + } + + /** + * 通过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; + } +} diff --git a/src/main/java/digital/laboratory/platform/entrustment/service/EntrustmentService.java b/src/main/java/digital/laboratory/platform/entrustment/service/EntrustmentService.java index 3138c97..debf74f 100644 --- a/src/main/java/digital/laboratory/platform/entrustment/service/EntrustmentService.java +++ b/src/main/java/digital/laboratory/platform/entrustment/service/EntrustmentService.java @@ -11,6 +11,7 @@ import digital.laboratory.platform.entrustment.dto.EntrustmentDTO; import digital.laboratory.platform.entrustment.entity.Entrustment; import digital.laboratory.platform.entrustment.entity.EntrustmentIdentificationMaterial; import digital.laboratory.platform.entrustment.vo.EntrustmentVO; +import digital.laboratory.platform.entrustment.vo.MaterialListForBookVo; import digital.laboratory.platform.sys.entity.Deliverer; import digital.laboratory.platform.sys.entity.SysUser; import digital.laboratory.platform.sys.vo.entrustment.MarkersVO; @@ -20,6 +21,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.List; +import java.util.Map; /** * 委托服务类 @@ -81,6 +83,10 @@ public interface EntrustmentService extends IService { * @return */ public String buildEntrustReq(List materialList); + + //构造鉴定事项确认书文书中的检材列表 + List getMaterialBookVoList(List materialList); + /** * 构建检材描述 * @param materialList @@ -124,10 +130,33 @@ public interface EntrustmentService extends IService { Entrustment bizDeliver_Save(Entrustment entrust, DLPUser dlpUser); + /** + * 委托创建人送检提交 + * @param entrust + * @param opCode + * @param dlpUser + * @return + */ Entrustment bizDeliver_Apply(Entrustment entrust, Integer opCode, DLPUser dlpUser); + /** + * 下载鉴定委托书 + * @param id + * @param theHttpServletRequest + * @param httpServletResponse + * @return + */ String bizGetPDFEntrustmentLetter(String id, HttpServletRequest theHttpServletRequest, HttpServletResponse httpServletResponse); + /** + * 构建委托函数据映射 + * + * @param ev 委托VO对象 + * @return 数据映射 + * @throws IllegalAccessException 如果访问对象的属性或方法时发生非法访问异常 + */ + Map buildEntrustLetterDataMap(EntrustmentVO ev) throws IllegalAccessException; + Entrustment bizAccept_Save(Entrustment entrust, DLPUser dlpUser); Entrustment bizAccept_Apply(Entrustment entrust, Integer opCode, DLPUser dlpUser); 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 a24406b..0a5ee79 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 @@ -40,6 +40,7 @@ import digital.laboratory.platform.entrustment.entity.*; import digital.laboratory.platform.entrustment.enums.AnalysisOptionEnums; import digital.laboratory.platform.entrustment.enums.EntrustAlterApplyStatus; import digital.laboratory.platform.entrustment.enums.EntrustmentStatusConstants; +import digital.laboratory.platform.entrustment.event.PushDataToLabsCareEvent; import digital.laboratory.platform.entrustment.handler.AppStartupRunner; import digital.laboratory.platform.entrustment.mapper.EntrustmentMapper; import digital.laboratory.platform.entrustment.misc.ProcessFlowMapper; @@ -63,6 +64,7 @@ import io.seata.spring.annotation.GlobalTransactional; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang.StringUtils; import org.springframework.beans.BeanUtils; +import org.springframework.context.ApplicationContext; import org.springframework.mock.web.MockMultipartFile; import org.springframework.security.oauth2.provider.OAuth2Authentication; import org.springframework.stereotype.Service; @@ -158,6 +160,9 @@ public class EntrustmentServiceImpl extends ServiceImpl getMaterialBookVoList(List materialList) { + @Override + public List getMaterialBookVoList(List materialList) { List materialListForBookVoList = new ArrayList<>(); materialList.forEach(item -> { MaterialListForBookVo eg = getMaterialListForBookVo(item); @@ -2078,6 +2084,51 @@ public class EntrustmentServiceImpl extends ServiceImpl dm = BeanMap.create(ev); //ClassUtils.objectToMap(ev); + Map dm = buildEntrustLetterDataMap(ev); + + //----------------------------- + // 生成 word 版本的 + String entrustmentLetterFileName = "鉴定委托书-" + ev.getEntrustmentNo(); + + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + ossFile.fileGet(OSSDirectoryConstants.TEMPLATE_DIRECTORY + "/" + AppStartupRunner.getCfg(CommonConstants.DLP_CODE_ENTRUSTMENT_LETTER_TEMPLATE), bos); + + byte[] templateArray = bos.toByteArray(); + ByteArrayInputStream bis = new ByteArrayInputStream(templateArray); + bos.close(); + //处理要循环的表格 + MultipleRowTableRenderPolicy policy = new MultipleRowTableRenderPolicy(); + // 现在 bis 是模板的 InputStream + ConfigureBuilder builder = Configure.builder().buildGramer("${", "}").useSpringEL(false); + builder.bind("materialList", policy); + XWPFTemplate template = XWPFTemplate.compile(bis, builder.build()).render(dm); + bis.close(); + + ByteArrayOutputStream fosWord = new ByteArrayOutputStream(); + template.write(fosWord); + template.close(); + + //------------ + ByteArrayInputStream fisWord = new ByteArrayInputStream(fosWord.toByteArray()); + + + boolean fileSave = ossFile.fileSave(OSSDirectoryConstants.DOCUMENT_ENTRUSTMENT_DIRECTORY + "/" + ev.getId() + "/" + entrustmentLetterFileName + ".docx", fisWord); + fosWord.close(); + fisWord.close(); + System.out.println("转换为 Word 结束"); + return fileSave; + } + + + /** + * 构建委托函数据映射 + * + * @param ev 委托VO对象 + * @return 数据映射 + * @throws IllegalAccessException 如果访问对象的属性或方法时发生非法访问异常 + */ + @Override + public Map buildEntrustLetterDataMap(EntrustmentVO ev) throws IllegalAccessException { Map dm = ClassUtils.objectToMap(ev); if (ev.getEntrustmentTime() == null) { ev.setEntrustmentTime(LocalDateTime.now()); @@ -2154,38 +2205,7 @@ public class EntrustmentServiceImpl extends ServiceImpl