package cn.lihu.jh.module.ecg.service.queue; import cn.lihu.jh.framework.common.exception.ErrorCode; import cn.lihu.jh.framework.common.exception.enums.GlobalErrorCodeConstants; import cn.lihu.jh.framework.common.util.object.BeanUtils; import cn.lihu.jh.module.ecg.Utils; import cn.lihu.jh.module.ecg.controller.admin.room.vo.MonitorInfoVO; import cn.lihu.jh.module.ecg.dal.dataobject.checktype.CheckTypeDO; import cn.lihu.jh.module.ecg.dal.dataobject.queue.QueueDO; import cn.lihu.jh.module.ecg.dal.dataobject.queue.QueueStatisticDO; import cn.lihu.jh.module.ecg.dal.dataobject.room.RoomDO; import cn.lihu.jh.module.ecg.dal.mysql.call.CallMapper; import cn.lihu.jh.module.ecg.dal.mysql.checktype.CheckTypeMapper; import cn.lihu.jh.module.ecg.dal.mysql.devrent.DevRentMapper; import cn.lihu.jh.module.ecg.dal.mysql.queue.QueueMapper; import cn.lihu.jh.module.ecg.dal.mysql.room.RoomMapper; import cn.lihu.jh.module.ecg.enums.BedStatusEnum; import cn.lihu.jh.module.ecg.enums.QueueStatusEnum; import cn.lihu.jh.module.infra.api.config.ConfigApi; import cn.lihu.jh.module.system.api.oauth2.OAuth2TokenApi; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; import java.util.*; import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; import static cn.lihu.jh.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.lihu.jh.framework.common.pojo.CommonResult.error; import static cn.lihu.jh.module.ecg.enums.ErrorCodeConstants.*; /** * 排队 Service 数据库事务相关的方法 * * @author 芋道源码 */ @Component @Validated @Slf4j public class QueueServiceTxFunctions { @Resource private ConfigApi configApi; @Resource private OAuth2TokenApi oAuth2TokenApi; @Resource private QueueMapper queueMapper; @Resource private RoomMapper roomMapper; @Resource private CallMapper callMapper; @Resource private DevRentMapper devRentMapper; @Resource private CheckTypeMapper checkTypeMapper; AtomicInteger openingFlag = new AtomicInteger(0); AtomicInteger curSeqNum = new AtomicInteger(0); ConcurrentHashMap mapBedVsQueue = new ConcurrentHashMap<>(); // 装机工位..不进入优先队列 Map> mapCheckTypePriorityQueue = new HashMap(); // 基于类型的, 装机准备的优先队列 // Map> mapReadyPriorityQueue = new HashMap(); Map mapCheckTypeVsReadyMax = null; /** * 已关闭 或者 关闭中,可以开通工位 * @param roomId * @param bedNo * @return */ public ErrorCode bedOpen(Long roomId, String roomName, String bedNo) { BedQueueBO bedQueueBO2 = mapBedVsQueue.get( Utils.formatRoomBed(roomId, bedNo) ); if (null != bedQueueBO2) { log.error("bedOpen mapBedVsQueue has existed. " + roomId + " " + bedNo); return QUEUE_BED_EXIST; } // DB update List statusList = new ArrayList(); statusList.add(BedStatusEnum.CLOSED); Integer updateNum = roomMapper.setBedOpeningOpening(roomId, bedNo, BedStatusEnum.OPENING, statusList); if ( null==updateNum || 0 == updateNum ) { log.error("bedOpen DB invalid status. " + roomId + " " + bedNo); return ROOM_INVALID_STATUS; } List queueStatusList = new ArrayList<>(); queueStatusList.add(QueueStatusEnum.READY.getStatus()); List queueDOList = queueMapper.getBedQueueByStatus(roomId, bedNo, queueStatusList); RoomDO roomDO = roomMapper.getRoom(roomId, bedNo); // 新增..工位队列 BedQueueBO bedQueueBO = new BedQueueBO(); bedQueueBO.setRoomId(roomId); bedQueueBO.setRoomName(roomName); bedQueueBO.setBedNo(bedNo); bedQueueBO.setMaxQueueNum(getBedReadyMax(roomId, bedNo)); bedQueueBO.setQueueNum(new AtomicInteger(queueDOList.size())); bedQueueBO.setStatus(BedStatusEnum.OPENING.getStatus()); bedQueueBO.setCheckTypes( roomDO.getCheckTypes() ); bedQueueBO.setOpType( roomDO.getOpType() ); mapBedVsQueue.put( Utils.formatRoomBed(roomId, bedNo), bedQueueBO); return GlobalErrorCodeConstants.SUCCESS; } public ErrorCode bedClose(Long roomId, String bedNo) { BedQueueBO bedQueueBO = mapBedVsQueue.get( Utils.formatRoomBed(roomId, bedNo) ); if (null == bedQueueBO) { log.error("bedClose mapBedVsQueue DONOT existed. " + roomId + " " + bedNo); return QUEUE_BED_NOT_EXIST; } // 除了判断 准备候诊中 的人数,还需要 判断 过号的人数 //if (bedQueueBO.getQueueNum().get() >0) // return QUEUE_HAVE_PATIENT; List queueStatusList = new ArrayList<>(); queueStatusList.add(QueueStatusEnum.READY.getStatus()); queueStatusList.add(QueueStatusEnum.PASSED.getStatus()); queueStatusList.add(QueueStatusEnum.RECALLED.getStatus()); List queueDOList = queueMapper.getBedQueueByStatus(roomId, bedNo, queueStatusList); if (queueDOList.size() > 0) return QUEUE_HAVE_PATIENT; // DB update List statusList = new ArrayList(); statusList.add(BedStatusEnum.OPENING); statusList.add(BedStatusEnum.DOCTOR_ON); statusList.add(BedStatusEnum.PAUSE); Integer updateNum = roomMapper.setBedOpeningClosed(roomId, bedNo, BedStatusEnum.CLOSED, statusList); if ( null==updateNum || 0 == updateNum ) { log.error("bedClose DB invalid status. " + roomId + " " + bedNo); return ROOM_INVALID_STATUS; } mapBedVsQueue.remove( Utils.formatRoomBed(roomId, bedNo) ); removePriorityQueue(bedQueueBO); return GlobalErrorCodeConstants.SUCCESS; } public ErrorCode bedDoctorPause(Long roomId, String bedNo, Long docId, String docName) { BedQueueBO bedQueueBO = mapBedVsQueue.get( Utils.formatRoomBed(roomId, bedNo) ); if (null == bedQueueBO) { log.error("bedDoctorPause mapBedVsQueue DONOT existed. " + roomId + " " + bedNo); return QUEUE_BED_NOT_EXIST; } // DB update List statusList = new ArrayList(); statusList.add(BedStatusEnum.DOCTOR_ON); Integer updateNum = roomMapper.setBedDoctorStatus(roomId, bedNo, docId, BedStatusEnum.PAUSE, statusList); if ( null==updateNum || 0 == updateNum ) { log.error("bedDoctorPause DB invalid status. " + roomId + " " + bedNo); return ROOM_INVALID_STATUS; } bedQueueBO.setStatus(BedStatusEnum.PAUSE.getStatus()); removePriorityQueue(bedQueueBO); return GlobalErrorCodeConstants.SUCCESS; } public ErrorCode bedDoctorResume(Long roomId, String bedNo, Long docId, String docName) { BedQueueBO bedQueueBO = mapBedVsQueue.get( Utils.formatRoomBed(roomId, bedNo) ); if (null == bedQueueBO || !bedQueueBO.getStatus().equals(BedStatusEnum.PAUSE.getStatus())) { log.error("bedDoctorResume mapBedVsQueue DONOT existed OR NOT Paused. " + roomId + " " + bedNo); return QUEUE_BED_NOT_EXIST; } // DB update List statusList = new ArrayList(); statusList.add(BedStatusEnum.PAUSE); Integer updateNum = roomMapper.setBedDoctorStatus(roomId, bedNo, docId, BedStatusEnum.DOCTOR_ON, statusList); if ( null==updateNum || 0 == updateNum ) { log.error("bedDoctorResume DB invalid status. " + roomId + " " + bedNo); return ROOM_INVALID_STATUS; } bedQueueBO.setStatus(BedStatusEnum.DOCTOR_ON.getStatus()); addPriorityQueue(bedQueueBO); return GlobalErrorCodeConstants.SUCCESS; } public ErrorCode bedDoctorOn(Long roomId, String bedNo, Long docId, String docName) { BedQueueBO bedQueueBO = mapBedVsQueue.get( Utils.formatRoomBed(roomId, bedNo) ); if (null == bedQueueBO) { log.error("bedDoctorOn mapBedVsQueue DONOT existed. " + roomId + " " + bedNo); return QUEUE_BED_NOT_EXIST; } // DB update List statusList = new ArrayList(); statusList.add(BedStatusEnum.OPENING); Integer updateNum = roomMapper.setBedDoctorOn(roomId, bedNo, docId, docName, BedStatusEnum.DOCTOR_ON, statusList); if ( null==updateNum || 0 == updateNum ) { log.error("bedDoctorOn DB invalid status. " + roomId + " " + bedNo); return ROOM_INVALID_STATUS; } bedQueueBO.setStatus(BedStatusEnum.DOCTOR_ON.getStatus()); addPriorityQueue(bedQueueBO); return GlobalErrorCodeConstants.SUCCESS; } public ErrorCode bedDoctorOff(Long roomId, String bedNo, Long docId, String docName) { BedQueueBO bedQueueBO = mapBedVsQueue.get( Utils.formatRoomBed( roomId, bedNo ) ); if (null == bedQueueBO) { log.error("bedDoctorOff mapBedVsQueue DONOT existed. " + roomId + " " + bedNo); return QUEUE_BED_NOT_EXIST; } // DB update List statusList = new ArrayList(); statusList.add(BedStatusEnum.DOCTOR_ON); statusList.add(BedStatusEnum.PAUSE); Integer updateNum = roomMapper.setBedDoctorOff(roomId, bedNo, docId, BedStatusEnum.OPENING, statusList); if ( null==updateNum || 0 == updateNum ) { log.error("bedDoctorOff DB invalid status. " + roomId + " " + bedNo); return ROOM_INVALID_STATUS; } removePriorityQueue(bedQueueBO); bedQueueBO.setStatus(BedStatusEnum.OPENING.getStatus()); return GlobalErrorCodeConstants.SUCCESS; } /* 2024.11.11 // 常规 或者 领用 时 医生 取下一位患者 public ErrorCode nextPatient(Long roomId, String bedNo) { // 从 DB 把该工位.序号最小的 [就诊准备中] 的人 设置为 [就诊中] (或领用中) Integer updateNum = queueMapper.updateBedQueueStatus(roomId, bedNo, QueueStatusEnum.READY.getStatus(), QueueStatusEnum.ONSTAGE.getStatus()); // 该工位 没有 [就诊准备中] 人员 if (null == updateNum || 0 == updateNum) { return QUEUE_NOT_READY_PATIENT; } // 优先队列中 该工位 就诊准备中人的数量 减一 BedQueueBO bo = mapBedVsQueue.get( Utils.formatRoomBed( roomId, bedNo ) ); bo.queueNum.getAndDecrement(); // 可能已经【并发的】在 hurry-up 中改变了值 refreshPriorityQueue(bo); return GlobalErrorCodeConstants.SUCCESS; } */ // 常规 或者 领用 时 医生 取下一位患者 public ErrorCode nextPatient(Long roomId, String bedNo) { QueueDO firstReadyQueueItem = queueMapper.getFirstItemByBedAndStatus(roomId, bedNo, QueueStatusEnum.READY.getStatus()); // 该工位 没有 [就诊准备中] 人员 if (null == firstReadyQueueItem) { return QUEUE_NOT_READY_PATIENT; } // QueueStatusEnum.READY => QueueStatusEnum.ONSTAGE firstReadyQueueItem.setStatus(QueueStatusEnum.ONSTAGE.getStatus()); queueMapper.updateById( firstReadyQueueItem ); // 优先队列中 该工位 就诊准备中人的数量 减一 BedQueueBO bo = mapBedVsQueue.get( Utils.formatRoomBed( roomId, bedNo ) ); bo.queueNum.getAndDecrement(); // 可能已经【并发的】在 hurry-up 中改变了值 refreshPriorityQueue(bo); return GlobalErrorCodeConstants.SUCCESS; } // 装机时 医生 取下一位患者 public ErrorCode nextInstallPatient(Long roomId, String bedNo) { // 从 DB 把 序号最小的 [已领用] [已召回-安装] 的人 设置为 [安装中] QueueDO firstItem = queueMapper.getFirstItemByRoomAndStatus(roomId, List.of(QueueStatusEnum.RECEIVED.getStatus(), QueueStatusEnum.RECALLED_INSTALL.getStatus())); // 该工位 没有 [已领用] | [已召回-安装] 人员 if (null == firstItem) { return QUEUE_NOT_READY_PATIENT; } firstItem.setStatus( QueueStatusEnum.INSTALLING.getStatus() ); firstItem.setBedNo( bedNo ); queueMapper.updateById( firstItem ); // 检查项目.亲和性 处理逻辑 CheckTypeDO checkTypeDO = getCheckTypeItem( firstItem.getBookCheckType() ); if (checkTypeDO.getAffinityCheckTypes().length > 0) { procAffinityWhenSomeOneEntryInstalling(firstItem.getPatId(), roomId, bedNo, checkTypeDO.getAffinityCheckTypes() ); } // 装机工位 无优先队列 // 优先队列中 该工位 [已领用]人的数量 减一 //BedQueueBO bo = mapBedVsQueue.get( Utils.formatRoomBed( roomId, bedNo ) ); //bo.queueNum.getAndDecrement(); // 可能已经【并发的】在 hurry-up 中改变了值 //refreshPriorityQueue(bo); return GlobalErrorCodeConstants.SUCCESS; } /** * 1. 每天开诊前 从DB同步工位的患者队列数据到 工位优先队列 * 2. 服务运维重启时 */ public ErrorCode bedReload() { mapCheckTypePriorityQueue.clear(); mapBedVsQueue.clear(); // 清除非当天的排队人员 queueMapper.clearQueue(); // 清除非当天的语音叫号记录 callMapper.clearCall(); // 从DB 获取 工位列表 List bedStatusEnumList = new ArrayList(); bedStatusEnumList.add(BedStatusEnum.OPENING); bedStatusEnumList.add(BedStatusEnum.DOCTOR_ON); bedStatusEnumList.add(BedStatusEnum.PAUSE); List roomDOList = roomMapper.simpleRoomList(bedStatusEnumList); List bedQueueBOList = roomDOList.stream().map(item -> BeanUtils.toBean(item, BedQueueBO.class)).toList(); // 从DB 获取 队列中 就诊准备中人员统计 列表 List queueStatusList = new ArrayList<>(); queueStatusList.add(QueueStatusEnum.READY.getStatus()); List queueStatisticDOList = queueMapper.queueStatistic(queueStatusList); bedQueueBOList.forEach(item -> { item.maxQueueNum = getBedReadyMax(item.roomId, item.bedNo); Optional queueStatisticDOOptional = queueStatisticDOList.stream().filter(it->it.getRoomId()==item.roomId && it.getBedNo().equals(item.getBedNo())).findFirst(); int queueNum = queueStatisticDOOptional.isPresent() ? queueStatisticDOOptional.get().getTotalInStatus() : 0; if ( item.maxQueueNum < queueNum ) throw new RuntimeException("init: exceed max queue number!"); item.queueNum.set( queueNum ); mapBedVsQueue.put( Utils.formatRoomBed(item.roomId, item.bedNo), item); if (BedStatusEnum.DOCTOR_ON.getStatus() == item.getStatus()) { addPriorityQueue(item); } }); Integer num = queueMapper.getMaxSeqNum(); curSeqNum = new AtomicInteger(null == num ? 0 : num); return GlobalErrorCodeConstants.SUCCESS; } public void resetRoom(Boolean needCloseBed) { if (needCloseBed) { // 踢出在座的医生 List bedStatusEnumList = new ArrayList(); bedStatusEnumList.add(BedStatusEnum.DOCTOR_ON); bedStatusEnumList.add(BedStatusEnum.PAUSE); List roomDOList = roomMapper.simpleRoomList(bedStatusEnumList); List userIdList = roomDOList.stream().map(roomDO -> roomDO.getDocId()).toList(); oAuth2TokenApi.tick(userIdList); // 所有工位状态 => 关闭 Integer ret = roomMapper.resetRoom(BedStatusEnum.CLOSED.getStatus()); } } public void hurryupAllBed() { if (0 == openingFlag.get()) return; mapBedVsQueue.values().forEach(bedQueueBO -> hurryupOneBed(bedQueueBO.roomId, bedQueueBO.bedNo)); } /** * 把医生候诊的队列塞满 */ public void hurryupOneBed(Long roomId, String bedNo) { if (0 == openingFlag.get()) return; BedQueueBO bedQueueBO = getBedQueueBO(roomId, bedNo); // 处理 过号-回来 的人 while (bedQueueBO.queueNum.get() < bedQueueBO.maxQueueNum) { // 查看 当前工位 是否有过号-回来的患者 Integer updateNum = queueMapper.queueRecalledPatient( bedQueueBO.getRoomId(), bedQueueBO.getRoomName(), bedQueueBO.getBedNo(), curSeqNum.get() + 1, // 过号回来,排到当前的下一位 QueueStatusEnum.RECALLED.getStatus(), // 不需要处理 [安装召回], 原因: 安装工位 没有优先队列 QueueStatusEnum.READY.getStatus()); if (null == updateNum || 0 == updateNum) break; // 召回 [过号] 患者后,处理 检查项目.亲和性 逻辑 QueueDO recalledQueueItem = queueMapper.getQueueItemBySeqNum(curSeqNum.get() + 1); CheckTypeDO checkTypeDO = getCheckTypeItem( recalledQueueItem.getBookCheckType() ); if ( checkTypeDO.getAffinityCheckTypes().length > 0) { procAffinityWhenRecalled(recalledQueueItem, checkTypeDO.getAffinityCheckTypes()); } curSeqNum.getAndIncrement(); // 可能已经【并发的】在 nextPatient 中改变了值 bedQueueBO.queueNum.incrementAndGet(); // 可能已经【并发的】在 nextPatient 中改变了优先队列顺序 refreshPriorityQueue(bedQueueBO); } // 处理 排队中 患者 hurryupOneBedCheckTypes( bedQueueBO ); } public void hurryupOneBedCheckTypes(BedQueueBO bedQueueBO) { while (bedQueueBO.queueNum.get() < bedQueueBO.maxQueueNum) { // 抢占 是否有排队中的患者 Integer updateNum = queueMapper.preemptWaitingPatientWithBedCheckTypes( bedQueueBO.getRoomId(), bedQueueBO.getRoomName(), bedQueueBO.getBedNo(), curSeqNum.get() + 1, QueueStatusEnum.WAITING.getStatus(), QueueStatusEnum.READY.getStatus(), bedQueueBO.checkTypes); // 没有抢到排队患者 if (null == updateNum || 0 == updateNum) { return; } QueueDO preemptQueueItem = queueMapper.getQueueItemBySeqNum(curSeqNum.get() + 1); CheckTypeDO checkTypeDO = getCheckTypeItem( preemptQueueItem.getBookCheckType() ); // 抢到排队患者后,处理 检查项目.亲和性 逻辑 if ( checkTypeDO.getAffinityCheckTypes().length > 0) { procAffinityWhenPreempt(preemptQueueItem, checkTypeDO.getAffinityCheckTypes()); } curSeqNum.getAndIncrement(); bedQueueBO.queueNum.incrementAndGet(); } // 改变了优先队列顺序 refreshPriorityQueue(bedQueueBO); } public void hurryupOneCheckType(Integer checkType) { PriorityBlockingQueue priorityQueue = mapCheckTypePriorityQueue.get(checkType); if (null == priorityQueue) return; while (true) { BedQueueBO bedQueueBO = priorityQueue.peek(); if (null == bedQueueBO) return; int curQueueNum = bedQueueBO.queueNum.get(); if (curQueueNum > bedQueueBO.maxQueueNum) throw new RuntimeException("hurryupOneCheckType: exceed max queue number!"); if (curQueueNum == bedQueueBO.maxQueueNum) return; // 查看 是否有排队中的患者 Integer updateNum = queueMapper.preemptWaitingPatient( bedQueueBO.getRoomId(), bedQueueBO.getRoomName(), bedQueueBO.getBedNo(), curSeqNum.get() + 1, QueueStatusEnum.WAITING.getStatus(), QueueStatusEnum.READY.getStatus(), checkType); // 没有抢到排队患者 if (null == updateNum || 0 == updateNum) { return; } QueueDO preemptQueueItem = queueMapper.getQueueItemBySeqNum(curSeqNum.get() + 1); CheckTypeDO checkTypeDO = getCheckTypeItem( preemptQueueItem.getBookCheckType() ); // 抢到排队患者后,处理 检查项目.亲和性 逻辑 if ( checkTypeDO.getAffinityCheckTypes().length > 0) { procAffinityWhenPreempt(preemptQueueItem, checkTypeDO.getAffinityCheckTypes()); } curSeqNum.getAndIncrement(); // 可能已经【并发的】在 nextPatient 中改变了值 bedQueueBO.queueNum.incrementAndGet(); // 可能已经【并发的】在 nextPatient 中改变了优先队列顺序 refreshPriorityQueue(bedQueueBO); } } public Integer getOpeningFlag() { return openingFlag.get(); } public void setOpeningFlag(Integer flag) { openingFlag.set(flag); } public void initCheckType() { List checkTypeDOList = checkTypeMapper.simpleCheckTypeList(); mapCheckTypeVsReadyMax = checkTypeDOList.stream().collect(Collectors.toMap(CheckTypeDO::getValue, checkType -> checkType)); } public CheckTypeDO getCheckTypeItem(Integer checkType) { return mapCheckTypeVsReadyMax.get( checkType ); } public BedQueueBO getBedQueueBO(Long roomId, String bedNo) { return mapBedVsQueue.get( Utils.formatRoomBed(roomId, bedNo) ); } public MonitorInfoVO getMonitorInfo() { MonitorInfoVO monitorInfoVO = new MonitorInfoVO(); monitorInfoVO.setOpeningFlag( openingFlag.get() ); roomBedStatistic(monitorInfoVO); return monitorInfoVO; } public void monitorInfo() { MonitorInfoVO monitorInfoVO = new MonitorInfoVO(); roomBedStatistic(monitorInfoVO); log.info(" opening " + openingFlag.get() + " " + monitorInfoVO.getQueueNum() + " " + monitorInfoVO.getActiveQueueNum() + " " + monitorInfoVO.getCheckTypeBedInfo().toString() ); } private void procAffinityWhenPreempt(QueueDO preemptQueueItem, Integer[] affinityCheckTypes) { List affinityItems = queueMapper.getCurPatGivenCheckTypesAndStatus( preemptQueueItem.getPatId(), affinityCheckTypes, QueueStatusEnum.WAITING.getStatus()); for (int i = 0; i < affinityItems.size(); i++) { QueueDO queueItem = affinityItems.get(i); queueItem.setStatus(QueueStatusEnum.AFFINITY_WAITING.getStatus()); //改变 排队状态 queueItem.setAffinityItem( 1 ); queueItem.setRoomId(preemptQueueItem.getRoomId()); queueItem.setRoomName(preemptQueueItem.getRoomName()); queueItem.setBedNo(preemptQueueItem.getBedNo()); queueItem.setSeqNum( preemptQueueItem.getSeqNum()); // 使用同一个 内部序号 queueMapper.updateById(queueItem); } } private void procAffinityWhenRecalled(QueueDO recalledQueueItem, Integer[] affinityCheckTypes) { List affinityItems = queueMapper.getCurPatGivenCheckTypesAndStatus( recalledQueueItem.getPatId(), affinityCheckTypes, QueueStatusEnum.AFFINITY_WAITING.getStatus()); for (int i = 0; i < affinityItems.size(); i++) { QueueDO queueItem = affinityItems.get(i); queueItem.setSeqNum( recalledQueueItem.getSeqNum() ); // 召回后,原内部序号更新 queueMapper.updateById(queueItem); } } private Integer getBedReadyMax(Long roomId, String bedNo) { RoomDO roomDO = roomMapper.getRoom(roomId, bedNo); Integer[] checkTypes = roomDO.getCheckTypes(); Integer ret = 0; for (int i=0; i { CheckTypeDO checkTypeDO = mapCheckTypeVsReadyMax.get(checkType); // 装机工位 不进 优先队列,不从排队中接收人 if (checkTypeDO.getNeedDevReady() == 1 && bedQueueBO.getOpType() == 2) { return; } PriorityBlockingQueue priorityQueue = mapCheckTypePriorityQueue.get(checkType); if (null == priorityQueue) { priorityQueue = new PriorityBlockingQueue(); mapCheckTypePriorityQueue.put( checkType, priorityQueue ); } if (!priorityQueue.contains(bedQueueBO)) { priorityQueue.offer(bedQueueBO); } else { log.error("bedDoctorResume priorityQueue still exist!. " + bedQueueBO.getRoomId() + " " + bedQueueBO.getBedNo()); } }); } private void removePriorityQueue(BedQueueBO bedQueueBO) { Integer[] checkTypes = bedQueueBO.getCheckTypes(); Arrays.stream(checkTypes).forEach(checkType -> { PriorityBlockingQueue priorityBlockingQueue = mapCheckTypePriorityQueue.get(checkType); if (null != priorityBlockingQueue) priorityBlockingQueue.remove(bedQueueBO); }); } private void refreshPriorityQueue(BedQueueBO bedQueueBO) { Integer[] checkTypes = bedQueueBO.getCheckTypes(); Arrays.stream(checkTypes).forEach(checkType -> { PriorityBlockingQueue priorityQueue = mapCheckTypePriorityQueue.get(checkType); priorityQueue.remove(bedQueueBO); priorityQueue.offer(bedQueueBO); }); } private void procAffinityWhenSomeOneEntryInstalling(String patId, Long roomId_operator, String bedNo_operator, Integer[] affinityCheckTypes) { // 对于 刚进入到 [安装中]的项, 如果存在 [已领用] 的亲和项,则需要其跟随 List affinityItems = queueMapper.getCurPatGivenCheckTypesAndStatus( patId, affinityCheckTypes, QueueStatusEnum.RECEIVED.getStatus()); for (int i = 0; i < affinityItems.size(); i++) { QueueDO queueItem = affinityItems.get(i); queueItem.setStatus(QueueStatusEnum.AFFINITY_RECEIVED.getStatus()); //改变 排队状态 queueItem.setRoomId(roomId_operator); queueItem.setBedNo(bedNo_operator); // 跟随到 装机 工位 queueMapper.updateById(queueItem); } } private void roomBedStatistic(MonitorInfoVO monitorInfoVO) { Map mapOpeningCheckBedStatInfo = new HashMap<>(); Map mapOpeningInstallBedStatInfo = new HashMap<>(); Map mapOperatingCheckBedStatInfo = new HashMap<>(); Map mapOperatingInstallBedStatInfo = new HashMap<>(); mapCheckTypeVsReadyMax.keySet().forEach( checkType -> { mapOpeningCheckBedStatInfo.put(checkType, 0); mapOpeningInstallBedStatInfo.put(checkType, 0); mapOperatingCheckBedStatInfo.put(checkType, 0); mapOperatingInstallBedStatInfo.put(checkType, 0); }); //开通的 和 运营中 的工位统计 mapBedVsQueue.values().forEach( bedQueueBO -> { Integer[] checkTypes = bedQueueBO.getCheckTypes(); Arrays.stream(checkTypes).forEach(checkType -> { if (bedQueueBO.opType == 0 || bedQueueBO.opType == 1) mapOpeningCheckBedStatInfo.put(checkType, mapOpeningCheckBedStatInfo.get(checkType) + 1 ); else mapOpeningInstallBedStatInfo.put(checkType, mapOpeningInstallBedStatInfo.get(checkType) + 1 ); if (bedQueueBO.getStatus() == BedStatusEnum.DOCTOR_ON.getStatus()) { if (bedQueueBO.opType == 0 || bedQueueBO.opType == 1) mapOperatingCheckBedStatInfo.put(checkType, mapOperatingCheckBedStatInfo.get(checkType) + 1); else mapOperatingInstallBedStatInfo.put(checkType, mapOperatingInstallBedStatInfo.get(checkType) + 1); } }); }); // 接收..排队中患者..的优先队列 HashSet hashSetOperatingBedQueue = new HashSet<>(); mapCheckTypePriorityQueue.values().forEach(priorityQueue->{ priorityQueue.stream().forEach(bedQueueBO -> hashSetOperatingBedQueue.add(bedQueueBO)); }); Map mapCheckTypeBedInfo = new HashMap<>(); mapCheckTypeVsReadyMax.keySet().forEach( checkType -> { String str = mapOpeningCheckBedStatInfo.get(checkType) + " " + mapOpeningInstallBedStatInfo.get(checkType) + " " + mapOperatingCheckBedStatInfo.get(checkType) + " " + mapOperatingInstallBedStatInfo.get(checkType) + " "; mapCheckTypeBedInfo.put( checkType, str); }); monitorInfoVO.setCheckTypeBedInfo(mapCheckTypeBedInfo); monitorInfoVO.setQueueNum(mapBedVsQueue.size()); monitorInfoVO.setActiveQueueNum((int) mapBedVsQueue.values().stream().filter(item -> item.getStatus() == BedStatusEnum.DOCTOR_ON.getStatus()).count()); monitorInfoVO.setPriorityQueueNum( hashSetOperatingBedQueue.size() ); monitorInfoVO.setMapBedVsQueue( mapBedVsQueue ); } }