From 4e67816b3c7bcdef7e971912a6c4fa3a4287f6d5 Mon Sep 17 00:00:00 2001 From: wyb <1977763549@qq.com> Date: Tue, 21 Mar 2023 15:36:12 +0800 Subject: [PATCH] =?UTF-8?q?=E5=90=88=E5=B9=B6=E6=8A=A5=E5=91=8A=E6=8E=A8?= =?UTF-8?q?=E9=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- data-config/js-report-config.xml | 25 + data-config/js-table-type.json | 5 + .../js-webservice-template-request.xml | 25 + .../js-webservice-template-response.xml | 11 + .../collection/mapper/TBasicMapper.java | 8 +- .../collection/webservice/ReceiveServer.java | 26 + .../webservice/impl/ReceiveServerImpl.java | 21 + .../config/ApplicationBusinessConfig.java | 18 + .../controller/ReportDownController.java | 44 + .../server/report/dto/ReportDownDto.java | 30 + .../report/dto/ReportDownPatientDto.java | 27 + .../report/dto/ReportDownScanFileDto.java | 41 + .../docus/server/report/dto/ReportDto.java | 68 ++ .../server/report/entity/AfCollectTask.java | 79 ++ .../server/report/entity/AfReportRecord.java | 103 +++ .../docus/server/report/entity/TBasic.java | 158 ++++ .../server/report/event/ReportDownEvent.java | 28 + .../report/listener/ReportDownListener.java | 83 ++ .../report/mapper/AfCollectTaskMapper.java | 27 + .../report/mapper/AfReportRecordMapper.java | 52 ++ .../server/report/service/ReportService.java | 24 + .../service/impl/ReportServiceImpl.java | 120 +++ .../com/docus/server/report/util/IdUtil.java | 19 + .../docus/server/report/util/JSXMLResult.java | 41 + .../server/report/util/TableJsonRead.java | 180 ++++ .../com/docus/server/report/util/XmlUtil.java | 850 ++++++++++++++++++ .../report/webservice/IReportServer.java | 39 + .../webservice/impl/SdryReportServerImpl.java | 529 +++++++++++ src/main/resources/bootstrap.yml | 2 + .../resources/mapper/AfCollectTaskMapper.xml | 17 + .../resources/mapper/AfReportRecordMapper.xml | 56 ++ src/main/resources/mapper/TBasicMapper.xml | 10 + 32 files changed, 2765 insertions(+), 1 deletion(-) create mode 100644 data-config/js-report-config.xml create mode 100644 data-config/js-table-type.json create mode 100644 data-config/js-webservice-template-request.xml create mode 100644 data-config/js-webservice-template-response.xml create mode 100644 src/main/java/com/docus/server/report/config/ApplicationBusinessConfig.java create mode 100644 src/main/java/com/docus/server/report/controller/ReportDownController.java create mode 100644 src/main/java/com/docus/server/report/dto/ReportDownDto.java create mode 100644 src/main/java/com/docus/server/report/dto/ReportDownPatientDto.java create mode 100644 src/main/java/com/docus/server/report/dto/ReportDownScanFileDto.java create mode 100644 src/main/java/com/docus/server/report/dto/ReportDto.java create mode 100644 src/main/java/com/docus/server/report/entity/AfCollectTask.java create mode 100644 src/main/java/com/docus/server/report/entity/AfReportRecord.java create mode 100644 src/main/java/com/docus/server/report/entity/TBasic.java create mode 100644 src/main/java/com/docus/server/report/event/ReportDownEvent.java create mode 100644 src/main/java/com/docus/server/report/listener/ReportDownListener.java create mode 100644 src/main/java/com/docus/server/report/mapper/AfCollectTaskMapper.java create mode 100644 src/main/java/com/docus/server/report/mapper/AfReportRecordMapper.java create mode 100644 src/main/java/com/docus/server/report/service/ReportService.java create mode 100644 src/main/java/com/docus/server/report/service/impl/ReportServiceImpl.java create mode 100644 src/main/java/com/docus/server/report/util/IdUtil.java create mode 100644 src/main/java/com/docus/server/report/util/JSXMLResult.java create mode 100644 src/main/java/com/docus/server/report/util/TableJsonRead.java create mode 100644 src/main/java/com/docus/server/report/util/XmlUtil.java create mode 100644 src/main/java/com/docus/server/report/webservice/IReportServer.java create mode 100644 src/main/java/com/docus/server/report/webservice/impl/SdryReportServerImpl.java create mode 100644 src/main/resources/mapper/AfCollectTaskMapper.xml create mode 100644 src/main/resources/mapper/AfReportRecordMapper.xml diff --git a/data-config/js-report-config.xml b/data-config/js-report-config.xml new file mode 100644 index 0000000..d74c2a3 --- /dev/null +++ b/data-config/js-report-config.xml @@ -0,0 +1,25 @@ + + + + /Request/Msg/INHOSP_INDEX_NO + + /Request/Msg/INHOSP_NO + + /Request/Msg/INHOSP_NUM + + /Request/Msg/UNIQUE_FILE + + /Request/Msg/FILE_NAME + + /Request/Msg/PDF_PATH + + /Request/Msg/TABLE_TYPE + + + + /Request/Msg/TABLE_TYPE + + + + + \ No newline at end of file diff --git a/data-config/js-table-type.json b/data-config/js-table-type.json new file mode 100644 index 0000000..3a7fd45 --- /dev/null +++ b/data-config/js-table-type.json @@ -0,0 +1,5 @@ +{ + "icu": "重症文件分段id", + "sa": "手麻文件分段id", + "other": "其他文件分段id" +} \ No newline at end of file diff --git a/data-config/js-webservice-template-request.xml b/data-config/js-webservice-template-request.xml new file mode 100644 index 0000000..0d32ef2 --- /dev/null +++ b/data-config/js-webservice-template-request.xml @@ -0,0 +1,25 @@ + + + + + 123456 + + 012345 + + 012345 + + 2 + + icu + + 20220303111800 + + 20220303111801 + + http://192.168.1.108:9012/file/0123_01.pdf + + 0123_01 + + AESHASHMD5DEFIND + + diff --git a/data-config/js-webservice-template-response.xml b/data-config/js-webservice-template-response.xml new file mode 100644 index 0000000..8ceb826 --- /dev/null +++ b/data-config/js-webservice-template-response.xml @@ -0,0 +1,11 @@ + + + + + 0 + + 123456 + + 成功! + + \ No newline at end of file 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 3c48018..afdf888 100644 --- a/src/main/java/com/docus/server/collection/mapper/TBasicMapper.java +++ b/src/main/java/com/docus/server/collection/mapper/TBasicMapper.java @@ -1,7 +1,6 @@ package com.docus.server.collection.mapper; -import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.docus.server.collection.entity.TBasic; import com.docus.server.collection.entity.TBasicExtend; import org.apache.ibatis.annotations.Param; @@ -15,6 +14,13 @@ import org.apache.ibatis.annotations.Param; * @since 2021-04-14 */ public interface TBasicMapper{ + /** + * 根据住院号和住院次数查询业务系统中病案主键 + * @param inpatientNo 住院号 + * @param admissTimes 住院次数 + * @return 病案主键 + */ + String getPatientIdByInpatientNoAndAdminssTimes(@Param("inpatientNo") String inpatientNo,@Param("adminssTimes") Integer admissTimes); Integer selectOne(@Param("jzh") String jzh); diff --git a/src/main/java/com/docus/server/collection/webservice/ReceiveServer.java b/src/main/java/com/docus/server/collection/webservice/ReceiveServer.java index 41f7ff4..95952dc 100644 --- a/src/main/java/com/docus/server/collection/webservice/ReceiveServer.java +++ b/src/main/java/com/docus/server/collection/webservice/ReceiveServer.java @@ -25,4 +25,30 @@ public interface ReceiveServer { * @return 返回结果 */ String userModify(String receiveUser); + + + /** + * 接收重症报告信息 + * + * @param icuReportMessage 重症报告信息 + * @return 返回信息 + */ + String pushICUReport(String icuReportMessage); + + /** + * 接收检查报告的信息 - 新增 + * + * @param inspectionReportMessage 检查报告信息 - 新增 + * @return 成功或者异常信息 + */ + String pushAddInspectionReport(String inspectionReportMessage); + + /** + * 接收检查报告的信息 - 更新 + * + * @param inspectionReportMessage 检查报告信息 -更新 + * @return 成功或者异常信息 + */ + String pushUpdateInspectionReport(String inspectionReportMessage); + } diff --git a/src/main/java/com/docus/server/collection/webservice/impl/ReceiveServerImpl.java b/src/main/java/com/docus/server/collection/webservice/impl/ReceiveServerImpl.java index b0191c2..22a9a51 100644 --- a/src/main/java/com/docus/server/collection/webservice/impl/ReceiveServerImpl.java +++ b/src/main/java/com/docus/server/collection/webservice/impl/ReceiveServerImpl.java @@ -4,6 +4,7 @@ import com.docus.server.collection.webservice.IDeptServer; import com.docus.server.collection.webservice.IUserServer; import com.docus.server.collection.webservice.ReceiveServer; import com.docus.server.collection.webservice.BasicService; +import com.docus.server.report.webservice.IReportServer; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -27,6 +28,8 @@ public class ReceiveServerImpl implements ReceiveServer { private IDeptServer deptServer; @Resource private BasicService basicService; + @Resource + private IReportServer reportServer; @Override @@ -48,4 +51,22 @@ public class ReceiveServerImpl implements ReceiveServer { public String userModify(String receiveUser) { return userServer.userModify(receiveUser); } + + + + + @Override + public String pushICUReport(String icuReportMessage) { + return reportServer.pushICUReport(icuReportMessage); + } + + @Override + public String pushAddInspectionReport(String inspectionReportMessage) { + return reportServer.pushAddInspectionReport(inspectionReportMessage); + } + + @Override + public String pushUpdateInspectionReport(String inspectionReportMessage) { + return reportServer.pushUpdateInspectionReport(inspectionReportMessage); + } } diff --git a/src/main/java/com/docus/server/report/config/ApplicationBusinessConfig.java b/src/main/java/com/docus/server/report/config/ApplicationBusinessConfig.java new file mode 100644 index 0000000..c4d05fd --- /dev/null +++ b/src/main/java/com/docus/server/report/config/ApplicationBusinessConfig.java @@ -0,0 +1,18 @@ +package com.docus.server.report.config; + +import lombok.Getter; +import lombok.Setter; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +/** + * 应用业务配置 + * @author wyb + */ +@Component +@Getter +@Setter +public class ApplicationBusinessConfig { + @Value("${docus.report.downurl:}") + private String downUrl; +} diff --git a/src/main/java/com/docus/server/report/controller/ReportDownController.java b/src/main/java/com/docus/server/report/controller/ReportDownController.java new file mode 100644 index 0000000..8c08e37 --- /dev/null +++ b/src/main/java/com/docus/server/report/controller/ReportDownController.java @@ -0,0 +1,44 @@ +package com.docus.server.report.controller; + +import com.docus.core.util.Func; +import com.docus.infrastructure.web.api.CommonResult; +import com.docus.server.report.service.ReportService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import java.util.List; + +/** + * @author wyb + * 文件上报下载服务 + */ +@Slf4j +@Api(tags = "文件上报,补偿控制") +@RestController +@RequestMapping("/report/makeup") +public class ReportDownController { + @Resource + private ReportService reportService; + + @ApiOperation(value = "根据任务id补偿报告下载") + @PostMapping("/makeupReportByTaskIds") + public CommonResult makeupReportByTaskIds(@RequestBody List taskIds){ + if (Func.isEmpty(taskIds)) { + return CommonResult.failed("补偿任务id不能为空!"); + } + try { + reportService.makeupReportByTaskIds(taskIds); + } catch (Exception ex) { + log.error(ex.getMessage(), ex); + return CommonResult.failed("补偿出现了一点小问题!"); + } + return CommonResult.success("补偿成功!"); + } + +} diff --git a/src/main/java/com/docus/server/report/dto/ReportDownDto.java b/src/main/java/com/docus/server/report/dto/ReportDownDto.java new file mode 100644 index 0000000..d61edaa --- /dev/null +++ b/src/main/java/com/docus/server/report/dto/ReportDownDto.java @@ -0,0 +1,30 @@ +package com.docus.server.report.dto; + + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; + +@Data +public class ReportDownDto { + @ApiModelProperty(value = "采集器id") + private String collectorid; + + @ApiModelProperty(value = "采集器ip") + private String ip; + + @ApiModelProperty(value = "分类id") + private String assortid; + + @ApiModelProperty(value = "患者信息") + private ReportDownPatientDto patient; + + @ApiModelProperty(value = "文件信息") + private List scanfiles; + + @ApiModelProperty(value = "扫描用户代码") + private String scanusercode; + @ApiModelProperty(value = "扫描用户名称") + private String scanusername; +} \ No newline at end of file diff --git a/src/main/java/com/docus/server/report/dto/ReportDownPatientDto.java b/src/main/java/com/docus/server/report/dto/ReportDownPatientDto.java new file mode 100644 index 0000000..083bd37 --- /dev/null +++ b/src/main/java/com/docus/server/report/dto/ReportDownPatientDto.java @@ -0,0 +1,27 @@ +package com.docus.server.report.dto; + +import com.docus.server.report.entity.AfReportRecord; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@Data +public class ReportDownPatientDto { + @ApiModelProperty(value = "记帐号") + private String jzh; + @ApiModelProperty(value = "住院次数,记帐号重复则加这个参数,无则Null") + private Integer admisstimes; + @ApiModelProperty(value = "病案主键,如有传则使用,无则使用jzh") + private String patientid; + @ApiModelProperty(value = "病案号") + private String inpatientno; + + @ApiModelProperty(value = "物理存储位置,有则传") + private String storagelocation; + + public ReportDownPatientDto(AfReportRecord reportRecord) { + this.patientid = reportRecord.getPatientId(); + this.jzh = reportRecord.getJzh(); + this.admisstimes = reportRecord.getAdmissTimes(); + this.inpatientno = reportRecord.getInpatientNo(); + } +} diff --git a/src/main/java/com/docus/server/report/dto/ReportDownScanFileDto.java b/src/main/java/com/docus/server/report/dto/ReportDownScanFileDto.java new file mode 100644 index 0000000..1c711c7 --- /dev/null +++ b/src/main/java/com/docus/server/report/dto/ReportDownScanFileDto.java @@ -0,0 +1,41 @@ +package com.docus.server.report.dto; + +import com.docus.server.report.entity.AfReportRecord; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@Data +public class ReportDownScanFileDto { + @ApiModelProperty(value = "任务id(如无效任务id,则不更新任务表数据)") + private Long taskid; + @ApiModelProperty(value = "文件标题") + private String filetitle; + @ApiModelProperty(value = "采集类型(文件来源 1:采集器;2:扫描生产软件)") + private int filesource; + @ApiModelProperty(value = "下载类型(1:服务器本地;2:ftp服务器;3:共享文件夹)") + private int filestoragetype; + @ApiModelProperty(value = "文件类型(1:url,2:base64,3:url base64,4:共享文件,5:本地文件base64)") + private int filetype=1; + @ApiModelProperty(value = "下载地址") + private String downurl; + // @ApiModelProperty(value = "档案信息") +// private String recordid; + @ApiModelProperty(value = "采集流水号") + private String serialnum; + + @ApiModelProperty(value = "排序日期") + private String sortdate; + + @ApiModelProperty(value = "是否作废 : 0:否 不作废,1:是 作废") + private int cancel=0; + + public ReportDownScanFileDto(AfReportRecord reportRecord) { + this.taskid=reportRecord.getTaskId(); + this.filetitle=reportRecord.getFileName(); + this.filesource= 1; + this.filestoragetype=1; + this.filetype=reportRecord.getDownType(); + this.downurl=reportRecord.getDownUrl(); + this.serialnum=reportRecord.getSerialnum(); + } +} diff --git a/src/main/java/com/docus/server/report/dto/ReportDto.java b/src/main/java/com/docus/server/report/dto/ReportDto.java new file mode 100644 index 0000000..2b74c3e --- /dev/null +++ b/src/main/java/com/docus/server/report/dto/ReportDto.java @@ -0,0 +1,68 @@ +package com.docus.server.report.dto; + +import lombok.Data; + +/** + * 报告推送信息 + */ +@Data +public class ReportDto { + /** + * 住院号 + */ + private String inpatientNo; + /** + * 记账号/住院流水号 + */ + private String jzh; + /** + * 住院次数 + */ + private Integer admisstimes; + /** + * 采集来源系统 + */ + private String sysFlag; + /** + * 下载地址 + */ + private String downUrl; + /** + * 文件名 + */ + private String fileTitle; + /** + * 采集流水号/文件唯一id + */ + private String serialnum; + + /** + * 文件分类id + */ + private String assortId; + + /** + * 采集类型(文件来源 1:采集器;2:扫描生产软件) + */ + private String fileSource; + + /** + * 文件保存位置类型 1:服务器本地;2:ftp服务器;3:共享文件夹 + */ + private String filestoragetype; + + /** + * 下载对应任务id ,接收处理 + */ + private Long taskId; + + /** + * 业务病案主键 + */ + private String patientId; + + /** + * 下载路径类型 1:url,2:base64,3:url base64,4:共享文件,5:本地文件base64 + */ + private Integer downtype=1; +} diff --git a/src/main/java/com/docus/server/report/entity/AfCollectTask.java b/src/main/java/com/docus/server/report/entity/AfCollectTask.java new file mode 100644 index 0000000..f9cc8a8 --- /dev/null +++ b/src/main/java/com/docus/server/report/entity/AfCollectTask.java @@ -0,0 +1,79 @@ +package com.docus.server.report.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serializable; +import java.util.Date; + +/** + *

