Index: ssts-web/src/main/webapp/disinfectsystem/config/gzszyy/spring/HIS.xml =================================================================== diff -u -r37971 -r38003 --- ssts-web/src/main/webapp/disinfectsystem/config/gzszyy/spring/HIS.xml (.../HIS.xml) (revision 37971) +++ ssts-web/src/main/webapp/disinfectsystem/config/gzszyy/spring/HIS.xml (.../HIS.xml) (revision 38003) @@ -109,4 +109,16 @@ + + + + + + + + + + + \ No newline at end of file Fisheye: Tag 38003 refers to a dead (removed) revision in file `ssts-recyclingapplication/src/main/java/com/forgon/disinfectsystem/surgeryschedule/service/SurgeryScheduleManager.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 38003 refers to a dead (removed) revision in file `ssts-recyclingapplication/src/main/java/com/forgon/disinfectsystem/surgeryschedule/controller/SurgeryScheduleController.java'. Fisheye: No comparison available. Pass `N' to diff? Index: ssts-web/src/main/java/com/forgon/disinfectsystem/initdata/service/InitializeDataManagerImpl.java =================================================================== diff -u -r34436 -r38003 --- ssts-web/src/main/java/com/forgon/disinfectsystem/initdata/service/InitializeDataManagerImpl.java (.../InitializeDataManagerImpl.java) (revision 34436) +++ ssts-web/src/main/java/com/forgon/disinfectsystem/initdata/service/InitializeDataManagerImpl.java (.../InitializeDataManagerImpl.java) (revision 38003) @@ -54,14 +54,14 @@ import com.forgon.disinfectsystem.entity.basedatamanager.operationRoom.OperationRoom; import com.forgon.disinfectsystem.entity.basedatamanager.rinser.Rinser; import com.forgon.disinfectsystem.entity.basedatamanager.sterilisation.Sterilisation; -import com.forgon.disinfectsystem.entity.basedatamanager.sterilizer.Sterilizer; import com.forgon.disinfectsystem.entity.basedatamanager.supplyroomconfig.SupplyRoomConfig; import com.forgon.disinfectsystem.entity.basedatamanager.warehouse.WareHouse; import com.forgon.disinfectsystem.entity.invoicemanager.InvoicePlan; import com.forgon.disinfectsystem.entity.labeltemplate.LabelTemplate; import com.forgon.disinfectsystem.entity.sterilizationmanager.sterilizationrecord.SterilizationRecord; import com.forgon.disinfectsystem.entity.washanddisinfectmanager.washanddisinfectrecord.WashAndDisinfectRecord; import com.forgon.disinfectsystem.sterilizationmanager.sterilizationrecord.service.SterilizationRecordManager; +import com.forgon.disinfectsystem.surgeryschedule.service.SurgeryScheduleHL7Manager; import com.forgon.disinfectsystem.useRecord.service.UseRecordManager; import com.forgon.disinfectsystem.washanddisinfectmanager.washanddisinfectrecord.service.WashAndDisinfectRecordManager; import com.forgon.knowledge.service.KnowledgeFolderManager; @@ -137,6 +137,9 @@ @Autowired(required=false) private CameraDefinitionManager cameraDefinitionManager; + @Autowired(required=false) + private SurgeryScheduleHL7Manager surgeryScheduleHL7Manager; + public void setSterilizationRecordManager( SterilizationRecordManager sterilizationRecordManager) { this.sterilizationRecordManager = sterilizationRecordManager; @@ -311,6 +314,10 @@ if(dataSynchronizationManager != null){ dataSynchronizationManager.initializeRunOnceSyncData(); } + //启动手术排班信息HL7监听器GZSZYY-51 + if(surgeryScheduleHL7Manager != null){ + surgeryScheduleHL7Manager.startSurgeryScheduleHl7Monitor(); + } //当tomcat关掉后,完成灭菌和清洗的定时器会被销毁。所以启动时需要自动完成灭菌和清洗 timingAutoCompleteSterilization(); timingAutoCompleteWashRecord(); Index: ssts-recyclingapplication/src/main/java/com/forgon/disinfectsystem/surgeryschedule/service/SurgeryScheduleManager.java =================================================================== diff -u -r37968 -r38003 --- ssts-recyclingapplication/src/main/java/com/forgon/disinfectsystem/surgeryschedule/service/SurgeryScheduleManager.java (.../SurgeryScheduleManager.java) (revision 37968) +++ ssts-recyclingapplication/src/main/java/com/forgon/disinfectsystem/surgeryschedule/service/SurgeryScheduleManager.java (.../SurgeryScheduleHL7Manager.java) (revision 38003) @@ -1,17 +1,25 @@ package com.forgon.disinfectsystem.surgeryschedule.service; +import ca.uhn.hl7v2.model.Message; +import ca.uhn.hl7v2.protocol.ReceivingApplication; + import com.forgon.disinfectsystem.entity.operationreservation.SurgerySchedule; import com.forgon.tools.hibernate.BasePoManager; /** * 手术排班信息的managerGZSZYY-51 */ -public interface SurgeryScheduleManager extends BasePoManager { +public interface SurgeryScheduleHL7Manager extends BasePoManager, ReceivingApplication { /** * 接收并解析保存手术排班信息 * @param request */ public String recieveSurgerySchedule(String request); + + /** + * 启动手术排班信息HL7监听器 + */ + public void startSurgeryScheduleHl7Monitor(); } Fisheye: Tag 38003 refers to a dead (removed) revision in file `ssts-recyclingapplication/src/main/java/com/forgon/disinfectsystem/surgeryschedule/service/SurgeryScheduleManagerImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Index: ssts-recyclingapplication/src/main/java/com/forgon/disinfectsystem/surgeryschedule/service/SurgeryScheduleManagerImpl.java =================================================================== diff -u -r37972 -r38003 --- ssts-recyclingapplication/src/main/java/com/forgon/disinfectsystem/surgeryschedule/service/SurgeryScheduleManagerImpl.java (.../SurgeryScheduleManagerImpl.java) (revision 37972) +++ ssts-recyclingapplication/src/main/java/com/forgon/disinfectsystem/surgeryschedule/service/SurgeryScheduleManagerImpl.java (.../SurgeryScheduleHL7ManagerImpl.java) (revision 38003) @@ -2,40 +2,68 @@ import java.util.Date; import java.util.List; +import java.util.Map; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang.StringUtils; import ca.uhn.hl7v2.AcknowledgmentCode; import ca.uhn.hl7v2.DefaultHapiContext; +import ca.uhn.hl7v2.HL7Exception; import ca.uhn.hl7v2.HapiContext; +import ca.uhn.hl7v2.app.HL7Service; +import ca.uhn.hl7v2.llp.MinLowerLayerProtocol; import ca.uhn.hl7v2.model.GenericMessage; import ca.uhn.hl7v2.model.Message; import ca.uhn.hl7v2.parser.GenericModelClassFactory; import ca.uhn.hl7v2.parser.GenericParser; +import ca.uhn.hl7v2.parser.ParserConfiguration; +import ca.uhn.hl7v2.protocol.ReceivingApplicationException; import ca.uhn.hl7v2.util.Terser; +import com.forgon.directory.acegi.tools.AcegiHelper; import com.forgon.disinfectsystem.entity.operationreservation.SurgerySchedule; import com.forgon.exception.SystemException; +import com.forgon.log.model.Log; +import com.forgon.log.service.LogManager; import com.forgon.tools.date.DateTools; import com.forgon.tools.hibernate.BasePoManagerImpl; /** * 手术排班信息的managerGZSZYY-51 */ -public class SurgeryScheduleManagerImpl extends BasePoManagerImpl implements SurgeryScheduleManager { +public class SurgeryScheduleHL7ManagerImpl extends BasePoManagerImpl implements SurgeryScheduleHL7Manager { + + private HapiContext context = new DefaultHapiContext(); + + /** + * HL7 Server的监听端口,默认端口9001 + */ + private Integer port = 9001; + + private LogManager appLogManager; + + public void setPort(Integer port) { + this.port = port; + } + public void setAppLogManager(LogManager appLogManager) { + this.appLogManager = appLogManager; + } + @Override public String recieveSurgerySchedule(String hl7Str) { String resopnce = "消息接收成功"; - HapiContext context = null; + GenericMessage message = null; AcknowledgmentCode theAcknowledgementCode = AcknowledgmentCode.AA; SurgerySchedule surgerySchedule = null; try { //1、解析hl7 - context = new DefaultHapiContext(); context.setModelClassFactory(new GenericModelClassFactory()); GenericParser parse = context.getGenericParser(); @@ -94,40 +122,171 @@ e.printStackTrace(); resopnce = "消息接收失败:" + e.getMessage(); theAcknowledgementCode = AcknowledgmentCode.AE; - } finally { - try { - if(context != null){ - context.close(); - } - } catch (Exception e2) {} } - return buildAckMessage(message, theAcknowledgementCode, resopnce); + return buildEcodeAckMessage(message, theAcknowledgementCode, resopnce); } + + /** + * 解析HL7消息,保存手术排班信息 + * @param hl7Str + * @throws Exception + */ + private void recieveSurgerySchedule_internal(String hl7Str) throws Exception{ + SurgerySchedule surgerySchedule = null; + //解析hl7 + context.setModelClassFactory(new GenericModelClassFactory()); + GenericParser parse = context.getGenericParser(); + GenericMessage message = (GenericMessage) parse.parse(hl7Str); + + Terser terser = new Terser(message); + //手术申请单号(his) + String surgeryScheduleId = terser.get("/SCH-1"); + if(StringUtils.isBlank(surgeryScheduleId)){ + throw new SystemException("手术申请单号不能为空!"); + } + List list = this.getByProperty("surgeryScheduleId", surgeryScheduleId); + if(CollectionUtils.isNotEmpty(list)){ + surgerySchedule = list.get(0); + } + if(surgerySchedule == null){ + surgerySchedule = new SurgerySchedule(); + } + surgerySchedule.setSurgeryScheduleId(surgeryScheduleId); + //台次 + String surgeryScheduleTimes = terser.get("/SCH-3"); + surgerySchedule.setSurgeryScheduleTimes(surgeryScheduleTimes); + //手术预约时间 + String scheduleTimeStr = terser.get("/SCH-11(1)-4"); + if(StringUtils.isBlank(scheduleTimeStr)){ + throw new SystemException("手术预约时间不能为空!"); + } + Date scheduleTime = DateTools.coverStrToDate(scheduleTimeStr, "yyyyMMddHHmmss"); + if(scheduleTime == null){ + throw new SystemException("手术预约时间格式异常!"); + } + surgerySchedule.setScheduleTime(scheduleTime); + //住院号 + String hospitalNumber = terser.get("/PV1-19"); + if(StringUtils.isBlank(hospitalNumber)){ + throw new SystemException("住院号不能为空!"); + } + surgerySchedule.setHospitalNumber(hospitalNumber); + //手术名称 + String surgeryName = terser.get("/AIS-3-2"); + if(StringUtils.isBlank(surgeryName)){ + throw new SystemException("手术名称不能为空!"); + } + surgerySchedule.setSurgeryName(surgeryName); + //手术记录状态 + String surgeryStatus = terser.get("/AIS-10"); + if(StringUtils.isBlank(surgeryScheduleId)){ + throw new SystemException("手术记录状态不能为空!"); + } + surgerySchedule.setSurgeryStatus(surgeryStatus); + + //保存手术排班 + this.save(surgerySchedule); + } + /** * 构建HL7返回的消息 * @param message * @param theAcknowledgementCode * @param resopnce * @return */ - private String buildAckMessage(GenericMessage message, AcknowledgmentCode theAcknowledgementCode, String resopnce) { + private String buildEcodeAckMessage(GenericMessage message, AcknowledgmentCode theAcknowledgementCode, String resopnce) { if(message == null){ //推送过来的消息不存在时,只返回异常信息,不返回HL7消息 return resopnce; } //返回ACK的hl7消息 try { + Message ackMessage = buildAckMessage(message, theAcknowledgementCode, resopnce); + return ackMessage.encode(); + } catch (Exception e) { + e.printStackTrace(); + } + return resopnce; + } + + /** + * 返回ACK的hl7消息 + * @param message + * @param theAcknowledgementCode + * @param resopnce + * @return + */ + private Message buildAckMessage(Message message, AcknowledgmentCode theAcknowledgementCode, String resopnce){ + //返回ACK的hl7消息 + try { Message ackMessage = message.generateACK(theAcknowledgementCode, null); Terser ackTerser = new Terser(ackMessage); ackTerser.set("/MSH-7", DateTools.getCurrentDayByFormat("yyyyMMddHHmmss")); ackTerser.set("/MSH-17", "CHN"); ackTerser.set("/MSA-3", resopnce); - return ackMessage.encode(); + return ackMessage; } catch (Exception e) { e.printStackTrace(); } - return resopnce; + return null; } + @Override + public Message processMessage(Message theMessage, Map theMetadata) throws ReceivingApplicationException, HL7Exception { + String responceMessage = "消息接收成功"; + AcknowledgmentCode theAcknowledgementCode = AcknowledgmentCode.AA; + String sendingIP = (String) theMetadata.get("SENDING_IP"); + Integer sendingPort = (Integer) theMetadata.get("SENDING_PORT"); + try { + appLogManager.saveLog(AcegiHelper.getLoginUser(), "调用接口" , Log.TYPE_WRITE, String.format("调用手术排班接收接口(%s:%s),请求参数:%s", sendingIP, sendingPort, theMessage.encode())); + recieveSurgerySchedule_internal(theMessage.encode()); + } catch (Exception e) { + theAcknowledgementCode = AcknowledgmentCode.AA; + responceMessage = "消息接收失败:" + e.getMessage(); + e.printStackTrace(); + } + Message ackMessage = buildAckMessage(theMessage, theAcknowledgementCode, responceMessage); + if(ackMessage != null){ + appLogManager.saveLog(AcegiHelper.getLoginUser(), "调用接口" , Log.TYPE_WRITE, String.format("调用手术排班接收接口(%s:%s),请求参数:%s", sendingIP, sendingPort,ackMessage.encode())); + }else{ + appLogManager.saveLog(AcegiHelper.getLoginUser(), "调用接口" , Log.TYPE_WRITE, String.format("调用手术排班接收接口(%s:%s),请求参数:%s", sendingIP, sendingPort, responceMessage)); + } + return ackMessage; + } + + @Override + public boolean canProcess(Message theMessage) { + return true; + } + + @Override + public void startSurgeryScheduleHl7Monitor() { + try { + context = new DefaultHapiContext(); + ThreadPoolExecutor executor = new ThreadPoolExecutor( + 10, 3100, + 30, TimeUnit.SECONDS, + new ArrayBlockingQueue(100)); + executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); + MinLowerLayerProtocol mllp = new MinLowerLayerProtocol(); + mllp.setCharset("UTF-8"); + + context.setLowerLayerProtocol(mllp); + context.setExecutorService(executor); + + ParserConfiguration tParserConfiguration = new ParserConfiguration(); + tParserConfiguration.setValidating(false); + context.setParserConfiguration(tParserConfiguration); + + boolean useSecureConnection = false; + HL7Service HL7Service = context.newServer(port, useSecureConnection); + HL7Service.registerApplication(this); + HL7Service.startAndWait(); + } catch (Exception e) { + e.printStackTrace(); + } + } + } Index: ssts-web/src/main/webapp/WEB-INF/spring/applicationContext-disinfectsystem-service.xml =================================================================== diff -u -r37968 -r38003 --- ssts-web/src/main/webapp/WEB-INF/spring/applicationContext-disinfectsystem-service.xml (.../applicationContext-disinfectsystem-service.xml) (revision 37968) +++ ssts-web/src/main/webapp/WEB-INF/spring/applicationContext-disinfectsystem-service.xml (.../applicationContext-disinfectsystem-service.xml) (revision 38003) @@ -3009,13 +3009,4 @@ - - - - - - - - \ No newline at end of file Index: ssts-recyclingapplication/src/main/java/com/forgon/disinfectsystem/surgeryschedule/controller/SurgeryScheduleController.java =================================================================== diff -u -r37968 -r38003 --- ssts-recyclingapplication/src/main/java/com/forgon/disinfectsystem/surgeryschedule/controller/SurgeryScheduleController.java (.../SurgeryScheduleController.java) (revision 37968) +++ ssts-recyclingapplication/src/main/java/com/forgon/disinfectsystem/surgeryschedule/controller/SurgeryScheduleController.java (.../SurgeryScheduleHL7Controller.java) (revision 38003) @@ -11,19 +11,19 @@ import org.springframework.web.bind.annotation.RestController; import com.forgon.directory.acegi.tools.AcegiHelper; -import com.forgon.disinfectsystem.surgeryschedule.service.SurgeryScheduleManager; +import com.forgon.disinfectsystem.surgeryschedule.service.SurgeryScheduleHL7Manager; import com.forgon.log.model.Log; import com.forgon.log.service.LogManager; /** * 接收推送手术排班信息的接口地址GZSZYY-51 */ @RestController -@RequestMapping(value="/buttjoint/buttjointSurgeryScheduleController", produces = "application/json;charset=UTF-8") -public class SurgeryScheduleController { +@RequestMapping(value="/buttjoint/buttjointSurgeryScheduleHL7Controller", produces = "application/json;charset=UTF-8") +public class SurgeryScheduleHL7Controller { - @Autowired - private SurgeryScheduleManager surgeryScheduleManager; + @Autowired(required = false) + private SurgeryScheduleHL7Manager surgeryScheduleHL7Manager; @Autowired private LogManager appLogManager; @@ -42,7 +42,7 @@ requestStrBuilder.append(inputStr+"\r"); } appLogManager.saveLog(AcegiHelper.getLoginUser(), "调用接口" , Log.TYPE_WRITE, "调用手术排班接收接口,请求参数:" + requestStrBuilder.toString()); - result = surgeryScheduleManager.recieveSurgerySchedule(requestStrBuilder.toString()); + result = surgeryScheduleHL7Manager.recieveSurgerySchedule(requestStrBuilder.toString()); } catch (Exception e) { result = "消息接收失败:" + e.getMessage(); } finally {