eight
2024-09-27 e8f1b8e0380d7c868f4e3218688796f595151724
refactor: 用以支持springboot 事务注解
已添加1个文件
已修改11个文件
874 ■■■■ 文件已修改
jh-module-ecg/jh-module-ecg-biz/src/main/java/cn/lihu/jh/module/ecg/api/doctor/DoctorApiImpl.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
jh-module-ecg/jh-module-ecg-biz/src/main/java/cn/lihu/jh/module/ecg/service/queue/BedCloseCallable.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
jh-module-ecg/jh-module-ecg-biz/src/main/java/cn/lihu/jh/module/ecg/service/queue/BedDoctorNextPatientCallable.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
jh-module-ecg/jh-module-ecg-biz/src/main/java/cn/lihu/jh/module/ecg/service/queue/BedDoctorOffCallable.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
jh-module-ecg/jh-module-ecg-biz/src/main/java/cn/lihu/jh/module/ecg/service/queue/BedDoctorOnCallable.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
jh-module-ecg/jh-module-ecg-biz/src/main/java/cn/lihu/jh/module/ecg/service/queue/BedDoctorPauseCallable.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
jh-module-ecg/jh-module-ecg-biz/src/main/java/cn/lihu/jh/module/ecg/service/queue/BedDoctorResumeCallable.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
jh-module-ecg/jh-module-ecg-biz/src/main/java/cn/lihu/jh/module/ecg/service/queue/BedOpenCallable.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
jh-module-ecg/jh-module-ecg-biz/src/main/java/cn/lihu/jh/module/ecg/service/queue/BedReloadCallable.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
jh-module-ecg/jh-module-ecg-biz/src/main/java/cn/lihu/jh/module/ecg/service/queue/QueueService.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
jh-module-ecg/jh-module-ecg-biz/src/main/java/cn/lihu/jh/module/ecg/service/queue/QueueServiceImpl.java 395 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
jh-module-ecg/jh-module-ecg-biz/src/main/java/cn/lihu/jh/module/ecg/service/queue/QueueServiceTxFunctions.java 428 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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());
    }
}