package com.prolog.rdc.tms.app.service.business.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import com.google.common.collect.Lists;
import com.prolog.common.util.ToolKits;
import com.prolog.framework.common.message.RestMessage;
import com.prolog.framework.core.exception.BizException;
import com.prolog.framework.core.exception.PrologException;
import com.prolog.framework.core.pojo.Page;
import com.prolog.framework.core.restriction.Criteria;
import com.prolog.framework.core.restriction.Order;
import com.prolog.framework.core.restriction.Restriction;
import com.prolog.framework.core.restriction.Restrictions;
import com.prolog.framework.dao.util.PageUtils;
import com.prolog.product.core.framework.entity.UserEntity;
import com.prolog.product.core.framework.util.PlgFxUsrUtils;
import com.prolog.rdc.tms.app.constant.BussinessConstant;
import com.prolog.rdc.tms.app.constant.DataDictionaryConstant;
import com.prolog.rdc.tms.app.constant.SeriaNnumberConstant;
import com.prolog.rdc.tms.app.constant.StatusConstant;
import com.prolog.rdc.tms.app.constant.enums.AppointCreateModeEnum;
import com.prolog.rdc.tms.app.dao.mapper.*;
import com.prolog.rdc.tms.app.model.dto.PendingPickUpTakeNumberDTO;
import com.prolog.rdc.tms.app.model.dto.business.*;
import com.prolog.rdc.tms.app.model.entity.*;
import com.prolog.rdc.tms.app.model.vo.business.*;
import com.prolog.rdc.tms.app.service.business.TakeNumberService;
import com.prolog.rdc.tms.app.util.*;
import com.prolog.rdc.tms.model.dto.basicData.TmsBaseBranchApTimeDTO;
import com.prolog.rdc.tms.model.dto.basicData.TmsBaseBranchDTO;
import com.prolog.rdc.tms.model.dto.basicData.TmsBaseCarportDTO;
import com.prolog.rdc.tms.model.dto.message.SendMessageDTO;
import com.prolog.rdc.tms.model.entity.SysRefdatadModel;
import com.prolog.rdc.tms.model.enums.MessageOrderTypeEnum;
import com.prolog.rdc.tms.model.enums.MessageTypeEnum;
import com.prolog.rdc.tms.rmi.feign.MaindataFeign;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 取号管理实现层
 *
 * @author xiaoyf
 * @since 2022/4/18 12:43
 */
@Service
public class TakeNumberServiceImpl implements TakeNumberService {

	@Autowired
	private TmsAppointmentHeaderMapper tmsAppointmentHeaderMapper;

	@Autowired
	private ConvertorUtil convertorUtil;

	@Autowired
	private MaindataFeign maindataFeign;

	@Autowired
	private TmsLoadingBillHeaderMapper tmsLoadingBillHeaderMapper;

	@Autowired
	private TmsLoadingBillDetailMapper tmsLoadingBillDetailMapper;

	@Autowired
	private TmsAppointmentDetailMapper tmsAppointmentDetailMapper;

	@Autowired
	private TmsShipbillHeaderMapper tmsShipbillHeaderMapper;

	@Autowired
	private MaindataFeign maindataTmsResource;

	@Autowired
	private TmsShipbillPackageMapper tmsShipbillPackageMapper;

	@Autowired
	private TmsShipbillDetailMapper tmsShipbillDetailMapper;

	SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

	@Autowired
	private BusinessFlowUtil businessFlowUtil;

	/**
	 * 预约单分页查询
	 *
	 * @param
	 * @return
	 */
	@Override
	public List<TakeNumberPageDTO> queryPage(TakeNumberAppointQueryVO vo) throws Exception {
		UserEntity user = PlgFxUsrUtils.getUserEntity();
		ToolKits.isParamNull(user, "当前人员没有操作权限");

		List<SysRefdatadModel> dicData = convertorUtil.getDictionary(new String[] { DataDictionaryConstant.APPOINTMENT_TYPE, // 预约类型
				DataDictionaryConstant.APPOINTMENT_STATUS // 预约状态
		});

		Criteria criteria = Criteria.forClass(TmsAppointmentHeaderModel.class);
		Restriction r1 = Restrictions.eq(TmsAppointmentHeaderModel::getEnterpriseId, user.getEnterpriseId());
		Restriction r2 = Restrictions.eq(TmsAppointmentHeaderModel::getBranchId, vo.getBranchId());
		// 查询预约日期为今天的预约单
		Restriction r3 = Restrictions.between(TmsAppointmentHeaderModel::getAppointmentDate, DateUtil.parseDate(DateUtil.today()), DateUtil.parseDate(DateUtil.today()));
		Restriction r4 = ToolKits.isEmpty(vo.getDriverId()) ? null : Restrictions.eq(TmsAppointmentHeaderModel::getDriverId, vo.getDriverId());
		Restriction r5 = ToolKits.isEmpty(vo.getDriverPhoneNumber()) ? null : Restrictions.eq(TmsAppointmentHeaderModel::getDriverPhoneNumber, vo.getDriverPhoneNumber());
		Restriction r6 = ToolKits.isEmpty(vo.getVehiclePlateNumber()) ? null : Restrictions.eq(TmsAppointmentHeaderModel::getVehiclePlateNumber, vo.getVehiclePlateNumber());
		Restriction r7 = Restrictions.eq(TmsAppointmentHeaderModel::getStatus, DataDictionaryConstant.APPOINTMENT_STATUS_YSH);
		Restriction r8 = ToolKits.isEmpty(vo.getReserveNumber()) ? null : Restrictions.like(TmsAppointmentHeaderModel::getReserveNumber, "%" + vo.getReserveNumber() + "%");
		Restriction r9 = ToolKits.isEmpty(vo.getAppointmentType()) ? null : Restrictions.eq(TmsAppointmentHeaderModel::getAppointmentType, vo.getAppointmentType());
		Restriction r10 = ToolKits.isEmpty(vo.getBranchName()) ? null : Restrictions.like(TmsAppointmentHeaderModel::getBranchName, "%" + vo.getBranchName() + "%");
		Restriction r11 = ToolKits.isEmpty(vo.getDriverName()) ? null : Restrictions.like(TmsAppointmentHeaderModel::getDriverName, "%" + vo.getDriverName() + "%");
		Restriction r12 = Restrictions.isnull(TmsAppointmentHeaderModel::getQueueNumber);
		Restriction r13 = Restrictions.eq(TmsAppointmentHeaderModel::getQueueNumber, "");
		Restriction r14 = Restrictions.or(r12, r13);
		criteria.setRestriction(Restrictions.and(r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r14));
		List<TmsAppointmentHeaderModel> list = tmsAppointmentHeaderMapper.findByCriteria(criteria);

		List<TakeNumberPageDTO> dtos = Lists.newArrayList();
		for (TmsAppointmentHeaderModel model : list) {
			TakeNumberPageDTO dto = new TakeNumberPageDTO();
			BeanUtils.copyProperties(model, dto);
			dto.setAppointmentTypeName(ConvertorUtil.getName(dicData, DataDictionaryConstant.APPOINTMENT_TYPE, String.valueOf(dto.getAppointmentType())));
			dto.setStatusName(ConvertorUtil.getName(dicData, DataDictionaryConstant.APPOINTMENT_STATUS, String.valueOf(dto.getStatus())));

			Criteria loadBillCriteria = Criteria.forClass(TmsAppointmentDetailModel.class);
			Restriction loadBillRestriction = Restrictions.eq(TmsAppointmentDetailModel::getAppointmentId, model.getAppointmentId());
			loadBillCriteria.setRestriction(Restrictions.and(loadBillRestriction));
			List<TmsAppointmentDetailModel> tmsAppointmentDetailModels = tmsAppointmentDetailMapper.findByCriteria(loadBillCriteria);
			//设置预约单的派车单
			dto.setLoadingBillIds(DataUtils.getLoadingBillIds(tmsAppointmentDetailModels));
			// STD-DEVELOP20220908 xiaoyf bug修复bugid【24063】 start
			if (ToolKits.isNotEmpty(vo.getShipbillNo())) {
				// 查询预约单明细
				Criteria criteriaR = Criteria.forClass(TmsAppointmentDetailModel.class);
				Restriction rr1 = Restrictions.eq(TmsAppointmentDetailModel::getAppointmentId, model.getAppointmentId());
				Restriction rr2 = Restrictions.like(TmsAppointmentDetailModel::getShipbillNo, "%" + vo.getShipbillNo() + "%");
				Restriction rr3 = Restrictions.eq(TmsAppointmentDetailModel::getEnterpriseId, user.getEnterpriseId());
				criteriaR.setRestriction(Restrictions.and(rr1, rr2, rr3));
				List<TmsAppointmentDetailModel> tmsAppointmentDetails = tmsAppointmentDetailMapper.findByCriteria(criteriaR);
				if (ToolKits.isNotEmpty(tmsAppointmentDetails)) {
					dtos = Lists.newArrayList();
					dtos.add(dto);

					return dtos;
				}
			} else {
				dtos.add(dto);
			}
			// STD-DEVELOP20220908 xiaoyf bugid【24063】 end
		}
		return dtos;
	}

	/**
	 * 没有预约单时,查询运单列表,现场取号
	 *
	 * @param
	 * @return
	 */
	@Override
	public List<LoadingBillDetailDTO> queryShipbill(TakeNumberQueryVO vo) {
		ToolKits.isParamNull(vo, "请求参数不为空");
		ToolKits.isParamNull(vo.getBranchId(), "仓库ID不为空");

		UserEntity user = PlgFxUsrUtils.getUserEntity();
		ToolKits.isParamNull(user, "当前人员没有操作权限");

		Criteria criteria = Criteria.forClass(TmsLoadingBillDetailModel.class);
		Restriction r1 = Restrictions.eq(TmsLoadingBillDetailModel::getShipperType, DataDictionaryConstant.SHIPPER_TYPE_CK);
		Restriction r2 = Restrictions.eq(TmsLoadingBillDetailModel::getShipperId, vo.getBranchId());
		Restriction r3 = Restrictions.eq(TmsLoadingBillDetailModel::getEnterpriseId, user.getEnterpriseId());
		Restriction r4 = Restrictions.eq(TmsLoadingBillDetailModel::getStatus, DataDictionaryConstant.SHIPBILL_STATUS_PENDING_APP);
		Restriction r5 = Restrictions.eq(TmsLoadingBillDetailModel::getShipbillNo, vo.getShipbillNo());
		criteria.setRestriction(Restrictions.and(r1, r2, r3, r4, r5));
		List<TmsLoadingBillDetailModel> list = tmsLoadingBillDetailMapper.findByCriteria(criteria);

		List<LoadingBillDetailDTO> shipbillList = Lists.newArrayList();
		for (TmsLoadingBillDetailModel model : list) {
			if (ToolKits.isNotEmpty(model.getEstimatedPickupStartTime()) && ObjectUtil.notEqual(sdf.format(new Date()), sdf.format(model.getEstimatedPickupStartTime()))) {
				continue;
			}
			// 通过装车单明细查询装车单汇总
			TmsLoadingBillHeaderModel tmsLoadingBillHeader = tmsLoadingBillHeaderMapper.findById(model.getLoadingBillId(), TmsLoadingBillHeaderModel.class);
			if (ToolKits.isNotEmpty(tmsLoadingBillHeader)) {
				if (ToolKits.isNotEmpty(tmsLoadingBillHeader.getDriverId()) && ToolKits.isNotEmpty(tmsLoadingBillHeader.getDriverPhoneNumber()) && ToolKits.isNotEmpty(tmsLoadingBillHeader.getVehiclePlateNumber())) {
					if (ObjectUtil.equal(vo.getDriverId(), tmsLoadingBillHeader.getDriverId()) && ObjectUtil.equal(vo.getDriverPhoneNumber(), tmsLoadingBillHeader.getDriverPhoneNumber()) && ObjectUtil.equal(vo.getVehiclePlateNumber(), tmsLoadingBillHeader.getVehiclePlateNumber())) {
						LoadingBillDetailDTO dto = new LoadingBillDetailDTO();
						BeanUtils.copyProperties(model, dto);
						shipbillList.add(dto);
					}
				}
			}

		}
		return shipbillList;
	}

