0
+
+ + * 病案采集任务 + *
+ * + * @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); + + // 组织文件数据 + List0
" +
+ "500
" +
+ "+ * 文档地址: + * 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
\n" +
+ " \n" +
+ "
\n" +
+ " \n" +
+ " \n" +
+ "
\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " 突发特发性听觉丧失 \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ "
\n" +
+ " \n" +
+ "
\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " 无 \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ "
\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ "
\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ "
\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ "
\n" +
+ " \n" +
+ "
\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ "
\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ "
\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ "
\n" +
+ " \n" +
+ "
\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " 常规 \n" +
+ "
\n" +
+ " \n" +
+ "
\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ "
\n" +
+ " \n" +
+ "
\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ "
\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ "
\n" +
+ " \n" +
+ "
\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " 治愈 \n" +
+ "
\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ "
\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " 张存良 \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " 耳鼻咽喉头颈外科 \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " 突发特发性听觉丧失 \n" +
+ "
\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " 文本 \n" +
+ "
\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ "
\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ "
\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ "
\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ "
\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ "
\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ "
\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " 无 \n" +
+ "
\n" +
+ " \n" +
+ "
\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ "
\n" +
+ " \n" +
+ " 乳房病类 \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ "
\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ "
\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ "
\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ "
\n" +
+ " \n" +
+ "
\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ "
\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ "
\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ "