package cn.lihu.jh.module.ecg.service.queuesequence; 
 | 
  
 | 
import cn.lihu.jh.module.ecg.Utils; 
 | 
import cn.lihu.jh.module.ecg.dal.dataobject.checktype.CheckTypeDO; 
 | 
import cn.lihu.jh.module.ecg.dal.mysql.checktype.CheckTypeMapper; 
 | 
import cn.lihu.jh.module.infra.api.config.ConfigApi; 
 | 
import cn.lihu.jh.module.system.api.dict.DictDataApi; 
 | 
import cn.lihu.jh.module.system.api.dict.dto.DictDataRespDTO; 
 | 
import org.springframework.stereotype.Service; 
 | 
import org.springframework.validation.annotation.Validated; 
 | 
import org.springframework.transaction.annotation.Transactional; 
 | 
  
 | 
import java.time.LocalTime; 
 | 
import java.util.*; 
 | 
import cn.lihu.jh.module.ecg.controller.admin.queuesequence.vo.*; 
 | 
import cn.lihu.jh.module.ecg.dal.dataobject.queuesequence.QueueSequenceDO; 
 | 
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.queuesequence.QueueSequenceMapper; 
 | 
  
 | 
import javax.annotation.Resource; 
 | 
  
 | 
import static cn.lihu.jh.framework.common.exception.util.ServiceExceptionUtil.exception; 
 | 
import static cn.lihu.jh.module.ecg.Constants.*; 
 | 
import static cn.lihu.jh.module.ecg.enums.ErrorCodeConstants.*; 
 | 
  
 | 
/** 
 | 
 * 当天序号 Service 实现类 
 | 
 * 
 | 
 * @author 金华医院 
 | 
 */ 
 | 
@Service 
 | 
@Validated 
 | 
public class QueueSequenceServiceImpl implements QueueSequenceService { 
 | 
  
 | 
    @Resource 
 | 
    private ConfigApi configApi; 
 | 
  
 | 
    @Resource 
 | 
    private DictDataApi dictDataApi; 
 | 
  
 | 
    @Resource 
 | 
    private QueueSequenceMapper queueSequenceMapper; 
 | 
  
 | 
    @Resource 
 | 
    private CheckTypeMapper checkTypeMapper; 
 | 
  
 | 
    @Override 
 | 
    public void initQueueSequenceTable() { 
 | 
        queueSequenceMapper.clearQueueSequenceTableNotCurrent(); 
 | 
        Integer rowCount = queueSequenceMapper.getQueueSequenceTableRowCount(); 
 | 
        if (null == rowCount || 0 == rowCount) { 
 | 
            resetQueueSequence(); 
 | 
        } 
 | 
    } 
 | 
  
 | 
    @Override 
 | 
    public Integer createQueueSequence(QueueSequenceSaveReqVO createReqVO) { 
 | 
        // 插入 
 | 
        QueueSequenceDO queueSequence = BeanUtils.toBean(createReqVO, QueueSequenceDO.class); 
 | 
        queueSequenceMapper.insert(queueSequence); 
 | 
        // 返回 
 | 
        return queueSequence.getId(); 
 | 
    } 
 | 
  
 | 
    @Override 
 | 
    public void updateQueueSequence(QueueSequenceSaveReqVO updateReqVO) { 
 | 
        // 校验存在 
 | 
        validateQueueSequenceExists(updateReqVO.getId()); 
 | 
        // 更新 
 | 
        QueueSequenceDO updateObj = BeanUtils.toBean(updateReqVO, QueueSequenceDO.class); 
 | 
        queueSequenceMapper.updateById(updateObj); 
 | 
    } 
 | 
  
 | 
    @Override 
 | 
    public void deleteQueueSequence(Integer id) { 
 | 
        // 校验存在 
 | 
        validateQueueSequenceExists(id); 
 | 
        // 删除 
 | 
        queueSequenceMapper.deleteById(id); 
 | 
    } 
 | 
  
 | 
    private void validateQueueSequenceExists(Integer id) { 
 | 
        if (queueSequenceMapper.selectById(id) == null) { 
 | 
            throw exception(QUEUE_SEQUENCE_NOT_EXISTS); 
 | 
        } 
 | 
    } 
 | 
  
 | 
    @Override 
 | 
    public QueueSequenceDO getQueueSequence(Integer id) { 
 | 
        return queueSequenceMapper.selectById(id); 
 | 
    } 
 | 
  
 | 
    @Override 
 | 
    public List<QueueSequenceDO> selectGivenCheckTypeTimeslot(Integer checkType) { 
 | 
        return queueSequenceMapper.selectTimeslotByCheckType( checkType ); 
 | 
    } 
 | 
  
 | 
    @Override 
 | 
    public PageResult<QueueSequenceDO> getQueueSequencePage(QueueSequencePageReqVO pageReqVO) { 
 | 
        return queueSequenceMapper.selectPage(pageReqVO); 
 | 
    } 
 | 
  