	/**
	 * 按预约单取号
	 *
	 * @param
	 * @return
	 */
	@Override
	public String takeNumberByAppoint(TakeNumberByAppointVO vo) throws Exception {
		UserEntity user = PlgFxUsrUtils.getUserEntity();
		ToolKits.isParamNull(user, "当前人员没有操作权限");
		ToolKits.isParamNull(vo.getIds(), "请选择预约单");

		// 查询仓库信息
		RestMessage<TmsBaseBranchDTO> msg = maindataFeign.getOneBranch(vo.getBranchId());
		if (!msg.isSuccess()) {
			throw new PrologException("仓库查询接口调用失败：" + msg.getMessage());
		}
		ToolKits.isParamNull(msg.getData(), "仓库ID【" + vo.getBranchId() + "】不存在");
		// 仓库叫号处理方式
		Integer callMethod = msg.getData().getCallHandleType();
		ToolKits.isParamNull(msg.getData().getApTimeDTOList(), "仓库ID【" + vo.getBranchId() + "】未维护可预约时间段");

		// 判断仓库是否存在提货等待的车位
		RestMessage<List<TmsBaseCarportDTO>> restMessage = maindataFeign.queryCarportList(vo.getBranchId());
		if (!restMessage.isSuccess()) {
			throw new PrologException("仓库车位查询接口调用失败：" + restMessage.getMessage());
		}
		List<TmsBaseCarportDTO> filterList = Optional.ofNullable(restMessage.getData()).orElse(new ArrayList<>()).stream().filter(dto -> ObjectUtil.equal(dto.getType(), DataDictionaryConstant.CARPORT_TYPE_THDDQ)).collect(Collectors.toList());
		// 提货等待区车位数
		int count1 = filterList.size();

		// 当前时间
		Date date = DateUtil.date();

		for (String id : vo.getIds()) {
			// 预约号
			StringBuffer number = new StringBuffer();

			TmsAppointmentHeaderModel tmsAppointmentHeader = tmsAppointmentHeaderMapper.findById(id, TmsAppointmentHeaderModel.class);
			if (ToolKits.isNotEmpty(tmsAppointmentHeader)) {
				if (ToolKits.isNotEmpty(tmsAppointmentHeader.getQueueNumber())) {
					throw new PrologException("当前预约单已取号,无需重复取号!");
				}

				if (count1 == 0) {
					// 不存在提货等待的车位
					tmsAppointmentHeader.setStatus(DataDictionaryConstant.APPOINTMENT_STATUS_YQH);
				} else {
					// 存在 类型为【提货等待区】的仓库车位
					// 查询预约单中,当前仓库下,预约日期为今天,预约单状态为【等待中】的预约单记录条数
					Criteria criteria = Criteria.forClass(TmsAppointmentHeaderModel.class);
					Restriction r1 = Restrictions.eq(TmsAppointmentHeaderModel::getEnterpriseId, user.getEnterpriseId());
					Restriction r2 = Restrictions.eq(TmsAppointmentHeaderModel::getBranchId, vo.getBranchId());
					Restriction r3 = Restrictions.between(TmsAppointmentHeaderModel::getAppointmentDate, DateUtil.parseDate(DateUtil.today()), DateUtil.parseDate(DateUtil.today()));
					Restriction r4 = Restrictions.eq(TmsAppointmentHeaderModel::getStatus, DataDictionaryConstant.APPOINTMENT_STATUS_DDZ);
					criteria.setRestriction(Restrictions.and(r1, r2, r3, r4));
					List<TmsAppointmentHeaderModel> list = tmsAppointmentHeaderMapper.findByCriteria(criteria);
					// 等待区已使用车位数
					int count2 = ToolKits.isEmpty(list) ? 0 : list.size();
					if (count1 - count2 > 0) {
						// 当前仓库下还存在可用的空闲车位,更新当前预约单状态为【等待中】
						tmsAppointmentHeader.setStatus(DataDictionaryConstant.APPOINTMENT_STATUS_DDZ);
					} else {
						// 当前仓库下没有可用的空闲车位,更新当前预约单状态为【已取号】
						tmsAppointmentHeader.setStatus(DataDictionaryConstant.APPOINTMENT_STATUS_YQH);
					}
				}

				if (ToolKits.isNotEmpty(tmsAppointmentHeader.getAppointmentTime()) && tmsAppointmentHeader.getAppointmentTime().indexOf("-") != -1) {
					// 获取结束时间段
					String endTime = tmsAppointmentHeader.getAppointmentTime().split("-")[1];
					// 获取结束时间段中的小时部分
					String endhour = endTime.split(":")[0];

					// 获取开始时间段
					String startTime = tmsAppointmentHeader.getAppointmentTime().split("-")[0];
					// 获取开始时间段中的小时部分
					String startHour = startTime.split(":")[0];

					// 当前小时
					int hourNow = DateUtil.thisHour(true);

					// 判断当前时间是否在 当前预约单的 预约时间段内
					if (hourNow < Integer.parseInt(endhour)) {
						Criteria criteriaR = Criteria.forClass(TmsAppointmentHeaderModel.class);
						Restriction rr1 = Restrictions.eq(TmsAppointmentHeaderModel::getEnterpriseId, user.getEnterpriseId());
						Restriction rr2 = Restrictions.eq(TmsAppointmentHeaderModel::getBranchId, vo.getBranchId());
						Restriction rr3 = Restrictions.between(TmsAppointmentHeaderModel::getAppointmentDate, DateUtil.parseDate(DateUtil.today()), DateUtil.parseDate(DateUtil.today()));
						Restriction rr4 = Restrictions.eq(TmsAppointmentHeaderModel::getAppointmentTime, tmsAppointmentHeader.getAppointmentTime());
						Restriction rr5 = Restrictions.eq(TmsAppointmentHeaderModel::getAppointmentType, DataDictionaryConstant.APPOINTMENT_TYPE_TH);
						Restriction rr6 = Restrictions.isNotNull(TmsAppointmentHeaderModel::getQueueNumber);
						Restriction rr7 = Restrictions.isNotNull(TmsAppointmentHeaderModel::getQueueNumberTime);
						// 判断当前预约单是否包含紧急加急运单
						if (tmsAppointmentHeader.getUrgentQuantity() > 0) {
							number = new StringBuffer("急");

							Restriction rr8 = Restrictions.gt(TmsAppointmentHeaderModel::getUrgentQuantity, 0);
							criteriaR.setRestriction(Restrictions.and(rr1, rr2, rr3, rr4, rr5, rr6, rr7, rr8));
							List<TmsAppointmentHeaderModel> orderList = tmsAppointmentHeaderMapper.findByCriteria(criteriaR);

							// 获取最大排队号+1作为当前预约单的排队号，最大排队号为空从001开始
							if (ToolKits.isNotEmpty(orderList) && orderList.size() > 0) {
								// 取出所有排队号
								List<String> queueNumberList = orderList.stream().map(TmsAppointmentHeaderModel::getQueueNumber).collect(Collectors.toList());
								// 排队号转换类型
								List<BigDecimal> queueNumbers = queueNumberList.stream().map(s -> new BigDecimal(s.replace("急", ""))).collect(Collectors.toList());
								// 获取最大排队号
								BigDecimal queueNumberMax = queueNumbers.stream().reduce(queueNumbers.get(0), BigDecimal::max);
								// 自增加1生成当前预约单的取号号码
								number.append(queueNumberMax.add(new BigDecimal("1")));
							} else {
								// 生成今天预约单排队号(年月日+预约时间段开始小时数+预约时间段结束小时数+三位自增数)
								number.append(DateUtil.format(date, DatePattern.PURE_DATE_FORMAT)).append(startHour).append(endhour).append("001");
							}

							// 生成叫号顺序
							this.getCallNumber(user, tmsAppointmentHeader, callMethod, true);
						} else {
							Restriction rr8 = Restrictions.eq(TmsAppointmentHeaderModel::getUrgentQuantity, 0);
							criteriaR.setRestriction(Restrictions.and(rr1, rr2, rr3, rr4, rr5, rr6, rr7, rr8));
							List<TmsAppointmentHeaderModel> orderList = tmsAppointmentHeaderMapper.findByCriteria(criteriaR);

							// 获取最大排队号+1作为当前预约单的排队号，最大排队号为空从001开始
							if (ToolKits.isNotEmpty(orderList) && orderList.size() > 0) {
								// 取出所有排队号
								List<String> queueNumberList = orderList.stream().map(TmsAppointmentHeaderModel::getQueueNumber).collect(Collectors.toList());
								// 排队号转换类型
								List<BigDecimal> queueNumbers = queueNumberList.stream().map(s -> new BigDecimal(s)).collect(Collectors.toList());
								// 获取最大排队号
								BigDecimal queueNumberMax = queueNumbers.stream().reduce(queueNumbers.get(0), BigDecimal::max);
								// 自增加1生成当前预约单的取号号码
								number.append(queueNumberMax.add(new BigDecimal("1")));
							} else {
								// 生成今天预约单排队号(年月日+预约时间段开始小时数+预约时间段结束小时数+三位自增数)
								number.append(DateUtil.format(date, DatePattern.PURE_DATE_FORMAT)).append(startHour).append(endhour).append("001");
							}

							// 生成叫号顺序
							this.getCallNumber(user, tmsAppointmentHeader, callMethod, false);
						}
					} else {
						// 当前仓最后可预约时间
						int maxTime = 0;
						// 仓可预约时间段处理
						List<TmsBaseBranchApTimeDTO> tmsBaseBranchApTimeDTOs = msg.getData().getApTimeDTOList();
						for (TmsBaseBranchApTimeDTO tmsBaseBranchApTimeDTO : tmsBaseBranchApTimeDTOs) {
							int endHour = Integer.parseInt(tmsBaseBranchApTimeDTO.getEndTime().split(":")[0]);
							if (endHour > maxTime) {
								maxTime = endHour;
							}
						}
						// 获取开始时间段中的小时部分
						startHour = String.format("%0" + 2 + "d", maxTime);
						// 获取结束时间段中的小时部分
						endhour = String.format("%0" + 2 + "d", maxTime + 1);

						Criteria criteriaR = Criteria.forClass(TmsAppointmentHeaderModel.class);
						Restriction rr1 = Restrictions.eq(TmsAppointmentHeaderModel::getEnterpriseId, user.getEnterpriseId());
						Restriction rr2 = Restrictions.eq(TmsAppointmentHeaderModel::getBranchId, vo.getBranchId());
						Restriction rr3 = Restrictions.between(TmsAppointmentHeaderModel::getAppointmentDate, DateUtil.parseDate(DateUtil.today()), DateUtil.parseDate(DateUtil.today()));
						Restriction rr4 = Restrictions.eq(TmsAppointmentHeaderModel::getAppointmentType, DataDictionaryConstant.APPOINTMENT_TYPE_TH);
						Restriction rr5 = Restrictions.like(TmsAppointmentHeaderModel::getQueueNumber, "%" + startHour + endhour + "%");
						// 判断当前预约单是否包含紧急加急运单
						if (tmsAppointmentHeader.getUrgentQuantity() > 0) {
							// 生成今天预约单排队号(年月日+当前仓库设置的最晚时间段后的一个小时时间段+三位自增数)
							number = new StringBuffer("急");

							Restriction rr6 = Restrictions.gt(TmsAppointmentHeaderModel::getUrgentQuantity, 0);
							criteriaR.setRestriction(Restrictions.and(rr1, rr2, rr3, rr4, rr5, rr6));
							List<TmsAppointmentHeaderModel> orderList = tmsAppointmentHeaderMapper.findByCriteria(criteriaR);

							// 获取最大排队号+1作为当前预约单的排队号，最大排队号为空从001开始
							if (ToolKits.isNotEmpty(orderList) && orderList.size() > 0) {
								// 取出所有排队号
								List<String> queueNumberList = orderList.stream().map(TmsAppointmentHeaderModel::getQueueNumber).collect(Collectors.toList());
								// 排队号转换类型
								List<BigDecimal> queueNumbers = queueNumberList.stream().map(s -> new BigDecimal(s.replace("急", ""))).collect(Collectors.toList());
								// 获取最大排队号
								BigDecimal queueNumberMax = queueNumbers.stream().reduce(queueNumbers.get(0), BigDecimal::max);
								// 自增加1生成当前预约单的取号号码
								number.append(queueNumberMax.add(new BigDecimal("1")));
							} else {
								// 生成今天预约单排队号(年月日+当前仓库设置的最晚时间段后的一个小时时间段+三位自增数)
								number.append(DateUtil.format(date, DatePattern.PURE_DATE_FORMAT)).append(startHour).append(endhour).append("001");
							}

							// 生成叫号顺序
							this.getCallNumber(user, tmsAppointmentHeader, callMethod, true);

						} else {
							Restriction rr6 = Restrictions.eq(TmsAppointmentHeaderModel::getUrgentQuantity, 0);
							criteriaR.setRestriction(Restrictions.and(rr1, rr2, rr3, rr4, rr5, rr6));
							List<TmsAppointmentHeaderModel> orderList = tmsAppointmentHeaderMapper.findByCriteria(criteriaR);

							if (ToolKits.isNotEmpty(orderList) && orderList.size() > 0) {
								// 取出所有排队号
								List<String> queueNumberList = orderList.stream().map(TmsAppointmentHeaderModel::getQueueNumber).collect(Collectors.toList());
								// 排队号转换类型
								List<BigDecimal> queueNumbers = queueNumberList.stream().map(s -> new BigDecimal(s)).collect(Collectors.toList());
								// 获取最大排队号
								BigDecimal queueNumberMax = queueNumbers.stream().reduce(queueNumbers.get(0), BigDecimal::max);
								// 自增加1生成当前预约单的取号号码
								number.append(queueNumberMax.add(new BigDecimal("1")));
							} else {
								// 生成今天预约单排队号(年月日+当前仓库设置的最晚时间段后的一个小时时间段+三位自增数)
								number.append(DateUtil.format(date, DatePattern.PURE_DATE_FORMAT)).append(startHour).append(endhour).append("001");
							}

							// 生成叫号顺序
							this.getCallNumber(user, tmsAppointmentHeader, callMethod, false);
						}
					}
				} else {
					throw new PrologException("预约单【" + tmsAppointmentHeader.getAppointmentNo() + "】预约时间段不能为空或预约时间段数据格式不合法");
				}

				tmsAppointmentHeader.setUpdateperson(user.getNickname());
				tmsAppointmentHeader.setUpdatetime(date);

				if (ToolKits.isEmpty(number)) {
					throw new PrologException("排队号生成失败!");
				}
				tmsAppointmentHeader.setQueueNumber(number.toString());
				tmsAppointmentHeader.setQueueNumberTime(date);
				tmsAppointmentHeader.setCallNumberTime(date);
				tmsAppointmentHeaderMapper.update(tmsAppointmentHeader);
			} else {
				throw new PrologException("预约单查询失败");
			}
			MessageUtil.addMessage(new SendMessageDTO(MessageOrderTypeEnum.APPOINTMENT_NO.getCode(), MessageTypeEnum.TAKE_NUMBER.getCode(), Lists.newArrayList(id)));
			return number.toString();
		}

		return null;
	}