+ * 病案采集任务 + *

+ * + * @author 曾文和 + * @since 2021-05-07 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@ApiModel(value = "AfCollectTask对象", description = "病案采集任务") +public class AfCollectTask implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "id 主键") + @TableId(value = "id", type = IdType.INPUT) + private Long id; + + @ApiModelProperty(value = "病案主键") + private String patientId; + + @ApiModelProperty(value = "来源 1护理文书,2 电子病历,3 Pacs检查,4心电图,5手麻系统,6 Lis检验,7病案首页,8长临医嘱") + private String sysflag; + + @ApiModelProperty(value = "开始时间") + private Date startTime; + + @ApiModelProperty(value = "结束时间") + private Date endTime; + + @ApiModelProperty(value = "任务耗时(毫秒)") + private Long consumingTime; + + @ApiModelProperty(value = "-1 等待采集,0:未开始,1:正在采集,2:采集错误,3采集完成") + private String state; + + @ApiModelProperty(value = "同步时间") + private Date syncTime; + + @ApiModelProperty(value = "最新重新采集时间") + private Date recollectTime; + + @ApiModelProperty(value = "最新重新采集人") + private String recollectName; + + @ApiModelProperty(value = "备注") + private String remark; + + @ApiModelProperty(value = "报告唯一单号") + private String C1; + + @ApiModelProperty(value = "c2") + private String C2; + + @ApiModelProperty(value = "记账号") + private String C3; + + @ApiModelProperty(value = "c4") + private String C4; + + @ApiModelProperty(value = "c6") + private String C6; + + @ApiModelProperty(value = "c9") + private String C9; +} diff --git a/src/main/java/com/docus/server/report/entity/AfReportRecord.java b/src/main/java/com/docus/server/report/entity/AfReportRecord.java new file mode 100644 index 0000000..676fac1 --- /dev/null +++ b/src/main/java/com/docus/server/report/entity/AfReportRecord.java @@ -0,0 +1,103 @@ +package com.docus.server.report.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.docus.server.report.dto.ReportDto; +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; + +/** + * 上报记录保存表 + */ +@Data +public class AfReportRecord implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * af_collect_task 主键id + */ + private Long taskId; + + /** + * 住院号 + */ + private String inpatientNo; + + /** + * 住院流水号,记账号 + */ + private String jzh; + + /** + * 住院次数 + */ + private Integer admissTimes; + + /** + * 下载地址,多个使用 | 分隔 + */ + private String downUrl; + + /** + * 下载路径类型 1:url,2:base64,3:url base64,4:共享文件,5:本地文件base64 + */ + private Integer downType; + + /** + * 状态 0 未开始,可用于补偿,1 已发送下载 + */ + private Integer state; + + /** + * 报告唯一id + */ + private String serialnum; + + /** + * 报告来源 采集器标识 + */ + private String sysflag; + + /** + * 报告所属文件分段id + */ + private String zdAssortId; + + /** + * 记录创建时间 + */ + private Date createTime; + + /** + * 记录更新时间 + */ + private Date updateTime; + + /** + * 报告名称 + */ + private String fileName; + + /** + * 病案主键 + */ + private String patientId; + + + public AfReportRecord() { + } + public AfReportRecord(ReportDto reportDto){ + this.jzh=reportDto.getJzh(); + this.admissTimes=reportDto.getAdmisstimes(); + this.inpatientNo=reportDto.getInpatientNo(); + this.downUrl=reportDto.getDownUrl(); + this.sysflag=reportDto.getSysFlag(); + this.zdAssortId=reportDto.getAssortId(); + this.serialnum=reportDto.getSerialnum(); + this.fileName=reportDto.getFileTitle(); + this.downType=reportDto.getDowntype(); + } +} \ No newline at end of file diff --git a/src/main/java/com/docus/server/report/entity/TBasic.java b/src/main/java/com/docus/server/report/entity/TBasic.java new file mode 100644 index 0000000..42e40e4 --- /dev/null +++ b/src/main/java/com/docus/server/report/entity/TBasic.java @@ -0,0 +1,158 @@ +package com.docus.server.report.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serializable; +import java.util.Date; + +/** + *

+ * 病案基本信息 + *

+ * + * @author jiashi + * @since 2021-04-14 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@ApiModel(value = "TBasic对象", description = "病案基本信息") +public class TBasic implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "病案主键") + @TableId(value = "patient_id", type = IdType.ASSIGN_ID) + private String patientId; + + @ApiModelProperty(value = "住院次数") + private Integer admissTimes; + + @ApiModelProperty(value = "病案号") + private String inpatientNo; + + @ApiModelProperty(value = "住院ID号") + private String admissId; + + @ApiModelProperty(value = "患者姓名") + private String name; + + @ApiModelProperty(value = "盘号") + private String ph; + + @ApiModelProperty(value = "性别") + private String sex; + + @ApiModelProperty(value = "年龄_岁") + private Integer age; + + @ApiModelProperty(value = "年龄_月") + private Integer ageMonth; + + @ApiModelProperty(value = "年龄_天") + private Integer ageDay; + + @ApiModelProperty(value = "身份证") + private String idCard; + + @ApiModelProperty(value = "手机号码") + private String telphone; + + @ApiModelProperty(value = "住院日期") + private Date admissDate; + + @ApiModelProperty(value = "住院科室") + private String admissDept; + + @ApiModelProperty(value = "住院科室名称") + private String admissDeptName; + + @ApiModelProperty(value = "出院日期") + private Date disDate; + + @ApiModelProperty(value = "出院科室") + private String disDept; + + @ApiModelProperty(value = "出院科室名称") + private String disDeptName; + + @ApiModelProperty(value = "实际住院天数") + private Integer admissDays; + + @ApiModelProperty(value = "主管医生") + private String attending; + + @ApiModelProperty(value = "主管医生名称") + private String attendingName; + + @ApiModelProperty(value = "主要诊断编码") + private String mainDiagCode; + + @ApiModelProperty(value = "主要诊断名称") + private String mainDiagName; + + @ApiModelProperty(value = "主要手术编码") + private String mainOperateCode; + + @ApiModelProperty(value = "主要手术名称") + private String mainOperateName; + + @ApiModelProperty(value = "是否死亡") + private Integer isDead; + + @ApiModelProperty(value = "是否作废(0:否,1:是)") + private Integer isCancel; + + @ApiModelProperty(value = "创建时间") + private Date createTime; + + @ApiModelProperty(value = "修改时间") + private Date updateTime; + + @ApiModelProperty(value = "是否归档 1:已归档,0:未归档") + private Integer isArchive; + + @ApiModelProperty(value = "归档时间") + private Date archiveTime; + + @ApiModelProperty(value = "文件来源 1:af_archive_detail,2:t_scan_assort") + private Integer fileSource; + + @ApiModelProperty(value = "完整性描述") + private String integrityDesc; + + private String bColumn1; + + private String bColumn2; + + private String bColumn3; + + private String bColumn4; + + private String bColumn5; + + private Integer bColumn6; + + private Integer bColumn7; + + private Integer bColumn8; + + private Integer bColumn9; + + private Integer bColumn10; + + @ApiModelProperty(value = "姓名缩写(内部构成)") + private String nameSpell; + + @ApiModelProperty(value = "性别名称") + private String sexName; + + @ApiModelProperty(value = "记账号") + private String jzh; + + +} diff --git a/src/main/java/com/docus/server/report/event/ReportDownEvent.java b/src/main/java/com/docus/server/report/event/ReportDownEvent.java new file mode 100644 index 0000000..4f52abf --- /dev/null +++ b/src/main/java/com/docus/server/report/event/ReportDownEvent.java @@ -0,0 +1,28 @@ +package com.docus.server.report.event; + +import lombok.Getter; +import org.springframework.context.ApplicationEvent; + +/** + * 下载触发 + * @author wyb + */ +@Getter +public class ReportDownEvent extends ApplicationEvent { + /** + * 下载对应任务id ,接收处理 + */ + private final Long taskId; + + /** + * + * @param source 触发该事件的对象 + * @param taskId 该事件携带的信息 + */ + public ReportDownEvent(Object source,Long taskId) { + super(source); + this.taskId=taskId; + } + + +} diff --git a/src/main/java/com/docus/server/report/listener/ReportDownListener.java b/src/main/java/com/docus/server/report/listener/ReportDownListener.java new file mode 100644 index 0000000..a67f427 --- /dev/null +++ b/src/main/java/com/docus/server/report/listener/ReportDownListener.java @@ -0,0 +1,83 @@ +package com.docus.server.report.listener; + +import cn.hutool.http.HttpRequest; +import cn.hutool.http.HttpResponse; +import cn.hutool.http.HttpUtil; +import com.docus.core.util.Func; +import com.docus.infrastructure.web.api.CommonResult; +import com.docus.infrastructure.web.api.ResultCode; +import com.docus.server.report.config.ApplicationBusinessConfig; +import com.docus.server.report.dto.ReportDownDto; +import com.docus.server.report.dto.ReportDownPatientDto; +import com.docus.server.report.dto.ReportDownScanFileDto; +import com.docus.server.report.entity.AfReportRecord; +import com.docus.server.report.event.ReportDownEvent; +import com.docus.server.report.mapper.AfReportRecordMapper; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.event.EventListener; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.util.ArrayList; +import java.util.List; + +/** + * 上报下载监听 + * + * @author wyb + */ +@Component +@Slf4j +public class ReportDownListener { + @Resource + private ApplicationBusinessConfig applicationBusinessConfig; + + @Resource + private AfReportRecordMapper afReportRecordMapper; + + @EventListener + @Async("threadPoolExecutor") + public void reportDown(ReportDownEvent reportDownEvent) { + // 根据任务id获取上报记录信息 + AfReportRecord afReportRecord = afReportRecordMapper.getReportRecordInfoByTaskId(reportDownEvent.getTaskId()); + + // 组织基础信息数据 + ReportDownPatientDto reportDownPatientDto = new ReportDownPatientDto(afReportRecord); + + // 组织文件数据 + List reportDownScanFileDtos = new ArrayList<>(5); + ReportDownScanFileDto reportDownScanFileDto = new ReportDownScanFileDto(afReportRecord); + reportDownScanFileDtos.add(reportDownScanFileDto); + + // 组织下载数据,基础信息和文件数据 + ReportDownDto reportDownDto = new ReportDownDto(); + reportDownDto.setAssortid(afReportRecord.getZdAssortId()); + reportDownDto.setCollectorid(afReportRecord.getSysflag()); + reportDownDto.setScanusercode("admin"); + reportDownDto.setScanusername("admin"); + reportDownDto.setPatient(reportDownPatientDto); + reportDownDto.setScanfiles(reportDownScanFileDtos); + + // 下面是调用下载服务 + + String requestParam = Func.toJson(reportDownDto); + try { + log.info("调用下载服务,地址:{} ,参数:{}",applicationBusinessConfig.getDownUrl(),requestParam); + HttpRequest post = HttpUtil.createPost(applicationBusinessConfig.getDownUrl()); + post.timeout(5 * 1000); + post.header("Content-Type", "application/json; charset=utf-8"); + post.body(requestParam); + HttpResponse response = post.execute(); + String respBody = response.body(); + log.info("调用下载服务成功,响应参数:{}", respBody); + CommonResult commonResult = Func.readJson(respBody, CommonResult.class); + if (ResultCode.SUCCESS.getCode().equals(commonResult.getCode())) { + // 下载返回了成功更新状态 + afReportRecordMapper.updateStateByTaskId(reportDownEvent.getTaskId()); + } + } catch (Exception e) { + log.error("调用下载服务失败", e); + } + } +} diff --git a/src/main/java/com/docus/server/report/mapper/AfCollectTaskMapper.java b/src/main/java/com/docus/server/report/mapper/AfCollectTaskMapper.java new file mode 100644 index 0000000..f1545e6 --- /dev/null +++ b/src/main/java/com/docus/server/report/mapper/AfCollectTaskMapper.java @@ -0,0 +1,27 @@ +package com.docus.server.report.mapper; + +import com.docus.server.report.entity.AfCollectTask; +import org.apache.ibatis.annotations.Param; + +/** + * 任务采集表mapper + * @author wyb + * + */ +public interface AfCollectTaskMapper { + + + /** + * 保存任务 + * @param afCollectTask 采集任务 + * @return 数据库操作结果 + */ + int saveTask(@Param("task") AfCollectTask afCollectTask); + + /** + * 根据任务主键查询任务 + * @param taskId 任务主键 + * @return 任务信息 + */ + AfCollectTask getTaskById(@Param("id") Long taskId); +} diff --git a/src/main/java/com/docus/server/report/mapper/AfReportRecordMapper.java b/src/main/java/com/docus/server/report/mapper/AfReportRecordMapper.java new file mode 100644 index 0000000..5529275 --- /dev/null +++ b/src/main/java/com/docus/server/report/mapper/AfReportRecordMapper.java @@ -0,0 +1,52 @@ +package com.docus.server.report.mapper; + +import com.docus.server.report.entity.AfReportRecord; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * 上报记录保存表 + * @author wyb + */ +public interface AfReportRecordMapper { + /** + * 保存报告推送记录 + * @param afReportRecord 报告推送记录 + * @return 数据库操作结果 + */ + int saveRecord(@Param("reportRecord") AfReportRecord afReportRecord); + + /** + * 根据文件唯一号 住院号 住院次数 系统标识 得到唯一推送记录 + * @param serialnum 报告唯一号 + * @param inpatientNo 住院号 + * @param admisstimes 住院次数 + * @param sysFlag 系统标识 + * @return 报告推送记录 + */ + AfReportRecord getRecordBySerialnumAndInpatientNoAndSysFlag(@Param("serialnum") String serialnum, @Param("inpatientNo")String inpatientNo,@Param("admisstimes") Integer admisstimes, @Param("sysFlag")String sysFlag); + + /** + * 更新报告推送 主要更新 下载地址,下载类型,文件名称 + * @param afReportRecord 报告推送记录 + * @return 数据库操作结果 + */ + int updateRecordByTaskId(@Param("reportRecord")AfReportRecord afReportRecord); + + /** + * 更新记录的状态 + * @param taskId 任务id + * @return 数据库操作结果 + */ + int updateStateByTaskId(@Param("taskId") Long taskId); + + AfReportRecord getReportRecordInfoByTaskId(@Param("taskId") Long taskId); + + /** + * 根据任务id查询有patientId数据的任务id + * @param taskIds 任务id集合 + * @return 数据有patientId的任务id集合 + */ + List getHasPatientIdTaskIdsByTaskIds(@Param("taskIds") List taskIds); +} \ No newline at end of file diff --git a/src/main/java/com/docus/server/report/service/ReportService.java b/src/main/java/com/docus/server/report/service/ReportService.java new file mode 100644 index 0000000..e63ce61 --- /dev/null +++ b/src/main/java/com/docus/server/report/service/ReportService.java @@ -0,0 +1,24 @@ +package com.docus.server.report.service; + +import com.docus.server.report.dto.ReportDto; + +import java.util.List; + +/** + * 报告服务 + * @author wyb + */ +public interface ReportService { + + /** + * 上报文件 + * @param reportDto 上报文件参数 + */ + void report(ReportDto reportDto); + + /** + * 根据任务id集合补偿下载 + * @param taskIds 任务id集合 + */ + void makeupReportByTaskIds(List taskIds) throws Exception; +} diff --git a/src/main/java/com/docus/server/report/service/impl/ReportServiceImpl.java b/src/main/java/com/docus/server/report/service/impl/ReportServiceImpl.java new file mode 100644 index 0000000..783b434 --- /dev/null +++ b/src/main/java/com/docus/server/report/service/impl/ReportServiceImpl.java @@ -0,0 +1,120 @@ +package com.docus.server.report.service.impl; + +import com.docus.core.util.Func; +import com.docus.infrastructure.redis.service.IdService; +import com.docus.server.collection.mapper.TBasicMapper; +import com.docus.server.report.dto.ReportDto; +import com.docus.server.report.entity.AfCollectTask; +import com.docus.server.report.entity.AfReportRecord; +import com.docus.server.report.event.ReportDownEvent; +import com.docus.server.report.mapper.AfCollectTaskMapper; +import com.docus.server.report.mapper.AfReportRecordMapper; + +import com.docus.server.report.service.ReportService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.ApplicationContext; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.List; +import java.util.concurrent.TimeUnit; + +/** + * 报告服务实现类 + * + * @author wyb + */ +@Slf4j +@Service +public class ReportServiceImpl implements ReportService { + + @Resource + private ApplicationContext applicationContext; + @Resource + private AfCollectTaskMapper collectTaskMapper; + @Resource + private AfReportRecordMapper afReportRecordMapper; + @Resource + private TBasicMapper tBasicMapper; + @Resource + private IdService idService; + + @Override + public void report(ReportDto reportDto) { + String patientId = null; + try { + // 如果出现多条出错的情况,还是得保存收到的信息,人工干预处理 + patientId = tBasicMapper.getPatientIdByInpatientNoAndAdminssTimes(reportDto.getInpatientNo(), reportDto.getAdmisstimes()); + } catch (Exception ex) { + log.error("查询病案主键出错了", ex); + } + // 不验证数据,始终保存收到的信息 + AfReportRecord afReportRecord = afReportRecordMapper.getRecordBySerialnumAndInpatientNoAndSysFlag(reportDto.getSerialnum(), reportDto.getInpatientNo(), reportDto.getAdmisstimes(), reportDto.getSysFlag()); + if (afReportRecord == null) { + long id = idService.getDateSeq(); + afReportRecord = new AfReportRecord(reportDto); + afReportRecord.setTaskId(id); + afReportRecord.setPatientId(patientId); + afReportRecordMapper.saveRecord(afReportRecord); + } else { + // 更新 主要更新 url + afReportRecord.setDownUrl(reportDto.getDownUrl()); + afReportRecord.setDownType(reportDto.getDowntype()); + afReportRecord.setFileName(reportDto.getFileTitle()); + afReportRecord.setPatientId(patientId); + afReportRecordMapper.updateRecordByTaskId(afReportRecord); + } + // 不使用事务,不需要回滚上面的保存 + + // 根据记录中的任务id,查询是否需要新增任务 + if (Func.isBlank(patientId)) { + log.warn("病案号:{},住院次数:{} 未找到病案基础数据,暂不进行下载任务!", reportDto.getInpatientNo(), reportDto.getAdmisstimes()); + return; + } + // 判断是否需要保存任务 + AfCollectTask afCollectTask = collectTaskMapper.getTaskById(afReportRecord.getTaskId()); + if (afCollectTask == null) { + afCollectTask = new AfCollectTask(); + afCollectTask.setId(afReportRecord.getTaskId()); + afCollectTask.setC1(reportDto.getSerialnum()); + afCollectTask.setC2(reportDto.getFileTitle()); + afCollectTask.setC3(reportDto.getJzh()); + afCollectTask.setPatientId(patientId); + afCollectTask.setSysflag(reportDto.getSysFlag()); + afCollectTask.setState("0"); + afCollectTask.setPatientId(patientId); + collectTaskMapper.saveTask(afCollectTask); + } + // 都成功后发布下载事件 + applicationContext.publishEvent(new ReportDownEvent(this, afReportRecord.getTaskId())); + } + + @Override + public void makeupReportByTaskIds(List taskIds) throws Exception { + // 定义一批200查询,分批次 + final int oneBatchCount = 200; + int startIndex = 0; + int toIndex = oneBatchCount; + boolean loop = true; + do { + // 获取截取下标 + if (taskIds.size() <= oneBatchCount) { + toIndex = taskIds.size(); + // 最后一批截取 + loop = false; + } + // 截取每一批 + List makeupTaskIds = taskIds.subList(startIndex, toIndex); + makeupTaskIds = afReportRecordMapper.getHasPatientIdTaskIdsByTaskIds(makeupTaskIds); + if (Func.isNotEmpty(makeupTaskIds)) { + for (Long taskId : makeupTaskIds) { + // 发布下载事件 + applicationContext.publishEvent(new ReportDownEvent(this, taskId)); + // 等待防止过快 + TimeUnit.MILLISECONDS.sleep(50); + } + } + // 当截取长度小于集合长度,可以进行下次循环截取 + } while (loop); + } +} diff --git a/src/main/java/com/docus/server/report/util/IdUtil.java b/src/main/java/com/docus/server/report/util/IdUtil.java new file mode 100644 index 0000000..57781ca --- /dev/null +++ b/src/main/java/com/docus/server/report/util/IdUtil.java @@ -0,0 +1,19 @@ +package com.docus.server.report.util; + +import lombok.Data; + +import java.util.UUID; +import java.util.concurrent.ThreadLocalRandom; + +@Data +public class IdUtil { + /** + * 得到一个标准的 8-4-4-4-12 UUID + * @return 标准的 8-4-4-4-12 UUID + */ + public static String standardUUID(){ + ThreadLocalRandom random = ThreadLocalRandom.current(); + return (new UUID(random.nextLong(), random.nextLong())).toString(); + } + +} diff --git a/src/main/java/com/docus/server/report/util/JSXMLResult.java b/src/main/java/com/docus/server/report/util/JSXMLResult.java new file mode 100644 index 0000000..7c80654 --- /dev/null +++ b/src/main/java/com/docus/server/report/util/JSXMLResult.java @@ -0,0 +1,41 @@ +package com.docus.server.report.util; + +import lombok.Data; + +/** + * 嘉时软件自定义 成功/失败消息 XML 格式 + * @author wyb + */ +@Data +public class JSXMLResult { + + private static final String SUCCESS_TEMPLATE="" + + "" + + "0" + + "%s" + + "成功!" + + "" + + ""; + + private static final String FAILED_TEMPLATE="" + + "" + + "500" + + "%s" + + "%s" + + "" + + ""; + + public static String success(String msgId){ + return String.format(SUCCESS_TEMPLATE,msgId); + } + + public static String failed(String msgId,String message){ + return String.format(FAILED_TEMPLATE,msgId,message); + } + + public static void main(String[] args) { + System.out.println(success("100")); + System.out.println(failed("100","随便输出了")); + } + +} diff --git a/src/main/java/com/docus/server/report/util/TableJsonRead.java b/src/main/java/com/docus/server/report/util/TableJsonRead.java new file mode 100644 index 0000000..83270f6 --- /dev/null +++ b/src/main/java/com/docus/server/report/util/TableJsonRead.java @@ -0,0 +1,180 @@ +package com.docus.server.report.util; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.springframework.util.StringUtils; + +import java.io.*; + +public class TableJsonRead { + + /** + * 读取数据结构 + * @param path 路径后缀 + * @param fileName 文件名称 + * @return + */ + public T Read(String path,String fileName,Class clazz){ + String currentPath=CurrentPath(); + path = currentPath+"\\"+path; + StringBuilder sb = new StringBuilder(); + T dto =null; + File file = new File(path+"\\"+fileName); + try { + if (!file.getParentFile().exists()) { + file.getParentFile().mkdirs(); + } + if (!file.exists()) { + try { + file.createNewFile(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } else { + BufferedReader bufferedReader = null; + bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(file))); + String line; + while (!StringUtils.isEmpty(line = bufferedReader.readLine())) { + sb.append(line); + } + if (sb.length() > 0) { + ObjectMapper objectMapper = new ObjectMapper(); + //dto = (T)JSONObject.parse(sb.toString()); + dto= objectMapper.readValue(sb.toString(), clazz); + //dto = objectMapper.convertValue(o, new TypeReference() { }); + } + bufferedReader.close(); + } + + return dto; + } + catch (Exception ex){ + ex.printStackTrace(); + return null; + } + } + + public T Read(File file,Class clazz) { + StringBuilder sb = new StringBuilder(); + T dto =null; + try { + if (!file.getParentFile().exists()) { + file.getParentFile().mkdirs(); + } + if (!file.exists()) { + try { + file.createNewFile(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } else { + BufferedReader bufferedReader = null; + bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(file))); + String line; + while (!StringUtils.isEmpty(line = bufferedReader.readLine())) { + sb.append(line); + } + if (sb.length() > 0) { + ObjectMapper objectMapper = new ObjectMapper(); + //dto = (T)JSONObject.parse(sb.toString()); + dto= objectMapper.readValue(sb.toString(), clazz); + //dto = objectMapper.convertValue(o, new TypeReference() { }); + } + bufferedReader.close(); + } + + return dto; + } + catch (Exception ex){ + ex.printStackTrace(); + return null; + } + } + /** + * 取得当前jar路径 + * @return + */ + private String CurrentPath(){ + File dir = new File("."); + String currentpath =""; + try { + currentpath = dir.getCanonicalPath(); + } catch (IOException e) { + e.printStackTrace(); + } + return currentpath; + } + + /** + * 读取文件内容 + * @param path + * @param fileName + * @return + */ + public String ReadContent(String path,String fileName){ + String currentPath=CurrentPath(); + path = currentPath+"\\"+path; + StringBuilder sb = new StringBuilder(); + File file = new File(path+"\\"+fileName); + try { + if (!file.getParentFile().exists()) { + file.getParentFile().mkdirs(); + } + if (!file.exists()) { + try { + file.createNewFile(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } else { + BufferedReader bufferedReader = null; + bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(file))); + String line; + while (!StringUtils.isEmpty(line = bufferedReader.readLine())) { + sb.append(line); + } + + bufferedReader.close(); + } + + return sb.toString(); + } + catch (Exception ex){ + ex.printStackTrace(); + return null; + } + } + + /** + * 保存json至文件 + * @param path 路径后缀 + * @param fileName 文件名称 + * @param data json信息 + * @return + */ + public void Save(String path,String fileName,String data){ + String currentPath=CurrentPath(); + path = currentPath+"\\"+path; + FileWriter fwriter = null; + try { + File file = new File(path); + if (!file.getParentFile().exists()) { + file.getParentFile().mkdirs(); + } + fwriter = new FileWriter(path+"\\"+fileName); + fwriter.write(data); + } catch (IOException ex) { + ex.printStackTrace(); + } finally { + try { + fwriter.flush(); + fwriter.close(); + } catch (IOException ex) { + ex.printStackTrace(); + } + } + } + +} diff --git a/src/main/java/com/docus/server/report/util/XmlUtil.java b/src/main/java/com/docus/server/report/util/XmlUtil.java new file mode 100644 index 0000000..e199e2e --- /dev/null +++ b/src/main/java/com/docus/server/report/util/XmlUtil.java @@ -0,0 +1,850 @@ +/* + * Copyright (c) 2018-2028, DreamLu All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the dreamlu.net developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: DreamLu 卢春梦 (596392912@qq.com) + */ +package com.docus.server.report.util; + +import com.docus.core.util.Exceptions; +import com.docus.core.util.IoUtil; +import org.springframework.lang.Nullable; +import org.w3c.dom.*; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +import javax.xml.namespace.QName; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpressionException; +import javax.xml.xpath.XPathFactory; +import java.io.IOException; +import java.io.InputStream; +import java.io.StringReader; +import java.util.HashMap; +import java.util.Map; + +/** + * xpath解析xml + * + *
+ *     文档地址:
+ *     http://www.w3school.com.cn/xpath/index.asp
+ * 
+ * + * @author L.cm + */ +public class XmlUtil { + private final XPath path; + private final Document doc; + + private XmlUtil(InputSource inputSource) throws ParserConfigurationException, SAXException, IOException { + DocumentBuilderFactory dbf = getDocumentBuilderFactory(); + DocumentBuilder db = dbf.newDocumentBuilder(); + doc = db.parse(inputSource); + path = getXPathFactory().newXPath(); + } + + /** + * 创建工具类 + * + * @param inputSource inputSource + * @return XmlUtil + */ + private static XmlUtil create(InputSource inputSource) { + try { + return new XmlUtil(inputSource); + } catch (ParserConfigurationException | SAXException | IOException e) { + throw Exceptions.unchecked(e); + } + } + + /** + * 转换工具类 + * + * @param inputStream inputStream + * @return XmlUtil + */ + public static XmlUtil of(InputStream inputStream) { + InputSource inputSource = new InputSource(inputStream); + return create(inputSource); + } + + /** + * 转换工具类 + * + * @param xmlStr xmlStr + * @return XmlUtil + */ + public static XmlUtil of(String xmlStr) { + StringReader sr = new StringReader(xmlStr.trim()); + InputSource inputSource = new InputSource(sr); + XmlUtil xmlUtil = create(inputSource); + IoUtil.closeQuietly(sr); + return xmlUtil; + } + + /** + * 转换路径 + * + * @param expression 表达式 + * @param item 实体 + * @param returnType 返回类型 + * @return Object + */ + private Object evalXPath(String expression, @Nullable Object item, QName returnType) { + item = null == item ? doc : item; + try { + return path.evaluate(expression, item, returnType); + } catch (XPathExpressionException e) { + throw Exceptions.unchecked(e); + } + } + + /** + * 获取String + * + * @param expression 路径 + * @return {String} + */ + public String getString(String expression) { + return (String) evalXPath(expression, null, XPathConstants.STRING); + } + + /** + * 获取Boolean + * + * @param expression 路径 + * @return {String} + */ + public Boolean getBoolean(String expression) { + return (Boolean) evalXPath(expression, null, XPathConstants.BOOLEAN); + } + + /** + * 获取Number + * + * @param expression 路径 + * @return {Number} + */ + public Number getNumber(String expression) { + return (Number) evalXPath(expression, null, XPathConstants.NUMBER); + } + + /** + * 获取某个节点 + * + * @param expression 路径 + * @return {Node} + */ + public Node getNode(String expression) { + return (Node) evalXPath(expression, null, XPathConstants.NODE); + } + + /** + * 获取子节点 + * + * @param expression 路径 + * @return NodeList + */ + public NodeList getNodeList(String expression) { + return (NodeList) evalXPath(expression, null, XPathConstants.NODESET); + } + + + /** + * 获取String + * + * @param node 节点 + * @param expression 相对于node的路径 + * @return {String} + */ + public String getString(Object node, String expression) { + return (String) evalXPath(expression, node, XPathConstants.STRING); + } + + /** + * 获取 + * + * @param node 节点 + * @param expression 相对于node的路径 + * @return {String} + */ + public Boolean getBoolean(Object node, String expression) { + return (Boolean) evalXPath(expression, node, XPathConstants.BOOLEAN); + } + + /** + * 获取 + * + * @param node 节点 + * @param expression 相对于node的路径 + * @return {Number} + */ + public Number getNumber(Object node, String expression) { + return (Number) evalXPath(expression, node, XPathConstants.NUMBER); + } + + /** + * 获取某个节点 + * + * @param node 节点 + * @param expression 路径 + * @return {Node} + */ + public Node getNode(Object node, String expression) { + return (Node) evalXPath(expression, node, XPathConstants.NODE); + } + + /** + * 获取子节点 + * + * @param node 节点 + * @param expression 相对于node的路径 + * @return NodeList + */ + public NodeList getNodeList(Object node, String expression) { + return (NodeList) evalXPath(expression, node, XPathConstants.NODESET); + } + + /** + * 针对没有嵌套节点的简单处理 + * + * @return map集合 + */ + public Map toMap() { + Element root = doc.getDocumentElement(); + Map params = new HashMap<>(16); + + // 将节点封装成map形式 + NodeList list = root.getChildNodes(); + for (int i = 0; i < list.getLength(); i++) { + Node node = list.item(i); + if (node instanceof Element) { + params.put(node.getNodeName(), node.getTextContent()); + } + } + return params; + } + + private static volatile boolean preventedXXE = false; + + private static DocumentBuilderFactory getDocumentBuilderFactory() throws ParserConfigurationException { + DocumentBuilderFactory dbf = XmlHelperHolder.documentBuilderFactory; + if (!preventedXXE) { + preventXXE(dbf); + } + return dbf; + } + + /** + * preventXXE + * + * @param dbf + * @throws ParserConfigurationException + */ + private static void preventXXE(DocumentBuilderFactory dbf) throws ParserConfigurationException { + // This is the PRIMARY defense. If DTDs (doctypes) are disallowed, almost all XML entity attacks are prevented + // Xerces 2 only - http://xerces.apache.org/xerces2-j/features.html#disallow-doctype-decl + dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); + + // If you can't completely disable DTDs, then at least do the following: + // Xerces 1 - http://xerces.apache.org/xerces-j/features.html#external-general-entities + // Xerces 2 - http://xerces.apache.org/xerces2-j/features.html#external-general-entities + + // JDK7+ - http://xml.org/sax/features/external-general-entities + dbf.setFeature("http://xml.org/sax/features/external-general-entities", false); + + // Xerces 1 - http://xerces.apache.org/xerces-j/features.html#external-parameter-entities + // Xerces 2 - http://xerces.apache.org/xerces2-j/features.html#external-parameter-entities + + // JDK7+ - http://xml.org/sax/features/external-parameter-entities + dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + + // Disable external DTDs as well + dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); + + // and these as well, per Timothy Morgan's 2014 paper: "XML Schema, DTD, and Entity Attacks" + dbf.setXIncludeAware(false); + dbf.setExpandEntityReferences(false); + preventedXXE = true; + } + + private static XPathFactory getXPathFactory() { + return XmlHelperHolder.xPathFactory; + } + + /** + * 内部类单例 + */ + private static class XmlHelperHolder { + private static DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); + private static XPathFactory xPathFactory = XPathFactory.newInstance(); + } + private static String str; + static { + str=" \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 59 \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 205室 \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 耳鼻咽喉头颈外科 \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 2号楼16楼西区 \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 南方医科大学顺德医院 \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + "
\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 突发特发性听觉丧失 \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + "
\n" + + "
\n" + + " \n" + + " \n" + + "
\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 常规 \n" + + " \n" + + " \n" + + "
\n" + + "
\n" + + " \n" + + " \n" + + "
\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + "
\n" + + "
\n" + + " \n" + + " \n" + + "
\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + "
\n" + + "
\n" + + " \n" + + " \n" + + "
\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 治愈 \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 张存良 \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 耳鼻咽喉头颈外科 \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 突发特发性听觉丧失 \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 文本 \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 乳房病类 \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + "
\n" + + "
\n" + + "
\n" + + "
\n" + + "
\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 治愈 \n" + + " \n" + + " O \n" + + " \n" + + " 0 \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 01 \n" + + " \n" + + " 出院医嘱 \n" + + " \n" + + "
\n"; + } + + public static void main(String[] args) { + XmlUtil a=XmlUtil.of(str); + Node node=null; + //id-消息流水号 + node = a.getNode("/PRPA_HIP0032/id/@extension"); + String serialId = node.toString(); + System.out.println(serialId); + //住院流水号 + node = a.getNode("/PRPA_HIP0032/controlActProcess/subject/encounterEvent/item/@extension"); + String jzh = node.toString(); + System.out.println(jzh); + //住院号标识 + node = a.getNode("/PRPA_HIP0032/controlActProcess/subject/encounterEvent/id/item/@extension"); + String inpatientNo = node.toString(); + System.out.println(inpatientNo); + //住院次数[] + node = a.getNode("/PRPA_HIP0032/controlActProcess/subject/encounterEvent/lengthOfStayQuantity[@unit='次']/@value"); + String admissTimes=node.toString(); + System.out.println(admissTimes); + //姓名 + node = a.getNode("/PRPA_HIP0032/controlActProcess/subject/encounterEvent/subject/patient/patientPerson/name/item/part/@value"); + String name = node.toString(); + System.out.println(name); + //入院日期时间 + node = a.getNode("/PRPA_HIP0032/controlActProcess/subject/encounterEvent/effectiveTime/low/@value"); + String admissDate = node.toString(); + System.out.println(admissDate); + //出院日期时间 + node = a.getNode("/PRPA_HIP0032/controlActProcess/subject/encounterEvent/effectiveTime/high/@value"); + String disDate = node.toString(); + System.out.println(disDate); + //入院诊断科室名称[] + node = a.getNode("/PRPA_HIP0032/controlActProcess/subject/encounterEvent/component[@displayName='入院诊断']/section/entry[@displayName='入院诊断-西医条目']/observation/performer/assignedEntity/representedOrganization/name"); + String admissDeptName = node.getTextContent(); + System.out.println(admissDeptName); + //出院诊断科室名称[] + node = a.getNode("/PRPA_HIP0032/controlActProcess/subject/encounterEvent/component[@displayName='出院诊断']/section/entry[@displayName='出院诊断-西医条目']/observation/performer/assignedEntity/representedOrganization/name"); + String disDeptName = node.getTextContent(); + System.out.println(disDeptName); + //主治医师[] + node = a.getNode("/PRPA_HIP0032/controlActProcess/subject/encounterEvent/authenticator[@displayName='主治医师']/assignedEntity/assignedPerson/name"); + String attendingName = node.getTextContent(); + System.out.println(attendingName); + } +} diff --git a/src/main/java/com/docus/server/report/webservice/IReportServer.java b/src/main/java/com/docus/server/report/webservice/IReportServer.java new file mode 100644 index 0000000..99cc0ca --- /dev/null +++ b/src/main/java/com/docus/server/report/webservice/IReportServer.java @@ -0,0 +1,39 @@ +package com.docus.server.report.webservice; + +import javax.jws.WebMethod; +import javax.jws.WebService; + +/** + * @author Fang Ruichuan + * @date 2022-11-14 19:03 + */ +@WebService +public interface IReportServer { + /** + * 接收手麻报告信息 + * @param saReportMessage 手麻报告信息 + * @return 返回信息 + */ + String pushSAReport(String saReportMessage); + + /** + * 接收重症报告信息 + * @param icuReportMessage 重症报告信息 + * @return 返回信息 + */ + String pushICUReport(String icuReportMessage); + + /** + * 接收检查报告的信息 - 新增 + * @param inspectionReportMessage 检查报告信息 - 新增 + * @return 成功或者异常信息 + */ + String pushAddInspectionReport(String inspectionReportMessage); + + /** + * 接收检查报告的信息 - 更新 + * @param inspectionReportMessage 检查报告信息 -更新 + * @return 成功或者异常信息 + */ + String pushUpdateInspectionReport(String inspectionReportMessage); +} diff --git a/src/main/java/com/docus/server/report/webservice/impl/SdryReportServerImpl.java b/src/main/java/com/docus/server/report/webservice/impl/SdryReportServerImpl.java new file mode 100644 index 0000000..e80760d --- /dev/null +++ b/src/main/java/com/docus/server/report/webservice/impl/SdryReportServerImpl.java @@ -0,0 +1,529 @@ +package com.docus.server.report.webservice.impl; + +import com.alibaba.fastjson.JSONObject; +import com.docus.core.util.DateUtil; +import com.docus.core.util.Func; +import com.docus.infrastructure.core.exception.BaseException; +import com.docus.server.report.dto.ReportDto; +import com.docus.server.report.service.ReportService; +import com.docus.server.report.util.IdUtil; +import com.docus.server.report.util.JSXMLResult; +import com.docus.server.report.util.TableJsonRead; +import com.docus.server.report.util.XmlUtil; +import com.docus.server.report.webservice.IReportServer; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.w3c.dom.Node; + +import javax.annotation.Resource; +import java.util.Date; + +/** + * @author wyb + * @date 2023年3月3日13:42:36 + */ +@Service +@Slf4j +public class SdryReportServerImpl implements IReportServer { + + @Resource + private ReportService reportService; + + @Override + public String pushSAReport(String saReportMessage) { + // 待做 + log.info("收到手麻消息:{}", saReportMessage); + String msgId = ""; + try { + XmlUtil xmlUtil = XmlUtil.of(saReportMessage); + Node msgNode = xmlUtil.getNode("/Request/Msg/ID"); + msgId = msgNode.getTextContent(); + ReportDto reportDto = getReportDtoByJSXML(xmlUtil); + verifyReportDto(reportDto); + reportService.report(reportDto); + return JSXMLResult.success(msgId); + } catch (BaseException baseException) { + log.error(baseException.getMessage(), baseException); + return JSXMLResult.failed(msgId, baseException.getMessage()); + } catch (Exception ex) { + log.error(ex.getMessage(), ex); + return JSXMLResult.failed(msgId, "系统故障!"); + } + } + + + /** + * 嘉时自定义接收接口使用,从xml工具读取返回文件上报需要的数据 + * + * @param xmlUtil xml消息工具封装 + * @return 文件上报数据 + */ + public ReportDto getReportDtoByJSXML(XmlUtil xmlUtil) { + TableJsonRead jsonRead = new TableJsonRead(); + JSONObject tableTypeJson = jsonRead.Read("data-config", "js-table-type.json", JSONObject.class); + String jsReportConfigXml = jsonRead.ReadContent("data-config", "js-report-config.xml"); + XmlUtil configXmlUtil = XmlUtil.of(jsReportConfigXml); + + Node inpatientNoXpathNode = configXmlUtil.getNode("/REPORT/INPATIENT_NO"); + String inpatientNoXpath = inpatientNoXpathNode.getTextContent(); + Node inpatientNoNode = xmlUtil.getNode(inpatientNoXpath); + String inpatientNo = inpatientNoNode.getTextContent(); + + Node jzhXpathNode = configXmlUtil.getNode("/REPORT/JZH"); + String jzhXpath = jzhXpathNode.getTextContent(); + Node jzhNode = xmlUtil.getNode(jzhXpath); + String jzh = jzhNode.getTextContent(); + + Node admissTimesXpathNode = configXmlUtil.getNode("/REPORT/ADMISS_TIMES"); + String admissTimesXpath = admissTimesXpathNode.getTextContent(); + Node admissTimesNode = xmlUtil.getNode(admissTimesXpath); + Integer admissTimes = Integer.valueOf(admissTimesNode.getTextContent()); + + Node serialnumXpathNode = configXmlUtil.getNode("/REPORT/SERIALNUM"); + String serialnumXpath = serialnumXpathNode.getTextContent(); + Node serialnumNode = xmlUtil.getNode(serialnumXpath); + String serialnum = serialnumNode.getTextContent(); + + Node fileTitleXpathNode = configXmlUtil.getNode("/REPORT/FILE_TITLE"); + String fileTitleXpath = fileTitleXpathNode.getTextContent(); + Node fileTitleNode = xmlUtil.getNode(fileTitleXpath); + String fileTitle = fileTitleNode.getTextContent(); + + Node downUrlXpathNode = configXmlUtil.getNode("/REPORT/DOWNURL"); + String downUrlXpath = downUrlXpathNode.getTextContent(); + Node downUrlNode = xmlUtil.getNode(downUrlXpath); + String downUrl = downUrlNode.getTextContent(); + + Node tableTypeXpathNode = configXmlUtil.getNode("/REPORT/TABLE_TYPE"); + String tableTypeXpath = tableTypeXpathNode.getTextContent(); + Node tableTypeNode = xmlUtil.getNode(tableTypeXpath); + String tableType = tableTypeNode.getTextContent(); + + + Node assortIdXpathNode = configXmlUtil.getNode("/REPORT/ASSORT_ID"); + String assortIdXpath = assortIdXpathNode.getTextContent(); + String assortId; + if (Func.isBlank(assortIdXpath)) { + // 如果没有配置 取value 属性,如果value也未配置 取 tableType 对应的json配置,最终方案默认 other 分段 + Node assortIdValueNode = assortIdXpathNode.getAttributes().getNamedItem("value"); + if (Func.isEmpty(assortIdValueNode)) { + assortId = assortIdValueNode.getNodeValue(); + } else { + assortId = tableTypeJson.getString(tableType); + } + if (Func.isBlank(assortId)) { + assortId = tableTypeJson.getString("other"); + } + } else { + Node assortIdNode = xmlUtil.getNode(assortIdXpath); + assortId = assortIdNode.getTextContent(); + } + + Node sysFlagXpathNode = configXmlUtil.getNode("/REPORT/SYSTEM_FLAG"); + String sysFlagXpath = sysFlagXpathNode.getTextContent(); + Node sysFlagNode = xmlUtil.getNode(sysFlagXpath); + String sysFlag = sysFlagNode.getTextContent(); + + Node fileSourceXpathNode = configXmlUtil.getNode("/REPORT/FILESOURCE"); + String fileSourceXpath = fileSourceXpathNode.getTextContent(); + String fileSource; + if (Func.isBlank(fileSourceXpath)) { + Node fileSourceValueNode = fileSourceXpathNode.getAttributes().getNamedItem("value"); + if (Func.isEmpty(fileSourceValueNode)) { + fileSource = null; + } else { + fileSource = fileSourceValueNode.getNodeValue(); + } + + } else { + Node fileSourceNode = xmlUtil.getNode(fileSourceXpath); + fileSource = fileSourceNode.getTextContent(); + } + + + Node fileStorageTypeXpathNode = configXmlUtil.getNode("/REPORT/FILE_STORAGE_TYPE"); + String fileStorageTypeXpath = fileStorageTypeXpathNode.getTextContent(); + String fileStorageType; + if (Func.isBlank(fileStorageTypeXpath)) { + Node filestoragetypeValueNode = fileStorageTypeXpathNode.getAttributes().getNamedItem("value"); + if (Func.isEmpty(filestoragetypeValueNode)) { + fileStorageType = "1"; + } else { + fileStorageType = filestoragetypeValueNode.getNodeValue(); + } + + } else { + Node filestoragetypeNode = xmlUtil.getNode(fileStorageTypeXpath); + fileStorageType = filestoragetypeNode.getTextContent(); + } + + ReportDto reportDto = new ReportDto(); + reportDto.setAdmisstimes(admissTimes); + reportDto.setInpatientNo(inpatientNo); + reportDto.setJzh(jzh); + reportDto.setSerialnum(serialnum); + reportDto.setFileTitle(fileTitle); + reportDto.setDownUrl(downUrl); + reportDto.setAssortId(assortId); + reportDto.setSysFlag(sysFlag); + reportDto.setFileSource(fileSource); + reportDto.setFilestoragetype(fileStorageType); + return reportDto; + } + + @Override + public String pushICUReport(String icuReportMessage) { + log.info("收到重症消息:{}", icuReportMessage); + String msgId = ""; + try { + XmlUtil xmlUtil = XmlUtil.of(icuReportMessage); + Node msgNode = xmlUtil.getNode("/Request/Msg/ID"); + msgId = msgNode.getTextContent(); + ReportDto reportDto = getReportDtoByJSXML(xmlUtil); + verifyReportDto(reportDto); + reportService.report(reportDto); + return JSXMLResult.success(msgId); + } catch (BaseException baseException) { + log.error(baseException.getMessage(), baseException); + return JSXMLResult.failed(msgId, baseException.getMessage()); + } catch (Exception ex) { + log.error(ex.getMessage(), ex); + return JSXMLResult.failed(msgId, "系统故障!"); + } + } + + @Override + public String pushAddInspectionReport(String inspectionReportMessage) { + log.info("收到检查报告新增消息:{}", inspectionReportMessage); + String msgId = ""; + String sender = ""; + String receiver = ""; + try { + XmlUtil xmlUtil = XmlUtil.of(inspectionReportMessage); + msgId = xmlUtil.getNode("/POOR_HIP1008/id/@extension").getNodeValue(); + sender = xmlUtil.getNode("/POOR_HIP1008/sender/device/id/item/@extension").getNodeValue(); + receiver = xmlUtil.getNode("/POOR_HIP1008/receiver/device/id/item/@extension").getNodeValue(); + + ReportDto reportDto = getReportDtoByInspectionInsert(xmlUtil); + verifyReportDto(reportDto); + reportService.report(reportDto); + return insertSuccess(msgId, sender, receiver); + } catch (BaseException baseException) { + log.error(baseException.getMessage(), baseException); + return insertFailed(msgId, sender, receiver, baseException.getMessage()); + } catch (Exception ex) { + log.error(ex.getMessage(), ex); + return insertFailed(msgId, sender, receiver, "系统错误!"); + } + } + + + @Override + public String pushUpdateInspectionReport(String inspectionReportMessage) { + log.info("收到检查报告更新消息{}", inspectionReportMessage); + String msgId = ""; + String sender = ""; + String receiver = ""; + try { + XmlUtil xmlUtil = XmlUtil.of(inspectionReportMessage); + msgId = xmlUtil.getNode("/POOR_HIP1009/id/@extension").getNodeValue(); + sender = xmlUtil.getNode("/POOR_HIP1009/sender/device/id/item/@extension").getNodeValue(); + receiver = xmlUtil.getNode("/POOR_HIP1009/receiver/device/id/item/@extension").getNodeValue(); + + ReportDto reportDto = getReportDtoByInspectionUpdate(xmlUtil); + verifyReportDto(reportDto); + reportService.report(reportDto); + return updateSuccess(msgId, sender, receiver); + } catch (BaseException baseException) { + log.error(baseException.getMessage(), baseException); + return updateFailed(msgId, sender, receiver, baseException.getMessage()); + } catch (Exception ex) { + log.error(ex.getMessage(), ex); + return updateFailed(msgId, sender, receiver, "系统错误"); + } + + } + + /** + * 验证上报文件的信息 + * + * @param reportDto 上报文件的信息 + * @throws BaseException 验证不通过抛出业务异常 + */ + private void verifyReportDto(ReportDto reportDto) throws BaseException { + + if (Func.isBlank(reportDto.getInpatientNo())) { + throw new BaseException("住院号不能为空!"); + } + + if (Func.isEmpty(reportDto.getAdmisstimes()) && Func.isBlank(reportDto.getJzh())) { + throw new BaseException("当住院号与住院次数都为空时,住院流水号/记账号不能为空!"); + } + + if (Func.isBlank(reportDto.getFileTitle())) { + throw new BaseException("文件名不能为空!"); + } + if (Func.isBlank(reportDto.getDownUrl())) { + throw new BaseException("文件下载路径不能为空!"); + } + } + + public ReportDto getReportDtoByInspectionInsert(XmlUtil inspectionInsertXmlUtil) { + + Node inpatientNoNode = inspectionInsertXmlUtil.getNode("/POOR_HIP1008/controlActProcess/subject/recordTarget/patientRole/id[@root='2.16.156.10011.1.12']/@extension"); + String inpatientNo = inpatientNoNode.getNodeValue(); + + Node admissTimesNode = inspectionInsertXmlUtil.getNode("/POOR_HIP1008/controlActProcess/subject/recordTarget/patientRole/item[@root='1.2.156.112635.1.2.1.7']/@extension"); + Integer admissTimes = Integer.valueOf(admissTimesNode.getNodeValue()); + + // 检查报告单号标识 + Node reportFlagNode = inspectionInsertXmlUtil.getNode("/POOR_HIP1008/controlActProcess/subject/recordTarget/patientRole/id[@root='2.16.156.10011.1.32']/@extension"); + String reportFlag = reportFlagNode.getNodeValue(); + //电子申请单编号 + Node eafNoNode = inspectionInsertXmlUtil.getNode("/POOR_HIP1008/controlActProcess/subject/recordTarget/patientRole/id[@root='2.16.156.10011.1.24']/@extension"); + String eafNo = eafNoNode.getNodeValue(); + String serialnum = reportFlag + "@" + eafNo; + + Node assortIdNode = inspectionInsertXmlUtil.getNode("/POOR_HIP1008/controlActProcess/subject/component/structuredBody/component[@displayName='检查报告']/section/entry[@displayName='检查类型']/observation/code/@displayName"); + String assortId = assortIdNode.getNodeValue(); + + Node sysFlagNode = inspectionInsertXmlUtil.getNode("/POOR_HIP1008/controlActProcess/subject/component/structuredBody/component[@displayName='检查报告']/section/entry[@displayName='检查类型']/observation/code/@displayName"); + String sysFlag = sysFlagNode.getNodeValue(); + + Node fileTitleNode = inspectionInsertXmlUtil.getNode("/POOR_HIP1008/controlActProcess/subject/component/structuredBody/component[@displayName='检查报告']/section/entry[@displayName='检查报告类型']/observation/code/@displayName"); + String fileTitle = fileTitleNode.getNodeValue(); + + Node downUrlNode = inspectionInsertXmlUtil.getNode("/POOR_HIP1008/controlActProcess/subject/component/structuredBody/component[@displayName='检查报告图像']/report/entry[@displayName='检查报告图像URL地址']/observation/value"); + String downUrl = downUrlNode.getTextContent(); + + ReportDto reportDto = new ReportDto(); + reportDto.setAdmisstimes(admissTimes); + reportDto.setInpatientNo(inpatientNo); + reportDto.setSerialnum(serialnum); + reportDto.setFileTitle(fileTitle); + reportDto.setDownUrl(downUrl); + reportDto.setAssortId(assortId); + reportDto.setSysFlag(sysFlag); + reportDto.setFileSource("1"); + reportDto.setFilestoragetype("1"); + return reportDto; + } + + public ReportDto getReportDtoByInspectionUpdate(XmlUtil inspectionUpdateXmlUtil) { + Node inpatientNoNode = inspectionUpdateXmlUtil.getNode("/POOR_HIP1009/controlActProcess/subject/recordTarget/patientRole/id[@root='2.16.156.10011.1.12']/@extension"); + String inpatientNo = inpatientNoNode.getNodeValue(); + + Node admissTimesNode = inspectionUpdateXmlUtil.getNode("/POOR_HIP1009/controlActProcess/subject/recordTarget/patientRole/item[@root='1.2.156.112635.1.2.1.7']/@extension"); + Integer admissTimes = Integer.valueOf(admissTimesNode.getNodeValue()); + + // 检查报告单号标识 + Node reportFlagNode = inspectionUpdateXmlUtil.getNode("/POOR_HIP1009/controlActProcess/subject/recordTarget/patientRole/id[@root='2.16.156.10011.1.32']/@extension"); + String reportFlag = reportFlagNode.getNodeValue(); + //电子申请单编号 + Node eafNoNode = inspectionUpdateXmlUtil.getNode("/POOR_HIP1009/controlActProcess/subject/recordTarget/patientRole/id[@root='2.16.156.10011.1.24']/@extension"); + String eafNo = eafNoNode.getNodeValue(); + String serialnum = reportFlag + "@" + eafNo; + + Node assortIdNode = inspectionUpdateXmlUtil.getNode("/POOR_HIP1009/controlActProcess/subject/component/structuredBody/component[@displayName='检查报告']/section/entry[@displayName='检查类型']/observation/code/@displayName"); + String assortId = assortIdNode.getNodeValue(); + + Node sysFlagNode = inspectionUpdateXmlUtil.getNode("/POOR_HIP1009/controlActProcess/subject/component/structuredBody/component[@displayName='检查报告']/section/entry[@displayName='检查类型']/observation/code/@displayName"); + String sysFlag = sysFlagNode.getNodeValue(); + + Node fileTitleNode = inspectionUpdateXmlUtil.getNode("/POOR_HIP1009/controlActProcess/subject/component/structuredBody/component[@displayName='检查报告']/section/entry[@displayName='检查报告类型']/observation/code/@displayName"); + String fileTitle = fileTitleNode.getNodeValue(); + + Node downUrlNode = inspectionUpdateXmlUtil.getNode("/POOR_HIP1009/controlActProcess/subject/component/structuredBody/component[@displayName='检查报告图像']/report/entry[@displayName='检查报告图像URL地址']/observation/value"); + String downUrl = downUrlNode.getTextContent(); + + + ReportDto reportDto = new ReportDto(); + reportDto.setAdmisstimes(admissTimes); + reportDto.setInpatientNo(inpatientNo); + reportDto.setSerialnum(serialnum); + reportDto.setFileTitle(fileTitle); + reportDto.setDownUrl(downUrl); + reportDto.setAssortId(assortId); + reportDto.setSysFlag(sysFlag); + reportDto.setFileSource("1"); + reportDto.setFilestoragetype("1"); + return reportDto; + } + + /** + * 返回检查报告新增成功消息 + * + * @param msgId 消息id + * @param sender 发送路由 + * @param receiver 接收路由 + * @return 新增成功消息响应 + */ + public String insertSuccess(String msgId, String sender, String receiver) { + String createTime = Func.format(new Date(), DateUtil.PATTERN_DATETIME_MINI); + return "\n" + + "\t\n" + + "\t\n" + + "\t\n" + + "\t\n" + + "\t\n" + + "\t\n" + + "\t\n" + + "\t\t\n" + + "\t\t\t\n" + + "\t\t\t\t\n" + + "\t\t\t\n" + + "\t\t\n" + + "\t\n" + + "\t\n" + + "\t\t\n" + + "\t\t\t\n" + + "\t\t\t\t\n" + + "\t\t\t\n" + + "\t\t\n" + + "\t\n" + + "\t\n" + + "\t\t\n" + + "\t\t\t\n" + + "\t\t\n" + + "\t\t\n" + + "\t\t\t\n" + + "\t\t\t\t\n" + + "\t\t\t\n" + + "\t\t\n" + + "\t\n" + + "\n"; + } + + /** + * 返回检查报告插入失败响应消息 + * + * @param msgId 消息id + * @param sender 发送路由 + * @param receiver 接收路由 + * @return 检查报告新增失败响应消息 + */ + public String insertFailed(String msgId, String sender, String receiver, String failedMessage) { + String createTime = Func.format(new Date(), DateUtil.PATTERN_DATETIME_MINI); + return "\n" + + "\t\n" + + "\t\n" + + "\t\n" + + "\t\n" + + "\t\n" + + "\t\n" + + "\t\n" + + "\t\t\n" + + "\t\t\t\n" + + "\t\t\t\t\n" + + "\t\t\t\n" + + "\t\t\n" + + "\t\n" + + "\t\n" + + "\t\t\n" + + "\t\t\t\n" + + "\t\t\t\t\n" + + "\t\t\t\n" + + "\t\t\n" + + "\t\n" + + "\t\n" + + "\t\t\n" + + "\t\t\t\n" + + "\t\t\n" + + "\t\t\n" + + "\t\t\t\n" + + "\t\t\t\t\n" + + "\t\t\t\n" + + "\t\t\n" + + "\t\n" + + "\n"; + } + + /** + * 返回检查报告更新成功响应消息 + * + * @param msgId 消息id + * @param sender 发送路由 + * @param receiver 接收路由 + * @return 更新成功响应消息 + */ + public String updateSuccess(String msgId, String sender, String receiver) { + String createTime = Func.format(new Date(), DateUtil.PATTERN_DATETIME_MINI); + return "\n" + + "\t\n" + + "\t\n" + + "\t\n" + + "\t\n" + + "\t\n" + + "\t\n" + + "\t\n" + + "\t\t\n" + + "\t\t\t\n" + + "\t\t\t\t\n" + + "\t\t\t\n" + + "\t\t\n" + + "\t\n" + + "\t\n" + + "\t\t\n" + + "\t\t\t\n" + + "\t\t\t\t\n" + + "\t\t\t\n" + + "\t\t\n" + + "\t\n" + + "\t\n" + + "\t\t\n" + + "\t\t\t\n" + + "\t\t\n" + + "\t\t\n" + + "\t\t\t\n" + + "\t\t\t\t\n" + + "\t\t\t\n" + + "\t\t\n" + + "\t\n" + + "\n"; + } + + /** + * 检查报告更新失败响应 + * + * @param msgId 消息id + * @param sender 发送路由 + * @param receiver 接收路由 + * @param failedMessage 失败信息 + * @return 更新失败响应信息 + */ + public String updateFailed(String msgId, String sender, String receiver, String failedMessage) { + String createTime = Func.format(new Date(), DateUtil.PATTERN_DATETIME_MINI); + return "\n" + + "\t\n" + + "\t\n" + + "\t\n" + + "\t\n" + + "\t\n" + + "\t\n" + + "\t\n" + + "\t\t\n" + + "\t\t\t\n" + + "\t\t\t\t\n" + + "\t\t\t\n" + + "\t\t\n" + + "\t\n" + + "\t\n" + + "\t\t\n" + + "\t\t\t\n" + + "\t\t\t\t\n" + + "\t\t\t\n" + + "\t\t\n" + + "\t\n" + + "\t\n" + + "\t\t\n" + + "\t\t\t\n" + + "\t\t\n" + + "\t\t\n" + + "\t\t\t\n" + + "\t\t\t\t\n" + + "\t\t\t\n" + + "\t\t\n" + + "\t\n" + + "\n"; + } +} diff --git a/src/main/resources/bootstrap.yml b/src/main/resources/bootstrap.yml index 75b9f9a..3a47538 100644 --- a/src/main/resources/bootstrap.yml +++ b/src/main/resources/bootstrap.yml @@ -47,6 +47,8 @@ docus: user: # 用户默认密码 defpwd: fd29cd53ec12616e5f36b77d4afffbff + report: + downurl: http://localhost:9291/api/downplatform/report mybatis-plus: configuration: map-underscore-to-camel-case: true diff --git a/src/main/resources/mapper/AfCollectTaskMapper.xml b/src/main/resources/mapper/AfCollectTaskMapper.xml new file mode 100644 index 0000000..bb4b4c1 --- /dev/null +++ b/src/main/resources/mapper/AfCollectTaskMapper.xml @@ -0,0 +1,17 @@ + + + + + INSERT INTO `docus_archivefile`.`af_collect_task`(`id`, `patient_id`, `sysflag`, + `state`, `C1`,`C2`, `C3`) + VALUES (#{task.id}, #{task.patientId}, #{task.sysflag}, '0', #{task.C1}, #{task.C2}, #{task.C3}); + + + + diff --git a/src/main/resources/mapper/AfReportRecordMapper.xml b/src/main/resources/mapper/AfReportRecordMapper.xml new file mode 100644 index 0000000..eddd271 --- /dev/null +++ b/src/main/resources/mapper/AfReportRecordMapper.xml @@ -0,0 +1,56 @@ + + + + + + INSERT INTO `docus_archivefile`.`af_report_record`(`task_id`, `inpatient_no`, `jzh`, `admiss_times`, `down_url`, + `down_type`, `state`, `serialnum`, `sysflag`, `zd_assort_id`, + `create_time`, `update_time`, `file_name`, `patient_id`) + VALUES (#{reportRecord.taskId}, #{reportRecord.inpatientNo}, #{reportRecord.jzh}, #{reportRecord.admissTimes}, + #{reportRecord.downUrl}, #{reportRecord.downType}, 0, #{reportRecord.serialnum}, + #{reportRecord.sysflag}, #{reportRecord.zdAssortId}, now(), now(), #{reportRecord.fileName}, + #{reportRecord.patientId}); + + + update `docus_archivefile`.`af_report_record` + set `down_url`=#{reportRecord.downUrl}, + `down_type`=#{reportRecord.downType}, + `state`=0, + `file_name`=#{reportRecord.fileName}, + `patient_id`=#{reportRecord.patientId}, + `update_time`=now() + where `task_id` = #{reportRecord.taskId} + + + update `docus_archivefile`.`af_report_record` + set `state`= 1, + `update_time`=now() + where `task_id` = #{taskId} + + + + + diff --git a/src/main/resources/mapper/TBasicMapper.xml b/src/main/resources/mapper/TBasicMapper.xml index 302fa9f..c495a1f 100644 --- a/src/main/resources/mapper/TBasicMapper.xml +++ b/src/main/resources/mapper/TBasicMapper.xml @@ -3,6 +3,16 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> + + + + + INSERT INTO `docus_medicalrecord`.`t_basic` (`admiss_days`,`is_dead`,`sex_name`,`bed_num`,`age`,`sex`,`id_card`,`dis_dept`,`patient_id`, `admiss_times`, `inpatient_no`,`name`, `admiss_date`, `admiss_dept_name`, `dis_date`, `dis_dept_name`,`attending_name`,`jzh`)