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

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

import com.prolog.rdc.tms.model.dto.message.SendMessageDTO;
import com.prolog.rdc.tms.model.enums.MessageOrderTypeEnum;
import com.prolog.rdc.tms.model.enums.MessageTypeEnum;
import com.prolog.rdc.tms.util.DataUtils;
import com.prolog.rdc.tms.util.MessageUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.prolog.common.util.DateUtils;
import com.prolog.common.util.ToolKits;
import com.prolog.framework.common.message.RestMessage;
import com.prolog.framework.core.exception.ParameterException;
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.constant.BussinessConstant;
import com.prolog.rdc.tms.constant.DataDictionaryConstant;
import com.prolog.rdc.tms.constant.StatusConstant;
import com.prolog.rdc.tms.dao.mapper.TmsAppointmentDetailMapper;
import com.prolog.rdc.tms.dao.mapper.TmsAppointmentHeaderMapper;
import com.prolog.rdc.tms.dao.mapper.TmsLoadingBillDetailMapper;
import com.prolog.rdc.tms.dao.mapper.TmsLoadingBillHeaderMapper;
import com.prolog.rdc.tms.dao.mapper.TmsShipbillHeaderMapper;
import com.prolog.rdc.tms.dao.mapper.TmsShipbillTransportLogMapper;
import com.prolog.rdc.tms.model.dto.AppointTimeCountDTO;
import com.prolog.rdc.tms.model.dto.CallNumberGetShipbillDTO;
import com.prolog.rdc.tms.model.dto.CallNumberPageDTO;
import com.prolog.rdc.tms.model.dto.CallNumberWaitingAreaDTO;
import com.prolog.rdc.tms.model.dto.PlatformAndVehicleDTO;
import com.prolog.rdc.tms.model.dto.PlatformAndVehicleListDTO;
import com.prolog.rdc.tms.model.dto.PlatformInfoDTO;
import com.prolog.rdc.tms.model.dto.TimeCountDTO;
import com.prolog.rdc.tms.model.dto.WaitingAreaDTO;
import com.prolog.rdc.tms.model.dto.WarehouseInfoDTO;
import com.prolog.rdc.tms.model.dto.basicConfigure.SignconfigPopDTO;
import com.prolog.rdc.tms.model.dto.basicData.TmsBaseBranchDTO;
import com.prolog.rdc.tms.model.dto.basicData.TmsBaseCarportDTO;
import com.prolog.rdc.tms.model.entity.SysRefdatadModel;
import com.prolog.rdc.tms.model.entity.TmsAppointmentDetailModel;
import com.prolog.rdc.tms.model.entity.TmsAppointmentHeaderModel;
import com.prolog.rdc.tms.model.entity.TmsLoadingBillDetailModel;
import com.prolog.rdc.tms.model.entity.TmsLoadingBillHeaderModel;
import com.prolog.rdc.tms.model.entity.TmsShipbillHeaderModel;
import com.prolog.rdc.tms.model.entity.TmsShipbillTransLogModel;
import com.prolog.rdc.tms.model.vo.CallNumberByBranchIdVO;
import com.prolog.rdc.tms.model.vo.CallNumberByNextOneVO;
import com.prolog.rdc.tms.model.vo.CallNumberGetShipbillVO;
import com.prolog.rdc.tms.model.vo.CallNumberQueryVO;
import com.prolog.rdc.tms.model.vo.CallNumberWaitingAreaVO;
import com.prolog.rdc.tms.model.vo.InsertSortVO;
import com.prolog.rdc.tms.model.vo.PassNumberVO;
import com.prolog.rdc.tms.model.vo.PlatformAndVehicleVO;
import com.prolog.rdc.tms.model.vo.ShipbillNodeTrackingSaveVO;
import com.prolog.rdc.tms.model.vo.ShipbillOperateLogSaveVO;
import com.prolog.rdc.tms.model.vo.basicConfigure.SignconfigPopVO;
import com.prolog.rdc.tms.rmi.feign.MaindataFeign;
import com.prolog.rdc.tms.service.CallNumberService;
import com.prolog.rdc.tms.service.ShipbillNodeTrackingService;
import com.prolog.rdc.tms.service.ShipbillOperateLogService;
import com.prolog.rdc.tms.util.ConvertorUtil;
import com.prolog.rdc.tms.util.PublicMethods;

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;

/**
 * 园区管理-叫号管理实现层
 * <p>
 * Company: 湖北普罗格科技股份有限公司
 *
 * @author zhangsj
 * @since 2022/7/8 14:12
 */
@Service
public class CallNumberServiceImpl implements CallNumberService {

	@Autowired
	private TmsAppointmentHeaderMapper tmsAppointmentHeaderMapper;

	@Autowired
	private TmsAppointmentDetailMapper tmsAppointmentDetailMapper;

	@Autowired
	private MaindataFeign maindataTmsResource;

	@Autowired
	private ConvertorUtil convertorUtil;

	@Autowired
	private MaindataFeign maindataFeign;

	@Autowired
	private TmsLoadingBillDetailMapper tmsLoadingBillDetailMapper;

	@Autowired
	private TmsShipbillHeaderMapper tmsShipbillHeaderMapper;

	@Autowired
	private ShipbillOperateLogService shipbillOperateLogService;

	@Autowired
	private ShipbillNodeTrackingService shipbillNodeTrackingService;

	@Autowired
	private TmsShipbillTransportLogMapper tmsShipbillTransportLogMapper;

	@Autowired
	private TmsLoadingBillHeaderMapper tmsLoadingBillHeaderMapper;

