From ef9b0aa3a6be65e2ea9e4f2fa8182c9996f99ec2 Mon Sep 17 00:00:00 2001 From: wyb <1977763549@qq.com> Date: Fri, 21 Jul 2023 17:18:38 +0800 Subject: [PATCH] =?UTF-8?q?=E9=AA=8C=E8=AF=81=E6=8A=A4=E7=90=86=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E6=95=B0=E9=87=8F=EF=BC=8C=E8=BF=9B=E8=A1=8C=E8=B4=A8?= =?UTF-8?q?=E6=8E=A7=E6=88=96=E8=80=85=E5=BC=82=E5=B8=B8=E7=9A=84=E6=8E=A8?= =?UTF-8?q?=E9=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../collection/mapper/TBasicMapper.java | 8 ++ .../server/common/config/RedisConfig.java | 37 ++++++ .../util/RedisKeyExpirationHandler.java | 42 ++++++ .../util/RedisKeyExpirationListener.java | 42 ++++++ .../report/api/ShunDePeopleService.java | 21 ++- .../report/api/dto/SdNurDocFailRequest.java | 47 +++++++ .../report/api/dto/SdNurDocFailResponse.java | 21 +++ .../api/impl/ShunDePeopleServiceImpl.java | 26 +++- .../report/config/SdRyReportQueryConfig.java | 4 + .../report/consts/ReportDownloadWait.java | 15 +++ .../report/controller/ApiTestController.java | 8 ++ .../report/controller/MockTestController.java | 13 +- .../docus/server/report/job/ReportJob.java | 26 +++- .../NisReportDownloadWaitHandler.java | 125 ++++++++++++++++++ .../report/mapper/AfScanAssortMapper.java | 20 +++ .../service/ShunDePeopleBusinessService.java | 12 ++ .../impl/ShunDePeopleBusinessServiceImpl.java | 24 ++++ src/main/resources/bootstrap.yml | 4 + .../resources/mapper/AfScanAssortMapper.xml | 13 ++ src/main/resources/mapper/TBasicMapper.xml | 7 + 20 files changed, 498 insertions(+), 17 deletions(-) create mode 100644 src/main/java/com/docus/server/common/config/RedisConfig.java create mode 100644 src/main/java/com/docus/server/common/util/RedisKeyExpirationHandler.java create mode 100644 src/main/java/com/docus/server/common/util/RedisKeyExpirationListener.java create mode 100644 src/main/java/com/docus/server/report/api/dto/SdNurDocFailRequest.java create mode 100644 src/main/java/com/docus/server/report/api/dto/SdNurDocFailResponse.java create mode 100644 src/main/java/com/docus/server/report/consts/ReportDownloadWait.java create mode 100644 src/main/java/com/docus/server/report/listener/NisReportDownloadWaitHandler.java create mode 100644 src/main/java/com/docus/server/report/mapper/AfScanAssortMapper.java create mode 100644 src/main/java/com/docus/server/report/service/ShunDePeopleBusinessService.java create mode 100644 src/main/java/com/docus/server/report/service/impl/ShunDePeopleBusinessServiceImpl.java create mode 100644 src/main/resources/mapper/AfScanAssortMapper.xml diff --git a/src/main/java/com/docus/server/collection/mapper/TBasicMapper.java b/src/main/java/com/docus/server/collection/mapper/TBasicMapper.java index 9478e60..0faeabd 100644 --- a/src/main/java/com/docus/server/collection/mapper/TBasicMapper.java +++ b/src/main/java/com/docus/server/collection/mapper/TBasicMapper.java @@ -51,6 +51,13 @@ public interface TBasicMapper{ Integer getNurseFileCount(@Param("patientId")String patientId); + /** + * 护理采集过滤的文件数量 + * @param patientId 病案主键 + * @return 过滤的文件数量 + */ + Integer getNurseRemoveFileCount(@Param("patientId") String patientId); + /** * 保存护理采集删除文件数量 * @param patientId 病案主键 @@ -86,4 +93,5 @@ public interface TBasicMapper{ * @return 基础数据 */ TBasic getByPatientId(@Param("patientId") String patientId); + } diff --git a/src/main/java/com/docus/server/common/config/RedisConfig.java b/src/main/java/com/docus/server/common/config/RedisConfig.java new file mode 100644 index 0000000..5175c01 --- /dev/null +++ b/src/main/java/com/docus/server/common/config/RedisConfig.java @@ -0,0 +1,37 @@ +package com.docus.server.common.config; + +import com.docus.server.common.util.RedisKeyExpirationListener; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.data.redis.listener.PatternTopic; +import org.springframework.data.redis.listener.RedisMessageListenerContainer; + +@Configuration +public class RedisConfig { + @Autowired + private RedisConnectionFactory redisConnectionFactory; + @Autowired + private StringRedisTemplate stringRedisTemplate; + + @Bean + public RedisKeyExpirationListener redisKeyExpirationListener() { + return new RedisKeyExpirationListener(stringRedisTemplate); + } + + @Bean + public RedisMessageListenerContainer redisMessageListenerContainer(){ + RedisMessageListenerContainer redisMessageListenerContainer = new RedisMessageListenerContainer(); + redisMessageListenerContainer.setConnectionFactory(redisConnectionFactory); + // 监听 __keyevent@0__:expired ,使用键时间监听key的过期 + redisMessageListenerContainer.addMessageListener(redisKeyExpirationListener(), + new PatternTopic("__keyevent@*__:expired")); + + return redisMessageListenerContainer; + } + + + +} diff --git a/src/main/java/com/docus/server/common/util/RedisKeyExpirationHandler.java b/src/main/java/com/docus/server/common/util/RedisKeyExpirationHandler.java new file mode 100644 index 0000000..e2ef16f --- /dev/null +++ b/src/main/java/com/docus/server/common/util/RedisKeyExpirationHandler.java @@ -0,0 +1,42 @@ +package com.docus.server.common.util; + +import lombok.extern.slf4j.Slf4j; + +/** + * reidKey过期处理器 + * + * @author wyb + */ +@Slf4j +public abstract class RedisKeyExpirationHandler { + /** + * 处理redis过期的key + * + * @param expireRedisKey 过期的 redis key + */ + public void handle(String expireRedisKey) { + try { + businessHandle(expireRedisKey); + } catch (Exception ex) { + log.error("redis键:"+expireRedisKey+" 过期,处理发生异常:"+ex.getMessage(),ex); + handleException(expireRedisKey); + } + } + + ; + + /** + * 业务处理,异常调用异常方案 + * + * @param expireRedisKey 过期的 redis key + */ + public abstract void businessHandle(String expireRedisKey) throws Exception; + + /** + * 处理如果发生异常的解决方案 + * + * @param expireRedisKey 过期的 redis key + */ + public abstract void handleException(String expireRedisKey); + +} diff --git a/src/main/java/com/docus/server/common/util/RedisKeyExpirationListener.java b/src/main/java/com/docus/server/common/util/RedisKeyExpirationListener.java new file mode 100644 index 0000000..2603a23 --- /dev/null +++ b/src/main/java/com/docus/server/common/util/RedisKeyExpirationListener.java @@ -0,0 +1,42 @@ +package com.docus.server.common.util; + +import org.springframework.data.redis.connection.Message; +import org.springframework.data.redis.connection.MessageListener; +import org.springframework.data.redis.core.StringRedisTemplate; + +import java.util.List; +import java.util.Objects; +import java.util.concurrent.CopyOnWriteArrayList; + + +/** + * redis 键过期监听 + * + * @author wyb + */ +public class RedisKeyExpirationListener implements MessageListener { + private final StringRedisTemplate stringRedisTemplate; + private final List handlers = new CopyOnWriteArrayList<>(); + + public RedisKeyExpirationListener(StringRedisTemplate stringRedisTemplate) { + this.stringRedisTemplate = stringRedisTemplate; + } + + @Override + public void onMessage(Message message, byte[] bytes) { + byte[] body = message.getBody(); + String expireRedisKey = stringRedisTemplate.getStringSerializer().deserialize(body); + for (RedisKeyExpirationHandler handler : handlers) { + handler.handle(expireRedisKey); + } + } + /** + * 注册redisKey过期的处理器 + * + * @param handler redisKey过期的处理器 + */ + public void register(RedisKeyExpirationHandler handler) { + Objects.requireNonNull(handler); + handlers.add(handler); + } +} diff --git a/src/main/java/com/docus/server/report/api/ShunDePeopleService.java b/src/main/java/com/docus/server/report/api/ShunDePeopleService.java index f15c2ba..971d8ad 100644 --- a/src/main/java/com/docus/server/report/api/ShunDePeopleService.java +++ b/src/main/java/com/docus/server/report/api/ShunDePeopleService.java @@ -1,8 +1,6 @@ package com.docus.server.report.api; -import com.docus.server.report.api.dto.SdJxReportDto; -import com.docus.server.report.api.dto.SdNurseInsertSugarRequest; -import com.docus.server.report.api.dto.SdNurseInsertSugarResponse; +import com.docus.server.report.api.dto.*; import java.util.List; @@ -31,12 +29,15 @@ public interface ShunDePeopleService { /** * 根据顺德人医的报告交叉索引,查询检查报告 + * * @param sdJxReportDto 交叉索引和其他信息 * @return 检查报告 */ String getInspectReportByJxId(SdJxReportDto sdJxReportDto); + /** * 根据顺德人医的报告交叉索引,查询Lis检验报告 + * * @param sdJxReportDto 交叉索引和其他信息 * @return 检查报告 */ @@ -44,16 +45,26 @@ public interface ShunDePeopleService { /** * 根据检查流水或和报告序列号,指定要获取的报告,PACS将生成PDF格式的报告,并将PDF文件的BASE64编码串返回。 - * @param examNo 检查流水号 + * + * @param examNo 检查流水号 * @param reportNo 报告序号 * @return pdfBase64 */ - String getBase64PdfFromPacs(String examNo,String reportNo); + String getBase64PdfFromPacs(String examNo, String reportNo); /** * 顺德人医,查询移动护理报告 + * * @param request 查询参数 * @return 移动护理报告 */ SdNurseInsertSugarResponse getNurseInsertSugarReport(SdNurseInsertSugarRequest request); + + /** + * 顺德人医,移动护理异常推送 + * + * @param request 推送参数 + * @return 移动护理推送结果 + */ + SdNurDocFailResponse pushSdNurDocFail(SdNurDocFailRequest request); } diff --git a/src/main/java/com/docus/server/report/api/dto/SdNurDocFailRequest.java b/src/main/java/com/docus/server/report/api/dto/SdNurDocFailRequest.java new file mode 100644 index 0000000..29be160 --- /dev/null +++ b/src/main/java/com/docus/server/report/api/dto/SdNurDocFailRequest.java @@ -0,0 +1,47 @@ +package com.docus.server.report.api.dto; + +import lombok.Getter; + +import java.util.Objects; + +/** + * 顺德人医 移动护理文档异常推送请求参数 + * + * @author jiashi + */ +@Getter +public class SdNurDocFailRequest { + /** + * 接口名称,默认值:nurse_doc_fai + */ + private final String tradeCode; + /** + * 住院号 + */ + private final String zyh; + /** + * 住院次数 + */ + private final String visit_id; + /** + * 错误代码(默认值-1) + */ + private final String error_code; + /** + * 错误描述 + */ + private final String error_msg; + + public SdNurDocFailRequest(String zyh, String visit_id, String tradeCode,String error_code,String error_msg) { + Objects.requireNonNull(zyh); + Objects.requireNonNull(visit_id); + Objects.requireNonNull(tradeCode); + Objects.requireNonNull(error_code); + Objects.requireNonNull(error_msg); + this.tradeCode = tradeCode; + this.zyh = zyh; + this.visit_id = visit_id; + this.error_code = error_code; + this.error_msg = error_msg; + } +} diff --git a/src/main/java/com/docus/server/report/api/dto/SdNurDocFailResponse.java b/src/main/java/com/docus/server/report/api/dto/SdNurDocFailResponse.java new file mode 100644 index 0000000..4d114d7 --- /dev/null +++ b/src/main/java/com/docus/server/report/api/dto/SdNurDocFailResponse.java @@ -0,0 +1,21 @@ +package com.docus.server.report.api.dto; + +import lombok.Data; + +/** + * 顺德人医 移动护理文档异常推送请求返回体 + * + * @author jiashi + */ +@Data +public class SdNurDocFailResponse { + /** + * 接收代码 + */ + private String error_code; + /** + * 接收提示 + */ + private String error_msg; + +} diff --git a/src/main/java/com/docus/server/report/api/impl/ShunDePeopleServiceImpl.java b/src/main/java/com/docus/server/report/api/impl/ShunDePeopleServiceImpl.java index 078bc14..3c605a0 100644 --- a/src/main/java/com/docus/server/report/api/impl/ShunDePeopleServiceImpl.java +++ b/src/main/java/com/docus/server/report/api/impl/ShunDePeopleServiceImpl.java @@ -7,10 +7,7 @@ import com.alibaba.fastjson.JSON; import com.docus.core.util.DateUtil; import com.docus.core.util.Func; import com.docus.server.report.api.ShunDePeopleService; -import com.docus.server.report.api.dto.SdJxReportDto; -import com.docus.server.report.api.dto.SdNurseInsertSugarRequest; -import com.docus.server.report.api.dto.SdNurseInsertSugarResponse; -import com.docus.server.report.api.dto.SdPacsServerConfig; +import com.docus.server.report.api.dto.*; import com.docus.server.report.client.JaxWsDynamicClient; import com.docus.server.report.config.SdRyReportQueryConfig; import com.docus.server.report.util.IdUtil; @@ -43,6 +40,7 @@ public class ShunDePeopleServiceImpl implements ShunDePeopleService { private static final Lock INSPECT_REPORT_LOCK = new ReentrantLock(); private static final Lock LIS_REPORT_LOCK = new ReentrantLock(); private static final Lock NURSE_INSERT_SUGAR_LOCK = new ReentrantLock(); + private static final Lock NURSE_INSERT_SUGAR_PUSH_ERR_LOCK = new ReentrantLock(); @Resource private SdRyReportQueryConfig sdRyReportQueryConfig; @@ -178,6 +176,26 @@ public class ShunDePeopleServiceImpl implements ShunDePeopleService { NURSE_INSERT_SUGAR_LOCK.unlock(); } } + + @Override + public SdNurDocFailResponse pushSdNurDocFail(SdNurDocFailRequest request) { + String randomUuid = Func.randomUUID(); + NURSE_INSERT_SUGAR_PUSH_ERR_LOCK.lock(); + try { + String body=Func.toJson(request); + log.info("[{}] 移动护理推送错误,请求地址:{},参数:{}", randomUuid,sdRyReportQueryConfig.getReportQueryNurseInsertSugarErrPushUrl(), body); + String respBody = sendPost(sdRyReportQueryConfig.getReportQueryNurseInsertSugarErrPushUrl(), body); + log.info("[{}] 移动护理推送错误,响应:{}", randomUuid, respBody); + TimeUnit.MILLISECONDS.sleep(sdRyReportQueryConfig.getReportQueryNurseInsertSugarErrPushInterval()); + return JSON.parseObject(respBody,SdNurDocFailResponse.class); + }catch (Exception ex){ + log.error("["+randomUuid+"]"+"移动护理推送异常,出错了:" + ex.getMessage(), ex); + return null; + }finally { + NURSE_INSERT_SUGAR_PUSH_ERR_LOCK.unlock(); + } + } + private String organizationQuerySdRyInspectReportUrl(String reportQueryLisUrl) { return reportQueryLisUrl + "/query?uuid=" + IdUtil.standardUUID() + "&action=" + sdRyReportQueryConfig.getReportQueryInspectAction() + diff --git a/src/main/java/com/docus/server/report/config/SdRyReportQueryConfig.java b/src/main/java/com/docus/server/report/config/SdRyReportQueryConfig.java index 3358835..6a14a5a 100644 --- a/src/main/java/com/docus/server/report/config/SdRyReportQueryConfig.java +++ b/src/main/java/com/docus/server/report/config/SdRyReportQueryConfig.java @@ -61,4 +61,8 @@ public class SdRyReportQueryConfig { private String reportQueryNurseInsertSugarCollectorId; @Value("${sdry.report-query-url.nurseInsertSugar.defaultAssortType:other}") private String reportQueryNurseInsertSugarDefaultAssortType; + @Value("${sdry.report-query-url.nurseInsertSugar.pushErr.url:}") + private String reportQueryNurseInsertSugarErrPushUrl; + @Value("${sdry.report-query-url.nurseInsertSugar.pushErr.interval:1000}") + private int reportQueryNurseInsertSugarErrPushInterval; } diff --git a/src/main/java/com/docus/server/report/consts/ReportDownloadWait.java b/src/main/java/com/docus/server/report/consts/ReportDownloadWait.java new file mode 100644 index 0000000..c96ee9e --- /dev/null +++ b/src/main/java/com/docus/server/report/consts/ReportDownloadWait.java @@ -0,0 +1,15 @@ +package com.docus.server.report.consts; + +/** + * 报告下载等待参数 + */ +public interface ReportDownloadWait { + /** + * 等待报告下载完成的时间 单位秒 + */ + int REPORT_DOWNLOAD_WAIT_TIME = 30 * 60; + /** + * 等待报告下载完成的redisKey,docus:collect:report:download:wait:{采集器id}:{病案主键} + */ + String REPORT_DOWNLOAD_WAIT_KEY = "docus:collect:report:download:wait:%s:%s"; +} diff --git a/src/main/java/com/docus/server/report/controller/ApiTestController.java b/src/main/java/com/docus/server/report/controller/ApiTestController.java index 10ed215..9cdf8fd 100644 --- a/src/main/java/com/docus/server/report/controller/ApiTestController.java +++ b/src/main/java/com/docus/server/report/controller/ApiTestController.java @@ -3,6 +3,7 @@ package com.docus.server.report.controller; import com.docus.infrastructure.web.api.CommonResult; import com.docus.server.report.api.ShunDePeopleService; import com.docus.server.report.api.TaskDistributeService; +import com.docus.server.report.api.dto.SdNurDocFailRequest; import com.docus.server.report.api.dto.SdNurseInsertSugarRequest; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; @@ -35,6 +36,13 @@ public class ApiTestController { SdNurseInsertSugarRequest sdNurseInsertSugarRequest = new SdNurseInsertSugarRequest(inpatientNo, admissTimes, traceCode); return CommonResult.success(shunDePeopleService.getNurseInsertSugarReport(sdNurseInsertSugarRequest)); } + @ApiOperation(value = "移动护理报告推送错误接口测试") + @GetMapping("/nisPushErrTest") + public CommonResult nisPushErrTest(@Param("inpatientNo") String inpatientNo, @Param("admissTimes") String admissTimes,@Param("errorCode") String errorCode,@Param("errMsg") String errMsg) { + final String traceCode = "nurse_doc_fail"; + SdNurDocFailRequest failRequest = new SdNurDocFailRequest(inpatientNo,admissTimes,traceCode,errorCode,errMsg); + return CommonResult.success(shunDePeopleService.pushSdNurDocFail(failRequest)); + } @ApiOperation(value = "获取任务测试") @PostMapping("/getTaskTest") diff --git a/src/main/java/com/docus/server/report/controller/MockTestController.java b/src/main/java/com/docus/server/report/controller/MockTestController.java index 74c785e..4637bb6 100644 --- a/src/main/java/com/docus/server/report/controller/MockTestController.java +++ b/src/main/java/com/docus/server/report/controller/MockTestController.java @@ -1,5 +1,7 @@ package com.docus.server.report.controller; +import com.alibaba.fastjson.JSON; +import com.docus.server.report.api.dto.SdNurDocFailRequest; import com.docus.server.report.api.dto.SdNurseInsertSugarRequest; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; @@ -18,7 +20,7 @@ public class MockTestController { @PostMapping("/nurseReturnMock") @ApiOperation("护理请求模拟数据") public String nurseReturnMock(@RequestBody SdNurseInsertSugarRequest request){ - log.info("收到护理请求消息:{},返回模拟数据!",request); + log.info("收到护理请求消息:{},返回模拟数据!",JSON.toJSONString(request)); String result="{\n" + " \"data\": [\n" + " {\n" + @@ -57,6 +59,15 @@ public class MockTestController { return result; } + @PostMapping("/nurseErrMock") + @ApiOperation("护理异常推送模拟数据") + public String nurseReturnMock(@RequestBody SdNurDocFailRequest request){ + log.info("收到护理异常推送消息:{},返回模拟数据!", JSON.toJSONString(request)); + String result="{\"error_code\":\"1\",\"error_msg\":\"接收成功\"}"; + System.out.println(result); + return result; + } + public static void main(String[] args) { String result="{\n" + " \"data\": [\n" + diff --git a/src/main/java/com/docus/server/report/job/ReportJob.java b/src/main/java/com/docus/server/report/job/ReportJob.java index 38f1e6f..40e7a8e 100644 --- a/src/main/java/com/docus/server/report/job/ReportJob.java +++ b/src/main/java/com/docus/server/report/job/ReportJob.java @@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSONObject; import com.docus.core.util.Func; import com.docus.infrastructure.core.exception.BaseException; import com.docus.infrastructure.redis.service.IdService; +import com.docus.infrastructure.redis.service.RedisOps; import com.docus.infrastructure.web.api.ResultCode; import com.docus.server.collection.entity.TBasic; import com.docus.server.collection.mapper.TBasicMapper; @@ -14,11 +15,13 @@ import com.docus.server.report.config.SdRyCollectNurseInsertSugarConfig; import com.docus.server.report.config.SdRyReportQueryConfig; import com.docus.server.report.config.TaskValidateConfig; import com.docus.server.report.config.ZdAssortConfig; +import com.docus.server.report.consts.ReportDownloadWait; import com.docus.server.report.entity.AfJobTime; import com.docus.server.report.entity.AfReportRecord; import com.docus.server.report.mapper.AfJobTimeMapper; import com.docus.server.report.mapper.AfReportRecordMapper; import com.docus.server.report.service.ReportService; +import com.docus.server.report.service.ShunDePeopleBusinessService; import com.docus.server.report.util.TableJsonRead; import com.docus.server.report.util.XmlUtil; import com.docus.server.report.validate.CollectTaskValidation; @@ -63,6 +66,10 @@ public class ReportJob { private TaskDistributeService taskDistributeService; @Resource private ShunDePeopleService shunDePeopleService; + @Resource + private ShunDePeopleBusinessService shunDePeopleBusinessService; + @Resource + RedisOps redisOps; @XxlJob("SdRyLisCollectJob") public void sdRyLisCollectJob() { @@ -176,14 +183,18 @@ public class ReportJob { if (Func.isNotEmpty(nurseInsertSugarReportList)) { Integer filesNumber = nurseInsertSugarReportList.get(0).getFILES_NUMBER(); Integer nurseFileCount = tBasicMapper.getNurseFileCount(patientId); - if (filesNumber == null || nurseFileCount == null) { - log.warn("{} , {},未保存护理提交的文件数量或者未获取到接口返回的文件数量!", inpatientNo, admissTimes); - nurseFileCountError(inpatientNo, admissTimes); + if (filesNumber == null) { + log.warn("{} ,{},接口未返回文件数量!",inpatientNo,admissTimes); + return; + } + if (nurseFileCount == null) { + log.warn("{} , {},未获取到护理提交的文件数量!", inpatientNo, admissTimes); + shunDePeopleBusinessService.nurseFileCountError(inpatientNo, admissTimes,"未获取到护理提交的文件数量!"); return; } if (!filesNumber.equals(nurseFileCount)) { log.warn("{} , {},护理提交的文件数量与接口返回的文件数量不匹配!", inpatientNo, admissTimes); - nurseFileCountError(inpatientNo, admissTimes); + shunDePeopleBusinessService.nurseFileCountError(inpatientNo, admissTimes,"护理提交的文件数量与接口返回的文件数量不匹配"); return; } // 从配置获取需要过滤的文件名称 @@ -219,6 +230,9 @@ public class ReportJob { collectFileCount++; } log.info("住院号:{},住院次数{},护理采集文件: {} 条", inpatientNo, admissTimes, collectFileCount); + // 设置一个redisKey,过期被监听处理 + String redisKey=String.format(ReportDownloadWait.REPORT_DOWNLOAD_WAIT_KEY,reportQueryNurseInsertSugarCollectorId,patientId); + redisOps.setEx(redisKey,"0",ReportDownloadWait.REPORT_DOWNLOAD_WAIT_TIME); } } @@ -234,9 +248,7 @@ public class ReportJob { return false; } - private void nurseFileCountError(String inpatientNo, Integer admissTimes) { - // todo 未提供! - } + /** * 判断是否是需要作废的病案 diff --git a/src/main/java/com/docus/server/report/listener/NisReportDownloadWaitHandler.java b/src/main/java/com/docus/server/report/listener/NisReportDownloadWaitHandler.java new file mode 100644 index 0000000..b5e47ed --- /dev/null +++ b/src/main/java/com/docus/server/report/listener/NisReportDownloadWaitHandler.java @@ -0,0 +1,125 @@ +package com.docus.server.report.listener; + +import com.docus.infrastructure.redis.service.RedisOps; +import com.docus.server.collection.entity.TBasic; +import com.docus.server.collection.mapper.TBasicMapper; +import com.docus.server.common.util.RedisKeyExpirationHandler; +import com.docus.server.common.util.RedisKeyExpirationListener; +import com.docus.server.report.config.SdRyReportQueryConfig; +import com.docus.server.report.consts.ReportDownloadWait; +import com.docus.server.report.mapper.AfScanAssortMapper; +import com.docus.server.report.service.ShunDePeopleBusinessService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; +import javax.annotation.Resource; + +/** + * @author WYBDEV + */ +@Component +@Slf4j +public class NisReportDownloadWaitHandler extends RedisKeyExpirationHandler { + @Autowired + private RedisKeyExpirationListener redisKeyExpirationListener; + @Autowired + private RedisOps redisOps; + @Autowired + private SdRyReportQueryConfig sdRyReportQueryConfig; + @Autowired + private TBasicMapper tBasicMapper; + @Autowired + private AfScanAssortMapper scanAssortMapper; + @Resource + private ShunDePeopleBusinessService shunDePeopleBusinessService; + + @PostConstruct + public void registerRedisKeyExpireListener() { + redisKeyExpirationListener.register(this); + } + + public static void main(String[] args) { + String collectId = "3"; + String redisKey = String.format(ReportDownloadWait.REPORT_DOWNLOAD_WAIT_KEY, collectId, "20230501"); + System.out.println(redisKey); + String redisKeyPrefix1 = String.format(ReportDownloadWait.REPORT_DOWNLOAD_WAIT_KEY, collectId, ""); + System.out.println(redisKey.startsWith(redisKeyPrefix1)); + // 得到病案主键 + System.out.println(redisKey.replace(redisKeyPrefix1, "")); + } + + @Override + public void businessHandle(String expireRedisKey) throws Exception { + // 是否是护理采集要校验的redisKey,校验护理采集下载的文件数量是否和推送过滤后的匹配,匹配则调用 质控,不匹配发送异常信息 + if (!isNisReportWaitKey(expireRedisKey)) { + return; + } + String patientId = getPatientId(expireRedisKey); + log.info("病案主键:{} 护理采集数量校对开始!", patientId); + boolean verifyNisFileCountResult = verifyNisFileCountAndPushErr(patientId); + if (verifyNisFileCountResult) { + nisQualityControl(patientId); + } + } + + private boolean verifyNisFileCountAndPushErr(String patientId) { + TBasic tBasic = tBasicMapper.getByPatientId(patientId); + String inpatientNo = tBasic.getInpatientNo(); + Integer admissTimes = tBasic.getAdmissTimes(); + Integer submitNurseFileCount = tBasicMapper.getNurseFileCount(patientId); + // 判断提交的文件数量 + if (submitNurseFileCount == null || submitNurseFileCount == 0) { + log.warn("{} , {},未获取到护理提交的文件数量!", inpatientNo, admissTimes); + shunDePeopleBusinessService.nurseFileCountError(inpatientNo, admissTimes, "未获取到护理提交的文件数量!"); + return false; + } + // 有些报告在采集的时候会过滤掉,有记录过滤的条数,计算实际应该要采集到的文件数量,和文件表数量做对比,文件表数量的小于应该采集到的,推送错误信息 + Integer nurseRemoveFileCount = tBasicMapper.getNurseRemoveFileCount(patientId); + int realFileCount = submitNurseFileCount - nurseRemoveFileCount; + String collectorId = sdRyReportQueryConfig.getReportQueryNurseInsertSugarCollectorId(); + Integer downloadSuccessFileCount = scanAssortMapper.countByPatientAndCollectorId(patientId, collectorId); + if (downloadSuccessFileCount < realFileCount) { + shunDePeopleBusinessService.nurseFileCountError(inpatientNo, admissTimes, "未完整采集该病案的文件!"); + return false; + } + return true; + } + + private void nisQualityControl(String patientId) { + // todo 调用护理质控接口等待 质控那边开发 + log.info("调用护理质控:{}", patientId); + } + + + @Override + public void handleException(String expireRedisKey) { + // 异常主键重新推送 + redisOps.setEx(expireRedisKey, "0", ReportDownloadWait.REPORT_DOWNLOAD_WAIT_TIME); + } + + /** + * 是否是护理报告等待的redisKey + * + * @param expireRedisKey 过期的redisKey + * @return 是否是护理报告等待的redisKey + */ + private boolean isNisReportWaitKey(String expireRedisKey) { + String collectorId = sdRyReportQueryConfig.getReportQueryNurseInsertSugarCollectorId(); + // 护理报告的key的前缀 + String nisKeyPrefix = String.format(ReportDownloadWait.REPORT_DOWNLOAD_WAIT_KEY, collectorId, ""); + return expireRedisKey.startsWith(nisKeyPrefix); + } + + /** + * 获取病案主键id + */ + private String getPatientId(String expireRedisKey) { + String collectorId = sdRyReportQueryConfig.getReportQueryNurseInsertSugarCollectorId(); + // 护理报告的key的前缀 + String nisKeyPrefix = String.format(ReportDownloadWait.REPORT_DOWNLOAD_WAIT_KEY, collectorId, ""); + return expireRedisKey.replace(nisKeyPrefix, ""); + } + +} diff --git a/src/main/java/com/docus/server/report/mapper/AfScanAssortMapper.java b/src/main/java/com/docus/server/report/mapper/AfScanAssortMapper.java new file mode 100644 index 0000000..af7dfbe --- /dev/null +++ b/src/main/java/com/docus/server/report/mapper/AfScanAssortMapper.java @@ -0,0 +1,20 @@ +package com.docus.server.report.mapper; + +import org.apache.ibatis.annotations.Param; + +/** + * 文件表mapper + * + * @author wyb + */ +public interface AfScanAssortMapper { + + /** + * 根据病案主键和采集器id查询文件表数量 + * + * @param patientId 病案主键 + * @param collectorId 采集器id + * @return 文件表数量 + */ + Integer countByPatientAndCollectorId(@Param("patientId") String patientId, @Param("collectorId") String collectorId); +} diff --git a/src/main/java/com/docus/server/report/service/ShunDePeopleBusinessService.java b/src/main/java/com/docus/server/report/service/ShunDePeopleBusinessService.java new file mode 100644 index 0000000..f75e97b --- /dev/null +++ b/src/main/java/com/docus/server/report/service/ShunDePeopleBusinessService.java @@ -0,0 +1,12 @@ +package com.docus.server.report.service; + +public interface ShunDePeopleBusinessService { + /** + * 护理文件数量校验不成功 + * + * @param inpatientNo 病案号 + * @param admissTimes 住院次数 + * @param errorMsg 错误信息 + */ + void nurseFileCountError(String inpatientNo, Integer admissTimes, String errorMsg); +} diff --git a/src/main/java/com/docus/server/report/service/impl/ShunDePeopleBusinessServiceImpl.java b/src/main/java/com/docus/server/report/service/impl/ShunDePeopleBusinessServiceImpl.java new file mode 100644 index 0000000..0c297e2 --- /dev/null +++ b/src/main/java/com/docus/server/report/service/impl/ShunDePeopleBusinessServiceImpl.java @@ -0,0 +1,24 @@ +package com.docus.server.report.service.impl; + +import com.docus.server.report.api.ShunDePeopleService; +import com.docus.server.report.api.dto.SdNurDocFailRequest; +import com.docus.server.report.service.ShunDePeopleBusinessService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; + +@Service +@Slf4j +public class ShunDePeopleBusinessServiceImpl implements ShunDePeopleBusinessService { + @Resource + private ShunDePeopleService shunDePeopleService; + + @Override + public void nurseFileCountError(String inpatientNo, Integer admissTimes,String errorMsg) { + final String traceCode = "nurse_doc_fail"; + final String errorCode = "-1"; + SdNurDocFailRequest failRequest = new SdNurDocFailRequest(inpatientNo,admissTimes.toString(),traceCode,errorCode,errorMsg); + shunDePeopleService.pushSdNurDocFail(failRequest); + } +} diff --git a/src/main/resources/bootstrap.yml b/src/main/resources/bootstrap.yml index efb835c..b44c88f 100644 --- a/src/main/resources/bootstrap.yml +++ b/src/main/resources/bootstrap.yml @@ -77,6 +77,10 @@ sdry: url: http://127.0.0.1:9311/api/mockTest/nurseReturnMock interval: 1000 defaultAssortType: hl-other + # 异常推送 地址和调用时间间隔 ms + pushErr: + url: http://127.0.0.1:9311/api/mockTest/nurseErrMock + interval: 1000 diff --git a/src/main/resources/mapper/AfScanAssortMapper.xml b/src/main/resources/mapper/AfScanAssortMapper.xml new file mode 100644 index 0000000..33ade3f --- /dev/null +++ b/src/main/resources/mapper/AfScanAssortMapper.xml @@ -0,0 +1,13 @@ + + + + + + diff --git a/src/main/resources/mapper/TBasicMapper.xml b/src/main/resources/mapper/TBasicMapper.xml index be397bc..327cacb 100644 --- a/src/main/resources/mapper/TBasicMapper.xml +++ b/src/main/resources/mapper/TBasicMapper.xml @@ -177,6 +177,12 @@ from `docus_medicalrecord`.`t_basic_extend` WHERE patient_id=#{patientId} + + +