eight
2024-08-20 48e5224994cc500e6e0d898e7e9d3c8c9ad16062
jh-module-ecg/jh-module-ecg-biz/src/main/java/cn/lihu/jh/module/ecg/service/queue/queueServiceImpl.java
@@ -1,19 +1,29 @@
package cn.lihu.jh.module.ecg.service.queue;
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.dataobject.room.RoomStatisticsDO;
import cn.lihu.jh.module.ecg.dal.mysql.room.RoomMapper;
import cn.lihu.jh.module.ecg.enums.QueueStatusEnum;
import lombok.Data;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
import cn.lihu.jh.module.ecg.controller.admin.queue.vo.*;
import cn.lihu.jh.module.ecg.dal.dataobject.queue.queueDO;
import cn.lihu.jh.module.ecg.dal.dataobject.queue.QueueDO;
import cn.lihu.jh.framework.common.pojo.PageResult;
import cn.lihu.jh.framework.common.pojo.PageParam;
import cn.lihu.jh.framework.common.util.object.BeanUtils;
import cn.lihu.jh.module.ecg.dal.mysql.queue.queueMapper;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.atomic.AtomicInteger;
import static cn.lihu.jh.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.lihu.jh.module.ecg.enums.ErrorCodeConstants.*;
@@ -25,26 +35,36 @@
 */