	/**
	 * 获取叫号顺序
	 * 
	 * @param user                 用户对象
	 * @param tmsAppointmentHeader 预约单对象
	 * @param callMethod           取号方式
	 * @param urgent               是否急单
	 */
	public void getCallNumber(UserEntity user, TmsAppointmentHeaderModel tmsAppointmentHeader, Integer callMethod, boolean urgent) {
		// 查询预约单
		Criteria criteria = Criteria.forClass(TmsAppointmentHeaderModel.class);
		Restriction r1 = Restrictions.eq(TmsAppointmentHeaderModel::getEnterpriseId, user.getEnterpriseId());
		Restriction r2 = Restrictions.eq(TmsAppointmentHeaderModel::getBranchId, tmsAppointmentHeader.getBranchId());
		Restriction r3 = Restrictions.between(TmsAppointmentHeaderModel::getAppointmentDate, DateUtil.parseDate(DateUtil.today()), DateUtil.parseDate(DateUtil.today()));
		Restriction r4 = Restrictions.isNotNull(TmsAppointmentHeaderModel::getQueueNumber);
		Restriction r5 = Restrictions.in(TmsAppointmentHeaderModel::getStatus, new Integer[] { DataDictionaryConstant.APPOINTMENT_STATUS_YQH, DataDictionaryConstant.APPOINTMENT_STATUS_DDZ });
		criteria.setRestriction(Restrictions.and(r1, r2, r3, r4, r5));
		List<TmsAppointmentHeaderModel> tmsAppointmentHeaderModels = tmsAppointmentHeaderMapper.findByCriteria(criteria);

		// 按排队号叫号
		if (ObjectUtil.equal(callMethod, DataDictionaryConstant.CALL_HANDLE_TYPE_NUMBER)) {
			if (urgent) {
				// 紧急预约单处理
				if (ToolKits.isNotEmpty(tmsAppointmentHeaderModels)) {
					// 筛选紧急的预约单
					List<TmsAppointmentHeaderModel> urgentAppointmenList = tmsAppointmentHeaderModels.stream().filter(s -> s.getUrgentQuantity().intValue() > 0).collect(Collectors.toList());
					if (ToolKits.isNotEmpty(urgentAppointmenList)) {
						// 取出所有排队号
						List<String> callNumberList = urgentAppointmenList.stream().map(TmsAppointmentHeaderModel::getCallNumber).collect(Collectors.toList());
						// 排队号转换类型
						List<BigDecimal> callNumbers = callNumberList.stream().map(s -> new BigDecimal(s)).collect(Collectors.toList());
						// 获取最大排队号
						BigDecimal callNumber = callNumbers.stream().reduce(callNumbers.get(0), BigDecimal::max);
						// 排队号加1
						tmsAppointmentHeader.setCallNumber(String.valueOf(callNumber.add(new BigDecimal("1"))));
					} else {
						// 排队号初始值
						tmsAppointmentHeader.setCallNumber(String.valueOf(BussinessConstant.CALL_NUMBER));
					}

					// 筛选非紧急的预约单
					List<TmsAppointmentHeaderModel> notUrgentAppointmenList = tmsAppointmentHeaderModels.stream().filter(s -> s.getUrgentQuantity().intValue() == 0).collect(Collectors.toList());
					for (TmsAppointmentHeaderModel notUrgentAppointmen : notUrgentAppointmenList) {
						// 叫号顺序顺延1
						notUrgentAppointmen.setCallNumber(((new BigDecimal(notUrgentAppointmen.getCallNumber())).add(new BigDecimal("1"))).toString());
						tmsAppointmentHeaderMapper.update(notUrgentAppointmen);
					}
				} else {
					// 排队号初始值
					tmsAppointmentHeader.setCallNumber(String.valueOf(BussinessConstant.CALL_NUMBER));
				}
			} else {
				// 非紧急预约单处理
				if (ToolKits.isNotEmpty(tmsAppointmentHeaderModels)) {
					// 取出所有排队号
					List<String> callNumberList = tmsAppointmentHeaderModels.stream().map(TmsAppointmentHeaderModel::getCallNumber).collect(Collectors.toList());
					// 排队号转换类型
					List<BigDecimal> callNumbers = callNumberList.stream().map(s -> new BigDecimal(s)).collect(Collectors.toList());
					// 获取最大排队号
					BigDecimal callNumber = callNumbers.stream().reduce(callNumbers.get(0), BigDecimal::max);
					// 排队号加1
					tmsAppointmentHeader.setCallNumber(String.valueOf(callNumber.add(new BigDecimal("1"))));
				} else {
					// 排队号初始值
					tmsAppointmentHeader.setCallNumber(String.valueOf(BussinessConstant.CALL_NUMBER));
				}
			}
		} else if (ObjectUtil.equal(callMethod, DataDictionaryConstant.CALL_HANDLE_TYPE_WAITINGAREA)) {
			// 紧急预约单处理
			if (urgent) {
				// 判断当前预约单是否等待中
				if (ObjectUtil.equal(tmsAppointmentHeader.getStatus(), DataDictionaryConstant.APPOINTMENT_STATUS_DDZ)) {
					if (ToolKits.isNotEmpty(tmsAppointmentHeaderModels)) {
						// TODO
						// 筛选紧急且为等待中的预约单
						List<TmsAppointmentHeaderModel> urgentAndDdzAppointmenList = tmsAppointmentHeaderModels.stream().filter(s -> s.getUrgentQuantity().intValue() > 0 && s.getStatus().intValue() == DataDictionaryConstant.APPOINTMENT_STATUS_DDZ.intValue()).collect(Collectors.toList());
						if (ToolKits.isNotEmpty(urgentAndDdzAppointmenList)) {
							// 取出所有排队号
							List<String> callNumberList = urgentAndDdzAppointmenList.stream().map(TmsAppointmentHeaderModel::getCallNumber).collect(Collectors.toList());
							// 排队号转换类型
							List<BigDecimal> callNumbers = callNumberList.stream().map(s -> new BigDecimal(s)).collect(Collectors.toList());
							// 获取最大排队号
							BigDecimal callNumber = callNumbers.stream().reduce(callNumbers.get(0), BigDecimal::max);
							// 排队号加1
							tmsAppointmentHeader.setCallNumber(String.valueOf(callNumber.add(new BigDecimal("1"))));

							// 其余的预约单叫号顺序顺延一位
							List<TmsAppointmentHeaderModel> otherAppointmenList = tmsAppointmentHeaderModels.stream().filter(s -> new BigDecimal(s.getCallNumber()).compareTo(callNumber) > 0).collect(Collectors.toList());
							for (TmsAppointmentHeaderModel otherAppointmen : otherAppointmenList) {
								// 叫号顺序顺延1
								otherAppointmen.setCallNumber(((new BigDecimal(otherAppointmen.getCallNumber())).add(new BigDecimal("1"))).toString());
								tmsAppointmentHeaderMapper.update(otherAppointmen);
							}
						} else {
							// 排队号初始值
							tmsAppointmentHeader.setCallNumber(String.valueOf(BussinessConstant.CALL_NUMBER));

							// 其余的预约单叫号顺序顺延一位
							for (TmsAppointmentHeaderModel tmsAppointmentHeaderModel : tmsAppointmentHeaderModels) {
								// 叫号顺序顺延1
								tmsAppointmentHeaderModel.setCallNumber(((new BigDecimal(tmsAppointmentHeaderModel.getCallNumber())).add(new BigDecimal("1"))).toString());
								tmsAppointmentHeaderMapper.update(tmsAppointmentHeaderModel);
							}
						}
					} else {
						// 排队号初始值
						tmsAppointmentHeader.setCallNumber(String.valueOf(BussinessConstant.CALL_NUMBER));
					}
				} else {
					// 当前预约单非等待中状态处理
					if (ToolKits.isNotEmpty(tmsAppointmentHeaderModels)) {
						// 判断是否有等待中的预约单
						List<TmsAppointmentHeaderModel> ddzAppointmenList = tmsAppointmentHeaderModels.stream().filter(s -> s.getStatus().intValue() == DataDictionaryConstant.APPOINTMENT_STATUS_DDZ.intValue()).collect(Collectors.toList());
						if (ToolKits.isNotEmpty(ddzAppointmenList)) {
							// 取出所有叫号顺序
							List<String> callNumberList = ddzAppointmenList.stream().map(TmsAppointmentHeaderModel::getCallNumber).collect(Collectors.toList());
							// 叫号顺序转换类型
							List<BigDecimal> callNumbers = callNumberList.stream().map(s -> new BigDecimal(s)).collect(Collectors.toList());
							// 获取等待区最大叫号顺序
							BigDecimal callNumber = callNumbers.stream().reduce(callNumbers.get(0), BigDecimal::max);

							// 判断等待区最后一位是否紧急预约单(即最大叫号顺序对应的预约单)
							TmsAppointmentHeaderModel endDdqAppointment = ddzAppointmenList.stream().filter(s -> s.getCallNumber().equals(callNumber.toString())).findAny().orElse(null);
							// 最后一位是紧急预约单
							if (endDdqAppointment.getUrgentQuantity().intValue() > 0) {
								// 非等待区叫号重新排序
								List<TmsAppointmentHeaderModel> fddzAppointmenList = tmsAppointmentHeaderModels.stream().filter(s -> s.getStatus().intValue() != DataDictionaryConstant.APPOINTMENT_STATUS_DDZ.intValue()).collect(Collectors.toList());
								// 非等待区是否存在预约单
								if (ToolKits.isNotEmpty(fddzAppointmenList)) {
									// 非等待区是否有紧急预约单
									List<TmsAppointmentHeaderModel> urgentAppointmenList = fddzAppointmenList.stream().filter(s -> s.getUrgentQuantity().intValue() > 0).collect(Collectors.toList());
									// 非等待区存在紧急预约单
									if (ToolKits.isNotEmpty(urgentAppointmenList)) {
										// 取出所有排队号
										List<String> callNumberList1 = urgentAppointmenList.stream().map(TmsAppointmentHeaderModel::getCallNumber).collect(Collectors.toList());
										// 排队号转换类型
										List<BigDecimal> callNumbers1 = callNumberList1.stream().map(s -> new BigDecimal(s)).collect(Collectors.toList());
										// 获取最大排队号
										BigDecimal callNumber1 = callNumbers1.stream().reduce(callNumbers1.get(0), BigDecimal::max);
										// 排队号加1
										tmsAppointmentHeader.setCallNumber(String.valueOf(callNumber1.add(new BigDecimal("1"))));

										// 其他预约单叫号顺序顺延1
										List<TmsAppointmentHeaderModel> otherAppointmenList = fddzAppointmenList.stream().filter(s -> new BigDecimal(s.getCallNumber()).compareTo(callNumber1) > 0).collect(Collectors.toList());
										for (TmsAppointmentHeaderModel otherAppointmen : otherAppointmenList) {
											// 叫号顺序顺延1
											otherAppointmen.setCallNumber(((new BigDecimal(otherAppointmen.getCallNumber())).add(new BigDecimal("1"))).toString());
											tmsAppointmentHeaderMapper.update(otherAppointmen);
										}
									} else {
										// 非等待区没有紧急预约单
										tmsAppointmentHeader.setCallNumber(String.valueOf(callNumber.add(new BigDecimal("1"))));

										// 非等待区预约单叫号顺序顺延1
										for (TmsAppointmentHeaderModel tmsAppointmentHeaderModel : fddzAppointmenList) {
											tmsAppointmentHeaderModel.setCallNumber(((new BigDecimal(tmsAppointmentHeaderModel.getCallNumber())).add(new BigDecimal("1"))).toString());
											tmsAppointmentHeaderMapper.update(tmsAppointmentHeaderModel);
										}
									}
								} else {
									// 非等待区没有紧急预约单
									tmsAppointmentHeader.setCallNumber(String.valueOf(callNumber.add(new BigDecimal("1"))));
								}
							} else {
								// 最后一位非紧急预约单
								// 等待区中是否存在紧急预约单
								List<TmsAppointmentHeaderModel> urgentAppointmenList = ddzAppointmenList.stream().filter(s -> s.getUrgentQuantity().intValue() > 0).collect(Collectors.toList());
								// 等待区中存在紧急预约单
								if (ToolKits.isNotEmpty(urgentAppointmenList)) {
									// 取出所有排队号
									List<String> callNumberList1 = urgentAppointmenList.stream().map(TmsAppointmentHeaderModel::getCallNumber).collect(Collectors.toList());
									// 排队号转换类型
									List<BigDecimal> callNumbers1 = callNumberList1.stream().map(s -> new BigDecimal(s)).collect(Collectors.toList());
									// 获取最大排队号
									BigDecimal callNumber1 = callNumbers1.stream().reduce(callNumbers1.get(0), BigDecimal::max);
									// 排队号加1
									tmsAppointmentHeader.setCallNumber(String.valueOf(callNumber1.add(new BigDecimal("1"))));
									tmsAppointmentHeader.setStatus(DataDictionaryConstant.APPOINTMENT_STATUS_DDZ);

									// 其他预约单叫号顺序顺延1
									List<TmsAppointmentHeaderModel> otherAppointmenList = tmsAppointmentHeaderModels.stream().filter(s -> new BigDecimal(s.getCallNumber()).compareTo(callNumber1) > 0).collect(Collectors.toList());
									for (TmsAppointmentHeaderModel otherAppointmen : otherAppointmenList) {
										if (otherAppointmen.getCallNumber().equals(callNumber.toString())) {
											otherAppointmen.setStatus(DataDictionaryConstant.APPOINTMENT_STATUS_YQH);
										}

										// 叫号顺序顺延1
										otherAppointmen.setCallNumber(((new BigDecimal(otherAppointmen.getCallNumber())).add(new BigDecimal("1"))).toString());
										tmsAppointmentHeaderMapper.update(otherAppointmen);
									}
								} else {
									tmsAppointmentHeader.setCallNumber(String.valueOf(BussinessConstant.CALL_NUMBER));
									tmsAppointmentHeader.setStatus(DataDictionaryConstant.APPOINTMENT_STATUS_DDZ);

									// 其他预约单顺延1位
									for (TmsAppointmentHeaderModel tmsAppointmentHeaderModel : tmsAppointmentHeaderModels) {
										if (tmsAppointmentHeaderModel.getCallNumber().equals(callNumber.toString())) {
											tmsAppointmentHeaderModel.setStatus(DataDictionaryConstant.APPOINTMENT_STATUS_YQH);
										}
										tmsAppointmentHeaderModel.setCallNumber(((new BigDecimal(tmsAppointmentHeaderModel.getCallNumber())).add(new BigDecimal("1"))).toString());
										tmsAppointmentHeaderMapper.update(tmsAppointmentHeaderModel);
									}
								}
							}
						} else {
							// 判断是否存在紧急的预约单
							List<TmsAppointmentHeaderModel> urgentAppointmenList = tmsAppointmentHeaderModels.stream().filter(s -> s.getUrgentQuantity().intValue() > 0).collect(Collectors.toList());
							if (ToolKits.isNotEmpty(urgentAppointmenList)) {
								// 取出所有排队号
								List<String> callNumberList = urgentAppointmenList.stream().map(TmsAppointmentHeaderModel::getCallNumber).collect(Collectors.toList());
								// 排队号转换类型
								List<BigDecimal> callNumbers = callNumberList.stream().map(s -> new BigDecimal(s)).collect(Collectors.toList());
								// 获取最大排队号
								BigDecimal callNumber = callNumbers.stream().reduce(callNumbers.get(0), BigDecimal::max);
								// 排队号加1
								tmsAppointmentHeader.setCallNumber(String.valueOf(callNumber.add(new BigDecimal("1"))));

								// 其他预约单叫号顺序顺延1
								List<TmsAppointmentHeaderModel> otherAppointmenList = tmsAppointmentHeaderModels.stream().filter(s -> new BigDecimal(s.getCallNumber()).compareTo(callNumber) > 0).collect(Collectors.toList());
								for (TmsAppointmentHeaderModel otherAppointmen : otherAppointmenList) {
									// 叫号顺序顺延1
									otherAppointmen.setCallNumber(((new BigDecimal(otherAppointmen.getCallNumber())).add(new BigDecimal("1"))).toString());
									tmsAppointmentHeaderMapper.update(otherAppointmen);
								}
							} else {
								// 排队号初始值
								tmsAppointmentHeader.setCallNumber(String.valueOf(BussinessConstant.CALL_NUMBER));
								// 其他预约单叫号顺序顺延1
								for (TmsAppointmentHeaderModel tmsAppointmentHeaderModel : tmsAppointmentHeaderModels) {
									tmsAppointmentHeaderModel.setCallNumber(((new BigDecimal(tmsAppointmentHeaderModel.getCallNumber())).add(new BigDecimal("1"))).toString());
									tmsAppointmentHeaderMapper.update(tmsAppointmentHeaderModel);
								}
							}
						}
					} else {
						// 排队号初始值
						tmsAppointmentHeader.setCallNumber(String.valueOf(BussinessConstant.CALL_NUMBER));
					}
				}
			} else {
				// 非紧急预约单处理
				if (ToolKits.isNotEmpty(tmsAppointmentHeaderModels)) {
					// 取出所有排队号
					List<String> callNumberList = tmsAppointmentHeaderModels.stream().map(TmsAppointmentHeaderModel::getCallNumber).collect(Collectors.toList());
					// 排队号转换类型
					List<BigDecimal> callNumbers = callNumberList.stream().map(s -> new BigDecimal(s)).collect(Collectors.toList());
					// 获取最大排队号
					BigDecimal callNumber = callNumbers.stream().reduce(callNumbers.get(0), BigDecimal::max);
					// 排队号加1
					tmsAppointmentHeader.setCallNumber(String.valueOf(callNumber.add(new BigDecimal("1"))));
				} else {
					// 排队号初始值
					tmsAppointmentHeader.setCallNumber(String.valueOf(BussinessConstant.CALL_NUMBER));
				}
			}
		} else {
			throw new PrologException("叫号方式【" + callMethod + "】错误");
		}
	}

