jh-module-ecg/jh-module-ecg-biz/src/main/java/cn/lihu/jh/module/ecg/api/doctor/DoctorApiImpl.java
@@ -22,7 +22,7 @@ return GlobalErrorCodeConstants.SUCCESS; } return queueService.bedDoctorOff(roomDO.getRoomId(), roomDO.getBedNo(), userId, userName); return queueService.startBedDoctorOff(roomDO.getRoomId(), roomDO.getBedNo(), userId, userName); } } jh-module-ecg/jh-module-ecg-biz/src/main/java/cn/lihu/jh/module/ecg/service/queue/BedCloseCallable.java
@@ -6,11 +6,11 @@ public class BedCloseCallable implements Callable<ErrorCode> { QueueService queueService; QueueServiceTxFunctions queueService; private Long roomId; private String bedNo; public BedCloseCallable(QueueService queueService, Long roomId, String bedNo) public BedCloseCallable(QueueServiceTxFunctions queueService, Long roomId, String bedNo) { super(); this.roomId = roomId; jh-module-ecg/jh-module-ecg-biz/src/main/java/cn/lihu/jh/module/ecg/service/queue/BedDoctorNextPatientCallable.java
@@ -7,11 +7,11 @@ public class BedDoctorNextPatientCallable implements Callable<ErrorCode> { QueueService queueService; QueueServiceTxFunctions queueService; private Long roomId; private String bedNo; public BedDoctorNextPatientCallable(QueueService queueService, Long roomId, String bedNo) public BedDoctorNextPatientCallable(QueueServiceTxFunctions queueService, Long roomId, String bedNo) { super(); this.roomId = roomId; jh-module-ecg/jh-module-ecg-biz/src/main/java/cn/lihu/jh/module/ecg/service/queue/BedDoctorOffCallable.java
@@ -6,13 +6,13 @@ public class BedDoctorOffCallable implements Callable<ErrorCode> { QueueService queueService; QueueServiceTxFunctions queueService; private Long roomId; private String bedNo; private Long docId; private String docName; public BedDoctorOffCallable(QueueService queueService, Long roomId, String bedNo, Long docId, String docName) public BedDoctorOffCallable(QueueServiceTxFunctions queueService, Long roomId, String bedNo, Long docId, String docName) { super(); this.queueService = queueService; jh-module-ecg/jh-module-ecg-biz/src/main/java/cn/lihu/jh/module/ecg/service/queue/BedDoctorOnCallable.java
@@ -6,13 +6,13 @@ public class BedDoctorOnCallable implements Callable<ErrorCode> { QueueService queueService; QueueServiceTxFunctions queueService; private Long roomId; private String bedNo; private Long docId; private String docName; public BedDoctorOnCallable(QueueService queueService, Long roomId, String bedNo, Long docId, String docName) public BedDoctorOnCallable(QueueServiceTxFunctions queueService, Long roomId, String bedNo, Long docId, String docName) { super(); this.queueService = queueService; jh-module-ecg/jh-module-ecg-biz/src/main/java/cn/lihu/jh/module/ecg/service/queue/BedDoctorPauseCallable.java
@@ -6,13 +6,13 @@ public class BedDoctorPauseCallable implements Callable<ErrorCode> { QueueService queueService; QueueServiceTxFunctions queueService; private Long roomId; private String bedNo; private Long docId; private String docName; public BedDoctorPauseCallable(QueueService queueService, Long roomId, String bedNo, Long docId, String docName) public BedDoctorPauseCallable(QueueServiceTxFunctions queueService, Long roomId, String bedNo, Long docId, String docName) { super(); this.queueService = queueService; jh-module-ecg/jh-module-ecg-biz/src/main/java/cn/lihu/jh/module/ecg/service/queue/BedDoctorResumeCallable.java
@@ -7,13 +7,13 @@ public class BedDoctorResumeCallable implements Callable<ErrorCode> { QueueService queueService; QueueServiceTxFunctions queueService; private Long roomId; private String bedNo; private Long docId; private String docName; public BedDoctorResumeCallable(QueueService queueService, Long roomId, String bedNo, Long docId, String docName) public BedDoctorResumeCallable(QueueServiceTxFunctions queueService, Long roomId, String bedNo, Long docId, String docName) { super(); this.queueService = queueService; jh-module-ecg/jh-module-ecg-biz/src/main/java/cn/lihu/jh/module/ecg/service/queue/BedOpenCallable.java
@@ -7,12 +7,12 @@ public class BedOpenCallable implements Callable<ErrorCode> { QueueService queueService; QueueServiceTxFunctions queueService; private Long roomId; private String roomName; private String bedNo; public BedOpenCallable(QueueService queueService, Long roomId, String roomName, String bedNo) public BedOpenCallable(QueueServiceTxFunctions queueService, Long roomId, String roomName, String bedNo) { super(); this.roomId = roomId; jh-module-ecg/jh-module-ecg-biz/src/main/java/cn/lihu/jh/module/ecg/service/queue/BedReloadCallable.java
@@ -6,9 +6,9 @@ public class BedReloadCallable implements Callable<ErrorCode> { QueueService queueService; QueueServiceTxFunctions queueService; public BedReloadCallable(QueueService queueService) public BedReloadCallable(QueueServiceTxFunctions queueService) { super(); this.queueService = queueService; jh-module-ecg/jh-module-ecg-biz/src/main/java/cn/lihu/jh/module/ecg/service/queue/QueueService.java
@@ -62,15 +62,6 @@ ErrorCode startBedDoctorOff(Long roomId, String bedNo, Long docId, String docName); ErrorCode startNextPatient(Long roomId, String bedNo); ErrorCode bedOpen(Long roomId, String roomName, String bedNo); ErrorCode bedClose(Long roomId, String bedNo); ErrorCode bedDoctorPause(Long roomId, String bedNo, Long docId, String docName); ErrorCode bedDoctorResume(Long roomId, String bedNo, Long docId, String docName); ErrorCode bedDoctorOn(Long roomId, String bedNo, Long docId, String docName); ErrorCode bedDoctorOff(Long roomId, String bedNo, Long docId, String docName); ErrorCode nextPatient(Long roomId, String bedNo); ErrorCode bedReload(); CommonResult<RoomRespVO> getRoom(Long roomId, String bedNo, Long docId); /** @@ -95,12 +86,6 @@ */ void queue(QueueSaveReqVO queueSaveReqVO); /** * æå»çåè¯çéå塿»¡ */ void hurryup(); /** * å»çå«ä¸ä¸ä½æ£è */ @@ -118,8 +103,6 @@ Integer recallPatient(Long roomId, String bedNo, String patId); Integer patientJump(String patId, Byte jumped ); void monitorInfo(); RoomDO getDocRoomInfo(Long docId); } jh-module-ecg/jh-module-ecg-biz/src/main/java/cn/lihu/jh/module/ecg/service/queue/QueueServiceImpl.java
@@ -48,6 +48,9 @@ public class QueueServiceImpl implements QueueService { @Resource QueueServiceTxFunctions queueServiceTxFunctions; @Resource private OAuth2TokenApi oAuth2TokenApi; @Resource @@ -62,20 +65,7 @@ @Resource private DevRentMapper devRentMapper; AtomicInteger openingFlag = new AtomicInteger(0); AtomicInteger curSeqNum = new AtomicInteger(0); PriorityBlockingQueue<BedQueueBO> priorityQueue = new PriorityBlockingQueue<>(); ConcurrentHashMap<String, BedQueueBO > mapBedVsQueue = new ConcurrentHashMap<>(); ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor(); Integer queueReadyMax = 0; Integer bigScrenWaitingSize = 5; Integer bigScrenPassedSize = 5; Integer bigScrenWaitingFrom = 0; Integer bigScrenPassedFrom = 0; @Override public Integer createqueue(QueueSaveReqVO createReqVO) { @@ -105,7 +95,7 @@ @Override public ErrorCode startBedOpen(Long roomId, String roomName, String bedNo) { Future<ErrorCode> future = singleThreadExecutor.submit( new BedOpenCallable(this, roomId, roomName, bedNo)); Future<ErrorCode> future = singleThreadExecutor.submit( new BedOpenCallable(queueServiceTxFunctions, roomId, roomName, bedNo)); try { ErrorCode ret = future.get(); @@ -122,7 +112,7 @@ @Override public ErrorCode startBedClose(Long roomId, String bedNo) { Future<ErrorCode> future = singleThreadExecutor.submit( new BedCloseCallable(this, roomId, bedNo)); Future<ErrorCode> future = singleThreadExecutor.submit( new BedCloseCallable(queueServiceTxFunctions, roomId, bedNo)); try { ErrorCode ret = future.get(); @@ -140,7 +130,7 @@ @Override public ErrorCode startBedDoctorPause(Long roomId, String bedNo, Long docId, String docName) { Future<ErrorCode> future = singleThreadExecutor.submit( new BedDoctorPauseCallable(this, roomId, bedNo, docId, docName) new BedDoctorPauseCallable(queueServiceTxFunctions, roomId, bedNo, docId, docName) ); try { @@ -159,7 +149,7 @@ @Override public ErrorCode startBedDoctorResume(Long roomId, String bedNo, Long docId, String docName) { Future<ErrorCode> future = singleThreadExecutor.submit( new BedDoctorResumeCallable(this, roomId, bedNo, docId, docName) new BedDoctorResumeCallable(queueServiceTxFunctions, roomId, bedNo, docId, docName) ); try { @@ -178,7 +168,7 @@ @Override public ErrorCode startBedDoctorOn(Long roomId, String bedNo, Long docId, String docName) { Future<ErrorCode> future = singleThreadExecutor.submit( new BedDoctorOnCallable(this, roomId, bedNo, docId, docName) new BedDoctorOnCallable(queueServiceTxFunctions, roomId, bedNo, docId, docName) ); try { @@ -197,7 +187,7 @@ @Override public ErrorCode startBedDoctorOff(Long roomId, String bedNo, Long docId, String docName) { Future<ErrorCode> future = singleThreadExecutor.submit( new BedDoctorOffCallable(this, roomId, bedNo, docId, docName) new BedDoctorOffCallable(queueServiceTxFunctions, roomId, bedNo, docId, docName) ); try { @@ -216,7 +206,7 @@ @Override public ErrorCode startNextPatient(Long roomId, String bedNo) { Future<ErrorCode> future = singleThreadExecutor.submit( new BedDoctorNextPatientCallable(this, roomId, bedNo) new BedDoctorNextPatientCallable(queueServiceTxFunctions, roomId, bedNo) ); try { @@ -235,112 +225,31 @@ @Override public void startHurryUp() { singleThreadExecutor.execute( () -> { hurryup(); queueServiceTxFunctions.hurryup(); }); } @Override public void startBedReload() { singleThreadExecutor.execute( () -> { bedReload(); hurryup(); monitorInfo(); queueServiceTxFunctions.bedReload(); queueServiceTxFunctions.hurryup(); queueServiceTxFunctions.monitorInfo(); }); } @Override public void startResetRoom() { singleThreadExecutor.execute( () -> { resetRoom(); bedReload(); monitorInfo(); queueServiceTxFunctions.resetRoom(); queueServiceTxFunctions.bedReload(); queueServiceTxFunctions.monitorInfo(); }); } @Override public MonitorInfoVO getMonitorInfo() { MonitorInfoVO monitorInfoVO = new MonitorInfoVO(); monitorInfoVO.setOpeningFlag( openingFlag.get() ); monitorInfoVO.setQueueNum( mapBedVsQueue.size() ); monitorInfoVO.setActiveQueueNum( priorityQueue.size() ); return monitorInfoVO; } /** * å·²å ³é æè å ³éä¸ï¼å¯ä»¥å¼éå·¥ä½ * @param roomId * @param bedNo * @return */ @Override public ErrorCode bedOpen(Long roomId, String roomName, String bedNo) { BedQueueBO bedQueueBO2 = mapBedVsQueue.get(String.format("%09d%s", roomId, bedNo)); if (null != bedQueueBO2) { log.error("bedOpen mapBedVsQueue has existed. " + roomId + " " + bedNo); return QUEUE_BED_EXIST; } // DB update List statusList = new ArrayList<BedStatusEnum>(); 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<Byte> queueStatusList = new ArrayList<>(); queueStatusList.add(QueueStatusEnum.READY.getStatus()); List<QueueDO> queueDOList = queueMapper.getDoctorQueueByStatus(roomId, bedNo, queueStatusList); // æ°å¢å·¥ä½ ä¼å éå BedQueueBO bedQueueBO = new BedQueueBO(); bedQueueBO.setRoomId(roomId); bedQueueBO.setRoomName(roomName); bedQueueBO.setBedNo(bedNo); bedQueueBO.setMaxQueueNum(queueReadyMax); bedQueueBO.setQueueNum(new AtomicInteger(queueDOList.size())); bedQueueBO.setStatus(BedStatusEnum.OPENING.getStatus()); priorityQueue.offer(bedQueueBO); mapBedVsQueue.put(String.format("%09d%s", roomId, bedNo), bedQueueBO); return GlobalErrorCodeConstants.SUCCESS; } @Override public ErrorCode bedClose(Long roomId, String bedNo) { BedQueueBO bedQueueBO = mapBedVsQueue.get(String.format("%09d%s", 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<Byte> queueStatusList = new ArrayList<>(); queueStatusList.add(QueueStatusEnum.READY.getStatus()); queueStatusList.add(QueueStatusEnum.PASSED.getStatus()); queueStatusList.add(QueueStatusEnum.RECALLED.getStatus()); List<QueueDO> queueDOList = queueMapper.getDoctorQueueByStatus(roomId, bedNo, queueStatusList); if (queueDOList.size() > 0) return QUEUE_HAVE_PATIENT; // DB update List statusList = new ArrayList<BedStatusEnum>(); 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(String.format("%09d%s", roomId, bedNo)); priorityQueue.remove(bedQueueBO); return GlobalErrorCodeConstants.SUCCESS; return queueServiceTxFunctions.getMonitorInfo(); } @Override @@ -350,7 +259,7 @@ return error(ROOM_NOT_SIT); } BedQueueBO bedQueueBO = mapBedVsQueue.get(String.format("%09d%s", roomId, bedNo)); BedQueueBO bedQueueBO = queueServiceTxFunctions.getBedQueueBO(roomId, bedNo); if (null == bedQueueBO) { log.error("getRoom mapBedVsQueue DONOT existed. " + roomId + " " + bedNo); return error(QUEUE_BED_NOT_EXIST); @@ -358,110 +267,6 @@ RoomRespVO roomRespVO = BeanUtils.toBean(roomDO, RoomRespVO.class); return success(roomRespVO); } @Override public ErrorCode bedDoctorPause(Long roomId, String bedNo, Long docId, String docName) { BedQueueBO bedQueueBO = mapBedVsQueue.get(String.format("%09d%s", roomId, bedNo)); if (null == bedQueueBO) { log.error("bedDoctorPause mapBedVsQueue DONOT existed. " + roomId + " " + bedNo); return QUEUE_BED_NOT_EXIST; } // DB update List statusList = new ArrayList<BedStatusEnum>(); 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()); priorityQueue.remove(bedQueueBO); return GlobalErrorCodeConstants.SUCCESS; } @Override public ErrorCode bedDoctorResume(Long roomId, String bedNo, Long docId, String docName) { BedQueueBO bedQueueBO = mapBedVsQueue.get(String.format("%09d%s", 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<BedStatusEnum>(); 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()); if (!priorityQueue.contains(bedQueueBO)) { priorityQueue.offer(bedQueueBO); } else { log.error("bedDoctorResume priorityQueue still exist!. " + roomId + " " + bedNo); return ECG_INNER_ERROR; } return GlobalErrorCodeConstants.SUCCESS; } @Override public ErrorCode bedDoctorOn(Long roomId, String bedNo, Long docId, String docName) { BedQueueBO bedQueueBO = mapBedVsQueue.get(String.format("%09d%s", roomId, bedNo)); if (null == bedQueueBO) { log.error("bedDoctorOn mapBedVsQueue DONOT existed. " + roomId + " " + bedNo); return QUEUE_BED_NOT_EXIST; } // DB update List statusList = new ArrayList<BedStatusEnum>(); 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()); return GlobalErrorCodeConstants.SUCCESS; } @Override public ErrorCode bedDoctorOff(Long roomId, String bedNo, Long docId, String docName) { BedQueueBO bedQueueBO = mapBedVsQueue.get(String.format("%09d%s", roomId, bedNo)); if (null == bedQueueBO) { log.error("bedDoctorOff mapBedVsQueue DONOT existed. " + roomId + " " + bedNo); return QUEUE_BED_NOT_EXIST; } // DB update List statusList = new ArrayList<BedStatusEnum>(); 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; } // 妿æ¯å¨ PAUSE ç¶æç¦»åº§çï¼éè¦éæ°å å ä¼å éå if (bedQueueBO.getStatus().equals(BedStatusEnum.PAUSE.getStatus())) { if (!priorityQueue.contains(bedQueueBO)) { priorityQueue.offer(bedQueueBO); } else { log.error("bedDoctorResume priorityQueue still exist!. " + roomId + " " + bedNo); return ECG_INNER_ERROR; } } bedQueueBO.setStatus(BedStatusEnum.OPENING.getStatus()); return GlobalErrorCodeConstants.SUCCESS; } private void validatequeueExists(Integer id) { @@ -480,122 +285,6 @@ return queueMapper.selectPage(pageReqVO); } /** * 1. æ¯å¤©å¼è¯å ä»DB忥工ä½çæ£è éåæ°æ®å° å·¥ä½ä¼å éå * 2. æå¡è¿ç»´é坿¶ */ @Override public ErrorCode bedReload() { priorityQueue.clear(); mapBedVsQueue.clear(); // æ¸ é¤éå½å¤©çæé人å queueMapper.clearQueue(); // æ¸ é¤éå½å¤©çè¯é³å«å·è®°å½ callMapper.clearCall(); // ä»DB è·å å·¥ä½å表 List<BedStatusEnum> bedStatusEnumList = new ArrayList<BedStatusEnum>(); bedStatusEnumList.add(BedStatusEnum.OPENING); bedStatusEnumList.add(BedStatusEnum.DOCTOR_ON); bedStatusEnumList.add(BedStatusEnum.PAUSE); List<RoomDO> roomDOList = roomMapper.simpleRoomList(bedStatusEnumList); List<BedQueueBO> bedQueueBOList = roomDOList.stream().map(item -> BeanUtils.toBean(item, BedQueueBO.class)).toList(); // ä»DB è·å éåä¸ å°±è¯åå¤ä¸äººåç»è®¡ å表 List<Byte> queueStatusList = new ArrayList<>(); queueStatusList.add(QueueStatusEnum.READY.getStatus()); List<QueueStatisticDO> queueStatisticDOList = queueMapper.queueStatistic(queueStatusList); bedQueueBOList.forEach(item -> { item.maxQueueNum = queueReadyMax; Optional<QueueStatisticDO> queueStatisticDOOptional = queueStatisticDOList.stream().filter(it->it.getRoomId()==item.roomId && it.getBedNo().equals(item.getBedNo())).findFirst(); int queueNum = queueStatisticDOOptional.isPresent() ? queueStatisticDOOptional.get().getTotalInStatus() : 0; if ( queueReadyMax < queueNum ) throw new RuntimeException("init: exceed max queue number!"); item.queueNum.set( queueNum ); mapBedVsQueue.put(String.format("%09d%s", item.roomId, item.bedNo), item); if (BedStatusEnum.PAUSE.getStatus() != item.getStatus()) { priorityQueue.offer(item); } }); Integer num = queueMapper.getMaxSeqNum(); curSeqNum = new AtomicInteger(null == num ? 0 : num); return GlobalErrorCodeConstants.SUCCESS; } /** * */ public void hurryup() { if (0 == openingFlag.get()) return; // å¤ç è¿å·-忥 ç人 for (BedQueueBO bedQueueBO : mapBedVsQueue.values()) { 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; curSeqNum.getAndIncrement(); // å¯è½å·²ç»ãå¹¶åçãå¨ nextPatient 䏿¹åäºå¼ bedQueueBO.queueNum.incrementAndGet(); // å¯è½å·²ç»ãå¹¶åçãå¨ nextPatient 䏿¹åäºä¼å éåé¡ºåº priorityQueue.remove(bedQueueBO); priorityQueue.offer(bedQueueBO); } } // å¤ç æéä¸ æ£è while (true) { BedQueueBO bedQueueBO = priorityQueue.peek(); if (null == bedQueueBO) return; int curQueueNum = bedQueueBO.queueNum.get(); if (curQueueNum > bedQueueBO.maxQueueNum) throw new RuntimeException("hurryup: exceed max queue number!"); if (curQueueNum == bedQueueBO.maxQueueNum) return; // æ¥ç æ¯å¦ææéä¸çæ£è Integer updateNum = queueMapper.preemptPatient( bedQueueBO.getRoomId(), bedQueueBO.getRoomName(), bedQueueBO.getBedNo(), curSeqNum.get() + 1, QueueStatusEnum.WAITING.getStatus(), QueueStatusEnum.READY.getStatus()); // æ²¡ææ¢å°æéæ£è if (null == updateNum || 0 == updateNum) { return; } curSeqNum.getAndIncrement(); // å¯è½å·²ç»ãå¹¶åçãå¨ nextPatient 䏿¹åäºå¼ bedQueueBO.queueNum.incrementAndGet(); // å¯è½å·²ç»ãå¹¶åçãå¨ nextPatient 䏿¹åäºä¼å éåé¡ºåº priorityQueue.remove(bedQueueBO); priorityQueue.offer(bedQueueBO); } } /** * é¢çº¦ç¡®è®¤åçæé @@ -613,25 +302,6 @@ devRentMapper.insert(devRent); startHurryUp(); } @Override public ErrorCode nextPatient(Long roomId, String bedNo) { // ä» DB æ åºå·æå°ç å°±è¯åå¤ä¸ç人 设置为就è¯ä¸ Integer updateNum = queueMapper.updateQueueStatus(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 䏿¹åäºå¼ priorityQueue.remove(bo); priorityQueue.offer(bo); return GlobalErrorCodeConstants.SUCCESS; } public void finishNextPatient(Long roomId, String bedNo) { @@ -678,19 +348,19 @@ @Override public void setQueueReadyMax(Integer max) { queueReadyMax = max; queueServiceTxFunctions.setQueueReadyMax( max ); } public void startBiz() { if (1 == openingFlag.get()) if (1 == queueServiceTxFunctions.getOpeningFlag()) return; openingFlag.set(1); queueServiceTxFunctions.setOpeningFlag(1); startBedReload(); } public void closeBiz() { openingFlag.set(0); queueServiceTxFunctions.setOpeningFlag(0); startBedReload(); } @@ -710,27 +380,8 @@ } @Override public void monitorInfo() { log.info("map " + mapBedVsQueue.size() + " priority " + priorityQueue.size() + " opening " + openingFlag.get()); } @Override public RoomDO getDocRoomInfo(Long docId) { return roomMapper.getRoomByDocId(docId); } public void resetRoom() { // 踢åºå¨åº§çå»ç List<BedStatusEnum> bedStatusEnumList = new ArrayList<BedStatusEnum>(); bedStatusEnumList.add(BedStatusEnum.DOCTOR_ON); bedStatusEnumList.add(BedStatusEnum.PAUSE); List<RoomDO> roomDOList = roomMapper.simpleRoomList(bedStatusEnumList); List<Long> userIdList = roomDOList.stream().map(roomDO -> roomDO.getDocId()).toList(); oAuth2TokenApi.tick(userIdList); // å ³éææå·¥ä½ Integer ret = roomMapper.resetRoom(BedStatusEnum.CLOSED.getStatus()); } } jh-module-ecg/jh-module-ecg-biz/src/main/java/cn/lihu/jh/module/ecg/service/queue/QueueServiceTxFunctions.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,428 @@ 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.pojo.CommonResult; import cn.lihu.jh.framework.common.pojo.PageResult; import cn.lihu.jh.framework.common.util.object.BeanUtils; import cn.lihu.jh.module.ecg.controller.admin.queue.vo.PatientStatisticVO; import cn.lihu.jh.module.ecg.controller.admin.queue.vo.QueuePageReqVO; import cn.lihu.jh.module.ecg.controller.admin.queue.vo.QueueSaveReqVO; import cn.lihu.jh.module.ecg.controller.admin.room.vo.MonitorInfoVO; import cn.lihu.jh.module.ecg.controller.admin.room.vo.RoomRespVO; import cn.lihu.jh.module.ecg.dal.dataobject.devrent.DevRentDO; import cn.lihu.jh.module.ecg.dal.dataobject.queue.BedQueueStatisticDO; 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.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.DevRentStateEnum; import cn.lihu.jh.module.ecg.enums.QueueStatusEnum; import cn.lihu.jh.module.system.api.oauth2.OAuth2TokenApi; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; import java.util.ArrayList; import java.util.List; import java.util.Optional; import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicInteger; 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.framework.common.pojo.CommonResult.success; import static cn.lihu.jh.module.ecg.enums.ErrorCodeConstants.*; /** * æé Service æ°æ®åºäºå¡ç¸å ³çæ¹æ³ * * @author èéæºç */ @Component @Validated @Slf4j public class QueueServiceTxFunctions { @Resource private OAuth2TokenApi oAuth2TokenApi; @Resource private queueMapper queueMapper; @Resource private RoomMapper roomMapper; @Resource private CallMapper callMapper; @Resource private DevRentMapper devRentMapper; AtomicInteger openingFlag = new AtomicInteger(0); AtomicInteger curSeqNum = new AtomicInteger(0); PriorityBlockingQueue<BedQueueBO> priorityQueue = new PriorityBlockingQueue<>(); ConcurrentHashMap<String, BedQueueBO > mapBedVsQueue = new ConcurrentHashMap<>(); Integer queueReadyMax = 0; /** * å·²å ³é æè å ³éä¸ï¼å¯ä»¥å¼éå·¥ä½ * @param roomId * @param bedNo * @return */ public ErrorCode bedOpen(Long roomId, String roomName, String bedNo) { BedQueueBO bedQueueBO2 = mapBedVsQueue.get(String.format("%09d%s", roomId, bedNo)); if (null != bedQueueBO2) { log.error("bedOpen mapBedVsQueue has existed. " + roomId + " " + bedNo); return QUEUE_BED_EXIST; } // DB update List statusList = new ArrayList<BedStatusEnum>(); 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<Byte> queueStatusList = new ArrayList<>(); queueStatusList.add(QueueStatusEnum.READY.getStatus()); List<QueueDO> queueDOList = queueMapper.getDoctorQueueByStatus(roomId, bedNo, queueStatusList); // æ°å¢å·¥ä½ ä¼å éå BedQueueBO bedQueueBO = new BedQueueBO(); bedQueueBO.setRoomId(roomId); bedQueueBO.setRoomName(roomName); bedQueueBO.setBedNo(bedNo); bedQueueBO.setMaxQueueNum(queueReadyMax); bedQueueBO.setQueueNum(new AtomicInteger(queueDOList.size())); bedQueueBO.setStatus(BedStatusEnum.OPENING.getStatus()); priorityQueue.offer(bedQueueBO); mapBedVsQueue.put(String.format("%09d%s", roomId, bedNo), bedQueueBO); return GlobalErrorCodeConstants.SUCCESS; } public ErrorCode bedClose(Long roomId, String bedNo) { BedQueueBO bedQueueBO = mapBedVsQueue.get(String.format("%09d%s", 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<Byte> queueStatusList = new ArrayList<>(); queueStatusList.add(QueueStatusEnum.READY.getStatus()); queueStatusList.add(QueueStatusEnum.PASSED.getStatus()); queueStatusList.add(QueueStatusEnum.RECALLED.getStatus()); List<QueueDO> queueDOList = queueMapper.getDoctorQueueByStatus(roomId, bedNo, queueStatusList); if (queueDOList.size() > 0) return QUEUE_HAVE_PATIENT; // DB update List statusList = new ArrayList<BedStatusEnum>(); 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(String.format("%09d%s", roomId, bedNo)); priorityQueue.remove(bedQueueBO); return GlobalErrorCodeConstants.SUCCESS; } public ErrorCode bedDoctorPause(Long roomId, String bedNo, Long docId, String docName) { BedQueueBO bedQueueBO = mapBedVsQueue.get(String.format("%09d%s", roomId, bedNo)); if (null == bedQueueBO) { log.error("bedDoctorPause mapBedVsQueue DONOT existed. " + roomId + " " + bedNo); return QUEUE_BED_NOT_EXIST; } // DB update List statusList = new ArrayList<BedStatusEnum>(); 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()); priorityQueue.remove(bedQueueBO); return GlobalErrorCodeConstants.SUCCESS; } public ErrorCode bedDoctorResume(Long roomId, String bedNo, Long docId, String docName) { BedQueueBO bedQueueBO = mapBedVsQueue.get(String.format("%09d%s", 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<BedStatusEnum>(); 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()); if (!priorityQueue.contains(bedQueueBO)) { priorityQueue.offer(bedQueueBO); } else { log.error("bedDoctorResume priorityQueue still exist!. " + roomId + " " + bedNo); return ECG_INNER_ERROR; } return GlobalErrorCodeConstants.SUCCESS; } public ErrorCode bedDoctorOn(Long roomId, String bedNo, Long docId, String docName) { BedQueueBO bedQueueBO = mapBedVsQueue.get(String.format("%09d%s", roomId, bedNo)); if (null == bedQueueBO) { log.error("bedDoctorOn mapBedVsQueue DONOT existed. " + roomId + " " + bedNo); return QUEUE_BED_NOT_EXIST; } // DB update List statusList = new ArrayList<BedStatusEnum>(); 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()); return GlobalErrorCodeConstants.SUCCESS; } public ErrorCode bedDoctorOff(Long roomId, String bedNo, Long docId, String docName) { BedQueueBO bedQueueBO = mapBedVsQueue.get(String.format("%09d%s", roomId, bedNo)); if (null == bedQueueBO) { log.error("bedDoctorOff mapBedVsQueue DONOT existed. " + roomId + " " + bedNo); return QUEUE_BED_NOT_EXIST; } // DB update List statusList = new ArrayList<BedStatusEnum>(); 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; } // 妿æ¯å¨ PAUSE ç¶æç¦»åº§çï¼éè¦éæ°å å ä¼å éå if (bedQueueBO.getStatus().equals(BedStatusEnum.PAUSE.getStatus())) { if (!priorityQueue.contains(bedQueueBO)) { priorityQueue.offer(bedQueueBO); } else { log.error("bedDoctorResume priorityQueue still exist!. " + roomId + " " + bedNo); return ECG_INNER_ERROR; } } bedQueueBO.setStatus(BedStatusEnum.OPENING.getStatus()); return GlobalErrorCodeConstants.SUCCESS; } public ErrorCode nextPatient(Long roomId, String bedNo) { // ä» DB æ åºå·æå°ç å°±è¯åå¤ä¸ç人 设置为就è¯ä¸ Integer updateNum = queueMapper.updateQueueStatus(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 䏿¹åäºå¼ priorityQueue.remove(bo); priorityQueue.offer(bo); return GlobalErrorCodeConstants.SUCCESS; } /** * 1. æ¯å¤©å¼è¯å ä»DB忥工ä½çæ£è éåæ°æ®å° å·¥ä½ä¼å éå * 2. æå¡è¿ç»´é坿¶ */ public ErrorCode bedReload() { priorityQueue.clear(); mapBedVsQueue.clear(); // æ¸ é¤éå½å¤©çæé人å queueMapper.clearQueue(); // æ¸ é¤éå½å¤©çè¯é³å«å·è®°å½ callMapper.clearCall(); // ä»DB è·å å·¥ä½å表 List<BedStatusEnum> bedStatusEnumList = new ArrayList<BedStatusEnum>(); bedStatusEnumList.add(BedStatusEnum.OPENING); bedStatusEnumList.add(BedStatusEnum.DOCTOR_ON); bedStatusEnumList.add(BedStatusEnum.PAUSE); List<RoomDO> roomDOList = roomMapper.simpleRoomList(bedStatusEnumList); List<BedQueueBO> bedQueueBOList = roomDOList.stream().map(item -> BeanUtils.toBean(item, BedQueueBO.class)).toList(); // ä»DB è·å éåä¸ å°±è¯åå¤ä¸äººåç»è®¡ å表 List<Byte> queueStatusList = new ArrayList<>(); queueStatusList.add(QueueStatusEnum.READY.getStatus()); List<QueueStatisticDO> queueStatisticDOList = queueMapper.queueStatistic(queueStatusList); bedQueueBOList.forEach(item -> { item.maxQueueNum = queueReadyMax; Optional<QueueStatisticDO> queueStatisticDOOptional = queueStatisticDOList.stream().filter(it->it.getRoomId()==item.roomId && it.getBedNo().equals(item.getBedNo())).findFirst(); int queueNum = queueStatisticDOOptional.isPresent() ? queueStatisticDOOptional.get().getTotalInStatus() : 0; if ( queueReadyMax < queueNum ) throw new RuntimeException("init: exceed max queue number!"); item.queueNum.set( queueNum ); mapBedVsQueue.put(String.format("%09d%s", item.roomId, item.bedNo), item); if (BedStatusEnum.PAUSE.getStatus() != item.getStatus()) { priorityQueue.offer(item); } }); Integer num = queueMapper.getMaxSeqNum(); curSeqNum = new AtomicInteger(null == num ? 0 : num); return GlobalErrorCodeConstants.SUCCESS; } public void resetRoom() { // 踢åºå¨åº§çå»ç List<BedStatusEnum> bedStatusEnumList = new ArrayList<BedStatusEnum>(); bedStatusEnumList.add(BedStatusEnum.DOCTOR_ON); bedStatusEnumList.add(BedStatusEnum.PAUSE); List<RoomDO> roomDOList = roomMapper.simpleRoomList(bedStatusEnumList); List<Long> userIdList = roomDOList.stream().map(roomDO -> roomDO.getDocId()).toList(); oAuth2TokenApi.tick(userIdList); // å ³éææå·¥ä½ Integer ret = roomMapper.resetRoom(BedStatusEnum.CLOSED.getStatus()); } /** * æå»çåè¯çéå塿»¡ */ public void hurryup() { if (0 == openingFlag.get()) return; // å¤ç è¿å·-忥 ç人 for (BedQueueBO bedQueueBO : mapBedVsQueue.values()) { 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; curSeqNum.getAndIncrement(); // å¯è½å·²ç»ãå¹¶åçãå¨ nextPatient 䏿¹åäºå¼ bedQueueBO.queueNum.incrementAndGet(); // å¯è½å·²ç»ãå¹¶åçãå¨ nextPatient 䏿¹åäºä¼å éåé¡ºåº priorityQueue.remove(bedQueueBO); priorityQueue.offer(bedQueueBO); } } // å¤ç æéä¸ æ£è while (true) { BedQueueBO bedQueueBO = priorityQueue.peek(); if (null == bedQueueBO) return; int curQueueNum = bedQueueBO.queueNum.get(); if (curQueueNum > bedQueueBO.maxQueueNum) throw new RuntimeException("hurryup: exceed max queue number!"); if (curQueueNum == bedQueueBO.maxQueueNum) return; // æ¥ç æ¯å¦ææéä¸çæ£è Integer updateNum = queueMapper.preemptPatient( bedQueueBO.getRoomId(), bedQueueBO.getRoomName(), bedQueueBO.getBedNo(), curSeqNum.get() + 1, QueueStatusEnum.WAITING.getStatus(), QueueStatusEnum.READY.getStatus()); // æ²¡ææ¢å°æéæ£è if (null == updateNum || 0 == updateNum) { return; } curSeqNum.getAndIncrement(); // å¯è½å·²ç»ãå¹¶åçãå¨ nextPatient 䏿¹åäºå¼ bedQueueBO.queueNum.incrementAndGet(); // å¯è½å·²ç»ãå¹¶åçãå¨ nextPatient 䏿¹åäºä¼å éåé¡ºåº priorityQueue.remove(bedQueueBO); priorityQueue.offer(bedQueueBO); } } public Integer getOpeningFlag() { return openingFlag.get(); } public void setOpeningFlag(Integer flag) { openingFlag.set(flag); } public void setQueueReadyMax(Integer max) { queueReadyMax = max; } public BedQueueBO getBedQueueBO(Long roomId, String bedNo) { return mapBedVsQueue.get(String.format("%09d%s", roomId, bedNo)); } public MonitorInfoVO getMonitorInfo() { MonitorInfoVO monitorInfoVO = new MonitorInfoVO(); monitorInfoVO.setOpeningFlag( openingFlag.get() ); monitorInfoVO.setQueueNum( mapBedVsQueue.size() ); monitorInfoVO.setActiveQueueNum( priorityQueue.size() ); return monitorInfoVO; } public void monitorInfo() { log.info("map " + mapBedVsQueue.size() + " priority " + priorityQueue.size() + " opening " + openingFlag.get()); } }