	/**
	 * 主界面仓库查询
	 *
	 * @param callNumberByBranchIdVO
	 * @return
	 */
	@Override
	public WarehouseInfoDTO queryWarehouseInfoData(CallNumberByBranchIdVO callNumberByBranchIdVO) {
		UserEntity user = PlgFxUsrUtils.getUserEntity();
		ToolKits.isParamNull(user, "当前人员没有操作权限");
		// 权限控制 仅支持自有账号操作
		if (!user.getUserType().equals(BussinessConstant.USER_TYPE_ZY)) {
			throw new PrologException("当前人员没有操作权限");
		}

		// 返回数据
		WarehouseInfoDTO warehouseInfoDTO = new WarehouseInfoDTO();

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

		// 查询下一个车辆
		Criteria criteriaAppointment = Criteria.forClass(TmsAppointmentHeaderModel.class);
		Restriction appointment1 = Restrictions.eq(TmsAppointmentHeaderModel::getBranchId, callNumberByBranchIdVO.getBranchId());
		Restriction appointment2 = Restrictions.in(TmsAppointmentHeaderModel::getStatus, new Integer[] { DataDictionaryConstant.APPOINTMENT_STATUS_YQH, DataDictionaryConstant.APPOINTMENT_STATUS_DDZ });
		criteriaAppointment.setRestriction(Restrictions.and(appointment1, appointment2));
		criteriaAppointment.setOrder(Order.newInstance().asc("callNumber"));

		List<TmsAppointmentHeaderModel> tmsAppointmentHeaderModelList = tmsAppointmentHeaderMapper.findByCriteria(criteriaAppointment);

		// 下一辆车
		String nextVehicle = ToolKits.isEmpty(tmsAppointmentHeaderModelList) ? "" : tmsAppointmentHeaderModelList.get(0).getVehiclePlateNumber();

		// 获取仓库车位信息
		RestMessage<List<TmsBaseCarportDTO>> restMessage1 = maindataTmsResource.queryCarportList(callNumberByBranchIdVO.getBranchId());
		if (!restMessage1.isSuccess()) {
			throw new RuntimeException("获取仓库的车位信息失败!");
		}
		List<TmsBaseCarportDTO> tmsBaseCarportDTOList = restMessage1.getData();

		// 权限控制获取月台
		List<TmsBaseCarportDTO> tmsBaseCarportDTOS = tmsBaseCarportDTOList.stream().filter(o -> ToolKits.isNotEmpty(o.getOperatorIds()) && o.getOperatorIds().contains(user.getUserid().toString())).collect(Collectors.toList());

		// 获取提货和通用月台
		List<TmsBaseCarportDTO> tmsBaseCarportDTOByPickUp = tmsBaseCarportDTOS.stream().filter(o -> DataDictionaryConstant.CARPORT_TYPE_TH.equals(o.getType()) && DataDictionaryConstant.CARPORT_TYPE_TY.equals(o.getType()) && DataDictionaryConstant.STATUS_ENABLE.equals(o.getStatus())).collect(Collectors.toList());

		// 月台信息集合
		List<PlatformInfoDTO> platformInfoDTOS = Lists.newArrayList();
		for (TmsBaseCarportDTO tmsBaseCarportDTO : tmsBaseCarportDTOByPickUp) {
			PlatformInfoDTO platformInfoDTO = new PlatformInfoDTO();
			BeanUtils.copyProperties(tmsBaseCarportDTO, platformInfoDTO);
			// 查询对应预约单
			Criteria criteria = Criteria.forClass(TmsAppointmentHeaderModel.class);
			Restriction r1 = Restrictions.eq(TmsAppointmentHeaderModel::getBranchId, callNumberByBranchIdVO.getBranchId());
			Restriction r2 = Restrictions.eq(TmsAppointmentHeaderModel::getPlatformCode, tmsBaseCarportDTO.getCode());
			Restriction r3 = Restrictions.eq(TmsAppointmentHeaderModel::getStatus, new Integer[] { DataDictionaryConstant.APPOINTMENT_STATUS_YJH, DataDictionaryConstant.APPOINTMENT_STATUS_KSZX });
			criteria.setRestriction(Restrictions.and(r1, r2, r3));

			List<TmsAppointmentHeaderModel> tmsAppointmentHeaderModels = tmsAppointmentHeaderMapper.findByCriteria(criteria);

			if (ToolKits.isNotEmpty(tmsAppointmentHeaderModels)) {
				// 装卸时长
				StringBuffer loadingTime = new StringBuffer();
				long time = 0;

				// 封装信息
				TmsAppointmentHeaderModel tmsAppointmentHeaderModel = tmsAppointmentHeaderModels.get(0);
				platformInfoDTO.setCurrentVehicle(tmsAppointmentHeaderModel.getVehiclePlateNumber());
				platformInfoDTO.setQueueNumberTime(tmsAppointmentHeaderModel.getQueueNumberTime());

				// 计算装卸时长
				if (ToolKits.isNotEmpty(tmsAppointmentHeaderModel.getQueueNumberTime())) {
					time = DateUtil.between(date, tmsAppointmentHeaderModel.getQueueNumberTime(), DateUnit.MINUTE);
					loadingTime.append(time);
					loadingTime.append("分钟");
				} else {
					loadingTime.append("0分钟");
				}
				platformInfoDTO.setLoadingTime(loadingTime.toString());

				// 下一辆车
				platformInfoDTO.setNextVehicle(nextVehicle);
			}
		}
		warehouseInfoDTO.setPlatformInfoDTOS(platformInfoDTOS);

		// 等待区信息集合
		WaitingAreaDTO waitingAreaDTO = new WaitingAreaDTO();
		List<String> vehiclePlateNumbers = Lists.newArrayList();
		// 查询等待区对应预约单
		Criteria criteria = Criteria.forClass(TmsAppointmentHeaderModel.class);
		Restriction r1 = Restrictions.eq(TmsAppointmentHeaderModel::getBranchId, callNumberByBranchIdVO.getBranchId());
		Restriction r2 = Restrictions.in(TmsAppointmentHeaderModel::getStatus, new Integer[] { DataDictionaryConstant.APPOINTMENT_STATUS_DDZ });
		criteria.setRestriction(Restrictions.and(r1, r2));

		List<TmsAppointmentHeaderModel> tmsAppointmentHeaderModels = tmsAppointmentHeaderMapper.findByCriteria(criteria);
		if (ToolKits.isNotEmpty(tmsAppointmentHeaderModels)) {
			vehiclePlateNumbers = tmsAppointmentHeaderModels.stream().map(TmsAppointmentHeaderModel::getVehiclePlateNumber).collect(Collectors.toList());
		}
		waitingAreaDTO.setVehiclePlateNumbers(vehiclePlateNumbers);
		warehouseInfoDTO.setWaitingAreaDTO(waitingAreaDTO);
		return warehouseInfoDTO;
	}