	/**
	 * 按运单取号
	 *
	 * @param
	 * @return
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public String takeNumberByShipbill(TakeNumberByShipbillVO vo) throws Exception {
		ToolKits.isParamNull(vo, "取号请求参数不为空");
		ToolKits.isParamNull(vo.getIds(), "请选择需要取号的运单");

		UserEntity user = PlgFxUsrUtils.getUserEntity();
		ToolKits.isParamNull(user, "当前人员没有操作权限");

		List<TmsLoadingBillDetailModel> loadingBillDetailModels = tmsLoadingBillDetailMapper.findByIds(TmsLoadingBillDetailModel.class, vo.getIds().stream().toArray(),null);
		if (ToolKits.isEmpty(loadingBillDetailModels)) {
			throw new PrologException("派车单明细不存在");
		}
		List<TmsLoadingBillDetailModel> noTakeAndCallShipbillHeaderModels = loadingBillDetailModels.stream()
																								   .filter(h->!h.getFlowConfig()
																												.contains(DataDictionaryConstant.FLOW_CONFIG_APPOINTMENT_TN_CN))
																								   .collect(Collectors.toList());
		if (ToolKits.isNotEmpty(noTakeAndCallShipbillHeaderModels) && noTakeAndCallShipbillHeaderModels.size() != vo.getIds().size()) {
			throw new PrologException("请勾选相同预约流程的运单");
		}
		List<TmsLoadingBillDetailModel> hasTakeAndCallShipbillHeaderModels = loadingBillDetailModels.stream().filter(h->h.getFlowConfig()
																														 .contains(DataDictionaryConstant.FLOW_CONFIG_APPOINTMENT_TN_CN))
																									.collect(Collectors.toList());
		if (ToolKits.isNotEmpty(hasTakeAndCallShipbillHeaderModels) && hasTakeAndCallShipbillHeaderModels.size() != vo.getIds().size()) {
			throw new PrologException("请勾选相同预约流程的运单");
		}

		Criteria appointCriteria = Criteria.forClass(TmsAppointmentDetailModel.class);
		Restriction appointRestriction = Restrictions.in(TmsAppointmentDetailModel::getShipbillId,
				loadingBillDetailModels.stream()
									   .map(TmsLoadingBillDetailModel::getShipbillId)
									   .distinct().collect(Collectors.toList()));
		appointCriteria.setRestriction(Restrictions.and(appointRestriction));
		List<TmsAppointmentDetailModel> tmsAppointmentDetailModelList = tmsAppointmentDetailMapper.findByCriteria(appointCriteria);
		if (CollectionUtil.isNotEmpty(tmsAppointmentDetailModelList)) {
			List<TmsAppointmentHeaderModel> appointmentModelList = tmsAppointmentHeaderMapper.findByIds(
					TmsAppointmentHeaderModel.class, tmsAppointmentDetailModelList.stream().map(
							TmsAppointmentDetailModel::getAppointmentId).distinct().collect(Collectors.toList()).toArray(), null);
			if (!appointmentModelList.stream().allMatch(headerModel -> DataDictionaryConstant.APPOINTMENT_STATUS_QX.equals(headerModel.getStatus()))) {
				throw new BizException("运单重复取号");
			}
		}

		// 查询仓库信息
		RestMessage<TmsBaseBranchDTO> restMessage1 = maindataFeign.getOneBranch(vo.getBranchId());
		if (!restMessage1.isSuccess()) {
			throw new PrologException("仓库查询接口调用失败：" + restMessage1.getMessage());
		}
		ToolKits.isParamNull(restMessage1.getData(), "仓库ID【" + vo.getBranchId() + "】不存在");
		// 仓库叫号处理方式
		Integer callMethod = restMessage1.getData().getCallHandleType();
		ToolKits.isParamNull(restMessage1.getData().getApTimeDTOList(), "仓库ID【" + vo.getBranchId() + "】未维护可预约时间段");
		// 最后可预约时间小时部分
		Integer hour = 0;
		// 最后可预约时间分钟部分
		String minute = "00";
		// 仓可预约时间段处理
		List<TmsBaseBranchApTimeDTO> tmsBaseBranchApTimeDTOs = restMessage1.getData().getApTimeDTOList();
		for (TmsBaseBranchApTimeDTO tmsBaseBranchApTimeDTO : tmsBaseBranchApTimeDTOs) {
			Integer endHour = Integer.parseInt(tmsBaseBranchApTimeDTO.getEndTime().split(":")[0]);
			if (endHour > hour) {
				hour = endHour;
				minute = tmsBaseBranchApTimeDTO.getEndTime().split(":")[1];
			}
		}

		// 预约时间段开始小时
		String startHour = String.format("%0" + 2 + "d", hour);
		// 预约时间段结束小时
		String endhour = String.format("%0" + 2 + "d", hour + 1);

		// 当前时间
		Date date = DateUtil.date();

		// 获取预约单ID
		RestMessage<String> restMessageId = maindataFeign.getCodeNumberByCode(SeriaNnumberConstant.TMS_APPOINTMENT_HEADER_ID, "L");
		if (!restMessageId.isSuccess()) {
			throw new PrologException("生成预约主表ID失败");
		}

		TmsAppointmentHeaderModel tmsAppointmentHeader = new TmsAppointmentHeaderModel();
		tmsAppointmentHeader.setAppointmentId(restMessageId.getData());
		tmsAppointmentHeader.setAppointmentNo(restMessageId.getData());
		tmsAppointmentHeader.setAppointmentType(DataDictionaryConstant.APPOINTMENT_TYPE_TH);
		tmsAppointmentHeader.setBranchId(vo.getBranchId());
		tmsAppointmentHeader.setBranchCode(vo.getBranchCode());
		tmsAppointmentHeader.setBranchName(vo.getBranchName());
		tmsAppointmentHeader.setBranchAddress(vo.getBranchAddress());
		tmsAppointmentHeader.setAppointmentDate(DateUtil.parseDate(DateUtil.today()));
		tmsAppointmentHeader.setAppointmentTime(startHour + ":" + minute + "-" + endhour + ":" + minute);
		tmsAppointmentHeader.setReserveNumberTime(date);
		tmsAppointmentHeader.setCallNumberTime(date);
		tmsAppointmentHeader.setQueueNumberTime(date);
		tmsAppointmentHeader.setDriverId(vo.getDriverId());
		tmsAppointmentHeader.setDriverCode(vo.getDriverCode());
		tmsAppointmentHeader.setDriverName(vo.getDriverName());
		tmsAppointmentHeader.setDriverPhoneNumber(vo.getDriverPhoneNumber());
		tmsAppointmentHeader.setVehiclePlateNumber(vo.getVehiclePlateNumber());

		// 获取明细ID
		RestMessage<List<String>> restMessage = maindataFeign.getCodeNumberByCodes(SeriaNnumberConstant.TMS_APPOINTMENT_DETAIL_ID, "L", vo.getIds().size());
		if (!restMessage.isSuccess()) {
			throw new PrologException("批量生成预约单明细ID失败:" + restMessage.getMessage());
		}

		// 是否理货完成标识
		Boolean tallyStatus = false;
		Boolean hasTakeNumAndCallNum = false;
		Boolean hasLoading = false;
		// 紧急运单数
		Integer urgentQuantity = 0;
		BigDecimal totPcs = BigDecimal.valueOf(0);
		BigDecimal totVolume = BigDecimal.valueOf(0);
		BigDecimal totWeight = BigDecimal.valueOf(0);
		for (int i = 0; i < vo.getIds().size(); i++) {
			// 装车单明细ID
			String id = vo.getIds().get(i);
			// 查下装车单明细
			TmsLoadingBillDetailModel tmsLoadingBillDetail = tmsLoadingBillDetailMapper.findById(id, TmsLoadingBillDetailModel.class);
			ToolKits.isParamNull(tmsLoadingBillDetail, "明细ID【" + id + "】不存在");

			if (ToolKits.isNotEmpty(tmsLoadingBillDetail.getFlowConfig())
					&& tmsLoadingBillDetail.getFlowConfig().contains(DataDictionaryConstant.FLOW_CONFIG_APPOINTMENT_TN_CN)) {
				hasTakeNumAndCallNum = true;
			}

			int nextStatus = DataDictionaryConstant.SHIPBILL_STATUS_APP_ING;
			if (ToolKits.isNotEmpty(tmsLoadingBillDetail.getFlowConfig()) && tmsLoadingBillDetail.getFlowConfig().contains(DataDictionaryConstant.FLOW_CONFIG_ARRANGE_GOODS)) {
				tallyStatus = true;
				nextStatus = DataDictionaryConstant.SHIPBILL_STATUS_LH_START;
			}
			if (ToolKits.isNotEmpty(tmsLoadingBillDetail.getFlowConfig()) && tmsLoadingBillDetail.getFlowConfig().contains(DataDictionaryConstant.FLOW_CONFIG_LOAD_UNLOAD)) {
				hasLoading = true;
			}
			int flowStatus = businessFlowUtil.judgmentNextFlowSts(tmsLoadingBillDetail.getFlowConfig(), DataDictionaryConstant.FLOW_CONFIG_APPOINTMENT);
			if (hasTakeNumAndCallNum &&
					NumberUtil.isGreater(BigDecimal.valueOf(flowStatus),BigDecimal.valueOf(DataDictionaryConstant.SHIPBILL_STATUS_ZX_START))) {
				nextStatus = flowStatus;
			} else if (!hasTakeNumAndCallNum ) {
				nextStatus = flowStatus;
			}
			// 生成预约明细
			TmsAppointmentDetailModel tmsAppointmentDetail = new TmsAppointmentDetailModel();
			BeanUtils.copyProperties(tmsLoadingBillDetail, tmsAppointmentDetail);
			tmsAppointmentDetail.setId(restMessage.getData().get(i));
			tmsAppointmentDetail.setAppointmentId(tmsAppointmentHeader.getAppointmentId());
			tmsAppointmentDetail.setAppointmentNo(tmsAppointmentHeader.getAppointmentNo());
			tmsAppointmentDetail.setCreatetime(date);
			tmsAppointmentDetail.setCreateperson(user.getNickname());
			tmsAppointmentDetail.setUpdatetime(date);
			tmsAppointmentDetail.setUpdateperson(user.getNickname());
			tmsAppointmentDetail.setEnterpriseId(user.getEnterpriseId());
			tmsAppointmentDetail.setEnterpriseName(user.getEnterpriseName());
			tmsAppointmentDetail.setStatus(nextStatus);
			tmsAppointmentDetail.setLoadingBillId(tmsLoadingBillDetail.getLoadingBillId());
			tmsAppointmentDetailMapper.save(tmsAppointmentDetail);

			// 同步更新装车单明细和运单状态
			tmsLoadingBillDetail.setStatus(nextStatus);
			tmsLoadingBillDetail.setUpdatetime(date);
			tmsLoadingBillDetail.setUpdateperson(user.getNickname());
			tmsLoadingBillDetailMapper.update(tmsLoadingBillDetail);

			TmsShipbillHeaderModel tmsShipbillHeader = tmsShipbillHeaderMapper.findById(tmsLoadingBillDetail.getShipbillId(), TmsShipbillHeaderModel.class);
			if (ToolKits.isNotEmpty(tmsShipbillHeader)) {
				tmsShipbillHeader.setStatus(nextStatus);
				tmsShipbillHeader.setUpdatetime(date);
				tmsShipbillHeader.setUpdateperson(user.getNickname());
				tmsShipbillHeaderMapper.update(tmsShipbillHeader);
			} else {
				throw new PrologException("运单查询失败");
			}

			if (ObjectUtil.equal(DataDictionaryConstant.ORDER_TYPE_JJ, tmsLoadingBillDetail.getOrderType()) || ObjectUtil.equal(DataDictionaryConstant.ORDER_TYPE_JJJ, tmsLoadingBillDetail.getOrderType())) {
				urgentQuantity++;
			}

			// 计算汇总的总件数 总体积 总重量
			totPcs = totPcs.add(tmsLoadingBillDetail.getTotalPcs());
			totVolume = totVolume.add(tmsLoadingBillDetail.getTotalVolume());
			totWeight = totWeight.add(tmsLoadingBillDetail.getTotalWeight());
		}
		if (hasTakeNumAndCallNum) {
			if (!hasLoading && !tallyStatus) {
				tmsAppointmentHeader.setStatus(DataDictionaryConstant.APPOINTMENT_STATUS_ZXWC);
			} else {
				// 判断仓库是否存在提货等待的车位
				RestMessage<List<TmsBaseCarportDTO>> restMessage2 = maindataFeign.queryCarportList(vo.getBranchId());
				if (!restMessage2.isSuccess()) {
					throw new PrologException("仓库车位查询接口调用失败：" + restMessage2.getMessage());
				}
				List<TmsBaseCarportDTO> filterList = Optional.ofNullable(restMessage2.getData()).orElse(new ArrayList<>()).stream().filter(dto -> ObjectUtil.equal(dto.getType(), DataDictionaryConstant.CARPORT_TYPE_THDDQ)).collect(Collectors.toList());
				// 提货等待区车位数
				int count1 = filterList.size();

				if (count1 == 0) {
					// 不存在提货等待的车位
					tmsAppointmentHeader.setStatus(DataDictionaryConstant.APPOINTMENT_STATUS_YQH);
				} else {
					// 查询预约单中,当前仓库下,预约日期为今天,预约单状态为【等待中】的预约单记录条数
					Criteria criteria = Criteria.forClass(TmsAppointmentHeaderModel.class);
					Restriction r1 = Restrictions.eq(TmsAppointmentHeaderModel::getEnterpriseId, user.getEnterpriseId());
					Restriction r2 = Restrictions.eq(TmsAppointmentHeaderModel::getBranchId, vo.getBranchId());
					Restriction r3 = Restrictions.between(TmsAppointmentHeaderModel::getAppointmentDate, DateUtil.parseDate(DateUtil.today()), DateUtil.parseDate(DateUtil.today()));
					Restriction r4 = Restrictions.eq(TmsAppointmentHeaderModel::getStatus, DataDictionaryConstant.APPOINTMENT_STATUS_DDZ);
					criteria.setRestriction(Restrictions.and(r1, r2, r3, r4));
					List<TmsAppointmentHeaderModel> list = tmsAppointmentHeaderMapper.findByCriteria(criteria);
					// 等待区已使用车位数
					int count2 = ToolKits.isEmpty(list) ? 0 : list.size();
					if (count1 - count2 > 0) {
						// 当前仓库下还存在可用的空闲车位,更新当前预约单状态为【等待中】
						tmsAppointmentHeader.setStatus(DataDictionaryConstant.APPOINTMENT_STATUS_DDZ);
					} else {
						// 当前仓库下没有可用的空闲车位,更新当前预约单状态为【已取号】
						tmsAppointmentHeader.setStatus(DataDictionaryConstant.APPOINTMENT_STATUS_YQH);
					}
				}
			}
		} else {
			if (tallyStatus) {
				tmsAppointmentHeader.setStatus(DataDictionaryConstant.APPOINTMENT_STATUS_DLH);
			} else if (hasLoading) {
				tmsAppointmentHeader.setStatus(DataDictionaryConstant.APPOINTMENT_STATUS_DZX);
			} else {
				tmsAppointmentHeader.setStatus(DataDictionaryConstant.APPOINTMENT_STATUS_ZXWC);
			}
		}

		tmsAppointmentHeader.setUrgentQuantity(urgentQuantity);
		tmsAppointmentHeader.setShipbillQuantity(vo.getIds().size());
		tmsAppointmentHeader.setTotalPcs(totPcs);
		tmsAppointmentHeader.setTotalVolume(totVolume);
		tmsAppointmentHeader.setTotalWeight(totWeight);
		tmsAppointmentHeader.setEnterpriseId(user.getEnterpriseId());
		tmsAppointmentHeader.setEnterpriseName(user.getEnterpriseName());
		tmsAppointmentHeader.setCreatetime(date);
		tmsAppointmentHeader.setCreateperson(user.getNickname());
		tmsAppointmentHeader.setUpdatetime(date);
		tmsAppointmentHeader.setUpdateperson(user.getNickname());
		tmsAppointmentHeader.setCreateMode(AppointCreateModeEnum.SHIP.getCode());
		if (tallyStatus) {
			// 未理货
			tmsAppointmentHeader.setTallyStatus(DataDictionaryConstant.TALLY_STATUS_WLH);
		} else {
			// 理货完成
			tmsAppointmentHeader.setTallyStatus(DataDictionaryConstant.TALLY_STATUS_LHWC);
		}

		// 获取取号顺序
		String number = this.getShipbillQueueNumber(user, date, tmsAppointmentHeader, callMethod, startHour, endhour);
		ToolKits.isParamNull(number, "预约取号失败");

		// 预约单保存
		tmsAppointmentHeaderMapper.save(tmsAppointmentHeader);
		MessageUtil.addMessage(new SendMessageDTO(MessageOrderTypeEnum.SHIP_NO.getCode(), MessageTypeEnum.TAKE_NUMBER.getCode(), vo.getIds()));
		return number;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public String takeNumberByLoadingBill(TakeNumberByLoadingBillVO vo) {
		PendingPickUpTakeNumberDTO pendingPickUpTakeNumberDTO = takeNumberByLoadingBillList(Lists.newArrayList(vo.getLoadingBillId()));
		return pendingPickUpTakeNumberDTO.getQueueNumber();
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public PendingPickUpTakeNumberDTO takeNumberByLoadingBillList(List<String> loadingBillIdList) {
		UserEntity user = PlgFxUsrUtils.getUserEntity();
		ToolKits.isParamNull(user, "当前人员没有操作权限");

		Criteria appointCriteria = Criteria.forClass(TmsAppointmentDetailModel.class);
		Restriction appointRestriction = Restrictions.in(TmsAppointmentDetailModel::getLoadingBillId, loadingBillIdList.toArray());
		appointCriteria.setRestriction(Restrictions.and(appointRestriction));
		List<TmsAppointmentDetailModel> tmsAppointmentDetailModelList = tmsAppointmentDetailMapper.findByCriteria(appointCriteria);
		if (CollectionUtil.isNotEmpty(tmsAppointmentDetailModelList)) {
			List<TmsAppointmentHeaderModel> appointmentModelList = tmsAppointmentHeaderMapper.findByIds(
					TmsAppointmentHeaderModel.class, tmsAppointmentDetailModelList.stream().map(
							TmsAppointmentDetailModel::getAppointmentId).distinct().collect(Collectors.toList()).toArray(), null);
			if (!appointmentModelList.stream().allMatch(headerModel -> DataDictionaryConstant.APPOINTMENT_STATUS_QX.equals(headerModel.getStatus()))) {
				throw new BizException("派车单重复取号");
			}
		}

		TmsLoadingBillHeaderModel tmsLoadingBillHeaderModel =
				tmsLoadingBillHeaderMapper.findById(loadingBillIdList.get(0), TmsLoadingBillHeaderModel.class);

		Criteria criteria = Criteria.forClass(TmsLoadingBillDetailModel.class);
		Restriction r1 = Restrictions.in(TmsLoadingBillDetailModel::getLoadingBillId, loadingBillIdList.toArray());
		criteria.setRestriction(Restrictions.and(r1));
		List<TmsLoadingBillDetailModel> tmsLoadingBillDetailModelList = tmsLoadingBillDetailMapper.findByCriteria(criteria);

		if (ToolKits.isEmpty(tmsLoadingBillDetailModelList)) {
			throw new PrologException("派车单明细不存在");
		}
		List<TmsLoadingBillDetailModel> noTakeAndCallShipbillHeaderModels = tmsLoadingBillDetailModelList.stream()
																								   .filter(h->!h.getFlowConfig()
																												.contains(DataDictionaryConstant.FLOW_CONFIG_APPOINTMENT_TN_CN))
																								   .collect(Collectors.toList());
		if (ToolKits.isNotEmpty(noTakeAndCallShipbillHeaderModels) && noTakeAndCallShipbillHeaderModels.size() != tmsLoadingBillDetailModelList.size()) {
			throw new PrologException("请勾选相同预约流程的运单");
		}
		List<TmsLoadingBillDetailModel> hasTakeAndCallShipbillHeaderModels = tmsLoadingBillDetailModelList.stream().filter(h->h.getFlowConfig()
																														 .contains(DataDictionaryConstant.FLOW_CONFIG_APPOINTMENT_TN_CN))
																									.collect(Collectors.toList());
		if (ToolKits.isNotEmpty(hasTakeAndCallShipbillHeaderModels) && hasTakeAndCallShipbillHeaderModels.size() != tmsLoadingBillDetailModelList.size()) {
			throw new PrologException("请勾选相同预约流程的运单");
		}

		List<String> shipBillIdList = tmsLoadingBillDetailModelList.stream().map(TmsLoadingBillDetailModel::getShipbillId).collect(Collectors.toList());
		criteria = Criteria.forClass(TmsShipbillHeaderModel.class);
		r1 = Restrictions.in(TmsShipbillHeaderModel::getShipbillId, shipBillIdList.toArray());
		criteria.setRestriction(Restrictions.and(r1));
		List<TmsShipbillHeaderModel> tmsShipbillHeaderModelList = tmsShipbillHeaderMapper.findByCriteria(criteria);
		// 查询仓库信息
		RestMessage<TmsBaseBranchDTO> restMessage1 = maindataFeign.getOneBranch(tmsShipbillHeaderModelList.get(0).getShipperId());
		if (!restMessage1.isSuccess()) {
			throw new PrologException("仓库查询接口调用失败：" + restMessage1.getMessage());
		}
		TmsBaseBranchDTO tmsBaseBranchDTO = restMessage1.getData();
		ToolKits.isParamNull(tmsBaseBranchDTO, "仓库ID【" + tmsShipbillHeaderModelList.get(0).getShipperId() + "】不存在");
		TakeNumberByShipbillVO vo = new TakeNumberByShipbillVO();
		vo.setBranchId(tmsBaseBranchDTO.getId());
		vo.setBranchCode(tmsBaseBranchDTO.getCode());
		vo.setBranchName(tmsBaseBranchDTO.getName());
		vo.setBranchAddress(tmsBaseBranchDTO.getAddress());
		vo.setDriverId(tmsLoadingBillHeaderModel.getDriverId());
		vo.setDriverCode(tmsLoadingBillHeaderModel.getDriverCode());
		vo.setDriverName(tmsLoadingBillHeaderModel.getDriverName());
		vo.setDriverPhoneNumber(tmsLoadingBillHeaderModel.getDriverPhoneNumber());
		vo.setVehiclePlateNumber(tmsLoadingBillHeaderModel.getVehiclePlateNumber());
		vo.setIds(tmsLoadingBillDetailModelList.stream().map(TmsLoadingBillDetailModel::getId).collect(Collectors.toList()));
		// 仓库叫号处理方式
		Integer callMethod = restMessage1.getData().getCallHandleType();
		ToolKits.isParamNull(restMessage1.getData().getApTimeDTOList(), "仓库ID【" + vo.getBranchId() + "】未维护可预约时间段");
		// 最后可预约时间小时部分
		Integer hour = 0;
		// 最后可预约时间分钟部分
		String minute = "00";
		// 仓可预约时间段处理
		List<TmsBaseBranchApTimeDTO> tmsBaseBranchApTimeDTOs = restMessage1.getData().getApTimeDTOList();
		for (TmsBaseBranchApTimeDTO tmsBaseBranchApTimeDTO : tmsBaseBranchApTimeDTOs) {
			Integer endHour = Integer.parseInt(tmsBaseBranchApTimeDTO.getEndTime().split(":")[0]);
			if (endHour > hour) {
				hour = endHour;
				minute = tmsBaseBranchApTimeDTO.getEndTime().split(":")[1];
			}
		}
		// 预约时间段开始小时
		String startHour = String.format("%0" + 2 + "d", hour);
		// 预约时间段结束小时
		String endhour = String.format("%0" + 2 + "d", hour + 1);

		// 当前时间
		Date date = DateUtil.date();
		// 获取预约单ID
		RestMessage<String> restMessageId = maindataFeign.getCodeNumberByCode(SeriaNnumberConstant.TMS_APPOINTMENT_HEADER_ID, "L");
		if (!restMessageId.isSuccess()) {
			throw new PrologException("生成预约主表ID失败");
		}

		TmsAppointmentHeaderModel tmsAppointmentHeader = new TmsAppointmentHeaderModel();
		tmsAppointmentHeader.setAppointmentId(restMessageId.getData());
		tmsAppointmentHeader.setAppointmentNo(restMessageId.getData());
		tmsAppointmentHeader.setAppointmentType(DataDictionaryConstant.APPOINTMENT_TYPE_TH);
		tmsAppointmentHeader.setBranchId(vo.getBranchId());
		tmsAppointmentHeader.setBranchCode(vo.getBranchCode());
		tmsAppointmentHeader.setBranchName(vo.getBranchName());
		tmsAppointmentHeader.setBranchAddress(vo.getBranchAddress());
		tmsAppointmentHeader.setAppointmentDate(DateUtil.parseDate(DateUtil.today()));
		tmsAppointmentHeader.setAppointmentTime(startHour + ":" + minute + "-" + endhour + ":" + minute);
		tmsAppointmentHeader.setReserveNumberTime(date);
		tmsAppointmentHeader.setCallNumberTime(date);
		tmsAppointmentHeader.setQueueNumberTime(date);
		tmsAppointmentHeader.setDriverId(vo.getDriverId());
		tmsAppointmentHeader.setDriverCode(vo.getDriverCode());
		tmsAppointmentHeader.setDriverName(vo.getDriverName());
		tmsAppointmentHeader.setDriverPhoneNumber(vo.getDriverPhoneNumber());
		tmsAppointmentHeader.setVehiclePlateNumber(vo.getVehiclePlateNumber());

		// 获取明细ID
		RestMessage<List<String>> restMessage = maindataFeign.getCodeNumberByCodes(SeriaNnumberConstant.TMS_APPOINTMENT_DETAIL_ID, "L", vo.getIds().size());
		if (!restMessage.isSuccess()) {
			throw new PrologException("批量生成预约单明细ID失败:" + restMessage.getMessage());
		}
		// 是否理货完成标识
		Boolean tallyStatus = false;
		Boolean hasTakeNumAndCallNum = false;
		Boolean hasLoading = false;
		// 紧急运单数
		Integer urgentQuantity = 0;
		BigDecimal totPcs = BigDecimal.valueOf(0);
		BigDecimal totVolume = BigDecimal.valueOf(0);
		BigDecimal totWeight = BigDecimal.valueOf(0);
		for (int i = 0; i < vo.getIds().size(); i++) {
			// 装车单明细ID
			String id = vo.getIds().get(i);
			// 查下装车单明细
			TmsLoadingBillDetailModel tmsLoadingBillDetail = tmsLoadingBillDetailMapper.findById(id, TmsLoadingBillDetailModel.class);
			ToolKits.isParamNull(tmsLoadingBillDetail, "明细ID【" + id + "】不存在");

			if (ToolKits.isNotEmpty(tmsLoadingBillDetail.getFlowConfig())
					&& tmsLoadingBillDetail.getFlowConfig().contains(DataDictionaryConstant.FLOW_CONFIG_APPOINTMENT_TN_CN)) {
				hasTakeNumAndCallNum = true;
			}
			int nextStatus = DataDictionaryConstant.SHIPBILL_STATUS_APP_ING;
			if (ToolKits.isNotEmpty(tmsLoadingBillDetail.getFlowConfig()) && tmsLoadingBillDetail.getFlowConfig().contains(DataDictionaryConstant.FLOW_CONFIG_ARRANGE_GOODS)) {
				tallyStatus = true;
				nextStatus = DataDictionaryConstant.SHIPBILL_STATUS_LH_START;
			}
			if (ToolKits.isNotEmpty(tmsLoadingBillDetail.getFlowConfig()) && tmsLoadingBillDetail.getFlowConfig().contains(DataDictionaryConstant.FLOW_CONFIG_LOAD_UNLOAD)) {
				hasLoading = true;
			}
			int flowStatus = businessFlowUtil.judgmentNextFlowSts(tmsLoadingBillDetail.getFlowConfig(), DataDictionaryConstant.FLOW_CONFIG_APPOINTMENT);
			if (hasTakeNumAndCallNum &&
					NumberUtil.isGreater(BigDecimal.valueOf(flowStatus),BigDecimal.valueOf(DataDictionaryConstant.SHIPBILL_STATUS_ZX_START))) {
				nextStatus = flowStatus;
			} else if (!hasTakeNumAndCallNum ) {
				nextStatus = flowStatus;
			}

			// 生成预约明细
			TmsAppointmentDetailModel tmsAppointmentDetail = new TmsAppointmentDetailModel();
			BeanUtils.copyProperties(tmsLoadingBillDetail, tmsAppointmentDetail);
			tmsAppointmentDetail.setId(restMessage.getData().get(i));
			tmsAppointmentDetail.setAppointmentId(tmsAppointmentHeader.getAppointmentId());
			tmsAppointmentDetail.setAppointmentNo(tmsAppointmentHeader.getAppointmentNo());
			tmsAppointmentDetail.setCreatetime(date);
			tmsAppointmentDetail.setCreateperson(user.getNickname());
			tmsAppointmentDetail.setUpdatetime(date);
			tmsAppointmentDetail.setUpdateperson(user.getNickname());
			tmsAppointmentDetail.setEnterpriseId(user.getEnterpriseId());
			tmsAppointmentDetail.setEnterpriseName(user.getEnterpriseName());
			tmsAppointmentDetail.setStatus(nextStatus);
			tmsAppointmentDetail.setLoadingBillId(tmsLoadingBillDetail.getLoadingBillId());
			tmsAppointmentDetailMapper.save(tmsAppointmentDetail);
			// 同步更新装车单明细和运单状态
			tmsLoadingBillDetail.setStatus(nextStatus);
			tmsLoadingBillDetail.setUpdatetime(date);
			tmsLoadingBillDetail.setUpdateperson(user.getNickname());
			tmsLoadingBillDetailMapper.update(tmsLoadingBillDetail);
			TmsShipbillHeaderModel tmsShipbillHeader = tmsShipbillHeaderMapper.findById(tmsLoadingBillDetail.getShipbillId(), TmsShipbillHeaderModel.class);
			if (ToolKits.isNotEmpty(tmsShipbillHeader)) {
				tmsShipbillHeader.setStatus(nextStatus);
				tmsShipbillHeader.setUpdatetime(date);
				tmsShipbillHeader.setUpdateperson(user.getNickname());
				tmsShipbillHeaderMapper.update(tmsShipbillHeader);
			} else {
				throw new PrologException("运单查询失败");
			}
			if (ObjectUtil.equal(DataDictionaryConstant.ORDER_TYPE_JJ, tmsLoadingBillDetail.getOrderType()) || ObjectUtil.equal(DataDictionaryConstant.ORDER_TYPE_JJJ, tmsLoadingBillDetail.getOrderType())) {
				urgentQuantity++;
			}
			// 计算汇总的总件数 总体积 总重量
			totPcs = totPcs.add(tmsLoadingBillDetail.getTotalPcs());
			totVolume = totVolume.add(tmsLoadingBillDetail.getTotalVolume());
			totWeight = totWeight.add(tmsLoadingBillDetail.getTotalWeight());
		}

		if (hasTakeNumAndCallNum) {
			if (!hasLoading && !tallyStatus) {
				tmsAppointmentHeader.setStatus(DataDictionaryConstant.APPOINTMENT_STATUS_ZXWC);
			} else {
				// 判断仓库是否存在提货等待的车位
				RestMessage<List<TmsBaseCarportDTO>> restMessage2 = maindataFeign.queryCarportList(vo.getBranchId());
				if (!restMessage2.isSuccess()) {
					throw new PrologException("仓库车位查询接口调用失败：" + restMessage2.getMessage());
				}
				List<TmsBaseCarportDTO> filterList = Optional.ofNullable(restMessage2.getData()).orElse(new ArrayList<>()).stream().filter(dto -> ObjectUtil.equal(dto.getType(), DataDictionaryConstant.CARPORT_TYPE_THDDQ)).collect(Collectors.toList());
				// 提货等待区车位数
				int count1 = filterList.size();

				if (count1 == 0) {
					// 不存在提货等待的车位
					tmsAppointmentHeader.setStatus(DataDictionaryConstant.APPOINTMENT_STATUS_YQH);
				} else {
					// 查询预约单中,当前仓库下,预约日期为今天,预约单状态为【等待中】的预约单记录条数
					Criteria criteriaAppointmentHeader = Criteria.forClass(TmsAppointmentHeaderModel.class);
					r1 = Restrictions.eq(TmsAppointmentHeaderModel::getEnterpriseId, user.getEnterpriseId());
					Restriction r2 = Restrictions.eq(TmsAppointmentHeaderModel::getBranchId, vo.getBranchId());
					Restriction r3 = Restrictions.between(TmsAppointmentHeaderModel::getAppointmentDate, DateUtil.parseDate(DateUtil.today()), DateUtil.parseDate(DateUtil.today()));
					Restriction r4 = Restrictions.eq(TmsAppointmentHeaderModel::getStatus, DataDictionaryConstant.APPOINTMENT_STATUS_DDZ);
					criteriaAppointmentHeader.setRestriction(Restrictions.and(r1, r2, r3, r4));
					List<TmsAppointmentHeaderModel> list = tmsAppointmentHeaderMapper.findByCriteria(criteriaAppointmentHeader);
					// 等待区已使用车位数
					int count2 = ToolKits.isEmpty(list) ? 0 : list.size();
					if (count1 - count2 > 0) {
						// 当前仓库下还存在可用的空闲车位,更新当前预约单状态为【等待中】
						tmsAppointmentHeader.setStatus(DataDictionaryConstant.APPOINTMENT_STATUS_DDZ);
					} else {
						// 当前仓库下没有可用的空闲车位,更新当前预约单状态为【已取号】
						tmsAppointmentHeader.setStatus(DataDictionaryConstant.APPOINTMENT_STATUS_YQH);
					}
				}
			}
		} else {
			if (tallyStatus) {
				tmsAppointmentHeader.setStatus(DataDictionaryConstant.APPOINTMENT_STATUS_DLH);
			} else if (hasLoading) {
				tmsAppointmentHeader.setStatus(DataDictionaryConstant.APPOINTMENT_STATUS_DZX);
			} else {
				tmsAppointmentHeader.setStatus(DataDictionaryConstant.APPOINTMENT_STATUS_ZXWC);
			}
		}

		tmsAppointmentHeader.setUrgentQuantity(urgentQuantity);
		tmsAppointmentHeader.setShipbillQuantity(vo.getIds().size());
		tmsAppointmentHeader.setTotalPcs(totPcs);
		tmsAppointmentHeader.setTotalVolume(totVolume);
		tmsAppointmentHeader.setTotalWeight(totWeight);
		tmsAppointmentHeader.setEnterpriseId(user.getEnterpriseId());
		tmsAppointmentHeader.setEnterpriseName(user.getEnterpriseName());
		tmsAppointmentHeader.setCreatetime(date);
		tmsAppointmentHeader.setCreateperson(user.getNickname());
		tmsAppointmentHeader.setUpdatetime(date);
		tmsAppointmentHeader.setUpdateperson(user.getNickname());
		tmsAppointmentHeader.setCreateMode(AppointCreateModeEnum.LOADING.getCode());
		if (tallyStatus) {
			// 未理货
			tmsAppointmentHeader.setTallyStatus(DataDictionaryConstant.TALLY_STATUS_WLH);
		} else {
			// 理货完成
			tmsAppointmentHeader.setTallyStatus(DataDictionaryConstant.TALLY_STATUS_LHWC);
		}
		// 获取取号顺序
		String number = this.getShipbillQueueNumber(user, date, tmsAppointmentHeader, callMethod, startHour, endhour);
		ToolKits.isParamNull(number, "预约取号失败");
		// 预约单保存
		tmsAppointmentHeaderMapper.save(tmsAppointmentHeader);
		PendingPickUpTakeNumberDTO pendingPickUpTakeNumberDTO = new PendingPickUpTakeNumberDTO();
		pendingPickUpTakeNumberDTO.setAppointmentDate(DateUtil.formatDate(tmsAppointmentHeader.getAppointmentDate()));
		pendingPickUpTakeNumberDTO.setAppointmentId(tmsAppointmentHeader.getAppointmentId());
		pendingPickUpTakeNumberDTO.setAppointmentTime(tmsAppointmentHeader.getAppointmentTime());
		pendingPickUpTakeNumberDTO.setAppointNumber(tmsAppointmentHeader.getAppointmentId());
		pendingPickUpTakeNumberDTO.setDriverName(tmsAppointmentHeader.getDriverName());
		pendingPickUpTakeNumberDTO.setDriverTel(tmsAppointmentHeader.getDriverPhoneNumber());
		pendingPickUpTakeNumberDTO.setQueueNumber(tmsAppointmentHeader.getQueueNumber());
		pendingPickUpTakeNumberDTO.setShipBillNums(tmsAppointmentHeader.getShipbillQuantity());
		pendingPickUpTakeNumberDTO.setShipBillPackages(tmsAppointmentHeader.getTotalPcs().intValue());
		pendingPickUpTakeNumberDTO.setShipfromDate(DateUtil.formatDate(tmsAppointmentHeader.getAppointmentDate()) + " " + tmsAppointmentHeader.getAppointmentTime());
		pendingPickUpTakeNumberDTO.setShipfromAddress(tmsAppointmentHeader.getBranchAddress());
		pendingPickUpTakeNumberDTO.setVehiclePlateNumber(tmsAppointmentHeader.getVehiclePlateNumber());
		pendingPickUpTakeNumberDTO.setShipfromName(tmsAppointmentHeader.getBranchName());
		pendingPickUpTakeNumberDTO.setShipfromId(tmsAppointmentHeader.getBranchId().toString());
		MessageUtil.addMessage(new SendMessageDTO(MessageOrderTypeEnum.LOADING_NO.getCode(), MessageTypeEnum.TAKE_NUMBER.getCode(), loadingBillIdList));
		return pendingPickUpTakeNumberDTO;
	}

	/**
	 * 获取取号顺序
	 * 
	 * @param user
	 * @param date
	 * @param tmsAppointmentHeader
	 * @param callMethod
	 * @param startHour
	 * @param endhour
	 * @return
	 */
	public String getShipbillQueueNumber(UserEntity user, Date date, TmsAppointmentHeaderModel tmsAppointmentHeader, Integer callMethod, String startHour, String endhour) {
		Criteria criteria = Criteria.forClass(TmsAppointmentHeaderModel.class);
		Restriction r1 = Restrictions.eq(TmsAppointmentHeaderModel::getEnterpriseId, user.getEnterpriseId());
		Restriction r2 = Restrictions.eq(TmsAppointmentHeaderModel::getBranchId, tmsAppointmentHeader.getBranchId());
		Restriction r3 = Restrictions.between(TmsAppointmentHeaderModel::getAppointmentDate, DateUtil.parseDate(DateUtil.today()), DateUtil.parseDate(DateUtil.today()));
		Restriction r4 = Restrictions.eq(TmsAppointmentHeaderModel::getAppointmentType, DataDictionaryConstant.APPOINTMENT_TYPE_TH);
		Restriction r5 = Restrictions.like(TmsAppointmentHeaderModel::getQueueNumber, "%" + startHour + endhour + "%");

		// 预约号
		StringBuffer number = new StringBuffer();

		// 判断当前预约单是否包含紧急加急运单
		if (tmsAppointmentHeader.getUrgentQuantity() > 0) {
			// 生成今天预约单排队号(年月日+当前仓库设置的最晚时间段后的一个小时时间段+三位自增数)
			number = new StringBuffer("急");

			Restriction r6 = Restrictions.gt(TmsAppointmentHeaderModel::getUrgentQuantity, 0);
			criteria.setRestriction(Restrictions.and(r1, r2, r3, r4, r5, r6));
			List<TmsAppointmentHeaderModel> orderList = tmsAppointmentHeaderMapper.findByCriteria(criteria);

			// 获取最大排队号+1作为当前预约单的排队号，最大排队号为空从001开始
			if (ToolKits.isNotEmpty(orderList) && orderList.size() > 0) {
				// 取出所有排队号
				List<String> queueNumberList = orderList.stream().map(TmsAppointmentHeaderModel::getQueueNumber).collect(Collectors.toList());
				// 排队号转换类型
				List<BigDecimal> queueNumbers = queueNumberList.stream().map(s -> new BigDecimal(s.replace("急", ""))).collect(Collectors.toList());
				// 获取最大排队号
				BigDecimal queueNumberMax = queueNumbers.stream().reduce(queueNumbers.get(0), BigDecimal::max);
				// 自增加1生成当前预约单的取号号码
				number.append(queueNumberMax.add(new BigDecimal("1")));
				tmsAppointmentHeader.setQueueNumber(number.toString());
			} else {
				// 生成今天预约单排队号(年月日+当前仓库设置的最晚时间段后的一个小时时间段+三位自增数)
				number.append(DateUtil.format(date, DatePattern.PURE_DATE_FORMAT)).append(startHour).append(endhour).append("001");
				tmsAppointmentHeader.setQueueNumber(number.toString());
			}

			// 生成叫号顺序
			this.getCallNumber(user, tmsAppointmentHeader, callMethod, true);
		} else {
			Restriction r6 = Restrictions.eq(TmsAppointmentHeaderModel::getUrgentQuantity, 0);
			criteria.setRestriction(Restrictions.and(r1, r2, r3, r4, r5, r6));
			List<TmsAppointmentHeaderModel> orderList = tmsAppointmentHeaderMapper.findByCriteria(criteria);
			if (ToolKits.isNotEmpty(orderList) && orderList.size() > 0) {
				// 取出所有排队号
				List<String> queueNumberList = orderList.stream().map(TmsAppointmentHeaderModel::getQueueNumber).collect(Collectors.toList());
				// 排队号转换类型
				List<BigDecimal> queueNumbers = queueNumberList.stream().map(s -> new BigDecimal(s)).collect(Collectors.toList());
				// 获取最大排队号
				BigDecimal queueNumberMax = queueNumbers.stream().reduce(queueNumbers.get(0), BigDecimal::max);
				// 自增加1生成当前预约单的取号号码
				number.append(queueNumberMax.add(new BigDecimal("1")));
				tmsAppointmentHeader.setQueueNumber(number.toString());
			} else {
				// 生成今天预约单排队号(年月日+当前仓库设置的最晚时间段后的一个小时时间段+三位自增数)
				number.append(DateUtil.format(date, DatePattern.PURE_DATE_FORMAT)).append(startHour).append(endhour).append("001");
				tmsAppointmentHeader.setQueueNumber(number.toString());
			}

			// 生成叫号顺序
			this.getCallNumber(user, tmsAppointmentHeader, callMethod, false);
		}

		return number.toString();
	}

