| | |
| | | package cn.lihu.jh.module.ecg.service.queue; |
| | | |
| | | import cn.lihu.jh.module.ecg.dal.dataobject.queue.BedQueueStatisticDO; |
| | | import cn.lihu.jh.module.ecg.dal.dataobject.queue.QueueStatisticDO; |
| | | import java.util.*; |
| | | import java.util.concurrent.*; |
| | | import java.util.concurrent.atomic.AtomicInteger; |
| | | import javax.annotation.Resource; |
| | | |
| | | import cn.lihu.jh.module.ecg.dal.dataobject.room.RoomDO; |
| | | import cn.lihu.jh.module.ecg.dal.mysql.room.RoomMapper; |
| | | import cn.lihu.jh.module.ecg.enums.QueueStatusEnum; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.validation.annotation.Validated; |
| | | |
| | | import cn.lihu.jh.framework.common.exception.ErrorCode; |
| | | import cn.lihu.jh.framework.common.pojo.CommonResult; |
| | | import cn.lihu.jh.module.ecg.controller.admin.room.vo.RoomRespVO; |
| | | import cn.lihu.jh.module.ecg.dal.dataobject.queue.BedQueueStatisticDO; |
| | | import cn.lihu.jh.module.ecg.dal.dataobject.queue.QueueStatisticDO; |
| | | import cn.lihu.jh.module.ecg.dal.mysql.room.RoomMapper; |
| | | import cn.lihu.jh.module.ecg.enums.BedStatusEnum; |
| | | import cn.lihu.jh.module.ecg.enums.QueueStatusEnum; |
| | | import cn.lihu.jh.module.infra.api.config.ConfigApi; |
| | | import cn.lihu.jh.module.ecg.controller.admin.queue.vo.*; |
| | | import cn.lihu.jh.module.ecg.dal.dataobject.queue.QueueDO; |
| | | import cn.lihu.jh.framework.common.pojo.PageResult; |
| | | import cn.lihu.jh.framework.common.util.object.BeanUtils; |
| | | |
| | | import cn.lihu.jh.module.ecg.dal.mysql.queue.queueMapper; |
| | | |
| | | import javax.annotation.Resource; |
| | | |
| | | import java.util.*; |
| | | import java.util.concurrent.*; |
| | | import java.util.concurrent.atomic.AtomicInteger; |
| | | |
| | | import static cn.lihu.jh.framework.common.exception.enums.GlobalErrorCodeConstants.SUCCESS; |
| | | 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.*; |
| | | |
| | | /** |
| | |
| | | @Validated |
| | | public class QueueServiceImpl implements QueueService { |
| | | |
| | | final static Integer MAX_QUEUE_NUM = 3; |
| | | @Resource |
| | | private ConfigApi configApi; |
| | | |
| | | @Resource |
| | | private queueMapper queueMapper; |
| | |
| | | private RoomMapper roomMapper; |
| | | |
| | | AtomicInteger openingFlag = new AtomicInteger(0); |
| | | |
| | | AtomicInteger curSeqNum = new AtomicInteger(0); |
| | | |
| | | PriorityBlockingQueue<BedQueueBO> priorityQueue = new PriorityBlockingQueue<>(); |
| | |
| | | |
| | | ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor(); |
| | | |
| | | Integer queueReadyMax = 0; |
| | | |
| | | @Override |
| | | public Integer createqueue(QueueSaveReqVO createReqVO) { |
| | |
| | | } |
| | | |
| | | @Override |
| | | public Integer bedControl(Long roomId, String bedNo, Integer status) { |
| | | // 营业期间不能关闭工位 |
| | | if ( status == 0 && openingFlag.get() == 1 ) |
| | | return 301; |
| | | public ErrorCode startBedOpen(Long roomId, String bedNo) { |
| | | Future<ErrorCode> future = singleThreadExecutor.submit( new BedOpenCallable(this, roomId, bedNo)); |
| | | |
| | | // 当前状态 |
| | | roomMapper.select |
| | | |
| | | // DB update |
| | | Integer updateNum = roomMapper.setBedStatus(roomId, bedNo, status); |
| | | if ( null==updateNum || 0 == updateNum ) |
| | | return 310; |
| | | |
| | | if ( status == 10 ) { |
| | | BedQueueBO bedQueueBO = new BedQueueBO(); |
| | | bedQueueBO.setRoomId(roomId); |
| | | bedQueueBO.setBedNo(bedNo); |
| | | bedQueueBO.setMaxQueueNum(MAX_QUEUE_NUM); |
| | | bedQueueBO.setQueueNum(new AtomicInteger(0)); |
| | | priorityQueue.offer(bedQueueBO); |
| | | mapBedVsQueue.put(String.format("%09d%s", bedQueueBO.roomId, bedQueueBO.bedNo), bedQueueBO); |
| | | try { |
| | | ErrorCode ret = future.get(); |
| | | return ret; |
| | | } catch (InterruptedException e) { |
| | | e.printStackTrace(); |
| | | } catch (ExecutionException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | |
| | | return 0; |
| | | return ECG_INNER_ERROR; |
| | | } |
| | | |
| | | @Override |
| | | public ErrorCode startBedClose(Long roomId, String bedNo) { |
| | | Future<ErrorCode> future = singleThreadExecutor.submit( new BedCloseCallable(this, roomId, bedNo)); |
| | | |
| | | try { |
| | | ErrorCode ret = future.get(); |
| | | return ret; |
| | | } catch (InterruptedException e) { |
| | | e.printStackTrace(); |
| | | } catch (ExecutionException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | |
| | | return ECG_INNER_ERROR; |
| | | } |
| | | |
| | | @Override |
| | | public ErrorCode startBedDoctorPause(Long roomId, String bedNo, Long docId, String docName) { |
| | | Future<ErrorCode> future = singleThreadExecutor.submit( |
| | | new BedDoctorPauseCallable(this, roomId, bedNo, docId, docName) |
| | | ); |
| | | |
| | | try { |
| | | ErrorCode ret = future.get(); |
| | | return ret; |
| | | } catch (InterruptedException e) { |
| | | e.printStackTrace(); |
| | | } catch (ExecutionException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | |
| | | return ECG_INNER_ERROR; |
| | | } |
| | | |
| | | @Override |
| | | public ErrorCode startBedDoctorResume(Long roomId, String bedNo, Long docId, String docName) { |
| | | Future<ErrorCode> future = singleThreadExecutor.submit( |
| | | new BedDoctorResumeCallable(this, roomId, bedNo, docId, docName) |
| | | ); |
| | | |
| | | try { |
| | | ErrorCode ret = future.get(); |
| | | return ret; |
| | | } catch (InterruptedException e) { |
| | | e.printStackTrace(); |
| | | } catch (ExecutionException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | |
| | | return ECG_INNER_ERROR; |
| | | } |
| | | |
| | | @Override |
| | | public ErrorCode startBedDoctorOn(Long roomId, String bedNo, Long docId, String docName) { |
| | | Future<ErrorCode> future = singleThreadExecutor.submit( |
| | | new BedDoctorOnCallable(this, roomId, bedNo, docId, docName) |
| | | ); |
| | | |
| | | try { |
| | | ErrorCode ret = future.get(); |
| | | return ret; |
| | | } catch (InterruptedException e) { |
| | | e.printStackTrace(); |
| | | } catch (ExecutionException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | |
| | | return ECG_INNER_ERROR; |
| | | } |
| | | |
| | | @Override |
| | | public ErrorCode startBedDoctorOff(Long roomId, String bedNo, Long docId, String docName) { |
| | | Future<ErrorCode> future = singleThreadExecutor.submit( |
| | | new BedDoctorOffCallable(this, roomId, bedNo, docId, docName) |
| | | ); |
| | | |
| | | try { |
| | | ErrorCode ret = future.get(); |
| | | return ret; |
| | | } catch (InterruptedException e) { |
| | | e.printStackTrace(); |
| | | } catch (ExecutionException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | |
| | | return ECG_INNER_ERROR; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 已关闭 或者 关闭中,可以开通工位 |
| | | * @param roomId |
| | | * @param bedNo |
| | | * @return |
| | | */ |
| | | @Override |
| | | public ErrorCode bedOpen(Long roomId, String bedNo) { |
| | | // DB update |
| | | List statusList = new ArrayList<BedStatusEnum>(); |
| | | statusList.add(BedStatusEnum.CLOSED); |
| | | Integer updateNum = roomMapper.setBedStatus(roomId, bedNo, |
| | | BedStatusEnum.OPENING, statusList); |
| | | if ( null==updateNum || 0 == updateNum ) |
| | | 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.setBedNo(bedNo); |
| | | bedQueueBO.setMaxQueueNum(queueReadyMax); |
| | | bedQueueBO.setQueueNum(new AtomicInteger(queueDOList.size())); |
| | | bedQueueBO.setStatusEnum(BedStatusEnum.OPENING); |
| | | priorityQueue.offer(bedQueueBO); |
| | | mapBedVsQueue.put(String.format("%09d%s", roomId, bedNo), bedQueueBO); |
| | | return SUCCESS; |
| | | } |
| | | |
| | | @Override |
| | | public ErrorCode bedClose(Long roomId, String bedNo) { |
| | | BedQueueBO bedQueueBO = mapBedVsQueue.get(String.format("%09d%s", roomId, bedNo)); |
| | | if (null == bedQueueBO) |
| | | return QUEUE_BED_ABNORMAL; |
| | | |
| | | if (bedQueueBO.getQueueNum().get() >0) |
| | | return QUEUE_HAVE_PATIENT; |
| | | |
| | | BedStatusEnum destStatusEnum = destStatusEnum = BedStatusEnum.CLOSED; |
| | | mapBedVsQueue.remove(String.format("%09d%s", roomId, bedNo)); |
| | | priorityQueue.remove(bedQueueBO); |
| | | |
| | | // DB update |
| | | List statusList = new ArrayList<BedStatusEnum>(); |
| | | statusList.add(BedStatusEnum.OPENING); |
| | | statusList.add(BedStatusEnum.DOCTOR_ON); |
| | | statusList.add(BedStatusEnum.PAUSE); |
| | | Integer updateNum = roomMapper.setBedStatus(roomId, bedNo, destStatusEnum, statusList); |
| | | if ( null==updateNum || 0 == updateNum ) |
| | | return ROOM_INVALID_STATUS; |
| | | |
| | | return SUCCESS; |
| | | } |
| | | |
| | | @Override |
| | | public CommonResult<RoomRespVO> getRoom(Long roomId, String bedNo, Long docId) { |
| | | BedQueueBO bedQueueBO = mapBedVsQueue.get(String.format("%09d%s", roomId, bedNo)); |
| | | if (null == bedQueueBO) { |
| | | return error(QUEUE_BED_ABNORMAL); |
| | | } |
| | | |
| | | RoomDO roomDO = roomMapper.getRoom(roomId, bedNo, docId); |
| | | if (null == roomDO) { |
| | | return error(ECG_INNER_ERROR); |
| | | } |
| | | |
| | | 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) |
| | | return QUEUE_BED_ABNORMAL; |
| | | |
| | | bedQueueBO.setStatusEnum(BedStatusEnum.PAUSE); |
| | | priorityQueue.remove(bedQueueBO); |
| | | |
| | | // DB update |
| | | List statusList = new ArrayList<BedStatusEnum>(); |
| | | statusList.add(BedStatusEnum.DOCTOR_ON); |
| | | Integer updateNum = roomMapper.setBedDoctorPause(roomId, bedNo, docId, docName, |
| | | BedStatusEnum.PAUSE, statusList); |
| | | if ( null==updateNum || 0 == updateNum ) |
| | | return ROOM_INVALID_STATUS; |
| | | |
| | | return 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) |
| | | return QUEUE_BED_ABNORMAL; |
| | | |
| | | bedQueueBO.setStatusEnum(BedStatusEnum.DOCTOR_ON); |
| | | priorityQueue.offer(bedQueueBO); |
| | | |
| | | // DB update |
| | | List statusList = new ArrayList<BedStatusEnum>(); |
| | | statusList.add(BedStatusEnum.PAUSE); |
| | | Integer updateNum = roomMapper.setBedDoctorPause(roomId, bedNo, docId, docName, |
| | | BedStatusEnum.DOCTOR_ON, statusList); |
| | | if ( null==updateNum || 0 == updateNum ) |
| | | return ROOM_INVALID_STATUS; |
| | | |
| | | return 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) |
| | | return QUEUE_BED_ABNORMAL; |
| | | |
| | | // 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 ) |
| | | return ROOM_INVALID_STATUS; |
| | | |
| | | bedQueueBO.setStatusEnum(BedStatusEnum.DOCTOR_ON); |
| | | |
| | | return 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) |
| | | return QUEUE_BED_ABNORMAL; |
| | | |
| | | // DB update |
| | | List statusList = new ArrayList<BedStatusEnum>(); |
| | | statusList.add(BedStatusEnum.DOCTOR_ON); |
| | | Integer updateNum = roomMapper.setBedDoctorOff(roomId, bedNo, docId, docName, |
| | | BedStatusEnum.OPENING, statusList); |
| | | if ( null==updateNum || 0 == updateNum ) |
| | | return ROOM_INVALID_STATUS; |
| | | |
| | | bedQueueBO.setStatusEnum(BedStatusEnum.OPENING); |
| | | |
| | | return SUCCESS; |
| | | } |
| | | |
| | | private void validatequeueExists(Integer id) { |
| | |
| | | mapBedVsQueue.clear(); |
| | | |
| | | // 从DB 获取 工位列表 |
| | | List<RoomDO> roomDOList = roomMapper.simpleRoomList(); |
| | | 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<QueueStatisticDO> queueStatisticDOList = queueMapper.queueStatistic(queueStatusList); |
| | | |
| | | bedQueueBOList.forEach(item -> { |
| | | item.maxQueueNum = MAX_QUEUE_NUM; |
| | | 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 ( MAX_QUEUE_NUM < queueNum ) |
| | | if ( queueReadyMax < queueNum ) |
| | | throw new RuntimeException("init: exceed max queue number!"); |
| | | |
| | | item.queueNum.set( queueNum ); |
| | |
| | | return patientStatisticVO; |
| | | } |
| | | |
| | | @Override |
| | | public void setQueueReadyMax(Integer max) { |
| | | queueReadyMax = max; |
| | | } |
| | | |
| | | public void startBiz() { |
| | | if (1 == openingFlag.get()) |
| | | return; |
| | |
| | | } |
| | | |
| | | } |
| | | |