	/**
	 * 叫号管理-下一位
	 *
	 * @param callNumberByNextOneVO
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public Integer nextOneData(CallNumberByNextOneVO callNumberByNextOneVO) throws Exception {
		ToolKits.isParamNull(callNumberByNextOneVO.getPlatformCode(), "月台号不能为空");

		UserEntity user = PlgFxUsrUtils.getUserEntity();
		ToolKits.isParamNull(user, "当前人员没有操作权限");
		// 权限控制 仅支持自有账号操作
		if (!user.getUserType().equals(BussinessConstant.USER_TYPE_ZY)) {
			throw new PrologException("当前人员没有操作权限");
		}

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

		// 判断当前月台是否存在作业车辆
		if (ToolKits.isNotEmpty(callNumberByNextOneVO.getAppointmentId())) {
			// 根据预约单ID查询预约单
			TmsAppointmentHeaderModel tmsAppointmentHeaderModel = tmsAppointmentHeaderMapper.findById(callNumberByNextOneVO.getAppointmentId(), TmsAppointmentHeaderModel.class);
			ToolKits.isParamNull(tmsAppointmentHeaderModel, "预约单ID[" + callNumberByNextOneVO.getAppointmentId() + "]有误,查询为空");

			Assert.isTrue(DataDictionaryConstant.APPOINTMENT_STATUS_ZXWC.equals(tmsAppointmentHeaderModel.getStatus()), "该车还未装车完成");

			// 查询待叫号车辆
			Criteria criteria = Criteria.forClass(TmsAppointmentHeaderModel.class);
			Restriction r1 = Restrictions.eq(TmsAppointmentHeaderModel::getEnterpriseId, user.getEnterpriseId());
			Restriction r2 = Restrictions.eq(TmsAppointmentHeaderModel::getBranchId, callNumberByNextOneVO.getBranchId());
			Restriction r3 = Restrictions.in(TmsAppointmentHeaderModel::getStatus, new Integer[] { DataDictionaryConstant.APPOINTMENT_STATUS_YQH, DataDictionaryConstant.APPOINTMENT_STATUS_DDZ });
			Restriction r4 = Restrictions.between(TmsAppointmentHeaderModel::getAppointmentDate, DateUtil.parseDate(DateUtil.today()), DateUtil.parseDate(DateUtil.today()));
			Restriction r5 = Restrictions.eq(TmsAppointmentHeaderModel::getTallyStatus, DataDictionaryConstant.TALLY_STATUS_LHWC);
			criteria.setRestriction(Restrictions.and(r1, r2, r3, r4, r5));
			criteria.setOrder(Order.newInstance().asc("callNumber"));
			List<TmsAppointmentHeaderModel> tmsAppointmentHeaderModels = tmsAppointmentHeaderMapper.findByCriteria(criteria);

			// 判断是否有下一辆车
			if (ToolKits.isNotEmpty(tmsAppointmentHeaderModels)) {
				for (int i = 0; i < tmsAppointmentHeaderModels.size(); i++) {
					TmsAppointmentHeaderModel queueAppointment = tmsAppointmentHeaderModels.get(i);
					if (i == 0) {
						// 叫号第一辆车 状态调整为已叫号
						Map<String, Object> map = new HashMap<String, Object>();
						map.put("status", DataDictionaryConstant.APPOINTMENT_STATUS_YJH);
						map.put("platformCode", callNumberByNextOneVO.getPlatformCode());
						map.put("callNumberTime", date);
						map.put("updateperson", user.getNickname());
						map.put("updatetime", date);
						tmsAppointmentHeaderMapper.updateMapById(queueAppointment.getAppointmentId(), map, TmsAppointmentHeaderModel.class);

						// 更新装车单明细为开始装卸
						upLoadingDetail(queueAppointment, user, date);
						MessageUtil.addMessage(new SendMessageDTO(MessageOrderTypeEnum.APPOINTMENT_NO.getCode(), MessageTypeEnum.CALL_NUMBER.getCode(), Lists.newArrayList(queueAppointment.getAppointmentId())));
					} else {
						// 前一位预约单状态赋值给后一位预约单
						Map<String, Object> map = new HashMap<String, Object>();
						map.put("status", tmsAppointmentHeaderModels.get(i - 1).getStatus());
						map.put("updateperson", user.getNickname());
						map.put("updatetime", date);
						tmsAppointmentHeaderMapper.updateMapById(queueAppointment.getAppointmentId(), map, TmsAppointmentHeaderModel.class);
					}
				}
			} else {
				// 没有可叫号车辆
				return 0;
			}
		} else {
			// 查询可叫号车辆
			Criteria criteria = Criteria.forClass(TmsAppointmentHeaderModel.class);
			Restriction r1 = Restrictions.eq(TmsAppointmentHeaderModel::getEnterpriseId, user.getEnterpriseId());
			Restriction r2 = Restrictions.eq(TmsAppointmentHeaderModel::getBranchId, callNumberByNextOneVO.getBranchId());
			Restriction r3 = Restrictions.in(TmsAppointmentHeaderModel::getStatus, new Integer[] { DataDictionaryConstant.APPOINTMENT_STATUS_YQH, DataDictionaryConstant.APPOINTMENT_STATUS_DDZ });
			Restriction r4 = Restrictions.between(TmsAppointmentHeaderModel::getAppointmentDate, DateUtil.parseDate(DateUtil.today()), DateUtil.parseDate(DateUtil.today()));
			Restriction r5 = Restrictions.eq(TmsAppointmentHeaderModel::getTallyStatus, DataDictionaryConstant.TALLY_STATUS_LHWC);
			criteria.setRestriction(Restrictions.and(r1, r2, r3, r4, r5));
			criteria.setOrder(Order.newInstance().asc("callNumber"));
			List<TmsAppointmentHeaderModel> tmsAppointmentHeaderModels = tmsAppointmentHeaderMapper.findByCriteria(criteria);

			// 判断是否存在可叫号车辆
			if (ToolKits.isNotEmpty(tmsAppointmentHeaderModels)) {
				for (int i = 0; i < tmsAppointmentHeaderModels.size(); i++) {
					TmsAppointmentHeaderModel queueAppointment = tmsAppointmentHeaderModels.get(i);
					if (i == 0) {
						// 叫号第一辆车 状态调整为已叫号
						Map<String, Object> map = new HashMap<String, Object>();
						map.put("status", DataDictionaryConstant.APPOINTMENT_STATUS_YJH);
						map.put("platformCode", callNumberByNextOneVO.getPlatformCode());
						map.put("callNumberTime", date);
						map.put("updateperson", user.getNickname());
						map.put("updatetime", date);
						tmsAppointmentHeaderMapper.updateMapById(queueAppointment.getAppointmentId(), map, TmsAppointmentHeaderModel.class);

						// 更新装车单明细为开始装卸
						upLoadingDetail(queueAppointment, user, date);
						MessageUtil.addMessage(new SendMessageDTO(MessageOrderTypeEnum.APPOINTMENT_NO.getCode(), MessageTypeEnum.CALL_NUMBER.getCode(), Lists.newArrayList(queueAppointment.getAppointmentId())));
					} else {
						// 前一位预约单状态赋值给后一位预约单
						Map<String, Object> map = new HashMap<String, Object>();
						map.put("status", tmsAppointmentHeaderModels.get(i - 1).getStatus());
						map.put("updateperson", user.getNickname());
						map.put("updatetime", date);
						tmsAppointmentHeaderMapper.updateMapById(queueAppointment.getAppointmentId(), map, TmsAppointmentHeaderModel.class);
					}
				}
			} else {
				// 没有可叫号车辆
				return 0;
			}
		}

		return 1;
	}

	/**
	 * 更新装车单明细为待装卸
	 * 
	 * @param firstNumberAppointment
	 * @param user
	 * @param date
	 */
	public void upLoadingDetail(TmsAppointmentHeaderModel firstNumberAppointment, UserEntity user, Date date) {
		// 查询预约单明细
		Criteria criteriaAppointment = Criteria.forClass(TmsAppointmentDetailModel.class);
		Restriction appointment = Restrictions.eq(TmsAppointmentDetailModel::getAppointmentId, firstNumberAppointment.getAppointmentId());
		criteriaAppointment.setRestriction(appointment);
		List<TmsAppointmentDetailModel> tmsAppointmentDetailModels = tmsAppointmentDetailMapper.findByCriteria(criteriaAppointment);
		for (TmsAppointmentDetailModel tmsAppointmentDetailModel : tmsAppointmentDetailModels) {
			// 查询装车单明细
			Criteria criteria1 = Criteria.forClass(TmsLoadingBillDetailModel.class);
			Restriction r11 = Restrictions.eq(TmsLoadingBillDetailModel::getShipbillId, tmsAppointmentDetailModel.getShipbillId());
			Restriction r12 = Restrictions.eq(TmsLoadingBillDetailModel::getEnterpriseId, user.getEnterpriseId());
			criteria1.setRestriction(Restrictions.and(r11, r12));
			criteria1.setOrder(Order.newInstance().desc(new String[] { "createtime" }));
			List<TmsLoadingBillDetailModel> tmsLoadingBillDetailModels = tmsLoadingBillDetailMapper.findByCriteria(criteria1);
			Assert.isTrue(tmsLoadingBillDetailModels.size() > 0, "运单【" + tmsAppointmentDetailModel.getShipbillId() + "】查询失败");

			TmsLoadingBillDetailModel tmsLoadingBillDetailModel = tmsLoadingBillDetailModels.get(0);
			// 装车单明细更新为开始装卸状态
			tmsLoadingBillDetailModel.setStatus(DataDictionaryConstant.SHIPBILL_STATUS_ZX_START);
			tmsLoadingBillDetailModel.setUpdateperson(user.getNickname());
			tmsLoadingBillDetailModel.setUpdatetime(date);
			tmsLoadingBillDetailMapper.update(tmsLoadingBillDetailModel);

			// 更新调度单状态
			Criteria criteria2 = Criteria.forClass(TmsLoadingBillDetailModel.class);
			Restriction r21 = Restrictions.eq(TmsLoadingBillDetailModel::getLoadingBillId, tmsLoadingBillDetailModel.getLoadingBillId());
			Restriction r22 = Restrictions.eq(TmsLoadingBillDetailModel::getEnterpriseId, user.getEnterpriseId());
			criteria2.setRestriction(Restrictions.and(r21, r22));
			List<TmsLoadingBillDetailModel> loadingBillDetailModels = tmsLoadingBillDetailMapper.findByCriteria(criteria2);
			if (ToolKits.isNotEmpty(loadingBillDetailModels)) {
				List<TmsLoadingBillDetailModel> filterTmsLoadingBillDetailModels = loadingBillDetailModels.stream().filter(dto -> dto.getStatus().intValue() < DataDictionaryConstant.SHIPBILL_STATUS_ZX_START.intValue()).collect(Collectors.toList());
				if (ToolKits.isEmpty(filterTmsLoadingBillDetailModels)) {
					// 更新调度单状态为开始装卸
					Map<String, Object> map = Maps.newHashMap();
					map.put("updateperson", user.getNickname());
					map.put("updatetime", date);
					map.put("status", DataDictionaryConstant.LOADING_BILL_STATUS_ZX_START);
					tmsLoadingBillHeaderMapper.updateMapById(tmsLoadingBillDetailModel.getLoadingBillId(), map, TmsLoadingBillHeaderModel.class);
				}
			}

			// 运单更新
			Map<String, Object> mapUpdate = Maps.newHashMap();
			mapUpdate.put("updateperson", user.getNickname());
			mapUpdate.put("updatetime", date);
			mapUpdate.put("status", DataDictionaryConstant.SHIPBILL_STATUS_ZX_START);
			tmsShipbillHeaderMapper.updateMapById(tmsAppointmentDetailModel.getShipbillId(), mapUpdate, TmsShipbillHeaderModel.class);

			// 更新预约明细状态
			tmsAppointmentDetailModel.setStatus(DataDictionaryConstant.SHIPBILL_STATUS_ZX_START);
			tmsAppointmentDetailModel.setUpdateperson(user.getNickname());
			tmsAppointmentDetailModel.setUpdatetime(date);
			tmsAppointmentDetailMapper.update(tmsAppointmentDetailModel);

			// 更新父单状态
			String fatherShipbillId = tmsAppointmentDetailModel.getShipbillId();
			while (ToolKits.isNotEmpty(fatherShipbillId)) {
				fatherShipbillId = updateFatherShipBillEndArrange(fatherShipbillId, DataDictionaryConstant.SHIPBILL_STATUS_ZX_START, date);
			}
		}
	}