	/**
	 * 配载运单查询
	 *
	 * @param
	 * @return
	 */
	@SuppressWarnings("resource")
	@Override
	public List<TakeNumberPageDetailDTO> queryAppointDetail(AppointDetailQueryVO vo) throws Exception {
		UserEntity user = PlgFxUsrUtils.getUserEntity();
		ToolKits.isParamNull(user, "当前人员没有操作权限");
		if (ToolKits.isEmpty(vo.getAppointmentId())) {
			throw new PrologException("预约单ID不能为空");
		}

		// 数据字典翻译数据集合
		List<Map<String, Object>> data1 = Lists.newArrayList();
		List<Map<String, Object>> data2 = Lists.newArrayList();
		List<Map<String, Object>> data3 = Lists.newArrayList();
		List<Map<String, Object>> data4 = Lists.newArrayList();
		List<Map<String, Object>> data5 = Lists.newArrayList();
		List<Map<String, Object>> data6 = Lists.newArrayList();
		List<Map<String, Object>> data7 = Lists.newArrayList();
		List<Map<String, Object>> data8 = Lists.newArrayList();
		List<Map<String, Object>> data9 = Lists.newArrayList();
		List<Map<String, Object>> data10 = Lists.newArrayList();
		List<Map<String, Object>> data11 = Lists.newArrayList();
		List<Map<String, Object>> data12 = Lists.newArrayList();

		// 订单类型
		RestMessage<List<Map<String, Object>>> restMessage1 = maindataTmsResource.getDropDownById(DataDictionaryConstant.ORDER_TYPE, null, null, null);
		if (!restMessage1.isSuccess()) {
			throw new PrologException("订单类型翻译失败!");
		} else {
			data1 = restMessage1.getData();
		}
		// 订单业务类型
		RestMessage<List<Map<String, Object>>> restMessage2 = maindataTmsResource.getDropDownById(DataDictionaryConstant.ORDER_BUSINESS_TYPE, null, null, null);
		if (!restMessage2.isSuccess()) {
			throw new PrologException("订单业务类型翻译失败!");
		} else {
			data2 = restMessage2.getData();
		}
		// 配送方式
		RestMessage<List<Map<String, Object>>> restMessage3 = maindataTmsResource.getDropDownById(DataDictionaryConstant.DELIVERY_METHOD_TYPE, null, null, null);
		if (!restMessage3.isSuccess()) {
			throw new PrologException("配送方式翻译失败!");
		} else {
			data3 = restMessage3.getData();
		}
		// 运输类型(运输模式)
		RestMessage<List<Map<String, Object>>> restMessage4 = maindataTmsResource.getDropDownById(DataDictionaryConstant.TRANSPORT_TYPE, null, null, null);
		if (!restMessage4.isSuccess()) {
			throw new PrologException("运输类型(运输模式)翻译失败!");
		} else {
			data4 = restMessage4.getData();
		}
		// 温度要求
		RestMessage<List<Map<String, Object>>> restMessage5 = maindataTmsResource.getDropDownById(DataDictionaryConstant.TEMPERATURE_REQUIREMENT, null, null, null);
		if (!restMessage5.isSuccess()) {
			throw new PrologException("温度要求翻译失败!");
		} else {
			data5 = restMessage5.getData();
		}
		// 发货方类型
		RestMessage<List<Map<String, Object>>> restMessage6 = maindataTmsResource.getDropDownById(DataDictionaryConstant.SHIPPER_TYPE, null, null, null);
		if (!restMessage6.isSuccess()) {
			throw new PrologException("发货方类型翻译失败!");
		} else {
			data6 = restMessage6.getData();
		}
		// 收货方类型
		RestMessage<List<Map<String, Object>>> restMessage7 = maindataTmsResource.getDropDownById(DataDictionaryConstant.CONSIGNEE_TYPE, null, null, null);
		if (!restMessage7.isSuccess()) {
			throw new PrologException("收货方类型翻译失败!");
		} else {
			data7 = restMessage7.getData();
		}

		RestMessage<List<Map<String, Object>>> restMessage8 = maindataTmsResource.getDropDownById(DataDictionaryConstant.TRANSPORT_STATUS, null, null, null);
		if (!restMessage8.isSuccess()) {
			throw new PrologException("运输状态翻译失败!");
		} else {
			data8 = restMessage8.getData();
		}

		RestMessage<List<Map<String, Object>>> restMessage9 = maindataTmsResource.getDropDownById(DataDictionaryConstant.ABNORMAL_STATUS, null, null, null);
		if (!restMessage9.isSuccess()) {
			throw new PrologException("异常状态翻译失败!");
		} else {
			data9 = restMessage9.getData();
		}

		RestMessage<List<Map<String, Object>>> restMessage10 = maindataTmsResource.getDropDownById(DataDictionaryConstant.SCAN_STATUS, null, null, null);
		if (!restMessage10.isSuccess()) {
			throw new PrologException("扫描状态翻译失败!");
		} else {
			data10 = restMessage10.getData();
		}

		RestMessage<List<Map<String, Object>>> restMessage11 = maindataTmsResource.getDropDownById(DataDictionaryConstant.LINE_CARRIER_TYPE, null, null, null);
		if (!restMessage11.isSuccess()) {
			throw new PrologException("承运方类型翻译失败!");
		} else {
			data11 = restMessage11.getData();
		}

		RestMessage<List<Map<String, Object>>> restMessage12 = maindataTmsResource.getDropDownById(DataDictionaryConstant.SHIPBILL_STATUS, null, null, null);
		if (!restMessage12.isSuccess()) {
			throw new PrologException("运单状态翻译失败!");
		} else {
			data12 = restMessage12.getData();
		}

		TmsAppointmentHeaderModel tmsAppointmentHeader = tmsAppointmentHeaderMapper.findById(vo.getAppointmentId(), TmsAppointmentHeaderModel.class);
		if (ToolKits.isEmpty(tmsAppointmentHeader)) {
			throw new PrologException("预约单查询失败!");
		}
		String vehiclePlateNumber = tmsAppointmentHeader.getVehiclePlateNumber();

		Criteria criteria = Criteria.forClass(TmsAppointmentDetailModel.class);
		Restriction r1 = Restrictions.eq("appointmentId", vo.getAppointmentId());
		criteria.setRestriction(Restrictions.and(r1));
		criteria.setOrder(Order.newInstance().desc(new String[] { "updatetime" }));

		if (ToolKits.isNotEmpty(vo.getPageNum())) {
			PageUtils.startPage(vo.getPageNum(), vo.getPageSize());
		}
		List<TmsAppointmentDetailModel> list = tmsAppointmentDetailMapper.findByCriteria(criteria);

		List<TakeNumberPageDetailDTO> dtos = Lists.newArrayList();
		for (TmsAppointmentDetailModel model : list) {
			TakeNumberPageDetailDTO dto = new TakeNumberPageDetailDTO();
			BeanUtils.copyProperties(model, dto);

			dto.setOrderTypeName(PublicMethods.change(data1, String.valueOf(dto.getOrderType())));
			dto.setOrderBusinessTypeName(PublicMethods.change(data2, String.valueOf(dto.getOrderBusinessType())));
			dto.setDeliveryMethodTypeName(PublicMethods.change(data3, String.valueOf(dto.getDeliveryMethodType())));
			dto.setTransportTypeName(PublicMethods.change(data4, String.valueOf(dto.getTransportType())));
			dto.setTemperatureRequirementName(PublicMethods.change(data5, String.valueOf(dto.getTemperatureRequirement())));
			dto.setShipperTypeName(PublicMethods.change(data6, String.valueOf(dto.getShipperType())));
			dto.setConsigneeTypeName(PublicMethods.change(data7, String.valueOf(dto.getConsigneeType())));

			dto.setTransportStatusName(PublicMethods.change(data8, String.valueOf(dto.getTransportStatus())));
			dto.setAbnormalStatusName(PublicMethods.change(data9, String.valueOf(dto.getAbnormalStatus())));
			dto.setScanStatusName(PublicMethods.change(data10, String.valueOf(dto.getScanStatus())));
			dto.setCarrierTypeName(PublicMethods.change(data11, String.valueOf(dto.getCarrierType())));
			dto.setStatusName(PublicMethods.change(data12, String.valueOf(dto.getStatus())));
			dto.setVehiclePlateNumber(vehiclePlateNumber);

			StringBuffer consigneeProvinceCityDistrict = new StringBuffer();
			// 目的地
			consigneeProvinceCityDistrict.append(dto.getConsigneeProvinceName());
			consigneeProvinceCityDistrict.append(dto.getConsigneeCityName());
			consigneeProvinceCityDistrict.append(dto.getConsigneeDistrictName());
			dto.setConsigneeProvinceCityDistrict(consigneeProvinceCityDistrict.toString());

			StringBuffer shipperProvinceCityDistrict = new StringBuffer();
			shipperProvinceCityDistrict.append(dto.getShipperProvinceName());
			shipperProvinceCityDistrict.append(dto.getShipperCityName());
			shipperProvinceCityDistrict.append(dto.getShipperDistrictName());
			dto.setShipperProvinceCityDistrict(shipperProvinceCityDistrict.toString());

			// 收货方位置(经纬度判断)
			if (ToolKits.isNotEmpty(dto.getConsigneeLongitude()) && ToolKits.isNotEmpty(dto.getConsigneeLatitude())) {
				dto.setConsigneePositioning(StatusConstant.POSITIONING_YDW);
			} else {
				dto.setConsigneePositioning(StatusConstant.POSITIONING_WDW);
			}

			// 发货方位置(经纬度判断)
			if (ToolKits.isNotEmpty(dto.getShipperLongitude()) && ToolKits.isNotEmpty(dto.getShipperLatitude())) {
				dto.setShipperPositioning(StatusConstant.POSITIONING_YDW);
			} else {
				dto.setShipperPositioning(StatusConstant.POSITIONING_WDW);
			}

			// 获取包裹信息
			Criteria criteriaPkg = Criteria.forClass(TmsShipbillPackageModel.class);
			Restriction rr1 = Restrictions.eq(TmsShipbillPackageModel::getShipbillId, model.getShipbillId());
			Restriction rr2 = Restrictions.eq(TmsShipbillPackageModel::getEnterpriseId, user.getEnterpriseId());
			criteriaPkg.setRestriction(Restrictions.and(rr1, rr2));
			criteriaPkg.setOrder(Order.newInstance().desc(new String[] { "updatetime" }));

			List<TmsShipbillPackageModel> tmsShipbillPackageModels = tmsShipbillPackageMapper.findByCriteria(criteriaPkg);

			if (ToolKits.isNotEmpty(tmsShipbillPackageModels)) {
				List<PendingSubmitQueryPackageDTO> packageDTOList = Lists.newArrayList();
				for (TmsShipbillPackageModel packageModel : tmsShipbillPackageModels) {
					PendingSubmitQueryPackageDTO packageDTO = new PendingSubmitQueryPackageDTO();
					BeanUtils.copyProperties(packageModel, packageDTO);
					packageDTOList.add(packageDTO);
				}
				dto.setPendingSubmitQueryPackageDTOS(packageDTOList);
				dtos.add(dto);
				continue;
			}

			// 获取商品信息
			Criteria criteriaDetail = Criteria.forClass(TmsShipbillDetailModel.class);
			criteriaDetail.setRestriction(Restrictions.and(rr1, rr2));
			criteriaDetail.setOrder(Order.newInstance().desc(new String[] { "updatetime" }));
			List<TmsShipbillDetailModel> tmsShipbillDetailModels = tmsShipbillDetailMapper.findByCriteria(criteriaDetail);

			List<PendingSubmitQueryItemDTO> itemDTOList = Lists.newArrayList();
			for (TmsShipbillDetailModel detailModel : tmsShipbillDetailModels) {
				PendingSubmitQueryItemDTO itemDTO = new PendingSubmitQueryItemDTO();
				BeanUtils.copyProperties(detailModel, itemDTO);
				itemDTOList.add(itemDTO);
			}
			// 商品信息
			dto.setPendingSubmitQueryDetailDTOS(itemDTOList);

			dtos.add(dto);
		}

		if (ToolKits.isNotEmpty(vo.getPageNum())) {
			Page<TakeNumberPageDetailDTO> page = PageUtils.getPage(dtos);
			if (list instanceof com.github.pagehelper.Page) {
				com.github.pagehelper.Page<TmsAppointmentDetailModel> p0 = (com.github.pagehelper.Page<TmsAppointmentDetailModel>) list;
				page.setPageCount(p0.getPages());
				page.setPageNum(p0.getPageNum());
				page.setPageSize(p0.getPageSize());
				page.setTotalCount(p0.getTotal());
				page.setStartRow(p0.getStartRow());
				page.setEndRow(p0.getEndRow());
			}
			page.getList();
		}
		return dtos;
	}

}
