|  |  |  | 
|---|
|  |  |  | 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.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; | 
|---|
|  |  |  | 
|---|
|  |  |  | private OAuth2TokenApi oAuth2TokenApi; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | @Resource | 
|---|
|  |  |  | private queueMapper queueMapper; | 
|---|
|  |  |  | private QueueMapper queueMapper; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | @Resource | 
|---|
|  |  |  | private RoomMapper roomMapper; | 
|---|
|  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | ConcurrentHashMap<String, BedQueueBO > mapBedVsQueue = new ConcurrentHashMap<>(); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | // 基于类型的, 检查或装机的优先队列 | 
|---|
|  |  |  | Map<Integer, PriorityBlockingQueue<BedQueueBO>> mapCheckPriorityQueue = new HashMap(); | 
|---|
|  |  |  | // 装机工位..不进入优先队列 | 
|---|
|  |  |  | Map<Integer, PriorityBlockingQueue<BedQueueBO>> mapCheckTypePriorityQueue = new HashMap(); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | // 基于类型的, 装机准备的优先队列 | 
|---|
|  |  |  | Map<Integer, PriorityBlockingQueue<BedQueueBO>> mapReadyPriorityQueue = new HashMap(); | 
|---|
|  |  |  | // Map<Integer, PriorityBlockingQueue<BedQueueBO>> mapReadyPriorityQueue = new HashMap(); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | Map<Integer, CheckTypeDO> mapCheckTypeVsReadyMax = null; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | List<Byte> queueStatusList = new ArrayList<>(); | 
|---|
|  |  |  | queueStatusList.add(QueueStatusEnum.READY.getStatus()); | 
|---|
|  |  |  | List<QueueDO> queueDOList = queueMapper.getDoctorQueueByStatus(roomId, bedNo, queueStatusList); | 
|---|
|  |  |  | List<QueueDO> queueDOList = queueMapper.getBedQueueByStatus(roomId, bedNo, queueStatusList); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | RoomDO roomDO = roomMapper.getRoom(roomId, bedNo); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | 
|---|
|  |  |  | queueStatusList.add(QueueStatusEnum.READY.getStatus()); | 
|---|
|  |  |  | queueStatusList.add(QueueStatusEnum.PASSED.getStatus()); | 
|---|
|  |  |  | queueStatusList.add(QueueStatusEnum.RECALLED.getStatus()); | 
|---|
|  |  |  | List<QueueDO>  queueDOList = queueMapper.getDoctorQueueByStatus(roomId, bedNo, queueStatusList); | 
|---|
|  |  |  | List<QueueDO>  queueDOList = queueMapper.getBedQueueByStatus(roomId, bedNo, queueStatusList); | 
|---|
|  |  |  | if (queueDOList.size() > 0) | 
|---|
|  |  |  | return QUEUE_HAVE_PATIENT; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | 
|---|
|  |  |  | return GlobalErrorCodeConstants.SUCCESS; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | // 常规 或者 领用 时 医生 取下一位患者 | 
|---|
|  |  |  | public ErrorCode nextPatient(Long roomId, String bedNo) { | 
|---|
|  |  |  | // 从 DB 把 序号最小的 就诊准备中的人 设置为就诊中 | 
|---|
|  |  |  | Integer updateNum = queueMapper.updateQueueStatus(roomId, 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(String.format("%09d%s", roomId, bedNo)); | 
|---|
|  |  |  | bo.queueNum.getAndDecrement(); // 可能已经【并发的】在 hurry-up 中改变了值 | 
|---|
|  |  |  |  | 
|---|
|  |  |  | removePriorityQueue(bo); | 
|---|
|  |  |  | refreshPriorityQueue(bo); | 
|---|
|  |  |  | return GlobalErrorCodeConstants.SUCCESS; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | // 装机时 医生 取下一位患者 | 
|---|
|  |  |  | public ErrorCode nextInstallPatient(Long roomId, String bedNo) { | 
|---|
|  |  |  | // 从 DB 把 序号最小的 [已领用] 的人 设置为 [安装中] | 
|---|
|  |  |  | Integer updateNum = queueMapper.preemptReceivedPatient(roomId, bedNo, | 
|---|
|  |  |  | QueueStatusEnum.RECEIVED.getStatus(), QueueStatusEnum.INSTALLING.getStatus()); | 
|---|
|  |  |  | // 该工位 没有 [已领用] 人员 | 
|---|
|  |  |  | if (null == updateNum || 0 == updateNum) { | 
|---|
|  |  |  | return QUEUE_NOT_READY_PATIENT; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | // 装机工位 无优先队列 | 
|---|
|  |  |  | // 优先队列中 该工位 [已领用]人的数量 减一 | 
|---|
|  |  |  | //BedQueueBO bo = mapBedVsQueue.get(String.format("%09d%s", roomId, bedNo)); | 
|---|
|  |  |  | //bo.queueNum.getAndDecrement(); // 可能已经【并发的】在 hurry-up 中改变了值 | 
|---|
|  |  |  | //refreshPriorityQueue(bo); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | return GlobalErrorCodeConstants.SUCCESS; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | 
|---|
|  |  |  | * 2. 服务运维重启时 | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | public ErrorCode bedReload() { | 
|---|
|  |  |  | mapCheckPriorityQueue.clear(); | 
|---|
|  |  |  | mapCheckTypePriorityQueue.clear(); | 
|---|
|  |  |  | mapBedVsQueue.clear(); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | // 清除非当天的排队人员 | 
|---|
|  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | public void hurryupOneCheckType(Integer checkType) { | 
|---|
|  |  |  |  | 
|---|
|  |  |  | PriorityBlockingQueue<BedQueueBO> priorityQueue = mapCheckPriorityQueue.get(checkType); | 
|---|
|  |  |  | PriorityBlockingQueue<BedQueueBO> priorityQueue = mapCheckTypePriorityQueue.get(checkType); | 
|---|
|  |  |  | if (null == priorityQueue) | 
|---|
|  |  |  | return; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | 
|---|
|  |  |  | return; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | // 查看 是否有排队中的患者 | 
|---|
|  |  |  | Integer updateNum = queueMapper.preemptPatient( | 
|---|
|  |  |  | Integer updateNum = queueMapper.preemptWaitingPatient( | 
|---|
|  |  |  | bedQueueBO.getRoomId(), | 
|---|
|  |  |  | bedQueueBO.getRoomName(), | 
|---|
|  |  |  | bedQueueBO.getBedNo(), | 
|---|
|  |  |  | 
|---|
|  |  |  | private void addPriorityQueue(BedQueueBO bedQueueBO) { | 
|---|
|  |  |  | Integer[] checkTypes = bedQueueBO.getCheckTypes(); | 
|---|
|  |  |  | Arrays.stream(checkTypes).forEach(checkType -> { | 
|---|
|  |  |  | PriorityBlockingQueue<BedQueueBO> priorityQueue = mapCheckPriorityQueue.get(checkType); | 
|---|
|  |  |  | CheckTypeDO checkTypeDO = mapCheckTypeVsReadyMax.get(checkType); | 
|---|
|  |  |  | // 装机工位 不进 优先队列,不从排队中接收人 | 
|---|
|  |  |  | if (checkTypeDO.getNeedDevReady() == 1 && bedQueueBO.getOpType() == 2) { | 
|---|
|  |  |  | return; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | PriorityBlockingQueue<BedQueueBO> priorityQueue = mapCheckTypePriorityQueue.get(checkType); | 
|---|
|  |  |  | if (null == priorityQueue) { | 
|---|
|  |  |  | priorityQueue = new PriorityBlockingQueue<BedQueueBO>(); | 
|---|
|  |  |  | mapCheckTypePriorityQueue.put( checkType, priorityQueue ); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if (!priorityQueue.contains(bedQueueBO)) { | 
|---|
|  |  |  | priorityQueue.offer(bedQueueBO); | 
|---|
|  |  |  | } else { | 
|---|
|  |  |  | 
|---|
|  |  |  | private void removePriorityQueue(BedQueueBO bedQueueBO) { | 
|---|
|  |  |  | Integer[] checkTypes = bedQueueBO.getCheckTypes(); | 
|---|
|  |  |  | Arrays.stream(checkTypes).forEach(checkType -> { | 
|---|
|  |  |  | PriorityBlockingQueue<BedQueueBO> priorityBlockingQueue = mapCheckPriorityQueue.get(checkType); | 
|---|
|  |  |  | PriorityBlockingQueue<BedQueueBO> 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<BedQueueBO> priorityQueue = mapCheckPriorityQueue.get(checkType); | 
|---|
|  |  |  | PriorityBlockingQueue<BedQueueBO> priorityQueue = mapCheckTypePriorityQueue.get(checkType); | 
|---|
|  |  |  | priorityQueue.remove(bedQueueBO); | 
|---|
|  |  |  | priorityQueue.offer(bedQueueBO); | 
|---|
|  |  |  | }); | 
|---|
|  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | private void roomBedStatistic(MonitorInfoVO monitorInfoVO) { | 
|---|
|  |  |  | Map<Integer, Integer>  mapOpeningCheckBedStatInfo = new HashMap<>(); | 
|---|
|  |  |  | Map<Integer, Integer>  mapOpeningReadyBedStatInfo = new HashMap<>(); | 
|---|
|  |  |  | Map<Integer, Integer>  mapOpeningInstallBedStatInfo = new HashMap<>(); | 
|---|
|  |  |  | Map<Integer, Integer>  mapOperatingCheckBedStatInfo = new HashMap<>(); | 
|---|
|  |  |  | Map<Integer, Integer>  mapOperatingReadyBedStatInfo = new HashMap<>(); | 
|---|
|  |  |  | Map<Integer, Integer>  mapOperatingInstallBedStatInfo = new HashMap<>(); | 
|---|
|  |  |  | mapCheckTypeVsReadyMax.keySet().forEach( checkType -> { | 
|---|
|  |  |  | mapOpeningCheckBedStatInfo.put(checkType, 0); | 
|---|
|  |  |  | mapOpeningReadyBedStatInfo.put(checkType, 0); | 
|---|
|  |  |  | mapOpeningInstallBedStatInfo.put(checkType, 0); | 
|---|
|  |  |  | mapOperatingCheckBedStatInfo.put(checkType, 0); | 
|---|
|  |  |  | mapOperatingReadyBedStatInfo.put(checkType, 0); | 
|---|
|  |  |  | mapOperatingInstallBedStatInfo.put(checkType, 0); | 
|---|
|  |  |  | }); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | //开通的工位统计 | 
|---|
|  |  |  | //开通的 和 运营中 的工位统计 | 
|---|
|  |  |  | mapBedVsQueue.values().forEach( bedQueueBO -> { | 
|---|
|  |  |  | Integer[] checkTypes = bedQueueBO.getCheckTypes(); | 
|---|
|  |  |  | Arrays.stream(checkTypes).forEach(checkType -> { | 
|---|
|  |  |  | if (bedQueueBO.opType == 0) | 
|---|
|  |  |  | if (bedQueueBO.opType == 0 || bedQueueBO.opType == 1) | 
|---|
|  |  |  | mapOpeningCheckBedStatInfo.put(checkType, mapOpeningCheckBedStatInfo.get(checkType) + 1 ); | 
|---|
|  |  |  | else | 
|---|
|  |  |  | mapOpeningReadyBedStatInfo.put(checkType, mapOpeningReadyBedStatInfo.get(checkType) + 1 ); | 
|---|
|  |  |  | 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<BedQueueBO> hashSetOperatingBedQueue = new HashSet<>(); | 
|---|
|  |  |  | mapCheckPriorityQueue.values().forEach(priorityQueue->{ | 
|---|
|  |  |  | priorityQueue.stream().forEach(bedQueueBO -> hashSetOperatingBedQueue.add(bedQueueBO)); | 
|---|
|  |  |  | }); | 
|---|
|  |  |  | mapReadyPriorityQueue.values().forEach(priorityQueue->{ | 
|---|
|  |  |  | mapCheckTypePriorityQueue.values().forEach(priorityQueue->{ | 
|---|
|  |  |  | priorityQueue.stream().forEach(bedQueueBO -> hashSetOperatingBedQueue.add(bedQueueBO)); | 
|---|
|  |  |  | }); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | hashSetOperatingBedQueue.stream().forEach( bedQueueBO -> { | 
|---|
|  |  |  | Integer[] checkTypes = bedQueueBO.getCheckTypes(); | 
|---|
|  |  |  | Arrays.stream(checkTypes).forEach(checkType -> { | 
|---|
|  |  |  | if (bedQueueBO.opType == 0) | 
|---|
|  |  |  | mapOperatingCheckBedStatInfo.put(checkType, mapOperatingCheckBedStatInfo.get(checkType) + 1 ); | 
|---|
|  |  |  | else | 
|---|
|  |  |  | mapOperatingReadyBedStatInfo.put(checkType, mapOperatingReadyBedStatInfo.get(checkType) + 1 ); | 
|---|
|  |  |  | }); | 
|---|
|  |  |  | }); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | Map<Integer, String> mapCheckTypeBedInfo = new HashMap<>(); | 
|---|
|  |  |  | mapCheckTypeVsReadyMax.keySet().forEach( checkType -> { | 
|---|
|  |  |  | String str = mapOpeningCheckBedStatInfo.get(checkType) + " " + | 
|---|
|  |  |  | mapOpeningReadyBedStatInfo.get(checkType) + " " + | 
|---|
|  |  |  | mapOpeningInstallBedStatInfo.get(checkType) + " " + | 
|---|
|  |  |  | mapOperatingCheckBedStatInfo.get(checkType) + " " + | 
|---|
|  |  |  | mapOperatingReadyBedStatInfo.get(checkType) + " "; | 
|---|
|  |  |  | mapOperatingInstallBedStatInfo.get(checkType) + " "; | 
|---|
|  |  |  | mapCheckTypeBedInfo.put( checkType, str); | 
|---|
|  |  |  | }); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | monitorInfoVO.setCheckTypeBedInfo(mapCheckTypeBedInfo); | 
|---|
|  |  |  | monitorInfoVO.setQueueNum(mapBedVsQueue.size()); | 
|---|
|  |  |  | monitorInfoVO.setActiveQueueNum(hashSetOperatingBedQueue.size()); | 
|---|
|  |  |  | monitorInfoVO.setActiveQueueNum((int) mapBedVsQueue.values().stream().filter(item -> item.getStatus() == BedStatusEnum.DOCTOR_ON.getStatus()).count()); | 
|---|
|  |  |  | monitorInfoVO.setPriorityQueueNum( hashSetOperatingBedQueue.size() ); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | } | 
|---|