 | 
    @Override 
 | 
    public void resetQueueSequence() { 
 | 
        queueSequenceMapper.clearQueueSequenceTable(); 
 | 
  
 | 
        // 读取时段配置 
 | 
        String strBookTimeslotLength = configApi.getConfigValueByKey(BOOK_TIMESLOT_LENGTH); 
 | 
  
 | 
        // 方案1:配置中取    7:30,8:30,9:30,10:30,11:30,12:30,13:30,14:30,15:30 
 | 
        //String strBookTimeslotList = configApi.getConfigValueByKey(BOOK_TIMESLOT_LIST); 
 | 
        //List<LocalTime> timeslotList = Utils.parseTimeSlotList(strBookTimeslotList, Integer.valueOf(strBookTimeslotLength)); 
 | 
  
 | 
        List<DictDataRespDTO> dictBookTimeslotList = dictDataApi.getDictDataList(ECG_BOOK_TIMESLOT); 
 | 
  
 | 
        // 读取所有的检查类型 
 | 
        List<CheckTypeDO> checkTypeDOList =  checkTypeMapper.simpleCheckTypeList(); 
 | 
        checkTypeDOList.forEach( checkTypeDO -> { 
 | 
  
 | 
            for (int i=0; i < dictBookTimeslotList.size(); i++) { 
 | 
                QueueSequenceDO queueSequenceDO = new QueueSequenceDO(); 
 | 
                queueSequenceDO.setCheckType( checkTypeDO.getValue() ); 
 | 
                queueSequenceDO.setTimeSlot( Integer.valueOf(dictBookTimeslotList.get(i).getValue()) ); 
 | 
                queueSequenceDO.setQueueNo( i * checkTypeDO.getTimeslotBookNum() + checkTypeDO.getTimeslotReservedNum()); 
 | 
                queueSequenceDO.setQueueVipNo( i * checkTypeDO.getTimeslotBookNum()); 
 | 
                queueSequenceDO.setQueueFull( i * checkTypeDO.getTimeslotBookNum() + checkTypeDO.getTimeslotBookNum()); 
 | 
                queueSequenceDO.setQueueVipFull( i * checkTypeDO.getTimeslotBookNum() + checkTypeDO.getTimeslotReservedNum()); 
 | 
                queueSequenceMapper.insert( queueSequenceDO ); 
 | 
            }; 
 | 
        }); 
 | 
    } 
 | 
  
 | 
    @Override 
 | 
    @Transactional 
 | 
    public Integer distributeSeqNo(Integer checkType, Integer timeslot) { 
 | 
        Integer curSeqNo = queueSequenceMapper.selectQueueNoForUpdate(checkType, timeslot); 
 | 
        if (null == curSeqNo) { 
 | 
            // 从下一个时段 获取序号。原因系统用30分钟的间隔划分预约时间段,HIS的预约时间段可能是30分钟或60分钟 
 | 
            Integer nextTimeslot = getNextTimeSlot(timeslot, checkType); 
 | 
            if (null == nextTimeslot) { 
 | 
                throw exception(QUEUE_SEQUENCE_TIMESLOT_FULL); 
 | 
            } 
 | 
  
 | 
            curSeqNo = queueSequenceMapper.selectQueueNoForUpdate(checkType, nextTimeslot); 
 | 
            if (null == curSeqNo) { 
 | 
                throw exception(QUEUE_SEQUENCE_TIMESLOT_FULL); 
 | 
            } 
 | 
  
 | 
            Integer updateRowNum = queueSequenceMapper.updateGivenCheckTypeTimeslotSeqNo(checkType, nextTimeslot, curSeqNo); 
 | 
            if (null == updateRowNum || updateRowNum == 0) { 
 | 
                throw exception(QUEUE_SEQUENCE_TIMESLOT_EXCEPTION); 
 | 
            } 
 | 
  
 | 
        } else { 
 | 
            Integer updateRowNum = queueSequenceMapper.updateGivenCheckTypeTimeslotSeqNo(checkType, timeslot, curSeqNo); 
 | 
            if (null == updateRowNum || updateRowNum == 0) { 
 | 
                throw exception(QUEUE_SEQUENCE_TIMESLOT_EXCEPTION); 
 | 
            } 
 | 
        } 
 | 
  
 | 
        return curSeqNo + 1; 
 | 
    } 
 | 
  
 | 
    @Override 
 | 
    @Transactional 
 | 
    public Integer distributeVipSeqNo(Integer checkType, Integer timeslot) { 
 | 
        Integer curVipSeqNo = queueSequenceMapper.selectQueueVipNoForUpdate(checkType, timeslot); 
 | 
        if (null == curVipSeqNo) { 
 | 
            throw exception(QUEUE_SEQUENCE_TIMESLOT_FULL); 
 | 
        } 
 | 
  
 | 
        Integer updateRowNum = queueSequenceMapper.updateGivenCheckTypeTimeslotVipSeqNo(checkType, timeslot, curVipSeqNo); 
 | 
        if (null == updateRowNum || updateRowNum == 0) { 
 | 
            throw exception(QUEUE_SEQUENCE_TIMESLOT_EXCEPTION); 
 | 
        } 
 | 
  
 | 
        return curVipSeqNo + 1; 
 | 
    } 
 | 
  
 | 
    private Integer getNextTimeSlot(Integer timeslot, Integer checkType) { 
 | 
        List<DictDataRespDTO> dictBookTimeslotList = dictDataApi.getDictDataList(ECG_BOOK_TIMESLOT); 
 | 
        Optional<Integer> index = dictBookTimeslotList.stream() 
 | 
                .filter(e -> e.getValue().equals(String.valueOf(timeslot))) 
 | 
                .findFirst() 
 | 
                .map(dictBookTimeslotList::indexOf); 
 | 
        if (!index.isPresent()) 
 | 
            return null; 
 | 
  
 | 
        if (dictBookTimeslotList.size() <= (index.get() + 1)) 
 | 
            return null; 
 | 
  
 | 
        DictDataRespDTO dictDataRespDTO = dictBookTimeslotList.get(index.get() + 1); 
 | 
        return Integer.valueOf(dictDataRespDTO.getValue()); 
 | 
    } 
 | 
  
 | 
} 
 |