| | |
| | | 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.*; |
| | |
| | | */ |
| | | @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); |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | @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; |
| | | } |
| | | } |