@Service
@Validated
public class queueServiceImpl implements queueService {
public class QueueServiceImpl implements QueueService {
    final static Integer MAX_QUEUE_NUM = 2;
    AtomicInteger curSeqNum = new AtomicInteger(0);
    PriorityBlockingQueue<BedQueueBO> priorityQueue = new PriorityBlockingQueue<>();
    ConcurrentHashMap<String, BedQueueBO > mapBedVsQueue = new ConcurrentHashMap<>();
    @Resource
    private queueMapper queueMapper;
    @Resource
    private RoomMapper roomMapper;
    @Override
    public Integer createqueue(queueSaveReqVO createReqVO) {
    public Integer createqueue(QueueSaveReqVO createReqVO) {
        // 插入
        queueDO queue = BeanUtils.toBean(createReqVO, queueDO.class);
        QueueDO queue = BeanUtils.toBean(createReqVO, QueueDO.class);
        queueMapper.insert(queue);
        // 返回
        return queue.getId();
    }
    @Override
    public void updatequeue(queueSaveReqVO updateReqVO) {
    public void updatequeue(QueueSaveReqVO updateReqVO) {
        // 校验存在
        validatequeueExists(updateReqVO.getId());
        // 更新
        queueDO updateObj = BeanUtils.toBean(updateReqVO, queueDO.class);
        QueueDO updateObj = BeanUtils.toBean(updateReqVO, QueueDO.class);
        queueMapper.updateById(updateObj);
    }
@@ -63,13 +83,131 @@
    }
    @Override
    public queueDO getqueue(Integer id) {
    public QueueDO getqueue(Integer id) {
        return queueMapper.selectById(id);
    }
    @Override
    public PageResult<queueDO> getqueuePage(queuePageReqVO pageReqVO) {
    public PageResult<QueueDO> getqueuePage(QueuePageReqVO pageReqVO) {
        return queueMapper.selectPage(pageReqVO);
    }
}
    @Override
    public List<QueueStatisticDO> queueStatistics(List<Byte> statusList) {
        return queueMapper.queueStatistic(statusList);
    }
    @Override
    public void queue(QueueSaveReqVO queueSaveReqVO) {
        BedQueueBO bedQueueBO = priorityQueue.peek();
        if (null == bedQueueBO)
            return;
        if (bedQueueBO.queueNum.get() == bedQueueBO.maxQueueNum) {
            queueSaveReqVO.setStatus(QueueStatusEnum.WAITING.getStatus()); //排队中
            QueueDO queue = BeanUtils.toBean(queueSaveReqVO, QueueDO.class);
            queueMapper.insert(queue);  // queue.getId();
        } else if (bedQueueBO.queueNum.get() < bedQueueBO.maxQueueNum) {
            queueSaveReqVO.setStatus(QueueStatusEnum.READY.getStatus()); //候诊准备中
            queueSaveReqVO.setRoomId(bedQueueBO.getRoomId());
            queueSaveReqVO.setRoomName(bedQueueBO.getRoomName());
            queueSaveReqVO.setBedNo(bedQueueBO.getBedNo());
            queueSaveReqVO.setSeqNum(curSeqNum.get());
            QueueDO queue = BeanUtils.toBean(queueSaveReqVO, QueueDO.class);
            queueMapper.insert(queue);  // queue.getId();
            curSeqNum.getAndIncrement();
            bedQueueBO.queueNum.getAndIncrement();
            BedQueueBO bedQueueBO2 = priorityQueue.poll();
            priorityQueue.offer(bedQueueBO2);
        }
    }
    public void initQueue() {
        priorityQueue.clear();
        mapBedVsQueue.clear();
        // 从DB 获取 工位列表
        List<RoomDO> roomDOList = roomMapper.simpleRoomList();
        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 = MAX_QUEUE_NUM;
            Optional<QueueStatisticDO> queueStatisticDOOptional = queueStatisticDOList.stream().filter(it->it.getRoomId()==item.roomId && it.getBedNo().equals(item.getBedNo())).findFirst();
            item.queueNum.set( queueStatisticDOOptional.isPresent() ? queueStatisticDOOptional.get().getTotalInStatus() : 0 );
            priorityQueue.offer(item);
            mapBedVsQueue.put(String.format("%09d%s", item.roomId, item.bedNo), item);
        });
        Integer num = queueMapper.getMaxSeqNum();
        curSeqNum = new AtomicInteger(null == num ? 1 : ++num);
        hurryup();
    }
    /**
     * TODO 新开队列时,需要把排队中的人 转到 就诊准备 状态
     * 等到取下一个 排队中人员 的逻辑完成后,再回来不错
     */
    public void hurryup() {
        while (true) {
            BedQueueBO bedQueueBO = priorityQueue.peek();
            if (null == bedQueueBO)
                return;
            if (bedQueueBO.queueNum.get() == bedQueueBO.maxQueueNum)
                return;
            QueueDO  queue = queueMapper.getFirstInQueueByStatus(QueueStatusEnum.WAITING.getStatus());
            if (null == queue)
                return;
            queue.setStatus(QueueStatusEnum.READY.getStatus()); //候诊准备中
            queue.setRoomId(bedQueueBO.getRoomId());
            queue.setRoomName(bedQueueBO.getRoomName());
            queue.setBedNo(bedQueueBO.getBedNo());
            queue.setSeqNum(curSeqNum.get());
            queueMapper.updateById(queue);  // queue.getId();
            curSeqNum.getAndIncrement();
            bedQueueBO.queueNum.getAndIncrement();
            BedQueueBO bedQueueBO2 = priorityQueue.poll();
            priorityQueue.offer(bedQueueBO2);
        }
    }
    public  void finishPatient(Long roomId, String bedNo) {
        // 从 DB 把 就诊中的人 设置为就诊完成
        Integer ret =  queueMapper.updateQueueStatus(roomId, bedNo,
                QueueStatusEnum.ONSTAGE.getStatus(), QueueStatusEnum.FINISH.getStatus());
        System.out.println("完成数量: " + ret);
    }
    public  void nextPatient(Long roomId, String bedNo) {
        finishPatient(roomId, bedNo);
        // 从 DB 把 序号最小的 就诊准备中的人 设置为就诊中
        queueMapper.updateQueueStatus(roomId, bedNo,
                QueueStatusEnum.READY.getStatus(), QueueStatusEnum.ONSTAGE.getStatus());
        // 优先队列中 该工位 就诊准备中人的数量 减一
        BedQueueBO bo = mapBedVsQueue.get(String.format("%09d%s", roomId, bedNo));
        boolean breturn = priorityQueue.remove(bo);
        bo.queueNum.getAndDecrement();
        priorityQueue.offer(bo);
        hurryup();
    }
    public List<QueueDO> getDoctorQueueByStatus(Long roomId, String bedNo, List<Byte> statusList) {
        List<QueueDO> queueDOList = queueMapper.getDoctorQueueByStatus(roomId, bedNo, statusList);
        return queueDOList;
    }
}