	/**
	 * 递归更新父运单理货完成状态
	 *
	 * @param
	 * @return
	 */
	public String updateFatherShipBillEndArrange(String shipbillId, int status, Date date) {
		UserEntity user = PlgFxUsrUtils.getUserEntity();

		Map<String, Object> mapFatherUpdate = Maps.newHashMap();
		mapFatherUpdate.put("updateperson", user.getNickname());
		mapFatherUpdate.put("updatetime", date);
		mapFatherUpdate.put("status", status);
		TmsShipbillHeaderModel tmsShipbillHeaderModel = tmsShipbillHeaderMapper.findById(shipbillId, TmsShipbillHeaderModel.class);

		if (ToolKits.isNotEmpty(tmsShipbillHeaderModel.getFatherShipbillId()) && !tmsShipbillHeaderModel.getFatherShipbillId().equals(shipbillId)) {
			Map<String, Object> queryMap = Maps.newHashMap();
			queryMap.put("fatherShipbillId", tmsShipbillHeaderModel.getFatherShipbillId());
			List<TmsShipbillHeaderModel> list = tmsShipbillHeaderMapper.findByMap(queryMap, TmsShipbillHeaderModel.class);
			if (ToolKits.isNotEmpty(list) && list.size() > 0) {
				List<TmsShipbillHeaderModel> filterList = list.stream().filter(dto -> dto.getStatus().intValue() < status).collect(Collectors.toList());
				// 所有子单都理货完成了
				if (ToolKits.isEmpty(filterList)) {
					// 运单状态更新
					Criteria headerCriteria = Criteria.forClass(TmsShipbillHeaderModel.class);
					Restriction r1 = Restrictions.eq("shipbillId", tmsShipbillHeaderModel.getFatherShipbillId());
					Restriction r2 = Restrictions.eq("enterpriseId", user.getEnterpriseId());
					headerCriteria.setRestriction(Restrictions.and(r1, r2));
					tmsShipbillHeaderMapper.updateMapByCriteria(mapFatherUpdate, headerCriteria);

					// 调度单明细状态更新
					Criteria criteriaFatherLoadingBillDetail = Criteria.forClass(TmsLoadingBillDetailModel.class);
					criteriaFatherLoadingBillDetail.setRestriction(Restrictions.and(r1, r2));
					tmsLoadingBillDetailMapper.updateMapByCriteria(mapFatherUpdate, criteriaFatherLoadingBillDetail);

					// 维护运单节点数据
					ShipbillNodeTrackingSaveVO shipbillNodeTrackingSaveVO = new ShipbillNodeTrackingSaveVO();
					shipbillNodeTrackingSaveVO.setShipbillId(tmsShipbillHeaderModel.getShipbillId());
					shipbillNodeTrackingSaveVO.setShipbillNo(tmsShipbillHeaderModel.getShipbillNo());
					shipbillNodeTrackingSaveVO.setStatus(status);
					shipbillNodeTrackingSaveVO.setNodeEvent(DataDictionaryConstant.SHIPBILL_STATUSNAME_LH_END);
					shipbillNodeTrackingService.addShipbillNodeTrackingData(shipbillNodeTrackingSaveVO);

					// 维护运单日志保存
					ShipbillOperateLogSaveVO shipbillOperateLogSaveVO = new ShipbillOperateLogSaveVO();
					shipbillOperateLogSaveVO.setShipbillId(tmsShipbillHeaderModel.getShipbillId());
					shipbillOperateLogSaveVO.setShipbillNo(tmsShipbillHeaderModel.getShipbillNo());
					shipbillOperateLogSaveVO.setOperateEvent(DataDictionaryConstant.SHIPBILL_STATUSNAME_LH_END);
					shipbillOperateLogSaveVO.setOldStatus(tmsShipbillHeaderModel.getStatus());
					shipbillOperateLogSaveVO.setNewStatus(status);
					shipbillOperateLogService.addShipbillOperateLogData(shipbillOperateLogSaveVO);

					// 更新订单运输记录表
					Criteria criteriaTransport = Criteria.forClass(TmsShipbillTransLogModel.class);
					criteriaTransport.setRestriction(r1);
					Map<String, Object> mapTransportLogUpdate = Maps.newHashMap();
					mapTransportLogUpdate.put("updateperson", user.getNickname());
					mapTransportLogUpdate.put("updatetime", date);
					// 理货完成时间
					mapTransportLogUpdate.put("arrangeGoodsEndTime", date);
					tmsShipbillTransportLogMapper.updateMapByCriteria(mapTransportLogUpdate, criteriaTransport);

					return tmsShipbillHeaderModel.getFatherShipbillId();
				}
			}
		}
		return null;
	}

