feat: 顺德人医,HIP1112 检查/检验报告召回推送

master
wyb 7 months ago
parent 7ec1634b80
commit a9cb442250

@ -121,6 +121,14 @@ public interface ReceiveServer {
*/
String pushMaternalInfantRelationship(String maternalInfantRelationshipMessage);
/**
*
* /
* @param recallInspectionReportMessage /
* @return
*/
String pushRecallInspectionReport(String recallInspectionReportMessage);
/**
* @description
*/

@ -107,6 +107,10 @@ public class ReceiveServerImpl implements ReceiveServer {
public String pushMaternalInfantRelationship(String maternalInfantRelationshipMessage) {
return reportServer.pushMaternalInfantRelationship(maternalInfantRelationshipMessage);
}
@Override
public String pushRecallInspectionReport(String recallInspectionReportMessage) {
return reportServer.pushRecallInspectionReport(recallInspectionReportMessage);
}
@Override
public String cancelHospital(String message) {

@ -33,4 +33,6 @@ public interface AfCollectTaskMapper {
* @return
*/
int updateNewSubmit(@Param("id") Long id,@Param("c2") String fileName,@Param("c1") String serialnum);
int cancelFile(@Param("patientId")String patientId, @Param("sysFlag")String sysFlag,@Param("serialnum") String serialnum);
}

@ -28,4 +28,5 @@ public interface ReportService {
*/
void makeupThreePartyPushReportByTaskIds(List<Long> taskIds) throws Exception;
void cancel(String patientId, String sysFlag, String serialnum);
}

@ -209,4 +209,9 @@ public class ReportServiceImpl implements ReportService {
// 当截取长度小于集合长度,可以进行下次循环截取
} while (loop);
}
@Override
public void cancel(String patientId, String sysFlag, String serialnum) {
collectTaskMapper.cancelFile(patientId,sysFlag,serialnum);
}
}

@ -75,4 +75,12 @@ public interface IReportServer {
* @return
*/
String pushMaternalInfantRelationship(String maternalInfantRelationshipMessage);
/**
*
* /
* @param recallInspectionReportMessage /
* @return
*/
String pushRecallInspectionReport(String recallInspectionReportMessage);
}

@ -9,6 +9,7 @@ public interface WebserviceMessageType {
String HIP1009="HIP1009";
String HIP1010="HIP1010";
String HIP1011="HIP1011";
String HIP1112="HIP1112";
String HIP1166="HIP1166";
String HIP1264="HIP1264";
String ICU="ICU";

@ -0,0 +1,429 @@
package com.docus.server.report.webservice.impl;
import com.docus.core.util.DateUtil;
import com.docus.core.util.Func;
import com.docus.infrastructure.core.exception.BaseException;
import com.docus.server.collection.mapper.TBasicMapper;
import com.docus.server.report.service.ReportService;
import com.docus.server.report.util.IdUtil;
import com.docus.server.report.util.XmlUtil;
import com.docus.server.report.webservice.WebserviceMessageType;
import com.docus.server.report.webservice.WebserviceReceiveServerHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import javax.annotation.Resource;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Objects;
/**
* HIP1008-
*
* @author jiahsi
*/
@Service(WebserviceMessageType.HIP1112)
@Slf4j
public class HIP1112RecallInspectionReportHandler implements WebserviceReceiveServerHandler {
@Resource
private ReportService reportService;
@Resource
private TBasicMapper tBasicMapper;
public static void main(String[] args) {
String xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
"\n" +
"<POOR_HIP1112 xmlns=\"urn:hl7-org:v3\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ITSVersion=\"XML_1.0\" xsi:schemaLocation=\"urn:hl7-org:v3 ../multicacheschemas/POOR_IN200901UV.xsd\"> \n" +
" <!-- 消息ID --> \n" +
" <id extension=\"20925035-51e6-49f1-87d1-0d1c60d04133\"/> \n" +
" <!-- 消息创建时间 --> \n" +
" <creationTime value=\"20241204081625\"/> \n" +
" <!-- 交互ID --> \n" +
" <interactionId extension=\"POOR_IN200901UV23\"/> \n" +
" <!--消息用途: P(Production); D(Debugging); T(Training) --> \n" +
" <processingCode code=\"P\"/> \n" +
" <!-- 消息处理模式: A(Archive); I(Initial load); R(Restore from archive); T(Current\n" +
" processing) --> \n" +
" <processingModeCode code=\"R\"/> \n" +
" <!-- 消息应答: AL(Always); ER(Error/reject only); NE(Never) --> \n" +
" <acceptAckCode code=\"NE\"/> \n" +
" <!-- 接受者 --> \n" +
" <receiver typeCode=\"RCV\"> \n" +
" <device classCode=\"DEV\" determinerCode=\"INSTANCE\"> \n" +
" <!-- 接受者ID --> \n" +
" <id> \n" +
" <item root=\"2.16.156.10011.0.1.1\" extension=\"Orion-001\"/> \n" +
" </id> \n" +
" </device> \n" +
" </receiver> \n" +
" <!-- 发送者 --> \n" +
" <sender typeCode=\"SND\"> \n" +
" <device classCode=\"DEV\" determinerCode=\"INSTANCE\"> \n" +
" <!-- 发送者ID --> \n" +
" <id> \n" +
" <item root=\"2.16.156.10011.0.1.2\" extension=\"ES-001\"/> \n" +
" </id> \n" +
" </device> \n" +
" </sender> \n" +
" <!-- 封装的消息内容(按Excel填写) --> \n" +
" <controlActProcess classCode=\"CACT\" moodCode=\"EVN\"> \n" +
" <!-- 消息交互类型 @code: 新增 :new 修改:update --> \n" +
" <code code=\"new\"/> \n" +
" <subject typeCode=\"SUBJ\" xsi:nil=\"false\"> \n" +
" <placerGroup> \n" +
" <!-- 1代表新增2代表更新--> \n" +
" <code/> \n" +
" <!-- 召回状态 必须项未使用 --> \n" +
" <statusCode code=\"1\"/> \n" +
" <!-- 患者信息 --> \n" +
" <subject typeCode=\"SBJ\"> \n" +
" <patient classCode=\"PAT\"> \n" +
" <id> \n" +
" <!--域ID --> \n" +
" <item root=\"1.2.156.10011.1.2.1.2\" extension=\"3\"/> \n" +
" <!-- 患者ID --> \n" +
" <item root=\"2.16.156.10011.0.2.2\" extension=\"000498133200\"/> \n" +
" <!--住院号标识--> \n" +
" <item root=\"2.16.156.10011.1.12\" extension=\"10155733\"/> \n" +
" <!--门急诊号--> \n" +
" <item root=\"2.16.156.10011.1.11\" extension=\"\"/> \n" +
" </id> \n" +
" <providerOrganization classCode=\"ORG\" determinerCode=\"INSTANCE\"> \n" +
" <!--报告科室编码--> \n" +
" <id> \n" +
" <item extension=\"11\" root=\"1.2.156.10011.1.1.1\"/> \n" +
" </id> \n" +
" <!--报告科室名称 --> \n" +
" <name xsi:type=\"BAG_EN\"> \n" +
" <item> \n" +
" <part value=\"耳鼻咽喉头颈外科\"/> \n" +
" </item> \n" +
" </name> \n" +
" <asOrganizationPartOf classCode=\"PART\"> \n" +
" <wholeOrganization determinerCode=\"INSTANCE\" classCode=\"ORG\"> \n" +
" <!--医疗机构代码 --> \n" +
" <id> \n" +
" <item extension=\"4560886379\"/> \n" +
" </id> \n" +
" <!--医疗机构名称 --> \n" +
" <name xsi:type=\"BAG_EN\"> \n" +
" <item> \n" +
" <part value=\"南方医科大学顺德医院\"/> \n" +
" </item> \n" +
" </name> \n" +
" </wholeOrganization> \n" +
" </asOrganizationPartOf> \n" +
" </providerOrganization> \n" +
" </patient> \n" +
" </subject> \n" +
" <!--召回章节 如果多份报告召回,此处可循环--> \n" +
" <component> \n" +
" <!--召回报告号 检验/检查报告单号--> \n" +
" <id root=\"2.16.156.10011.1.32\" extension=\"0004276274_1\"/> \n" +
" <!--召回关联申请单号--> \n" +
" <inFulfillmentOf> \n" +
" <order> \n" +
" <!-- 关联申请单号(可多个) --> \n" +
" <id extension=\"253120897\"/> \n" +
" <id extension=\"1008611\"/> \n" +
" <!--可多个,当还有需要关联的医嘱号时参照上述格式添加--> \n" +
" </order> \n" +
" </inFulfillmentOf> \n" +
" <!--报告属性 1代表检验报告、2代表检查报告--> \n" +
" <reportAttribute extension=\"2\" displayName=\"检查报告\"/> \n" +
" <!--报告类型 013 微生物系统报告 007 检验系统报告--> \n" +
" <code code=\"001\" codeSystem=\"1.2.156.112672.1.1.27\"> \n" +
" <displayName value=\"检查系统报告\"/> \n" +
" </code> \n" +
" <!-- 报告召回信息 --> \n" +
" <performer typeCode=\"PRF\"> \n" +
" <time> \n" +
" <!-- 报告召回时间 --> \n" +
" <any value=\"20241204081625\"/> \n" +
" </time> \n" +
" <assignedEntity classCode=\"ASSIGNED\"> \n" +
" <!-- 报告召回操作人编码 --> \n" +
" <id> \n" +
" <item extension=\"3-621\" root=\"1.2.156.10011.1.1.2\"/> \n" +
" </id> \n" +
" <assignedPerson determinerCode=\"INSTANCE\" classCode=\"PSN\"> \n" +
" <!-- 报告召回操作人姓名 必须项已使用 --> \n" +
" <name xsi:type=\"BAG_EN\"> \n" +
" <item> \n" +
" <part value=\"陈泓钰\"/> \n" +
" </item> \n" +
" </name> \n" +
" </assignedPerson> \n" +
" </assignedEntity> \n" +
" </performer> \n" +
" <!--召回操作科室 --> \n" +
" <location typeCode=\"LOC\" xsi:nil=\"false\"> \n" +
" <!--必须项未使用 --> \n" +
" <time/> \n" +
" <!--就诊机构/科室 --> \n" +
" <serviceDeliveryLocation classCode=\"SDLOC\"> \n" +
" <serviceProviderOrganization determinerCode=\"INSTANCE\" classCode=\"ORG\"> \n" +
" <!--操作科室编码 --> \n" +
" <id> \n" +
" <item extension=\"11\" root=\"1.2.156.10011.1.1.1\"/> \n" +
" </id> \n" +
" <!--操作科室名称 --> \n" +
" <name xsi:type=\"BAG_EN\"> \n" +
" <item> \n" +
" <part value=\"耳鼻咽喉头颈外科\"/> \n" +
" </item> \n" +
" </name> \n" +
" </serviceProviderOrganization> \n" +
" </serviceDeliveryLocation> \n" +
" </location> \n" +
" <!--召回原因--> \n" +
" <reason contextConductionInd=\"true\"> \n" +
" <observation moodCode=\"EVN\" classCode=\"OBS\"> \n" +
" <!-- 必须项 未使用--> \n" +
" <code/> \n" +
" <value xsi:type=\"ST\" value=\"报告状态修改\"/> \n" +
" </observation> \n" +
" </reason> \n" +
" </component> \n" +
" <!--就诊 --> \n" +
" <componentOf1 contextConductionInd=\"false\" xsi:nil=\"false\" typeCode=\"COMP\"> \n" +
" <!--就诊 --> \n" +
" <encounter classCode=\"ENC\" moodCode=\"EVN\"> \n" +
" <id> \n" +
" <!-- 就诊次数 必须项已使用 --> \n" +
" <item extension=\"1\" root=\"1.2.156.10011.1.2.1.7\"/> \n" +
" <!-- 就诊流水号 --> \n" +
" <item extension=\"401373\" root=\"1.2.156.10011.1.2.1.6\"/> \n" +
" </id> \n" +
" <!--就诊类别编码 1:门诊2:急诊3:住院4:体检9:其他;--> \n" +
" <code codeSystem=\"1.2.156.10011.1.1.80\" code=\"3\"> \n" +
" <!-- 就诊类别名称 --> \n" +
" <displayName value=\"住院\"/> \n" +
" </code> \n" +
" <!--必须项未使用 --> \n" +
" <statusCode code=\"Active\"/> \n" +
" <!--病人(必须项未使用) --> \n" +
" <subject typeCode=\"SBJ\"> \n" +
" <patient classCode=\"PAT\"/> \n" +
" </subject> \n" +
" </encounter> \n" +
" </componentOf1> \n" +
" </placerGroup> \n" +
" </subject> \n" +
" </controlActProcess> \n" +
"</POOR_HIP1112>\n";
new HIP1112RecallInspectionReportHandler().handle(xml);
}
@Override
public String handle(String receiveMessage) {
log.info("检查/检验召回推送:{}", receiveMessage);
String msgId = "";
String sender = "";
String receiver = "";
try {
XmlUtil xmlUtil = XmlUtil.of(receiveMessage);
msgId = xmlUtil.getNode("/POOR_HIP1112/id/@extension").getNodeValue();
sender = xmlUtil.getNode("/POOR_HIP1112/sender/device/id/item/@extension").getNodeValue();
receiver = xmlUtil.getNode("/POOR_HIP1112/receiver/device/id/item/@extension").getNodeValue();
String inpatientNo;
int admissTimes;
String patientId;
String sysFlag = sender;
Node inpatientNoNode = xmlUtil.getNode("/POOR_HIP1112/controlActProcess/subject/placerGroup/subject/patient/id/item[@root='2.16.156.10011.1.12']/@extension");
if (Objects.isNull(inpatientNoNode)) {
throw new BaseException("未找到住院号节点!");
}
inpatientNo = inpatientNoNode.getNodeValue();
if (Func.isBlank(inpatientNo)) {
throw new BaseException("住院号解析为空!");
}
Node admissTimesNode = xmlUtil.getNode("/POOR_HIP1112/controlActProcess/subject/placerGroup/componentOf1/encounter/id/item[@root='1.2.156.10011.1.2.1.7']/@extension");
if (Objects.isNull(admissTimesNode)) {
throw new BaseException("未找到住院次数节点!");
}
try {
admissTimes = Integer.parseInt(admissTimesNode.getNodeValue());
} catch (Exception ex) {
throw new BaseException("无法解析住院次数!");
}
if (admissTimes <= 0) {
throw new BaseException("住院次数解析不正常应该为大于0的数字");
}
try {
patientId = tBasicMapper.getPatientIdByInpatientNoAndAdminssTimes(inpatientNo, admissTimes);
} catch (Exception ex) {
log.error("检查/检验召回,根据住院号:" + inpatientNo + ",和住院次数:" + admissTimes + ",无法匹配正确的患者!" + ex.getMessage(), ex);
throw new BaseException("匹配患者失败!");
}
if (Func.isBlank(patientId)) {
throw new BaseException("无法匹配患者!");
}
String jy = "1";
String jc = "2";
String reportAttribute = xmlUtil.getNode("/POOR_HIP1112/controlActProcess/subject/placerGroup/component/reportAttribute/@extension").getNodeValue();
Node reportFlagNode = xmlUtil.getNode("/POOR_HIP1112/controlActProcess/subject/placerGroup/component/id[@root='2.16.156.10011.1.32']/@extension");
String reportFlag = reportFlagNode.getNodeValue();
if (Func.isBlank(reportFlag)) {
throw new BaseException("报告单号为空!");
}
NodeList requestNoNodes = xmlUtil.getNodeList("/POOR_HIP1112/controlActProcess/subject/placerGroup/component/inFulfillmentOf/order/id/@extension");
int length = requestNoNodes.getLength();
if (length > 0) {
for (int i = 0; i < length; i++) {
Node item = requestNoNodes.item(i);
String requestNo = item.getNodeValue();
if (jc.equals(reportAttribute)) {
String jianChaFileSerialnum = getJcFileSerialnum(reportFlag, requestNo, sender);
reportService.cancel(patientId, sysFlag, jianChaFileSerialnum);
}
if (jy.equals(reportAttribute)) {
String jianYanFileSerialnum = getJyFileSerialnum(reportFlag, requestNo);
reportService.cancel(patientId, sysFlag, jianYanFileSerialnum);
}
}
} else {
if (jc.equals(reportAttribute)) {
String jianChaFileSerialnum = getJcFileSerialnum(reportFlag, null, sender);
if (Func.isNotBlank(jianChaFileSerialnum)) {
reportService.cancel(patientId, sysFlag, jianChaFileSerialnum);
}
}
}
return success(msgId, sender, receiver);
} catch (BaseException baseException) {
log.error(baseException.getMessage(), baseException);
return failed(msgId, sender, receiver, baseException.getMessage());
} catch (Exception ex) {
log.error(ex.getMessage(), ex);
return failed(msgId, sender, receiver, "系统错误!");
}
}
/**
* @param reportFlag
* @param requestNo
* @param sender
* @return id
*/
private String getJcFileSerialnum(String reportFlag, String requestNo, String sender) {
// 如果报告单号带下划线是合并报告,取报告单号下划线前的,可能有个别来源不需要
List<String> ignoreUnderlineSenders = Arrays.asList("lungFunction-001", "BL-001");
boolean splitCondition = reportFlag.contains("_") && !ignoreUnderlineSenders.contains(sender);
if (splitCondition) {
String[] split = reportFlag.split("_");
return split[0];
}
if (Objects.isNull(requestNo)) {
return null;
}
return reportFlag + "@" + requestNo;
}
/**
* @param reportFlag
* @param requestNo
* @return id
*/
private String getJyFileSerialnum(String reportFlag, String requestNo) {
return reportFlag + "@" + requestNo;
}
/**
*
*
* @param msgId id
* @param sender
* @param receiver
* @return
*/
public String success(String msgId, String sender, String receiver) {
String createTime = Func.format(new Date(), DateUtil.PATTERN_DATETIME_MINI);
return "<MCCI_IN000002UV01 xmlns=\"urn:hl7-org:v3\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ITSVersion=\"XML_1.0\" xsi:schemaLocation=\"urn:hl7-org:v3 file:///E:/hl7/HL7/v3ballot_fullsite_2011MAY/v3ballot/html/processable/multicacheschemas/MCCI _IN000002UV01.xsd\">" +
"<id extension=\"" + IdUtil.standardUUID() + "\"/>" +
"<creationTime value=\"" + createTime + "\"/>" +
"<interactionId root=\"2.16.840.1.113883.1.6\" extension=\"MCCI_IN000002UV01\"/>" +
"<processingCode code=\"P\"/>" +
"<processingModeCode/>" +
"<acceptAckCode code=\"AL\"/>" +
"<receiver typeCode=\"RCV\">" +
"<device classCode=\"DEV\" determinerCode=\"INSTANCE\">" +
"<id>" +
"<item extension=\"Orion-001\"/>" +
"</id>" +
"</device>" +
"</receiver>" +
"<sender typeCode=\"SND\">" +
"<device classCode=\"DEV\" determinerCode=\"INSTANCE\">" +
"<id>" +
"<item extension=\"PaperlessManagementMRIS-001\"/>" +
"</id>" +
"</device>" +
"</sender>" +
"<acknowledgement typeCode=\"AA\">" +
"<targetMessage>" +
"<id extension=\"" + msgId + "\"/>" +
"</targetMessage>" +
"<acknowledgementDetail>" +
"<text value=\"成功\"/>" +
"</acknowledgementDetail>" +
"</acknowledgement>" +
"</MCCI_IN000002UV01>";
}
/**
*
*
* @param msgId id
* @param sender
* @param receiver
* @return
*/
public String failed(String msgId, String sender, String receiver, String failedMessage) {
String createTime = Func.format(new Date(), DateUtil.PATTERN_DATETIME_MINI);
return "<MCCI_IN000002UV01 xmlns=\"urn:hl7-org:v3\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ITSVersion=\"XML_1.0\" xsi:schemaLocation=\"urn:hl7-org:v3 file:///E:/hl7/HL7/v3ballot_fullsite_2011MAY/v3ballot/html/processable/multicacheschemas/MCCI _IN000002UV01.xsd\">" +
"<id extension=\"" + IdUtil.standardUUID() + "\"/>" +
"<creationTime value=\"" + createTime + "\"/>" +
"<interactionId root=\"2.16.840.1.113883.1.6\" extension=\"MCCI_IN000002UV01\"/>" +
"<processingCode code=\"P\"/>" +
"<processingModeCode/>" +
"<acceptAckCode code=\"AL\"/>" +
"<receiver typeCode=\"RCV\">" +
"<device classCode=\"DEV\" determinerCode=\"INSTANCE\">" +
"<id>" +
"<item extension=\"Orion-001\"/>" +
"</id>" +
"</device>" +
"</receiver>" +
"<sender typeCode=\"SND\">" +
"<device classCode=\"DEV\" determinerCode=\"INSTANCE\">" +
"<id>" +
"<item extension=\"PaperlessManagementMRIS-001\"/>" +
"</id>" +
"</device>" +
"</sender>" +
"<acknowledgement typeCode=\"AE\">" +
"<targetMessage>" +
"<id extension=\"" + msgId + "\"/>" +
"</targetMessage>" +
"<acknowledgementDetail>" +
"<text value=\"" + failedMessage + "\"/>" +
"</acknowledgementDetail>" +
"</acknowledgement>" +
"</MCCI_IN000002UV01>";
}
}

@ -66,4 +66,9 @@ public class SdryReportServerImpl implements IReportServer {
public String pushMaternalInfantRelationship(String maternalInfantRelationshipMessage) {
return webserviceReceiveServerHandler.get(WebserviceMessageType.HIP1264).handle(maternalInfantRelationshipMessage);
}
@Override
public String pushRecallInspectionReport(String recallInspectionReportMessage) {
return webserviceReceiveServerHandler.get(WebserviceMessageType.HIP1112).handle(recallInspectionReportMessage);
}
}

@ -16,6 +16,13 @@
recollect_time=now()
where `id` = #{id}
</update>
<delete id="cancelFile">
update `docus_archivefile`.`t_scan_assort`
set is_del=1
where `patient_id` = #{patientId}
and source= #{sysFlag}
and file_column_1= #{serialnum}
</delete>
<select id="getTaskById" resultType="com.docus.server.report.entity.AfCollectTask">
select *

Loading…
Cancel
Save