	/**
	 * 预约单分页查询
	 *
	 * @param
	 */
	@SuppressWarnings("resource")
	@Override
	public Page<CallNumberPageDTO> queryAppoint(CallNumberQueryVO vo) throws Exception {
		UserEntity user = PlgFxUsrUtils.getUserEntity();
		ToolKits.isParamNull(user, "当前人员没有操作权限");

		List<SysRefdatadModel> dicData = convertorUtil.getDictionary(new String[] { DataDictionaryConstant.APPOINTMENT_TYPE, DataDictionaryConstant.APPOINTMENT_STATUS });

		PageUtils.startPage(vo.getPageNum(), vo.getPageSize());
		List<TmsAppointmentHeaderModel> list = tmsAppointmentHeaderMapper.callNumberQuery(user.getEnterpriseId(), vo.getBranchId(), DateUtil.parseDate(DateUtil.today()), vo.getAppointmentNo(), vo.getAppointmentType(), vo.getBranchName(), vo.getDriverName(), vo.getAppointmentTime());

		List<CallNumberPageDTO> dtos = Lists.newArrayList();
		for (TmsAppointmentHeaderModel model : list) {
			CallNumberPageDTO dto = new CallNumberPageDTO();
			BeanUtils.copyProperties(model, dto);
			dto.setAppointmentDateTime(DateUtil.formatDate(model.getAppointmentDate()) + " " + model.getAppointmentTime());
			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 criteria = Criteria.forClass(TmsAppointmentDetailModel.class);
			Restriction r1 = Restrictions.eq(TmsAppointmentDetailModel::getAppointmentId, model.getAppointmentId());
			criteria.setRestriction(r1);
			List<TmsAppointmentDetailModel> tmsAppointmentDetailModels = tmsAppointmentDetailMapper.findByCriteria(criteria);
			dto.setLoadingBillIds(DataUtils.getLoadingBillIds(tmsAppointmentDetailModels));
			dtos.add(dto);
		}

		Page<CallNumberPageDTO> page = PageUtils.getPage(dtos);
		if (list instanceof com.github.pagehelper.Page) {
			com.github.pagehelper.Page<TmsAppointmentHeaderModel> p0 = (com.github.pagehelper.Page<TmsAppointmentHeaderModel>) 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());
		}
		return page;
	}

	/**
	 * 仓库各预约时间段排队数查询
	 *
	 */
	@Override
	public List<AppointTimeCountDTO> queryTimeCount(CallNumberQueryVO vo) throws Exception {
		UserEntity user = PlgFxUsrUtils.getUserEntity();
		ToolKits.isParamNull(user, "当前人员没有操作权限");

		List<AppointTimeCountDTO> list = Lists.newArrayList();
		vo.setAppointmentDate(DateUtils.nowDate());
		List<TimeCountDTO> timeCounts = tmsAppointmentHeaderMapper.queryTimeCount(vo);
		for (TimeCountDTO timeCount : timeCounts) {
			AppointTimeCountDTO dto = new AppointTimeCountDTO();
			dto.setAppointmentTime(timeCount.getTime());
			dto.setCount(timeCount.getCount());
			list.add(dto);
		}
		return list;
	}

	/**
	 * 装卸月台与车辆列表查询
	 *
	 */
	@Override
	public List<PlatformAndVehicleDTO> platformAndVehicle(PlatformAndVehicleVO platformAndVehicleVO) throws Exception {
		UserEntity user = PlgFxUsrUtils.getUserEntity();
		ToolKits.isParamNull(user, "当前人员没有操作权限");

		List<PlatformAndVehicleDTO> platformAndVehicleDTOs = Lists.newArrayList();

		// 查询当前仓库的提货车位
		RestMessage<List<TmsBaseCarportDTO>> restMessage = maindataFeign.queryCarport(platformAndVehicleVO.getBranchId(), String.valueOf(user.getUserid()));
		Assert.isTrue(restMessage.isSuccess(), "仓库车位查询接口调用失败：" + restMessage.getMessage());
		Assert.isTrue(ToolKits.isNotEmpty(restMessage.getData()), "仓库【" + platformAndVehicleVO.getBranchId() + "】未维护车位信息");

		// 提货等待区车位(月台)对象
		List<TmsBaseCarportDTO> tmsBaseCarportDTOs = restMessage.getData().stream().filter(s -> s.getType().intValue() == DataDictionaryConstant.CARPORT_TYPE_TH.intValue()).collect(Collectors.toList());

		// 查询正在作业的预约单(装卸车辆)
		Criteria criteria = Criteria.forClass(TmsAppointmentHeaderModel.class);
		Restriction r1 = Restrictions.eq(TmsAppointmentHeaderModel::getEnterpriseId, user.getEnterpriseId());
		Restriction r2 = Restrictions.eq(TmsAppointmentHeaderModel::getBranchId, platformAndVehicleVO.getBranchId());
		Restriction r3 = Restrictions.eq(TmsAppointmentHeaderModel::getAppointmentDate, DateUtil.parseDate(DateUtil.today()));
		Restriction r4 = Restrictions.in(TmsAppointmentHeaderModel::getStatus, new Integer[] { DataDictionaryConstant.APPOINTMENT_STATUS_YJH, DataDictionaryConstant.APPOINTMENT_STATUS_KSZX, DataDictionaryConstant.APPOINTMENT_STATUS_YQH, DataDictionaryConstant.APPOINTMENT_STATUS_DDZ });
		Restriction r5 = Restrictions.eq(TmsAppointmentHeaderModel::getAppointmentType, DataDictionaryConstant.APPOINTMENT_TYPE_TH);
		criteria.setRestriction(Restrictions.and(r1, r2, r3, r4, r5));
		criteria.setOrder(Order.newInstance().asc("callNumber"));
		List<TmsAppointmentHeaderModel> tmsAppointmentHeaderModels = tmsAppointmentHeaderMapper.findByCriteria(criteria);

		// 装备装卸的预约单(升序)
		List<TmsAppointmentHeaderModel> readyAppointments = Optional.ofNullable(tmsAppointmentHeaderModels).orElse(new ArrayList<>()).parallelStream().filter(s -> s.getStatus().intValue() <= DataDictionaryConstant.APPOINTMENT_STATUS_DDZ.intValue()).sorted(Comparator.comparing(TmsAppointmentHeaderModel::getCallNumber)).collect(Collectors.toList());
		// 叫号后的预约单
		List<TmsAppointmentHeaderModel> callAppointments = tmsAppointmentHeaderModels.stream().filter(s -> s.getStatus().intValue() >= DataDictionaryConstant.APPOINTMENT_STATUS_YJH.intValue()).collect(Collectors.toList());

		for (TmsBaseCarportDTO tmsBaseCarportDTO : tmsBaseCarportDTOs) {
			PlatformAndVehicleDTO platformAndVehicleDTO = new PlatformAndVehicleDTO();
			platformAndVehicleDTO.setPlatformCode(tmsBaseCarportDTO.getCode());

			// 月台车辆信息集合
			List<PlatformAndVehicleListDTO> platformAndVehicleListDTOs = Lists.newArrayList();
			// 月台车辆信息
			PlatformAndVehicleListDTO platformAndVehicleListDTO = new PlatformAndVehicleListDTO();
			for (int i = 0; i < callAppointments.size(); i++) {
				TmsAppointmentHeaderModel callAppointment = callAppointments.get(i);
				if (tmsBaseCarportDTO.getCode().equals(callAppointment.getPlatformCode())) {
					// ID键
					platformAndVehicleListDTO.setId(ToolKits.getUUID());
					// 月台
					platformAndVehicleListDTO.setPlatformCode(callAppointment.getPlatformCode());
					// 预约单ID
					platformAndVehicleListDTO.setAppointmentId(callAppointment.getAppointmentId());
					// 当前装卸车辆
					platformAndVehicleListDTO.setVehiclePlateNumber(callAppointment.getVehiclePlateNumber());
					// 取号时间
					platformAndVehicleListDTO.setQueueNumberTime(callAppointment.getQueueNumberTime());
					// 进场时间
					platformAndVehicleListDTO.setInDate(callAppointment.getLoadAndUnloadStartTime());
					// 装车时长
					platformAndVehicleListDTO.setLoadingTime(String.valueOf(DateUtil.between(DateUtil.date(), callAppointment.getQueueNumberTime(), DateUnit.MINUTE)) + "分钟");
					if (i < readyAppointments.size()) {
						// 匹配下一装卸车辆
						platformAndVehicleListDTO.setNextVehiclePlateNumber(readyAppointments.get(i).getVehiclePlateNumber());
						platformAndVehicleListDTO.setNextAppointmentId(readyAppointments.get(i).getAppointmentId());
					}
				}
			}
			platformAndVehicleListDTOs.add(platformAndVehicleListDTO);
			platformAndVehicleDTO.setData(platformAndVehicleListDTOs);
			platformAndVehicleDTOs.add(platformAndVehicleDTO);
		}

		return platformAndVehicleDTOs;
	}

	/**
	 * 等待区车辆列表查询
	 *
	 */
	@Override
	public List<CallNumberWaitingAreaDTO> queryWaitingZone(CallNumberWaitingAreaVO callNumberWaitingAreaVO) throws Exception {
		UserEntity user = PlgFxUsrUtils.getUserEntity();
		ToolKits.isParamNull(user, "当前人员没有操作权限");

		// 判断仓库是否存在提货等待的车位
		RestMessage<List<TmsBaseCarportDTO>> restMessage = maindataFeign.queryCarportList(callNumberWaitingAreaVO.getBranchId());
		if (restMessage.isSuccess()) {
			if (ToolKits.isEmpty(restMessage.getData())) {
				return null;
			}
		} else {
			throw new ParameterException("仓库等待区查询接口调用失败：" + restMessage.getMessage());
		}

		// 等待区对象集合
		List<TmsBaseCarportDTO> filterList = restMessage.getData().stream().filter(dto -> ObjectUtil.equal(dto.getType(), DataDictionaryConstant.CARPORT_TYPE_THDDQ)).collect(Collectors.toList());
		if (ToolKits.isEmpty(filterList)) {
			return null;
		}

		// 响应集合
		List<CallNumberWaitingAreaDTO> callNumberWaitingAreaDTOs = Lists.newArrayList();

		// 查询等待区的预约单
		Criteria criteria = Criteria.forClass(TmsAppointmentHeaderModel.class);
		Restriction r1 = Restrictions.eq(TmsAppointmentHeaderModel::getEnterpriseId, user.getEnterpriseId());
		Restriction r2 = Restrictions.eq(TmsAppointmentHeaderModel::getBranchId, callNumberWaitingAreaVO.getBranchId());
		Restriction r3 = Restrictions.between(TmsAppointmentHeaderModel::getAppointmentDate, DateUtil.parseDate(DateUtil.today()), DateUtil.parseDate(DateUtil.today()));
		Restriction r4 = Restrictions.in(TmsAppointmentHeaderModel::getStatus, new Integer[] { DataDictionaryConstant.APPOINTMENT_STATUS_DDZ });
		criteria.setRestriction(Restrictions.and(r1, r2, r3, r4));
		criteria.setOrder(Order.newInstance().asc(new String[] { "callNumber" }));
		List<TmsAppointmentHeaderModel> tmsAppointmentHeaderModels = tmsAppointmentHeaderMapper.findByCriteria(criteria);
		for (TmsAppointmentHeaderModel tmsAppointmentHeaderModel : tmsAppointmentHeaderModels) {
			// 响应对象
			CallNumberWaitingAreaDTO callNumberWaitingAreaDTO = new CallNumberWaitingAreaDTO();
			BeanUtils.copyProperties(tmsAppointmentHeaderModel, callNumberWaitingAreaDTO);
			callNumberWaitingAreaDTOs.add(callNumberWaitingAreaDTO);
		}

		return callNumberWaitingAreaDTOs;
	}

	/**
	 * 运单查询
	 *
	 * @param callNumberGetShipbillVO
	 * @return
	 */
	@Override
	public List<CallNumberGetShipbillDTO> getShipbillData(CallNumberGetShipbillVO callNumberGetShipbillVO) {
		UserEntity user = PlgFxUsrUtils.getUserEntity();
		ToolKits.isParamNull(user, "当前人员没有操作权限");
		// 权限控制 仅支持自有账号操作
		if (!user.getUserType().equals(BussinessConstant.USER_TYPE_ZY)) {
			throw new PrologException("当前人员没有操作权限");
		}
		// 数据字典翻译数据集合
		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<SignconfigPopDTO> data8 = Lists.newArrayList();

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

		// 封装运单明细
		Criteria criteria = Criteria.forClass(TmsAppointmentDetailModel.class);
		Restriction r1 = Restrictions.eq("appointmentId", callNumberGetShipbillVO.getAppointmentId());
		criteria.setRestriction(r1);
		criteria.setOrder(Order.newInstance().asc(new String[] { "orderDate" }));

		List<TmsAppointmentDetailModel> tmsAppointmentDetailModels = tmsAppointmentDetailMapper.findByCriteria(criteria);

		// 明细集合
		List<CallNumberGetShipbillDTO> list = Lists.newArrayList();

		for (TmsAppointmentDetailModel model : tmsAppointmentDetailModels) {

			CallNumberGetShipbillDTO callNumberGetShipbillDTO = new CallNumberGetShipbillDTO();
			BeanUtils.copyProperties(model, callNumberGetShipbillDTO);

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

			StringBuffer consigneeProvinceCityDistrict = new StringBuffer();
			// 目的地
			consigneeProvinceCityDistrict.append(model.getConsigneeProvinceName());
			consigneeProvinceCityDistrict.append(model.getConsigneeCityName());
			consigneeProvinceCityDistrict.append(model.getConsigneeDistrictName());
			callNumberGetShipbillDTO.setConsigneeProvinceCityDistrict(consigneeProvinceCityDistrict.toString());
			// 始发地
			StringBuffer shipperProvinceCityDistrict = new StringBuffer();
			shipperProvinceCityDistrict.append(model.getShipperProvinceName());
			shipperProvinceCityDistrict.append(model.getShipperCityName());
			shipperProvinceCityDistrict.append(model.getShipperDistrictName());
			callNumberGetShipbillDTO.setShipperProvinceCityDistrict(shipperProvinceCityDistrict.toString());

			// 类型翻译
			callNumberGetShipbillDTO.setOrderTypeName(PublicMethods.change(data1, String.valueOf(model.getOrderType())));
			callNumberGetShipbillDTO.setOrderBusinessTypeName(PublicMethods.change(data2, String.valueOf(model.getOrderBusinessType())));
			callNumberGetShipbillDTO.setDeliveryMethodTypeName(PublicMethods.change(data3, String.valueOf(model.getDeliveryMethodType())));
			callNumberGetShipbillDTO.setTransportTypeName(PublicMethods.change(data4, String.valueOf(model.getTransportType())));
			callNumberGetShipbillDTO.setTemperatureRequirementName(PublicMethods.change(data5, String.valueOf(model.getTemperatureRequirement())));
			callNumberGetShipbillDTO.setShipperTypeName(PublicMethods.change(data6, String.valueOf(model.getShipperType())));
			callNumberGetShipbillDTO.setConsigneeTypeName(PublicMethods.change(data7, String.valueOf(model.getConsigneeType())));

			// 获取背景颜色和字体颜色
			Signconfig: for (SignconfigPopDTO signconfigPopDTO : data8) {
				// 标记类型匹配
				switch (signconfigPopDTO.getType()) {
				case DataDictionaryConstant.SIGNCONFIG_TYPE_DDLX: // 订单类型
					if (ToolKits.isNotEmpty(signconfigPopDTO.getMatching())) {
						// 判断是否匹配
						if (PublicMethods.compare(signconfigPopDTO.getMatching(), ToolKits.isNotEmpty(signconfigPopDTO.getStoredValue()) ? signconfigPopDTO.getStoredValue() : "", ToolKits.isNotEmpty(callNumberGetShipbillDTO.getOrderTypeName()) ? callNumberGetShipbillDTO.getOrderTypeName() : "")) {
							callNumberGetShipbillDTO.setBackground(ToolKits.isEmpty(signconfigPopDTO.getBackground()) ? "" : signconfigPopDTO.getBackground());
							callNumberGetShipbillDTO.setColor(ToolKits.isEmpty(signconfigPopDTO.getColor()) ? "" : signconfigPopDTO.getColor());

							callNumberGetShipbillDTO.setSignConfigId(signconfigPopDTO.getId());

							// 匹配上结束循环
							break Signconfig;
						}
					}
					break;
				case DataDictionaryConstant.SIGNCONFIG_TYPE_YWLX: // 业务类型
					if (ToolKits.isNotEmpty(signconfigPopDTO.getMatching())) {
						if (PublicMethods.compare(signconfigPopDTO.getMatching(), ToolKits.isNotEmpty(signconfigPopDTO.getStoredValue()) ? signconfigPopDTO.getStoredValue() : "", ToolKits.isNotEmpty(callNumberGetShipbillDTO.getOrderBusinessTypeName()) ? callNumberGetShipbillDTO.getOrderBusinessTypeName() : "")) {
							callNumberGetShipbillDTO.setBackground(ToolKits.isEmpty(signconfigPopDTO.getBackground()) ? "" : signconfigPopDTO.getBackground());
							callNumberGetShipbillDTO.setColor(ToolKits.isEmpty(signconfigPopDTO.getColor()) ? "" : signconfigPopDTO.getColor());

							callNumberGetShipbillDTO.setSignConfigId(signconfigPopDTO.getId());

							break Signconfig;
						}
					}
					break;
				case DataDictionaryConstant.SIGNCONFIG_TYPE_WDYQ: // 温度要求
					if (ToolKits.isNotEmpty(signconfigPopDTO.getMatching())) {
						if (PublicMethods.compare(signconfigPopDTO.getMatching(), ToolKits.isNotEmpty(signconfigPopDTO.getStoredValue()) ? signconfigPopDTO.getStoredValue() : "", ToolKits.isNotEmpty(callNumberGetShipbillDTO.getTemperatureRequirementName()) ? callNumberGetShipbillDTO.getTemperatureRequirementName() : "")) {
							callNumberGetShipbillDTO.setBackground(ToolKits.isEmpty(signconfigPopDTO.getBackground()) ? "" : signconfigPopDTO.getBackground());
							callNumberGetShipbillDTO.setColor(ToolKits.isEmpty(signconfigPopDTO.getColor()) ? "" : signconfigPopDTO.getColor());

							callNumberGetShipbillDTO.setSignConfigId(signconfigPopDTO.getId());

							break Signconfig;
						}
					}
					break;
				case DataDictionaryConstant.SIGNCONFIG_TYPE_PSFS: // 配送方式
					if (ToolKits.isNotEmpty(signconfigPopDTO.getMatching())) {
						if (PublicMethods.compare(signconfigPopDTO.getMatching(), ToolKits.isNotEmpty(signconfigPopDTO.getStoredValue()) ? signconfigPopDTO.getStoredValue() : "", ToolKits.isNotEmpty(callNumberGetShipbillDTO.getDeliveryMethodTypeName()) ? callNumberGetShipbillDTO.getDeliveryMethodTypeName() : "")) {
							callNumberGetShipbillDTO.setBackground(ToolKits.isEmpty(signconfigPopDTO.getBackground()) ? "" : signconfigPopDTO.getBackground());
							callNumberGetShipbillDTO.setColor(ToolKits.isEmpty(signconfigPopDTO.getColor()) ? "" : signconfigPopDTO.getColor());

							callNumberGetShipbillDTO.setSignConfigId(signconfigPopDTO.getId());

							break Signconfig;
						}
					}
					break;
				case DataDictionaryConstant.SIGNCONFIG_TYPE_DDBZ: // 订单备注
					if (ToolKits.isNotEmpty(signconfigPopDTO.getMatching())) {
						if (PublicMethods.compare(signconfigPopDTO.getMatching(), ToolKits.isNotEmpty(signconfigPopDTO.getStoredValue()) ? signconfigPopDTO.getStoredValue() : "", ToolKits.isNotEmpty(callNumberGetShipbillDTO.getMemo()) ? callNumberGetShipbillDTO.getMemo() : "")) {
							callNumberGetShipbillDTO.setBackground(ToolKits.isEmpty(signconfigPopDTO.getBackground()) ? "" : signconfigPopDTO.getBackground());
							callNumberGetShipbillDTO.setColor(ToolKits.isEmpty(signconfigPopDTO.getColor()) ? "" : signconfigPopDTO.getColor());

							callNumberGetShipbillDTO.setSignConfigId(signconfigPopDTO.getId());

							break Signconfig;
						}
					}
					break;
				}
			}

			list.add(callNumberGetShipbillDTO);
		}
		return list;
	}

	/**
	 * 过号
	 *
	 * @param
	 * @return
	 * @throws Exception
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void passNumber(PassNumberVO vo) throws Exception {
		ToolKits.isParamNull(vo, "请求参数不为空");
		ToolKits.isParamNull(vo.getAppointmentId(), "预约单ID不为空");

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

		if (!user.getUserType().equals(BussinessConstant.USER_TYPE_ZY)) {
			throw new PrologException("当前人员没有操作权限");
		}

		// 当前日期
		Date date = DateUtil.date();

		TmsAppointmentHeaderModel tmsAppointmentHeader = tmsAppointmentHeaderMapper.findById(vo.getAppointmentId(), TmsAppointmentHeaderModel.class);
		if (ToolKits.isNotEmpty(tmsAppointmentHeader)) {
			if (tmsAppointmentHeader.getStatus().intValue() >= DataDictionaryConstant.APPOINTMENT_STATUS_KSZX.intValue()) {
				throw new PrologException("当前车辆已开始装卸,不能过号");
			}

			RestMessage<TmsBaseBranchDTO> msg = maindataFeign.getOneBranch(tmsAppointmentHeader.getBranchId());
			if (!msg.isSuccess()) {
				throw new PrologException("仓库查询接口调用失败：" + msg.getMessage());
			}
			ToolKits.isParamNull(msg.getData(), "仓库【" + tmsAppointmentHeader.getBranchId() + "】不存在");
			// 仓库过号处理方式
			Integer passMethod = msg.getData().getOverNumHandleType();
			if (null == passMethod) {
				throw new PrologException("请先配置当前仓库的过号处理方式");
			}

			// 判断仓库是否存在提货等待的车位
			RestMessage<List<TmsBaseCarportDTO>> restMessage = maindataFeign.queryCarportList(tmsAppointmentHeader.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();

			if (ObjectUtil.equal(DataDictionaryConstant.OVER_NUM_HANDLE_TYPE_CXQH, passMethod)) {
				// 重新取号
				tmsAppointmentHeader.setStatus(DataDictionaryConstant.APPOINTMENT_STATUS_YSH);
				tmsAppointmentHeader.setQueueNumber(null);
				tmsAppointmentHeader.setQueueNumberTime(null);
				tmsAppointmentHeader.setCallNumber(null);
				tmsAppointmentHeader.setCallNumberTime(null);
			} else if (ObjectUtil.equal(DataDictionaryConstant.OVER_NUM_HANDLE_TYPE_HPSW, passMethod)) {
				// 查询后面排队的预约单
				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.in(TmsAppointmentHeaderModel::getStatus, new Integer[] { DataDictionaryConstant.APPOINTMENT_STATUS_YQH, DataDictionaryConstant.APPOINTMENT_STATUS_DDZ });
				criteria.setRestriction(Restrictions.and(r1, r2, r3, r4));
				criteria.setOrder(Order.newInstance().asc(new String[] { "callNumber" }));
				List<TmsAppointmentHeaderModel> tmsAppointmentHeaderModels = tmsAppointmentHeaderMapper.findByCriteria(criteria);
				ToolKits.isParamNull(tmsAppointmentHeaderModels, "后面没有排队车辆不需要过号");

				// 等待区内车辆数
				int count2 = tmsAppointmentHeaderModels.stream().filter(s -> s.getStatus().intValue() == DataDictionaryConstant.APPOINTMENT_STATUS_DDZ.intValue()).collect(Collectors.toList()).size();

				// 后面排队车辆小于三位
				if (tmsAppointmentHeaderModels.size() <= 3) {
					// 过号车辆排在末位
					if (count1 > count2) {
						// 存在空余等待区
						tmsAppointmentHeader.setStatus(DataDictionaryConstant.APPOINTMENT_STATUS_DDZ);
					} else {
						tmsAppointmentHeader.setStatus(DataDictionaryConstant.APPOINTMENT_STATUS_YQH);
					}

					tmsAppointmentHeader.setCallNumber(((new BigDecimal(tmsAppointmentHeaderModels.get(tmsAppointmentHeaderModels.size() - 1).getCallNumber())).add(new BigDecimal("1"))).toString());
					tmsAppointmentHeader.setCallNumberTime(date);
				} else {
					// 将第4位车辆状态及叫号顺序给到当前车辆，4位以后的车辆叫号顺序顺延一位
					tmsAppointmentHeader.setStatus(tmsAppointmentHeaderModels.get(3).getStatus());
					tmsAppointmentHeader.setCallNumber(tmsAppointmentHeaderModels.get(3).getCallNumber());
					tmsAppointmentHeader.setCallNumberTime(date);

					// 4位以后的车辆叫号顺序顺延一位
					for (int i = 3; i < tmsAppointmentHeaderModels.size(); i++) {
						TmsAppointmentHeaderModel appointmentHeader = tmsAppointmentHeaderModels.get(i);

						if (i == tmsAppointmentHeaderModels.size() - 1) {
							if (count1 > count2) {
								// 存在空余等待区
								appointmentHeader.setStatus(DataDictionaryConstant.APPOINTMENT_STATUS_DDZ);
							} else {
								appointmentHeader.setStatus(DataDictionaryConstant.APPOINTMENT_STATUS_YQH);
							}
						} else {
							// 后一位状态赋值给前一位
							appointmentHeader.setStatus(tmsAppointmentHeaderModels.get(i + 1).getStatus());
						}

						appointmentHeader.setCallNumber(((new BigDecimal(appointmentHeader.getCallNumber())).add(new BigDecimal("1"))).toString());
						appointmentHeader.setCallNumberTime(date);
						appointmentHeader.setUpdatetime(date);
						appointmentHeader.setUpdateperson(user.getNickname());
						tmsAppointmentHeaderMapper.update(appointmentHeader);
					}
				}
			} else if (ObjectUtil.equal(DataDictionaryConstant.OVER_NUM_HANDLE_TYPE_HPWW, passMethod)) {
				// 查询后面排队的预约单
				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.in(TmsAppointmentHeaderModel::getStatus, new Integer[] { DataDictionaryConstant.APPOINTMENT_STATUS_YQH, DataDictionaryConstant.APPOINTMENT_STATUS_DDZ });
				criteria.setRestriction(Restrictions.and(r1, r2, r3, r4));
				criteria.setOrder(Order.newInstance().asc(new String[] { "callNumber" }));
				List<TmsAppointmentHeaderModel> tmsAppointmentHeaderModels = tmsAppointmentHeaderMapper.findByCriteria(criteria);
				ToolKits.isParamNull(tmsAppointmentHeaderModels, "后面没有排队车辆不需要过号");

				// 等待区内车辆数
				int count2 = tmsAppointmentHeaderModels.stream().filter(s -> s.getStatus().intValue() == DataDictionaryConstant.APPOINTMENT_STATUS_DDZ.intValue()).collect(Collectors.toList()).size();

				// 后面排队车辆不超过5位
				if (tmsAppointmentHeaderModels.size() <= 5) {
					// 过号车辆排在末位
					if (count1 > count2) {
						// 存在空余等待区
						tmsAppointmentHeader.setStatus(DataDictionaryConstant.APPOINTMENT_STATUS_DDZ);
					} else {
						tmsAppointmentHeader.setStatus(DataDictionaryConstant.APPOINTMENT_STATUS_YQH);
					}

					tmsAppointmentHeader.setCallNumber(((new BigDecimal(tmsAppointmentHeaderModels.get(tmsAppointmentHeaderModels.size() - 1).getCallNumber())).add(new BigDecimal("1"))).toString());
					tmsAppointmentHeader.setCallNumberTime(date);
				} else {
					// 将第6位车辆状态及叫号顺序给到当前车辆，6位以后的车辆叫号顺序顺延一位
					tmsAppointmentHeader.setStatus(tmsAppointmentHeaderModels.get(5).getStatus());
					tmsAppointmentHeader.setCallNumber(tmsAppointmentHeaderModels.get(5).getCallNumber());
					tmsAppointmentHeader.setCallNumberTime(date);

					// 6位以后的车辆叫号顺序顺延一位
					for (int i = 5; i < tmsAppointmentHeaderModels.size(); i++) {
						TmsAppointmentHeaderModel appointmentHeader = tmsAppointmentHeaderModels.get(i);

						if (i == tmsAppointmentHeaderModels.size() - 1) {
							if (count1 > count2) {
								// 存在空余等待区
								appointmentHeader.setStatus(DataDictionaryConstant.APPOINTMENT_STATUS_DDZ);
							} else {
								appointmentHeader.setStatus(DataDictionaryConstant.APPOINTMENT_STATUS_YQH);
							}
						} else {
							// 后一位状态赋值给前一位
							appointmentHeader.setStatus(tmsAppointmentHeaderModels.get(i + 1).getStatus());
						}

						appointmentHeader.setCallNumber(((new BigDecimal(appointmentHeader.getCallNumber())).add(new BigDecimal("1"))).toString());
						appointmentHeader.setCallNumberTime(date);
						appointmentHeader.setUpdatetime(date);
						appointmentHeader.setUpdateperson(user.getNickname());
						tmsAppointmentHeaderMapper.update(appointmentHeader);
					}
				}
			} else {
				throw new ParameterException("过号方式【" + passMethod + "】未实现");
			}

			// 预约单解绑月台
			tmsAppointmentHeader.setPlatformCode(null);
			tmsAppointmentHeader.setUpdateperson(user.getNickname());
			tmsAppointmentHeader.setUpdatetime(date);
			tmsAppointmentHeaderMapper.update(tmsAppointmentHeader);

			// 查询预约单明细
			Criteria criteria1 = Criteria.forClass(TmsAppointmentDetailModel.class);
			Restriction r11 = Restrictions.eq(TmsAppointmentDetailModel::getEnterpriseId, user.getEnterpriseId());
			Restriction r12 = Restrictions.eq(TmsAppointmentDetailModel::getAppointmentId, tmsAppointmentHeader.getAppointmentId());
			criteria1.setRestriction(Restrictions.and(r11, r12));
			List<TmsAppointmentDetailModel> tmsAppointmentDetailModels = tmsAppointmentDetailMapper.findByCriteria(criteria1);
			for (TmsAppointmentDetailModel tmsAppointmentDetailModel : tmsAppointmentDetailModels) {
				// 运单操作日志保存
				ShipbillOperateLogSaveVO shipbillOperateLogSaveVO = new ShipbillOperateLogSaveVO();
				shipbillOperateLogSaveVO.setShipbillId(tmsAppointmentDetailModel.getShipbillId());
				shipbillOperateLogSaveVO.setShipbillNo(tmsAppointmentDetailModel.getShipbillNo());
				shipbillOperateLogSaveVO.setOperateEvent("过号");
				shipbillOperateLogSaveVO.setOldStatus(tmsAppointmentDetailModel.getStatus());
				shipbillOperateLogSaveVO.setNewStatus(tmsAppointmentDetailModel.getStatus());
				shipbillOperateLogService.addShipbillOperateLogData(shipbillOperateLogSaveVO);
			}
		} else {
			throw new ParameterException("预约单ID【" + vo.getAppointmentId() + "】不存在");
		}
	}

	/**
	 * 插队
	 *
	 * @param
	 * @return
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void insertSort(InsertSortVO vo) throws Exception {
		ToolKits.isParamNull(vo, "请求参数不为空");
		ToolKits.isParamNull(vo.getAppointmentId(), "预约单ID不为空");

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

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

		TmsAppointmentHeaderModel tmsAppointmentHeader = tmsAppointmentHeaderMapper.findById(vo.getAppointmentId(), TmsAppointmentHeaderModel.class);
		if (ToolKits.isNotEmpty(tmsAppointmentHeader)) {
			// 当前预约单的叫号顺序
			String currentCallnumber = tmsAppointmentHeader.getCallNumber();
			// 当前预约单状态
			Integer currentStatus = tmsAppointmentHeader.getStatus();

			// 查询前面排队的预约单
			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.lt(TmsAppointmentHeaderModel::getCallNumber, currentCallnumber);
			Restriction r5 = Restrictions.isNotNull(TmsAppointmentHeaderModel::getCallNumber);
			Restriction r6 = Restrictions.in(TmsAppointmentHeaderModel::getStatus, new Integer[] { DataDictionaryConstant.APPOINTMENT_STATUS_YQH, DataDictionaryConstant.APPOINTMENT_STATUS_DDZ });
			criteria.setRestriction(Restrictions.and(r1, r2, r3, r4, r5, r6));
			List<TmsAppointmentHeaderModel> tmsAppointmentHeaderModels = tmsAppointmentHeaderMapper.findByCriteria(criteria);
			ToolKits.isParamNull(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 minCallNumber = callNumbers.stream().reduce(callNumbers.get(0), BigDecimal::min);
			// 获取最大排队号
			BigDecimal maxCallNumber = callNumbers.stream().reduce(callNumbers.get(0), BigDecimal::max);

			// 首位预约单
			TmsAppointmentHeaderModel firstPlaceAppointmentHeader = tmsAppointmentHeaderModels.stream().filter(item -> item.getCallNumber().equals(minCallNumber.toString())).findAny().orElse(null);
			// 首位预约单状态
			Integer firstPlaceStatus = firstPlaceAppointmentHeader.getStatus();

			// 当前预约单的前一位
			TmsAppointmentHeaderModel previousAppointmentHeader = tmsAppointmentHeaderModels.stream().filter(item -> item.getCallNumber().equals(maxCallNumber.toString())).findAny().orElse(null);
			// 前一位预约单状态
			Integer previousStatus = previousAppointmentHeader.getStatus();

			// 按叫号顺序正序排列
			List<TmsAppointmentHeaderModel> ascAppointmentHeaders = tmsAppointmentHeaderModels.stream().sorted(Comparator.comparing(TmsAppointmentHeaderModel::getCallNumber)).collect(Collectors.toList());
			for (int i = 0; i < ascAppointmentHeaders.size(); i++) {
				TmsAppointmentHeaderModel model = ascAppointmentHeaders.get(i);

				// 最后一位
				if (i == ascAppointmentHeaders.size() - 1) {
					model.setStatus(previousStatus.intValue() == currentStatus.intValue() ? previousStatus : currentStatus);
				} else {
					model.setStatus(ascAppointmentHeaders.get(i + 1).getStatus());
				}

				// 排在当前预约单前面的预约单叫号顺序顺延一位
				model.setCallNumber(String.valueOf(Integer.parseInt(model.getCallNumber()) + 1));
				model.setCallNumberTime(date);
				model.setUpdatetime(date);
				model.setUpdateperson(user.getNickname());
				tmsAppointmentHeaderMapper.update(model);
			}

			// 当前预约单叫号顺序更新到第一位
			tmsAppointmentHeader.setCallNumber(String.valueOf(BussinessConstant.CALL_NUMBER));
			tmsAppointmentHeader.setCallNumberTime(date);
			tmsAppointmentHeader.setStatus(currentStatus.intValue() == firstPlaceStatus.intValue() ? currentStatus : firstPlaceStatus);
			tmsAppointmentHeader.setUpdateperson(user.getNickname());
			tmsAppointmentHeader.setUpdatetime(DateUtil.date());
			tmsAppointmentHeaderMapper.update(tmsAppointmentHeader);

			// 查询预约单明细
			Criteria criteria1 = Criteria.forClass(TmsAppointmentDetailModel.class);
			Restriction r11 = Restrictions.eq(TmsAppointmentDetailModel::getEnterpriseId, user.getEnterpriseId());
			Restriction r12 = Restrictions.eq(TmsAppointmentDetailModel::getAppointmentId, tmsAppointmentHeader.getAppointmentId());
			criteria1.setRestriction(Restrictions.and(r11, r12));
			List<TmsAppointmentDetailModel> tmsAppointmentDetailModels = tmsAppointmentDetailMapper.findByCriteria(criteria1);
			for (TmsAppointmentDetailModel tmsAppointmentDetailModel : tmsAppointmentDetailModels) {
				// 运单操作日志保存
				ShipbillOperateLogSaveVO shipbillOperateLogSaveVO = new ShipbillOperateLogSaveVO();
				shipbillOperateLogSaveVO.setShipbillId(tmsAppointmentDetailModel.getShipbillId());
				shipbillOperateLogSaveVO.setShipbillNo(tmsAppointmentDetailModel.getShipbillNo());
				shipbillOperateLogSaveVO.setOperateEvent("插队");
				shipbillOperateLogSaveVO.setOldStatus(tmsAppointmentDetailModel.getStatus());
				shipbillOperateLogSaveVO.setNewStatus(tmsAppointmentDetailModel.getStatus());
				shipbillOperateLogService.addShipbillOperateLogData(shipbillOperateLogSaveVO);
			}
		} else {
			throw new ParameterException("预约单ID【" + vo.getAppointmentId() + "】不存在");
		}
	}

}
