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

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import cn.hutool.core.thread.ThreadUtil;
import com.alibaba.fastjson.JSONObject;
import com.netflix.hystrix.strategy.concurrency.HystrixRequestContext;
import com.prolog.framework.authority.util.HystrixVarUtil;
import com.prolog.rdc.tms.model.vo.*;
import com.prolog.rdc.tms.service.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.ArrayUtils;
import org.apache.poi.util.StringUtil;
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.alibaba.fastjson.JSON;
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.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.constant.BussinessConstant;
import com.prolog.rdc.tms.constant.DataDictionaryConstant;
import com.prolog.rdc.tms.constant.SeriaNnumberConstant;
import com.prolog.rdc.tms.constant.StatusConstant;
import com.prolog.rdc.tms.constant.enums.StationTypeEnum;
import com.prolog.rdc.tms.dao.mapper.TmsLoadingBillDetailMapper;
import com.prolog.rdc.tms.dao.mapper.TmsLoadingBillHeaderMapper;
import com.prolog.rdc.tms.dao.mapper.TmsShipbillDetailMapper;
import com.prolog.rdc.tms.dao.mapper.TmsShipbillHeaderMapper;
import com.prolog.rdc.tms.dao.mapper.TmsShipbillNodeTrackingMapper;
import com.prolog.rdc.tms.dao.mapper.TmsShipbillPackageMapper;
import com.prolog.rdc.tms.dao.mapper.TmsShipbillTransportLogMapper;
import com.prolog.rdc.tms.model.dto.DeviceByOneDTO;
import com.prolog.rdc.tms.model.dto.DispatchCkApprovalSCDTO;
import com.prolog.rdc.tms.model.dto.ExportSendCarDTO;
import com.prolog.rdc.tms.model.dto.LoadingBillDetailMapDTO;
import com.prolog.rdc.tms.model.dto.LoadingBillMapDTO;
import com.prolog.rdc.tms.model.dto.LoadingSiteInfoDTO;
import com.prolog.rdc.tms.model.dto.SendCarItemPageDTO;
import com.prolog.rdc.tms.model.dto.SendCarMapDTO;
import com.prolog.rdc.tms.model.dto.SendCarMapDetailDTO;
import com.prolog.rdc.tms.model.dto.SendCarPackagePageDTO;
import com.prolog.rdc.tms.model.dto.SendCarPageDTO;
import com.prolog.rdc.tms.model.dto.SendCarPageDetailDTO;
import com.prolog.rdc.tms.model.dto.SendCarPrintHeadDTO;
import com.prolog.rdc.tms.model.dto.SendCarPrintTableDTO;
import com.prolog.rdc.tms.model.dto.SendCarShipbillPopDTODTO;
import com.prolog.rdc.tms.model.dto.SendCarViewByIdDTO;
import com.prolog.rdc.tms.model.dto.SendCarViewDTO;
import com.prolog.rdc.tms.model.dto.SendCarViewDetailByIdDTO;
import com.prolog.rdc.tms.model.dto.SendCarViewDetailDTO;
import com.prolog.rdc.tms.model.dto.ShipbillHeaderPageDTO;
import com.prolog.rdc.tms.model.dto.ShipbillInfoDTO;
import com.prolog.rdc.tms.model.dto.VehicleCheckDTO;
import com.prolog.rdc.tms.model.dto.basicConfigure.SignconfigPopDTO;
import com.prolog.rdc.tms.model.dto.basicData.ApprovalLogDTO;
import com.prolog.rdc.tms.model.dto.basicData.ApprovalNodeSelDTO;
import com.prolog.rdc.tms.model.dto.message.SendMessageDTO;
import com.prolog.rdc.tms.model.entity.ShipbillNodeTracking;
import com.prolog.rdc.tms.model.entity.SysRefdatadModel;
import com.prolog.rdc.tms.model.entity.TmsLoadingBillDetailModel;
import com.prolog.rdc.tms.model.entity.TmsLoadingBillHeaderModel;
import com.prolog.rdc.tms.model.entity.TmsShipbillDetailModel;
import com.prolog.rdc.tms.model.entity.TmsShipbillHeaderModel;
import com.prolog.rdc.tms.model.entity.TmsShipbillPackageModel;
import com.prolog.rdc.tms.model.entity.TmsShipbillTransLogModel;
import com.prolog.rdc.tms.model.enums.MessageOrderTypeEnum;
import com.prolog.rdc.tms.model.enums.MessageTypeEnum;
import com.prolog.rdc.tms.model.vo.basicConfigure.ApprovalBusinessNodeVO;
import com.prolog.rdc.tms.model.vo.basicConfigure.ApprovalOpenVO;
import com.prolog.rdc.tms.model.vo.basicConfigure.SignconfigPopVO;
import com.prolog.rdc.tms.model.vo.fleetManagement.VehicleCheckVO;
import com.prolog.rdc.tms.rmi.feign.MaindataFeign;
import com.prolog.rdc.tms.util.BusinessFlowUtil;
import com.prolog.rdc.tms.util.ConvertorUtil;
import com.prolog.rdc.tms.util.MessageUtil;
import com.prolog.rdc.tms.util.PublicMethods;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;

/**
 * 已派车实现层
 *
 * @author zhangsj
 * @since 2022-04-13 14:32:31
 */
@Service
@Slf4j
public class SendCarServiceImpl implements SendCarService {

	@Autowired
	private TmsLoadingBillHeaderMapper tmsLoadingBillHeaderMapper;

	@Autowired
	private TmsLoadingBillDetailMapper tmsLoadingBillDetailMapper;

	@Autowired
	private MaindataFeign maindataTmsResource;

	@Autowired
	private TmsShipbillHeaderMapper tmsShipbillHeaderMapper;

	@Autowired
	private ShipbillOperateLogService shipbillOperateLogService;

	@Autowired
	private ShipbillNodeTrackingService shipbillNodeTrackingService;

	@Autowired
	private TmsShipbillDetailMapper tmsShipbillDetailMapper;

	@Autowired
	private TmsShipbillPackageMapper tmsShipbillPackageMapper;

	@Autowired
	private TmsShipbillNodeTrackingMapper tmsShipbillNodeTrackingMapper;

	@Autowired
	private BusinessFlowUtil businessFlowUtil;

	@Autowired
	private TmsShipbillTransportLogMapper tmsShipbillTransportLogMapper;

	@Autowired
	private TrailerService trailerService;

	@Autowired
	private LoadingBillService loadingBillService;

	@Autowired
	private ConvertorUtil convertorUtil;

	@Autowired
	private WaitPickUpGoodsService pickUpGoodsService;

	/**
	 * 已派车分页查询
	 *
	 * @param sendCarPageVO
	 * @return
	 */
	@SuppressWarnings("resource")
	@Override
	public Page<SendCarPageDTO> sendcarPageData(SendCarPageVO sendCarPageVO) {
		ToolKits.isParamNull(sendCarPageVO, "汇总查询请求不为空");
		ToolKits.isParamNull(sendCarPageVO.getPageNum(), "当前页码不为空");
		ToolKits.isParamNull(sendCarPageVO.getPageSize(), "每页条数不为空");

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

		if (!user.getUserType().equals(BussinessConstant.USER_TYPE_ZY) && !user.getUserType().equals(BussinessConstant.USER_TYPE_CYS)) {
			ToolKits.isParamNull(user, "当前人员没有操作权限");
		}

		List<SysRefdatadModel> dicData = convertorUtil.getDictionary(new String[] { DataDictionaryConstant.LOADING_BILL_STATUS, // 已派车状态
				DataDictionaryConstant.CARRIER_SYS_FLAG, // 承运商系统标志
				DataDictionaryConstant.VEHICLE_TYPE_CATEGORY, // 车辆类别
				DataDictionaryConstant.VEHICLE_TYPE
		});

		// 添加查询条件
		Criteria criteria = Criteria.forClass(TmsLoadingBillHeaderModel.class);
		Restriction r1 = ToolKits.isEmpty(sendCarPageVO.getLoadingBillNo()) ? null : Restrictions.like("loadingBillNo", "%" + sendCarPageVO.getLoadingBillNo() + "%");
		Restriction r2 = ToolKits.isEmpty(sendCarPageVO.getStatus()) ? null : Restrictions.eq("status", sendCarPageVO.getStatus());
		Restriction r3 = ToolKits.isEmpty(sendCarPageVO.getCreateStartTime()) ? null : Restrictions.ge("createtime", sendCarPageVO.getCreateStartTime());
		Restriction r4 = ToolKits.isEmpty(sendCarPageVO.getCreateEndTime()) ? null : Restrictions.le("createtime", sendCarPageVO.getCreateEndTime());
		Restriction r5 = Restrictions.eq("carrierType", DataDictionaryConstant.LINE_CARRIER_TYPE_SJ);
		Restriction r6 = Restrictions.eq("enterpriseId", user.getEnterpriseId());
		Restriction r7 = null;
		if (user.getUserType().equals(BussinessConstant.USER_TYPE_ZY)) {
			r7 = Restrictions.eq("scheduleType", DataDictionaryConstant.SCHEDULE_TYPE_ZY);
		} else {
			r7 = Restrictions.eq("scheduleType", DataDictionaryConstant.SCHEDULE_TYPE_CYS);
		}
		criteria.setRestriction(Restrictions.and(r1, r2, r3, r4, r5, r6, r7));
		criteria.setOrder(Order.newInstance().desc(new String[] { "updatetime" }));

		PageUtils.startPage(sendCarPageVO.getPageNum(), sendCarPageVO.getPageSize());
		List<TmsLoadingBillHeaderModel> tmsLoadingBillHeaderModels = tmsLoadingBillHeaderMapper.findByCriteria(criteria);

		List<SendCarPageDTO> sendCarPageDTOS = Lists.newArrayList();
		for (TmsLoadingBillHeaderModel tmsLoadingBillHeaderModel : tmsLoadingBillHeaderModels) {
			SendCarPageDTO dto = new SendCarPageDTO();
			BeanUtils.copyProperties(tmsLoadingBillHeaderModel, dto);
			dto.setVehicleAscriptionName(ConvertorUtil.getName(dicData, DataDictionaryConstant.VEHICLE_TYPE, String.valueOf(dto.getVehicleAscription())));
			dto.setStatusName(ConvertorUtil.getName(dicData, DataDictionaryConstant.LOADING_BILL_STATUS, String.valueOf(dto.getStatus())));
			dto.setVehicleTypeCategoryName(ConvertorUtil.getName(dicData, DataDictionaryConstant.VEHICLE_TYPE_CATEGORY, dto.getVehicleTypeCategory()));
			dto.setCarrierSysFlagName(ConvertorUtil.getName(dicData, DataDictionaryConstant.CARRIER_SYS_FLAG, dto.getCarrierSysFlag()));
			sendCarPageDTOS.add(dto);
		}

		// 分页重组
		Page<SendCarPageDTO> page = PageUtils.getPage(sendCarPageDTOS);
		if (tmsLoadingBillHeaderModels instanceof com.github.pagehelper.Page) {
			com.github.pagehelper.Page<TmsLoadingBillHeaderModel> p0 = (com.github.pagehelper.Page<TmsLoadingBillHeaderModel>) tmsLoadingBillHeaderModels;
			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;
	}

	/**
	 * 已派车高级查询
	 *
	 * @param advancedQueryVO
	 * @return
	 */
	@SuppressWarnings("resource")
	public Page<SendCarPageDTO> pageAdvanced(SendCarAdsQueryVO advancedQueryVO) {
		ToolKits.isParamNull(advancedQueryVO, "高级查询请求不为空");
		ToolKits.isParamNull(advancedQueryVO.getPageNum(), "当前页码不为空");
		ToolKits.isParamNull(advancedQueryVO.getPageSize(), "每页条数不为空");

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

		if (!user.getUserType().equals(BussinessConstant.USER_TYPE_ZY) && !user.getUserType().equals(BussinessConstant.USER_TYPE_CYS)) {
			ToolKits.isParamNull(user, "当前人员没有操作权限");
		}

		List<SysRefdatadModel> dicData = convertorUtil.getDictionary(new String[] { DataDictionaryConstant.LOADING_BILL_STATUS, // 已派车状态
				DataDictionaryConstant.VEHICLE_TYPE_CATEGORY // 车辆类别
		});

		// 添加查询条件
		advancedQueryVO.setEnterpriseId(user.getEnterpriseId());
		advancedQueryVO.setCarrierType(DataDictionaryConstant.LINE_CARRIER_TYPE_SJ);
		if (user.getUserType().equals(BussinessConstant.USER_TYPE_ZY)) {
			advancedQueryVO.setScheduleType(DataDictionaryConstant.SCHEDULE_TYPE_ZY);
		} else {
			advancedQueryVO.setScheduleType(DataDictionaryConstant.SCHEDULE_TYPE_CYS);
		}
		// 获取高级查询配置
		String conditions = null;
		RestMessage<String> restMessageAdvancedCfg = maindataTmsResource.getQueryConfiguration(DataDictionaryConstant.BIZ_TYPE_SEND_CAR);
		if (!restMessageAdvancedCfg.isSuccess()) {
			// throw new RuntimeException("订单类型翻译失败!");
		} else {
			conditions = restMessageAdvancedCfg.getData();
		}
		advancedQueryVO.setSql(conditions);
		PageUtils.startPage(advancedQueryVO.getPageNum(), advancedQueryVO.getPageSize());
		List<SendCarPageDTO> tmsLoadingBillHeaderModels = tmsLoadingBillHeaderMapper.sendCarAdvanceQuery(advancedQueryVO);

		List<SendCarPageDTO> sendCarPageDTOS = Lists.newArrayList();
		for (SendCarPageDTO tmsLoadingBillHeaderModel : tmsLoadingBillHeaderModels) {
			SendCarPageDTO dto = new SendCarPageDTO();
			BeanUtils.copyProperties(tmsLoadingBillHeaderModel, dto);
			dto.setStatusName(ConvertorUtil.getName(dicData, DataDictionaryConstant.LOADING_BILL_STATUS, String.valueOf(dto.getStatus())));
			dto.setVehicleTypeCategoryName(ConvertorUtil.getName(dicData, DataDictionaryConstant.VEHICLE_TYPE_CATEGORY, dto.getVehicleTypeCategory()));
			sendCarPageDTOS.add(dto);
		}

		// 分页重组
		Page<SendCarPageDTO> page = PageUtils.getPage(sendCarPageDTOS);
		if (tmsLoadingBillHeaderModels instanceof com.github.pagehelper.Page) {
			com.github.pagehelper.Page<SendCarPageDTO> p0 = (com.github.pagehelper.Page<SendCarPageDTO>) tmsLoadingBillHeaderModels;
			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;
	}

	/**
	 * 已派车运单撤销
	 *
	 * @param ids
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void sendcarUndoData(List<String> ids) {
		ToolKits.isParamNull(ids, "派车单ID不为空");

		UserEntity user = PlgFxUsrUtils.getUserEntity();
		ToolKits.isParamNull(user, "当前人员没有操作权限");
		if (!user.getUserType().equals(BussinessConstant.USER_TYPE_ZY) && !user.getUserType().equals(BussinessConstant.USER_TYPE_CYS)) {
			ToolKits.isParamNull(user, "当前人员没有操作权限");
		}

		List<TmsLoadingBillHeaderModel> tmsLoadingBillHeaderModels = tmsLoadingBillHeaderMapper.findByIds(TmsLoadingBillHeaderModel.class, ids.toArray(), null);
		String str = tmsLoadingBillHeaderModels.stream().filter(o -> o.getStatus().intValue() > DataDictionaryConstant.LOADING_BILL_STATUS_WSH.intValue()).map(TmsLoadingBillHeaderModel::getLoadingBillNo).collect(Collectors.joining(","));
		if (ToolKits.isNotEmpty(str)) {
			throw new RuntimeException("托运单[" + str + "]已审核,不能撤销!");
		}

		// 查询明细内容
		Criteria criteria = Criteria.forClass(TmsLoadingBillDetailModel.class);
		Restriction r1 = Restrictions.in("loadingBillId", ids.toArray());
		criteria.setRestriction(r1);

		List<TmsLoadingBillDetailModel> tmsLoadingBillDetailModels = tmsLoadingBillDetailMapper.findByCriteria(criteria);

		for (TmsLoadingBillDetailModel tmsLoadingBillDetailModel : tmsLoadingBillDetailModels) {

			TmsShipbillHeaderModel tmsShipbillHeaderModel = tmsShipbillHeaderMapper.findById(tmsLoadingBillDetailModel.getShipbillId(), TmsShipbillHeaderModel.class);

			ShipbillOperateLogSaveVO shipbillOperateLogSaveVO = new ShipbillOperateLogSaveVO();
			// 运单状态回退
			Restriction r4 = null;
			if (user.getUserType().equals(BussinessConstant.USER_TYPE_ZY)) {
				Assert.isTrue(tmsShipbillHeaderModel.getStatus().intValue() <= DataDictionaryConstant.SHIPBILL_STATUS_DISPATCH.intValue(), "当前已调度审核不可回退");

				tmsShipbillHeaderModel.setStatus(DataDictionaryConstant.SHIPBILL_STATUS_REVIEW);

				shipbillOperateLogSaveVO.setOperateEvent(DataDictionaryConstant.SHIPBILL_STATUSNAME_REVOKE_SEND_CAR);
				shipbillOperateLogSaveVO.setOldStatus(DataDictionaryConstant.SHIPBILL_STATUS_DISPATCH);
				shipbillOperateLogSaveVO.setNewStatus(DataDictionaryConstant.SHIPBILL_STATUS_REVIEW);

				r4 = Restrictions.eq("status", DataDictionaryConstant.SHIPBILL_STATUS_DISPATCH);
			} else {
				Assert.isTrue(tmsShipbillHeaderModel.getCarrierShipbillStatus().intValue() <= DataDictionaryConstant.CARRIER_SHIPBILL_STATUS_DISPATCHED.intValue(), "当前已调度审核不可回退");

				tmsShipbillHeaderModel.setCarrierShipbillStatus(DataDictionaryConstant.CARRIER_SHIPBILL_STATUS_AUDITED);

				shipbillOperateLogSaveVO.setOperateEvent(DataDictionaryConstant.CARRIER_SHIPBILL_STATUSNAME_REVOKE_SEND_CAR);
				shipbillOperateLogSaveVO.setOldStatus(DataDictionaryConstant.CARRIER_SHIPBILL_STATUS_DISPATCHED);
				shipbillOperateLogSaveVO.setNewStatus(DataDictionaryConstant.CARRIER_SHIPBILL_STATUS_AUDITED);
				r4 = Restrictions.eq("status", DataDictionaryConstant.CARRIER_SHIPBILL_STATUS_DISPATCHED);
			}
			tmsShipbillHeaderModel.setUpdatetime(DateUtil.date());
			tmsShipbillHeaderModel.setUpdateperson(user.getNickname());
			tmsShipbillHeaderMapper.update(tmsShipbillHeaderModel);

			// 运单操作日志保存
			shipbillOperateLogSaveVO.setShipbillId(tmsLoadingBillDetailModel.getShipbillId());
			shipbillOperateLogSaveVO.setShipbillNo(tmsLoadingBillDetailModel.getShipbillNo());
			shipbillOperateLogService.addShipbillOperateLogData(shipbillOperateLogSaveVO,user);

			// 删除调度的节点信息
			Criteria criteriaNode = Criteria.forClass(ShipbillNodeTracking.class);
			Restriction r3 = Restrictions.eq("shipbillId", tmsLoadingBillDetailModel.getShipbillId());
			Restriction r5 = Restrictions.eq("enterpriseId", user.getEnterpriseId());
			criteriaNode.setRestriction(Restrictions.and(r3, r4, r5));
			tmsShipbillNodeTrackingMapper.deleteByCriteria(criteriaNode);
		}

		// 删除明细内容
		criteria = Criteria.forClass(TmsLoadingBillDetailModel.class);
		r1 = Restrictions.in("loadingBillId", ids.toArray());
		criteria.setRestriction(r1);
		tmsLoadingBillDetailMapper.deleteByCriteria(criteria);

		tmsLoadingBillHeaderMapper.deleteByIds(ids.toArray(), TmsLoadingBillHeaderModel.class);
	}

	/**
	 * 已派车审核
	 *
	 * @param ids
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void sendcarAuditData(List<String> ids) {
		ToolKits.isParamNull(ids, "派车单ID不为空");

		UserEntity user = PlgFxUsrUtils.getUserEntity();
		ToolKits.isParamNull(user, "当前人员没有操作权限");
		if (!user.getUserType().equals(BussinessConstant.USER_TYPE_ZY) && !user.getUserType().equals(BussinessConstant.USER_TYPE_CYS)) {
			ToolKits.isParamNull(user, "当前人员没有操作权限");
		}
		Date date = DateUtils.nowDate();
		autoSendcarAuditData(ids, user, date);

	}

	/**
	 * 自动已派车审核
	 *
	 * @param ids
	 */
	public void autoSendcarAuditData(List<String> ids, UserEntity user, Date date) {

		List<TmsLoadingBillHeaderModel> tmsLoadingBillHeaderModels = tmsLoadingBillHeaderMapper.findByIds(TmsLoadingBillHeaderModel.class, ids.toArray(), null);
		// 判断派车单是否已审核
		String str = tmsLoadingBillHeaderModels.stream().filter(o -> o.getStatus().intValue() != DataDictionaryConstant.LOADING_BILL_STATUS_WSH.intValue()).map(TmsLoadingBillHeaderModel::getLoadingBillNo).collect(Collectors.joining(","));

		if (ToolKits.isNotEmpty(str)) {
			throw new RuntimeException("托运单[" + str + "]不是待审核状态,不能调度审核!");
		}

		List<String> loadingBillIds = Lists.newArrayList();
		List<String> pickUpShipBillIds = Lists.newArrayList();
		for (TmsLoadingBillHeaderModel tmsLoadingBillHeaderModel : tmsLoadingBillHeaderModels) {
			// 反审核的派车单跳过运单处理
			if (ToolKits.isEmpty(tmsLoadingBillHeaderModel.getOldStatus())) {
				Criteria criteria = Criteria.forClass(TmsLoadingBillDetailModel.class);
				Restriction r1 = Restrictions.eq("loadingBillId", tmsLoadingBillHeaderModel.getLoadingBillId());
				criteria.setRestriction(r1);
				List<TmsLoadingBillDetailModel> tmsLoadingBillDetailModels = tmsLoadingBillDetailMapper.findByCriteria(criteria);

				int shipperTypeCnt = 0;
				int consigneeType = 0;
				Boolean matched = false;

				// 匹配调度审核审批流程
				for (TmsLoadingBillDetailModel loadingBillDetailModel : tmsLoadingBillDetailModels) {
					TmsShipbillHeaderModel tmsShipbillHeaderModel = tmsShipbillHeaderMapper.findById(loadingBillDetailModel.getShipbillId(), TmsShipbillHeaderModel.class);
					Assert.isTrue(null != tmsShipbillHeaderModel, "运单【" + tmsShipbillHeaderModel.getShipbillNo() + "】运单不存在,审核失败");

					if (user.getUserType().equals(BussinessConstant.USER_TYPE_ZY)) {
						matched = approvalOpen(tmsLoadingBillHeaderModel, tmsShipbillHeaderModel, DataDictionaryConstant.APPROVAL_FLOW_TYPE_DISPATCH, user);
					} else {
						matched = approvalOpen(tmsLoadingBillHeaderModel, tmsShipbillHeaderModel, DataDictionaryConstant.APPROVAL_FLOW_TYPE_DISPATCH_CARRIER, user);
					}
					if (matched) {
						break;
					}
				}
				if (matched) {
					tmsLoadingBillHeaderModel.setStatus(DataDictionaryConstant.LOADING_BILL_STATUS_DIS_APPROVAL);
				} else {
					tmsLoadingBillHeaderModel.setStatus(DataDictionaryConstant.LOADING_BILL_STATUS_YSH);
				}

				for (TmsLoadingBillDetailModel detailModel : tmsLoadingBillDetailModels) {
					if (DataDictionaryConstant.SHIPPER_TYPE_CK.equals(detailModel.getShipperType())) {
						shipperTypeCnt++;
					}
					if (DataDictionaryConstant.CONSIGNEE_TYPE_CK.equals(detailModel.getConsigneeType())) {
						consigneeType++;
					}
					ShipbillNodeTrackingSaveVO shipbillNodeTrackingSaveVO = new ShipbillNodeTrackingSaveVO();
					ShipbillOperateLogSaveVO shipbillOperateLogSaveVO = new ShipbillOperateLogSaveVO();
					Map<String, Object> mapUpdateShipbillHeader = Maps.newHashMap();
					Map<String, Object> mapUpdateLoadingDetail = Maps.newHashMap();

					mapUpdateShipbillHeader.put("updateperson", user.getNickname());
					mapUpdateShipbillHeader.put("updatetime", date);
					mapUpdateLoadingDetail.put("updateperson", user.getNickname());
					mapUpdateLoadingDetail.put("updatetime", date);
					if (!matched) {
						// 没有匹配到审批流程
						if (user.getUserType().equals(BussinessConstant.USER_TYPE_ZY)) {
							// 自有账号
							// 判定下一步流程
							int status = businessFlowUtil.judgmentNextFlowSts(detailModel.getFlowConfig(), DataDictionaryConstant.FLOW_CONFIG_CHECK);

							mapUpdateLoadingDetail.put("status", status);
							mapUpdateShipbillHeader.put("status", status);
							shipbillNodeTrackingSaveVO.setStatus(status);
							shipbillNodeTrackingSaveVO.setNodeEvent(DataDictionaryConstant.SHIPBILL_NODE_STATUSNAME_PC);
							shipbillOperateLogSaveVO.setOperateEvent(DataDictionaryConstant.SHIPBILL_NODE_STATUSNAME_PC);
							shipbillOperateLogSaveVO.setOldStatus(DataDictionaryConstant.SHIPBILL_STATUS_DISPATCH);
							shipbillOperateLogSaveVO.setNewStatus(status);

						} else if (user.getUserType().equals(BussinessConstant.USER_TYPE_CYS)) {
							// 承运商账号
							// 判定下一步流程
							int status = businessFlowUtil.judgmentNextFlowSts(detailModel.getCarrierFlowConfig(), DataDictionaryConstant.FLOW_CONFIG_CHECK);

							mapUpdateLoadingDetail.put("carrierShipbillStatus", DataDictionaryConstant.CARRIER_SHIPBILL_STATUS_DISPATCHED_CHECK);
							mapUpdateShipbillHeader.put("carrierShipbillStatus", DataDictionaryConstant.CARRIER_SHIPBILL_STATUS_DISPATCHED_CHECK);
							mapUpdateLoadingDetail.put("status", status);
							mapUpdateShipbillHeader.put("status", status);
							shipbillNodeTrackingSaveVO.setStatus(status);
							shipbillOperateLogSaveVO.setOldStatus(DataDictionaryConstant.CARRIER_SHIPBILL_STATUS_DISPATCHED);
							shipbillOperateLogSaveVO.setNewStatus(status);

							shipbillNodeTrackingSaveVO.setNodeEvent(DataDictionaryConstant.CARRIER_SHIPBILL_NODE_STATUSNAME_PC);
							shipbillOperateLogSaveVO.setOperateEvent(DataDictionaryConstant.CARRIER_SHIPBILL_NODE_STATUSNAME_PC);
						}

						// 更新运输记录表的调度审核时间
						Criteria criteriaTransLog = Criteria.forClass(TmsShipbillTransLogModel.class);
						Restriction r3 = Restrictions.eq(TmsShipbillTransLogModel::getShipbillId, detailModel.getShipbillId());
						Restriction r4 = Restrictions.eq(TmsShipbillTransLogModel::getEnterpriseId, user.getEnterpriseId());
						criteriaTransLog.setRestriction(Restrictions.and(r3, r4));

						Map<String, Object> mapUpdate = Maps.newHashMap();
						mapUpdate.put("updateperson", user.getNickname());
						mapUpdate.put("updatetime", date);
						mapUpdate.put("disCheckDt", date);
						tmsShipbillTransportLogMapper.updateMapByCriteria(mapUpdate, criteriaTransLog);

					} else {
						// 匹配到审批流程
						if (user.getUserType().equals(BussinessConstant.USER_TYPE_ZY)) {
							// 自有账号
							mapUpdateLoadingDetail.put("status", DataDictionaryConstant.SHIPBILL_STATUS_DISPATCH_CHECK_APPROVAL);
							mapUpdateShipbillHeader.put("status", DataDictionaryConstant.SHIPBILL_STATUS_DISPATCH_CHECK_APPROVAL);
							shipbillNodeTrackingSaveVO.setStatus(DataDictionaryConstant.SHIPBILL_STATUS_DISPATCH_CHECK_APPROVAL);
							shipbillNodeTrackingSaveVO.setNodeEvent(DataDictionaryConstant.SHIPBILL_NODE_STATUSNAME_DIS_APPROVAL);
							shipbillOperateLogSaveVO.setOperateEvent(DataDictionaryConstant.SHIPBILL_NODE_STATUSNAME_DIS_APPROVAL);
							shipbillOperateLogSaveVO.setOldStatus(DataDictionaryConstant.SHIPBILL_STATUS_DISPATCH);
							shipbillOperateLogSaveVO.setNewStatus(DataDictionaryConstant.SHIPBILL_STATUS_DISPATCH_CHECK_APPROVAL);

						} else if (user.getUserType().equals(BussinessConstant.USER_TYPE_CYS)) {
							// 承运商账号
							mapUpdateLoadingDetail.put("carrierShipbillStatus", DataDictionaryConstant.CARRIER_SHIPBILL_STATUS_DISPATCHED_APPROVAL);
							mapUpdateShipbillHeader.put("carrierShipbillStatus", DataDictionaryConstant.CARRIER_SHIPBILL_STATUS_DISPATCHED_APPROVAL);
							shipbillNodeTrackingSaveVO.setStatus(DataDictionaryConstant.CARRIER_SHIPBILL_STATUS_DISPATCHED_APPROVAL);
							shipbillOperateLogSaveVO.setOldStatus(DataDictionaryConstant.CARRIER_SHIPBILL_STATUS_DISPATCHED);
							shipbillOperateLogSaveVO.setNewStatus(DataDictionaryConstant.CARRIER_SHIPBILL_STATUS_DISPATCHED_APPROVAL);

							shipbillNodeTrackingSaveVO.setNodeEvent(DataDictionaryConstant.CARRIER_SHIPBILL_NODE_STATUSNAME_DIS_APPROVAL);
							shipbillOperateLogSaveVO.setOperateEvent(DataDictionaryConstant.CARRIER_SHIPBILL_NODE_STATUSNAME_DIS_APPROVAL);
						}
					}
					// 调度司机
					if (DataDictionaryConstant.LINE_CARRIER_TYPE_SJ.equals(detailModel.getCarrierType())) {
						mapUpdateShipbillHeader.put("vehicleTypeCategory", tmsLoadingBillHeaderModel.getVehicleTypeCategory());
						mapUpdateLoadingDetail.put("vehicleTypeCategory", tmsLoadingBillHeaderModel.getVehicleTypeCategory());
						// 冷藏冷冻恒温的运单
						if (!DataDictionaryConstant.TEMPERATURE_REQUIREMENT_CW.equals(detailModel.getTemperatureRequirement())) {
							mapUpdateShipbillHeader.put("vehicleDeviceId", tmsLoadingBillHeaderModel.getVehicleDeviceId());
							mapUpdateShipbillHeader.put("vehicleDeviceCode", tmsLoadingBillHeaderModel.getVehicleDeviceCode());
							mapUpdateShipbillHeader.put("vehicleDeviceName", tmsLoadingBillHeaderModel.getVehicleDeviceName());
							mapUpdateLoadingDetail.put("vehicleDeviceId", tmsLoadingBillHeaderModel.getVehicleDeviceId());
							mapUpdateLoadingDetail.put("vehicleDeviceCode", tmsLoadingBillHeaderModel.getVehicleDeviceCode());
							mapUpdateLoadingDetail.put("vehicleDeviceName", tmsLoadingBillHeaderModel.getVehicleDeviceName());
						}
					}
					// 更新运单计划发货件数
					Criteria shipBillCriteria = Criteria.forClass(TmsShipbillDetailModel.class);
					Restriction shipBillRestriction = Restrictions.eq("shipbillId", detailModel.getShipbillId());
					shipBillCriteria.setRestriction(shipBillRestriction);
					List<TmsShipbillDetailModel> tmsShipbillDetailModelList = tmsShipbillDetailMapper.findByCriteria(shipBillCriteria);
					if (CollectionUtil.isNotEmpty(tmsShipbillDetailModelList)) {
						tmsShipbillDetailModelList.forEach(tmsShipbillDetailModel -> {
							tmsShipbillDetailModel.setPlanDeliveryPcs(tmsShipbillDetailModel.getPcs());
							tmsShipbillDetailModel.setUpdateperson(user.getNickname());
							tmsShipbillDetailModel.setUpdatetime(date);
							tmsShipbillDetailMapper.update(tmsShipbillDetailModel);
						});
					}
					// 更改运单状态
					tmsShipbillHeaderMapper.updateMapById(detailModel.getShipbillId(), mapUpdateShipbillHeader, TmsShipbillHeaderModel.class);
					// 更新派车单明细状态
					tmsLoadingBillDetailMapper.updateMapById(detailModel.getId(), mapUpdateLoadingDetail, TmsLoadingBillDetailModel.class);
					// 新增节点信息
					shipbillNodeTrackingSaveVO.setShipbillId(detailModel.getShipbillId());
					shipbillNodeTrackingSaveVO.setShipbillNo(detailModel.getShipbillNo());
					shipbillNodeTrackingService.addShipbillNodeTrackingData(shipbillNodeTrackingSaveVO,user);

					// 新增日志信息
					shipbillOperateLogSaveVO.setShipbillId(detailModel.getShipbillId());
					shipbillOperateLogSaveVO.setShipbillNo(detailModel.getShipbillNo());
					shipbillOperateLogSaveVO.setOperateEvent(DataDictionaryConstant.SHIPBILL_NODE_STATUSNAME_PC);
					shipbillOperateLogService.addShipbillOperateLogData(shipbillOperateLogSaveVO,user);
					TmsShipbillHeaderModel shipbillHeaderModel = tmsShipbillHeaderMapper.findById(detailModel.getShipbillId(),TmsShipbillHeaderModel.class);
					if (ToolKits.isNotEmpty(shipbillHeaderModel)
							&& DataDictionaryConstant.CARRIERS_TYPE_EXPRESS.equals(shipbillHeaderModel.getCarriersType())) {
						pickUpShipBillIds.add(shipbillHeaderModel.getShipbillId());
					}
				}
				// 更改派车单状态
				// 装车单类型
				if (shipperTypeCnt == tmsLoadingBillDetailModels.size()) {
					tmsLoadingBillHeaderModel.setLoadingBillType(DataDictionaryConstant.LOADING_BILL_TYPE_CK);
				} else if (consigneeType == tmsLoadingBillDetailModels.size()) {
					tmsLoadingBillHeaderModel.setLoadingBillType(DataDictionaryConstant.LOADING_BILL_TYPE_RK);
				} else {
					tmsLoadingBillHeaderModel.setLoadingBillType(DataDictionaryConstant.LOADING_BILL_TYPE_QT);
				}
				tmsLoadingBillHeaderModel.setUpdateperson(user.getNickname());
				tmsLoadingBillHeaderModel.setUpdatetime(date);
				tmsLoadingBillHeaderMapper.update(tmsLoadingBillHeaderModel);

				loadingBillIds.add(tmsLoadingBillHeaderModel.getLoadingBillId());
			} else {
				tmsLoadingBillHeaderModel.setStatus(tmsLoadingBillHeaderModel.getOldStatus());
				tmsLoadingBillHeaderModel.setOldStatus(null);
				tmsLoadingBillHeaderModel.setUpdateperson(user.getNickname());
				tmsLoadingBillHeaderModel.setUpdatetime(date);
				tmsLoadingBillHeaderMapper.update(tmsLoadingBillHeaderModel);
			}
			MessageTypeEnum messageTypeEnum = MessageTypeEnum.SELF_DISPATCH_AUDIT;
			if (user.getUserType().equals(BussinessConstant.USER_TYPE_CYS)) {
				messageTypeEnum = MessageTypeEnum.CARRIER_DISPATCH_AUDIT;
			}
			MessageUtil.addMessage(new SendMessageDTO(MessageOrderTypeEnum.LOADING_NO.getCode(), messageTypeEnum.getCode(), Lists.newArrayList(tmsLoadingBillHeaderModel.getLoadingBillId())));
		}
		// 更新站点数
		loadingBillService.updateStationByLoadingBillIdList(loadingBillIds);

		if (ToolKits.isNotEmpty(pickUpShipBillIds)) {
			WaitPickUpGoodsStartShipmentVO pickUpVO = new WaitPickUpGoodsStartShipmentVO();
			pickUpVO.setShipbillIds(pickUpShipBillIds);
			pickUpVO.setDepartureMemo("三方快递自动启运登记");
			pickUpVO.setDepartureTime(DateUtil.date());
			log.info("三方快递{}自动启运...", JSONObject.toJSONString(pickUpShipBillIds));
			pickUpGoodsService.autoStartShipmentData(pickUpVO);
		}
	}

	/**
	 * 已派车地图查询
	 *
	 * @param ids
	 * @return
	 */
	@Override
	public List<SendCarMapDTO> sendcarMapQueryData(List<String> ids) {
		ToolKits.isParamNull(ids, "派车单ID不为空");

		UserEntity user = PlgFxUsrUtils.getUserEntity();
		ToolKits.isParamNull(user, "当前人员没有操作权限");
		if (!user.getUserType().equals(BussinessConstant.USER_TYPE_ZY) && !user.getUserType().equals(BussinessConstant.USER_TYPE_CYS)) {
			ToolKits.isParamNull(user, "当前人员没有操作权限");
		}

		// 返回数据集
		List<SendCarMapDTO> list = Lists.newArrayList();

		List<TmsLoadingBillHeaderModel> tmsLoadingBillHeaderModels = tmsLoadingBillHeaderMapper.findByIds(TmsLoadingBillHeaderModel.class, ids.toArray(), null);

		for (TmsLoadingBillHeaderModel tmsLoadingBillHeaderModel : tmsLoadingBillHeaderModels) {
			SendCarMapDTO dto = new SendCarMapDTO();
			BeanUtils.copyProperties(tmsLoadingBillHeaderModel, dto);

			// 明细数据集
			List<SendCarMapDetailDTO> sendCarMapDetailDTOS = Lists.newArrayList();

			// 封装明细数据
			Criteria criteria = Criteria.forClass(TmsLoadingBillDetailModel.class);
			Restriction r1 = Restrictions.eq("loadingBillId", tmsLoadingBillHeaderModel.getLoadingBillId());
			criteria.setRestriction(r1);
			criteria.setOrder(Order.newInstance().asc(new String[] { "shippingOrder" }));

			List<TmsLoadingBillDetailModel> tmsLoadingBillDetailModels = tmsLoadingBillDetailMapper.findByCriteria(criteria);
			for (TmsLoadingBillDetailModel tmsLoadingBillDetailModel : tmsLoadingBillDetailModels) {
				SendCarMapDetailDTO sendCarMapDetailDTO = new SendCarMapDetailDTO();
				BeanUtils.copyProperties(tmsLoadingBillDetailModel, sendCarMapDetailDTO);

				sendCarMapDetailDTOS.add(sendCarMapDetailDTO);
			}

			dto.setSendCarMapDetailDTOS(sendCarMapDetailDTOS);

			list.add(dto);
		}

		return list;
	}

	@Override
	public List<LoadingBillMapDTO> loadingBillMap(List<String> ids) {
		ToolKits.isParamNull(ids, "派车单ID不为空");
		List<TmsLoadingBillHeaderModel> tmsLoadingBillHeaderModelList = tmsLoadingBillHeaderMapper.findByIds(TmsLoadingBillHeaderModel.class, ids.toArray(), null);
		if (CollectionUtil.isEmpty(tmsLoadingBillHeaderModelList)) {
			throw new BizException("派车单不存在，ids=" + JSON.toJSONString(ids));
		}
		List<SysRefdatadModel> dicData = convertorUtil.getDictionary(new String[] { DataDictionaryConstant.SHIPPER_TYPE, DataDictionaryConstant.CONSIGNEE_TYPE });
		return tmsLoadingBillHeaderModelList.stream().map(tmsLoadingBillHeaderModel -> {
			LoadingBillMapDTO dto = BeanUtil.copyProperties(tmsLoadingBillHeaderModel, LoadingBillMapDTO.class);
			Criteria criteria = Criteria.forClass(TmsLoadingBillDetailModel.class);
			Restriction r1 = Restrictions.eq("loadingBillId", tmsLoadingBillHeaderModel.getLoadingBillId());
			criteria.setRestriction(r1);
			criteria.setOrder(Order.newInstance().asc(new String[] { "shippingOrder" }));
			List<TmsLoadingBillDetailModel> tmsLoadingBillDetailModelList = tmsLoadingBillDetailMapper.findByCriteria(criteria);

			if (CollectionUtil.isNotEmpty(tmsLoadingBillDetailModelList)) {
				dto.setLoadingBillDetailMapList(tmsLoadingBillDetailModelList.stream().flatMap(tmsLoadingBillDetailModel -> {
					LoadingBillDetailMapDTO detailMapDTO1 = BeanUtil.copyProperties(tmsLoadingBillDetailModel, LoadingBillDetailMapDTO.class);
					detailMapDTO1.setStationOrder(ObjectUtil.isNull(tmsLoadingBillDetailModel.getPickUpOrder()) ? 0 : tmsLoadingBillDetailModel.getPickUpOrder());
					detailMapDTO1.setStationType(StationTypeEnum.SHIPPER.getCode());
					detailMapDTO1.setStationTypeName(StationTypeEnum.SHIPPER.getDesc());
					detailMapDTO1.setType(tmsLoadingBillDetailModel.getShipperType());
					detailMapDTO1.setTypeName(ConvertorUtil.getName(dicData, DataDictionaryConstant.SHIPPER_TYPE, String.valueOf(tmsLoadingBillDetailModel.getShipperType())));
					detailMapDTO1.setUnitId(tmsLoadingBillDetailModel.getShipperUnitId());
					detailMapDTO1.setUnitCode(tmsLoadingBillDetailModel.getShipperUnitCode());
					detailMapDTO1.setUnitName(tmsLoadingBillDetailModel.getShipperUnitName());
					detailMapDTO1.setCode(tmsLoadingBillDetailModel.getShipperCode());
					detailMapDTO1.setName(tmsLoadingBillDetailModel.getShipperName());
					detailMapDTO1.setContact(tmsLoadingBillDetailModel.getShipperContact());
					detailMapDTO1.setPhoneNumber(tmsLoadingBillDetailModel.getShipperPhoneNumber());
					detailMapDTO1.setLandlineNumber(tmsLoadingBillDetailModel.getShipperLandlineNumber());
					detailMapDTO1.setEmail(tmsLoadingBillDetailModel.getShipperEmail());
					detailMapDTO1.setRelatedPhoneNumber(tmsLoadingBillDetailModel.getShipperRelatedPhoneNumber());
					detailMapDTO1.setAddress(tmsLoadingBillDetailModel.getShipperAddress());
					detailMapDTO1.setLongitude(tmsLoadingBillDetailModel.getShipperLongitude());
					detailMapDTO1.setLatitude(tmsLoadingBillDetailModel.getShipperLatitude());

					LoadingBillDetailMapDTO detailMapDTO2 = BeanUtil.copyProperties(tmsLoadingBillDetailModel, LoadingBillDetailMapDTO.class);
					detailMapDTO2.setStationOrder(ObjectUtil.isNull(tmsLoadingBillDetailModel.getShippingOrder()) ? 0 : tmsLoadingBillDetailModel.getShippingOrder());
					detailMapDTO2.setStationType(StationTypeEnum.CONSIGNEE.getCode());
					detailMapDTO2.setStationTypeName(StationTypeEnum.CONSIGNEE.getDesc());
					detailMapDTO2.setType(tmsLoadingBillDetailModel.getConsigneeType());
					detailMapDTO2.setTypeName(ConvertorUtil.getName(dicData, DataDictionaryConstant.CONSIGNEE_TYPE, String.valueOf(tmsLoadingBillDetailModel.getConsigneeType())));
					detailMapDTO2.setUnitId(tmsLoadingBillDetailModel.getConsigneeUnitId());
					detailMapDTO2.setUnitCode(tmsLoadingBillDetailModel.getConsigneeUnitCode());
					detailMapDTO2.setUnitName(tmsLoadingBillDetailModel.getConsigneeUnitName());
					detailMapDTO2.setCode(tmsLoadingBillDetailModel.getConsigneeCode());
					detailMapDTO2.setName(tmsLoadingBillDetailModel.getConsigneeName());
					detailMapDTO2.setContact(tmsLoadingBillDetailModel.getConsigneeContact());
					detailMapDTO2.setPhoneNumber(tmsLoadingBillDetailModel.getConsigneePhoneNumber());
					detailMapDTO2.setLandlineNumber(tmsLoadingBillDetailModel.getConsigneeLandlineNumber());
					detailMapDTO2.setEmail(tmsLoadingBillDetailModel.getConsigneeEmail());
					detailMapDTO2.setRelatedPhoneNumber(tmsLoadingBillDetailModel.getConsigneeRelatedPhoneNumber());
					detailMapDTO2.setAddress(tmsLoadingBillDetailModel.getConsigneeAddress());
					detailMapDTO2.setLongitude(tmsLoadingBillDetailModel.getConsigneeLongitude());
					detailMapDTO2.setLatitude(tmsLoadingBillDetailModel.getConsigneeLatitude());
					return Stream.of(detailMapDTO1, detailMapDTO2);
				}).sorted(Comparator.comparing(LoadingBillDetailMapDTO::getStationOrder)).collect(Collectors.toList()));
			}
			return dto;
		}).collect(Collectors.toList());
	}

	@Transactional(rollbackFor = Exception.class)
	@Override
	public void saveLoadingBillMapOrder(List<LoadingBillMapVO> loadingBillMapVOList) {
		ToolKits.isParamNull(loadingBillMapVOList, "派车单ID不为空");
		UserEntity user = PlgFxUsrUtils.getUserEntity();
		loadingBillMapVOList.forEach(loadingBillMapVO -> {
			List<LoadingBillDetailMapVO> loadingBillDetailMapVOList = loadingBillMapVO.getLoadingBillDetailMapList();
			Map<String, List<LoadingBillDetailMapVO>> resultMap = loadingBillDetailMapVOList.stream().collect(Collectors.groupingBy(LoadingBillDetailMapVO::getId));
			resultMap.forEach((key, value) -> {
				LoadingBillDetailMapVO vo1 = value.get(0);
				LoadingBillDetailMapVO vo2 = value.get(1);
				Map<String, Object> mapUpdate = Maps.newHashMap();
				if (StationTypeEnum.SHIPPER.getCode().equals(vo1.getStationType())) {
					mapUpdate.put("pickUpOrder", vo1.getStationOrder());
				}
				if (StationTypeEnum.CONSIGNEE.getCode().equals(vo1.getStationType())) {
					mapUpdate.put("shippingOrder", vo1.getStationOrder());
				}
				if (StationTypeEnum.SHIPPER.getCode().equals(vo2.getStationType())) {
					mapUpdate.put("pickUpOrder", vo2.getStationOrder());
				}
				if (StationTypeEnum.CONSIGNEE.getCode().equals(vo2.getStationType())) {
					mapUpdate.put("shippingOrder", vo2.getStationOrder());
				}
				mapUpdate.put("updateperson", user.getNickname());
				mapUpdate.put("updatetime", new Date());
				tmsLoadingBillDetailMapper.updateMapById(key, mapUpdate, TmsLoadingBillDetailModel.class);
			});
		});
	}

	/**
	 * 已派车计算里程
	 *
	 * @param sendCarCalculateMileageVOS
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void calculateMileageData(List<SendCarCalculateMileageVO> sendCarCalculateMileageVOS) {
		ToolKits.isParamNull(sendCarCalculateMileageVOS, "计算里程参数不为空");

		UserEntity user = PlgFxUsrUtils.getUserEntity();
		ToolKits.isParamNull(user, "当前人员没有操作权限");
		if (!user.getUserType().equals(BussinessConstant.USER_TYPE_ZY) && !user.getUserType().equals(BussinessConstant.USER_TYPE_CYS)) {
			ToolKits.isParamNull(user, "当前人员没有操作权限");
		}

		for (SendCarCalculateMileageVO sendCarCalculateMileageVO : sendCarCalculateMileageVOS) {
			ToolKits.isParamNull(sendCarCalculateMileageVO.getLoadingBillId(), "派车单ID不为空");
			ToolKits.isParamNull(sendCarCalculateMileageVO.getTotalMileage(), "总里程不为空");

			TmsLoadingBillHeaderModel tmsLoadingBillHeaderModel = tmsLoadingBillHeaderMapper.findById(sendCarCalculateMileageVO.getLoadingBillId(), TmsLoadingBillHeaderModel.class);
			ToolKits.isParamNull(tmsLoadingBillHeaderModel, "派车单ID[" + sendCarCalculateMileageVO.getLoadingBillId() + "]有误,查询为空!");

			tmsLoadingBillHeaderModel.setTotalMileage(sendCarCalculateMileageVO.getTotalMileage());

			tmsLoadingBillHeaderMapper.update(tmsLoadingBillHeaderModel);
		}
	}

	/**
	 * 导出所有数据
	 *
	 * @param sendCarExportAllVO
	 * @return
	 */
	@Override
	public List<ExportSendCarDTO> exportAllSendCarData(SendCarExportAllVO sendCarExportAllVO) {
		ToolKits.isParamNull(sendCarExportAllVO, "汇总查询请求不为空");

		UserEntity user = PlgFxUsrUtils.getUserEntity();
		ToolKits.isParamNull(user, "当前人员没有操作权限");
		if (!user.getUserType().equals(BussinessConstant.USER_TYPE_ZY) && !user.getUserType().equals(BussinessConstant.USER_TYPE_CYS)) {
			ToolKits.isParamNull(user, "当前人员没有操作权限");
		}

		// 数据字典翻译数据集合
		List<Map<String, Object>> data1 = Lists.newArrayList();

		// 装车单状态
		RestMessage<List<Map<String, Object>>> restMessage1 = maindataTmsResource.getDropDownById(DataDictionaryConstant.LOADING_BILL_STATUS, null, null, null);
		if (!restMessage1.isSuccess()) {
			throw new RuntimeException("已派车状态翻译失败!");
		} else {
			data1 = restMessage1.getData();
		}

		// 添加查询条件
		Criteria criteria = Criteria.forClass(TmsLoadingBillHeaderModel.class);
		Restriction r1 = ToolKits.isEmpty(sendCarExportAllVO.getLoadingBillNo()) ? null : Restrictions.like("loadingBillNo", "%" + sendCarExportAllVO.getLoadingBillNo() + "%");
		Restriction r2 = ToolKits.isEmpty(sendCarExportAllVO.getStatus()) ? null : Restrictions.eq("status", sendCarExportAllVO.getStatus());
		Restriction r3 = ToolKits.isEmpty(sendCarExportAllVO.getCreateStartTime()) ? null : Restrictions.ge("createtime", sendCarExportAllVO.getCreateStartTime());
		Restriction r4 = ToolKits.isEmpty(sendCarExportAllVO.getCreateEndTime()) ? null : Restrictions.le("createtime", sendCarExportAllVO.getCreateEndTime());
		Restriction r5 = Restrictions.eq("carrierType", DataDictionaryConstant.LINE_CARRIER_TYPE_SJ);
		Restriction r6 = Restrictions.eq("enterpriseId", user.getEnterpriseId());
		Restriction r7 = null;
		if (user.getUserType().equals(BussinessConstant.USER_TYPE_ZY)) {
			r7 = Restrictions.eq("scheduleType", DataDictionaryConstant.SCHEDULE_TYPE_ZY);
		} else {
			r7 = Restrictions.eq("scheduleType", DataDictionaryConstant.SCHEDULE_TYPE_CYS);
		}
		criteria.setRestriction(Restrictions.and(r1, r2, r3, r4, r5, r6, r7));
		criteria.setOrder(Order.newInstance().desc(new String[] { "updatetime" }));

		List<TmsLoadingBillHeaderModel> tmsLoadingBillHeaderModels = tmsLoadingBillHeaderMapper.findByCriteria(criteria);

		// 返回数据集
		List<ExportSendCarDTO> exportSendCarDTOS = Lists.newArrayList();

		for (TmsLoadingBillHeaderModel tmsLoadingBillHeaderModel : tmsLoadingBillHeaderModels) {
			ExportSendCarDTO dto = new ExportSendCarDTO();
			BeanUtils.copyProperties(tmsLoadingBillHeaderModel, dto);

			dto.setStatusName(PublicMethods.change(data1, String.valueOf(tmsLoadingBillHeaderModel.getStatus())));

			exportSendCarDTOS.add(dto);
		}

		return exportSendCarDTOS;
	}

	/**
	 * 导出当前页数据
	 *
	 * @param sendCarExportPageVO
	 * @return
	 */
	@Override
	public List<ExportSendCarDTO> exportPageSendCarData(SendCarExportPageVO sendCarExportPageVO) {
		ToolKits.isParamNull(sendCarExportPageVO, "汇总查询请求不为空");
		ToolKits.isParamNull(sendCarExportPageVO.getPageNum(), "当前页码不为空");
		ToolKits.isParamNull(sendCarExportPageVO.getPageSize(), "每页条数不为空");

		UserEntity user = PlgFxUsrUtils.getUserEntity();
		ToolKits.isParamNull(user, "当前人员没有操作权限");
		if (!user.getUserType().equals(BussinessConstant.USER_TYPE_ZY) && !user.getUserType().equals(BussinessConstant.USER_TYPE_CYS)) {
			ToolKits.isParamNull(user, "当前人员没有操作权限");
		}

		// 数据字典翻译数据集合
		List<Map<String, Object>> data1 = Lists.newArrayList();

		// 装车单状态
		RestMessage<List<Map<String, Object>>> restMessage1 = maindataTmsResource.getDropDownById(DataDictionaryConstant.LOADING_BILL_STATUS, null, null, null);
		if (!restMessage1.isSuccess()) {
			throw new RuntimeException("已派车状态翻译失败!");
		} else {
			data1 = restMessage1.getData();
		}

		// 添加查询条件
		Criteria criteria = Criteria.forClass(TmsLoadingBillHeaderModel.class);
		Restriction r1 = ToolKits.isEmpty(sendCarExportPageVO.getLoadingBillNo()) ? null : Restrictions.like("loadingBillNo", "%" + sendCarExportPageVO.getLoadingBillNo() + "%");
		Restriction r2 = ToolKits.isEmpty(sendCarExportPageVO.getStatus()) ? null : Restrictions.eq("status", sendCarExportPageVO.getStatus());
		Restriction r3 = ToolKits.isEmpty(sendCarExportPageVO.getCreateStartTime()) ? null : Restrictions.ge("createtime", sendCarExportPageVO.getCreateStartTime());
		Restriction r4 = ToolKits.isEmpty(sendCarExportPageVO.getCreateEndTime()) ? null : Restrictions.le("createtime", sendCarExportPageVO.getCreateEndTime());
		Restriction r5 = Restrictions.eq("carrierType", DataDictionaryConstant.LINE_CARRIER_TYPE_SJ);
		Restriction r6 = Restrictions.eq("enterpriseId", user.getEnterpriseId());
		Restriction r7 = null;
		if (user.getUserType().equals(BussinessConstant.USER_TYPE_ZY)) {
			r7 = Restrictions.eq("scheduleType", DataDictionaryConstant.SCHEDULE_TYPE_ZY);
		} else {
			r7 = Restrictions.eq("scheduleType", DataDictionaryConstant.SCHEDULE_TYPE_CYS);
		}
		criteria.setRestriction(Restrictions.and(r1, r2, r3, r4, r5, r6, r7));
		criteria.setOrder(Order.newInstance().desc(new String[] { "updatetime" }));

		PageUtils.startPage(sendCarExportPageVO.getPageNum(), sendCarExportPageVO.getPageSize());
		List<TmsLoadingBillHeaderModel> tmsLoadingBillHeaderModels = tmsLoadingBillHeaderMapper.findByCriteria(criteria);

		// 返回数据集
		List<ExportSendCarDTO> exportSendCarDTOS = Lists.newArrayList();

		for (TmsLoadingBillHeaderModel tmsLoadingBillHeaderModel : tmsLoadingBillHeaderModels) {
			ExportSendCarDTO dto = new ExportSendCarDTO();
			BeanUtils.copyProperties(tmsLoadingBillHeaderModel, dto);

			dto.setStatusName(PublicMethods.change(data1, String.valueOf(tmsLoadingBillHeaderModel.getStatus())));

			exportSendCarDTOS.add(dto);
		}

		return exportSendCarDTOS;
	}

	/**
	 * 导出选中数据
	 *
	 * @param ids
	 * @return
	 */
	@Override
	public List<ExportSendCarDTO> exportChooseSendCarData(List<String> ids) {
		ToolKits.isParamNull(ids, "派车单ID不为空");

		UserEntity user = PlgFxUsrUtils.getUserEntity();
		ToolKits.isParamNull(user, "当前人员没有操作权限");
		if (!user.getUserType().equals(BussinessConstant.USER_TYPE_ZY) && !user.getUserType().equals(BussinessConstant.USER_TYPE_CYS)) {
			ToolKits.isParamNull(user, "当前人员没有操作权限");
		}

		// 数据字典翻译数据集合
		List<Map<String, Object>> data1 = Lists.newArrayList();

		// 装车单状态
		RestMessage<List<Map<String, Object>>> restMessage1 = maindataTmsResource.getDropDownById(DataDictionaryConstant.LOADING_BILL_STATUS, null, null, null);
		if (!restMessage1.isSuccess()) {
			throw new RuntimeException("已派车状态翻译失败!");
		} else {
			data1 = restMessage1.getData();
		}

		List<TmsLoadingBillHeaderModel> tmsLoadingBillHeaderModels = tmsLoadingBillHeaderMapper.findByIds(TmsLoadingBillHeaderModel.class, ids.toArray(), null);

		// 返回数据集
		List<ExportSendCarDTO> exportSendCarDTOS = Lists.newArrayList();

		for (TmsLoadingBillHeaderModel tmsLoadingBillHeaderModel : tmsLoadingBillHeaderModels) {
			ExportSendCarDTO dto = new ExportSendCarDTO();
			BeanUtils.copyProperties(tmsLoadingBillHeaderModel, dto);

			dto.setStatusName(PublicMethods.change(data1, String.valueOf(tmsLoadingBillHeaderModel.getStatus())));

			exportSendCarDTOS.add(dto);
		}

		return exportSendCarDTOS;
	}

	/**
	 * 打印派车单
	 *
	 * @param id
	 * @return
	 */
	@Override
	public Map<String, Object> printSendCarData(String id) {
		ToolKits.isParamNull(id, "派车单ID不为空");

		UserEntity user = PlgFxUsrUtils.getUserEntity();
		ToolKits.isParamNull(user, "当前人员没有操作权限");
		if (!user.getUserType().equals(BussinessConstant.USER_TYPE_ZY) && !user.getUserType().equals(BussinessConstant.USER_TYPE_CYS)) {
			ToolKits.isParamNull(user, "当前人员没有操作权限");
		}

		TmsLoadingBillHeaderModel tmsLoadingBillHeaderModel = tmsLoadingBillHeaderMapper.findById(id, TmsLoadingBillHeaderModel.class);

		SendCarPrintHeadDTO sendCarPrintHeadDTO = new SendCarPrintHeadDTO();
		BeanUtils.copyProperties(tmsLoadingBillHeaderModel, sendCarPrintHeadDTO);

		// 表格数据集
		List<SendCarPrintTableDTO> sendCarPrintTableDTOS = Lists.newArrayList();

		Criteria criteria = Criteria.forClass(TmsLoadingBillDetailModel.class);
		Restriction r1 = Restrictions.eq("loadingBillId", id);
		criteria.setRestriction(r1);
		List<TmsLoadingBillDetailModel> tmsLoadingBillDetailModels = tmsLoadingBillDetailMapper.findByCriteria(criteria);

		for (TmsLoadingBillDetailModel tmsLoadingBillDetailModel : tmsLoadingBillDetailModels) {
			SendCarPrintTableDTO dto = new SendCarPrintTableDTO();
			BeanUtils.copyProperties(tmsLoadingBillDetailModel, dto);

			sendCarPrintTableDTOS.add(dto);
		}

		// TODO print

		return null;
	}

	/**
	 * 派车单查看
	 *
	 * @param id
	 * @return
	 */
	@Override
	public SendCarViewDTO viewSendCarData(String id) {
		ToolKits.isParamNull(id, "派车单ID不为空");

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

		// 数据字典翻译数据集合
		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();

		// 承运方类型
		RestMessage<List<Map<String, Object>>> restMessage1 = maindataTmsResource.getDropDownById(DataDictionaryConstant.LINE_CARRIER_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();
		}
		// 订单类型
		RestMessage<List<Map<String, Object>>> restMessage8 = maindataTmsResource.getDropDownById(DataDictionaryConstant.ORDER_TYPE, null, null, null);
		if (!restMessage8.isSuccess()) {
			throw new RuntimeException("订单类型翻译失败!");
		} else {
			data8 = restMessage8.getData();
		}

		TmsLoadingBillHeaderModel tmsLoadingBillHeaderModel = tmsLoadingBillHeaderMapper.findById(id, TmsLoadingBillHeaderModel.class);

		SendCarViewDTO dto = new SendCarViewDTO();
		BeanUtils.copyProperties(tmsLoadingBillHeaderModel, dto);

		// 拼接显示
		dto.setDriver(this.splicing(tmsLoadingBillHeaderModel.getDriverName(), tmsLoadingBillHeaderModel.getViceDriverName()));
		dto.setDeliveryman(this.splicing(tmsLoadingBillHeaderModel.getDeliverymanName(), tmsLoadingBillHeaderModel.getViceDeliverymanName()));
		dto.setLoadingRate(this.splicing(tmsLoadingBillHeaderModel.getWeightLoadingRate(), tmsLoadingBillHeaderModel.getVolumeLoadingRate()));

		// 承运方类型翻译
		dto.setCarrierTypeName(PublicMethods.change(data1, String.valueOf(dto.getCarrierType())));

		// 封装运单明细
		Criteria criteria = Criteria.forClass(TmsLoadingBillDetailModel.class);
		Restriction r1 = Restrictions.eq("loadingBillId", tmsLoadingBillHeaderModel.getLoadingBillId());
		criteria.setRestriction(r1);
		criteria.setOrder(Order.newInstance().asc(new String[] { "shippingOrder" }));

		List<TmsLoadingBillDetailModel> tmsLoadingBillDetailModels = tmsLoadingBillDetailMapper.findByCriteria(criteria);

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

		for (TmsLoadingBillDetailModel model : tmsLoadingBillDetailModels) {

			SendCarViewDetailDTO sendCarViewDetailDTO = new SendCarViewDetailDTO();
			BeanUtils.copyProperties(model, sendCarViewDetailDTO);

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

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

			list.add(sendCarViewDetailDTO);
		}

		dto.setSendCarViewDetailDTOS(list);

		return dto;
	}

	/**
	 * 派车单根据单号查看
	 *
	 * @param id
	 * @return
	 */
	@Override
	public SendCarViewByIdDTO viewSendCarByIdData(String id) {
		ToolKits.isParamNull(id, "派车单ID不为空");

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

		List<SysRefdatadModel> dicData = convertorUtil.getDictionary(new String[] { DataDictionaryConstant.LINE_CARRIER_TYPE, // 承运方类型
				DataDictionaryConstant.ORDER_BUSINESS_TYPE, // 订单业务类型
				DataDictionaryConstant.DELIVERY_METHOD_TYPE, // 配送方式
				DataDictionaryConstant.TRANSPORT_TYPE, // 运输类型
				DataDictionaryConstant.TEMPERATURE_REQUIREMENT, // 温度要求
				DataDictionaryConstant.SHIPPER_TYPE, // 发货方类型
				DataDictionaryConstant.CONSIGNEE_TYPE, // 收货方类型
				DataDictionaryConstant.ORDER_TYPE, // 订单类型
				DataDictionaryConstant.CARRIER_SYS_FLAG, // 承运商系统标志
				DataDictionaryConstant.VEHICLE_TYPE_CATEGORY // 车辆类别
		});

		TmsLoadingBillHeaderModel tmsLoadingBillHeaderModel = tmsLoadingBillHeaderMapper.findById(id, TmsLoadingBillHeaderModel.class);

		SendCarViewByIdDTO dto = new SendCarViewByIdDTO();
		BeanUtils.copyProperties(tmsLoadingBillHeaderModel, dto);

		// 拼接显示
		dto.setDriverId(this.splicing(ToolKits.isEmpty(tmsLoadingBillHeaderModel.getDriverId()) ? null : tmsLoadingBillHeaderModel.getDriverId().toString(), tmsLoadingBillHeaderModel.getViceDriverId()));
		dto.setDriverCode(this.splicing(tmsLoadingBillHeaderModel.getDriverCode(), tmsLoadingBillHeaderModel.getViceDriverCode()));
		dto.setDriverName(this.splicing(tmsLoadingBillHeaderModel.getDriverName(), tmsLoadingBillHeaderModel.getViceDriverName()));
		dto.setDriverPhoneNumber(this.splicing(tmsLoadingBillHeaderModel.getDriverPhoneNumber(), tmsLoadingBillHeaderModel.getViceDriverPhoneNumber()));
		dto.setDeliverymanId(this.splicing(ToolKits.isEmpty(tmsLoadingBillHeaderModel.getDeliverymanId()) ? null : tmsLoadingBillHeaderModel.getDeliverymanId().toString(), tmsLoadingBillHeaderModel.getViceDeliverymanId()));
		dto.setDeliverymanCode(this.splicing(tmsLoadingBillHeaderModel.getDeliverymanCode(), tmsLoadingBillHeaderModel.getViceDeliverymanCode()));
		dto.setDeliverymanName(this.splicing(tmsLoadingBillHeaderModel.getDeliverymanName(), tmsLoadingBillHeaderModel.getViceDeliverymanName()));
		dto.setDeliverymanPhoneNumber(this.splicing(tmsLoadingBillHeaderModel.getDeliverymanPhoneNumber(), tmsLoadingBillHeaderModel.getViceDeliverymanPhoneNumber()));
		dto.setLoadingRate(this.splicing(tmsLoadingBillHeaderModel.getWeightLoadingRate(), tmsLoadingBillHeaderModel.getVolumeLoadingRate()));
		dto.setCarrierSysFlagName(ConvertorUtil.getName(dicData, DataDictionaryConstant.CARRIER_SYS_FLAG, String.valueOf(tmsLoadingBillHeaderModel.getCarrierSysFlag())));

		// 承运方类型翻译
		dto.setCarrierTypeName(ConvertorUtil.getName(dicData, DataDictionaryConstant.LINE_CARRIER_TYPE, String.valueOf(dto.getCarrierType())));
		dto.setVehicleTypeCategoryName(ConvertorUtil.getName(dicData, DataDictionaryConstant.VEHICLE_TYPE_CATEGORY, String.valueOf(dto.getVehicleTypeCategory())));

		// 封装运单明细
		Criteria criteria = Criteria.forClass(TmsLoadingBillDetailModel.class);
		Restriction r1 = Restrictions.eq("loadingBillId", tmsLoadingBillHeaderModel.getLoadingBillId());
		criteria.setRestriction(r1);
		criteria.setOrder(Order.newInstance().asc(new String[] { "shippingOrder" }));

		List<TmsLoadingBillDetailModel> tmsLoadingBillDetailModels = tmsLoadingBillDetailMapper.findByCriteria(criteria);

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

		for (TmsLoadingBillDetailModel model : tmsLoadingBillDetailModels) {

			SendCarViewDetailByIdDTO sendCarViewDetailByIdDTO = new SendCarViewDetailByIdDTO();
			BeanUtils.copyProperties(model, sendCarViewDetailByIdDTO);

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

			// 类型翻译
			sendCarViewDetailByIdDTO.setOrderBusinessTypeName(ConvertorUtil.getName(dicData, DataDictionaryConstant.ORDER_BUSINESS_TYPE, String.valueOf(sendCarViewDetailByIdDTO.getOrderBusinessType())));
			sendCarViewDetailByIdDTO.setDeliveryMethodTypeName(ConvertorUtil.getName(dicData, DataDictionaryConstant.DELIVERY_METHOD_TYPE, String.valueOf(sendCarViewDetailByIdDTO.getDeliveryMethodType())));
			sendCarViewDetailByIdDTO.setTransportTypeName(ConvertorUtil.getName(dicData, DataDictionaryConstant.TRANSPORT_TYPE, String.valueOf(sendCarViewDetailByIdDTO.getTransportType())));
			sendCarViewDetailByIdDTO.setTemperatureRequirementName(ConvertorUtil.getName(dicData, DataDictionaryConstant.TEMPERATURE_REQUIREMENT, String.valueOf(sendCarViewDetailByIdDTO.getTemperatureRequirement())));
			sendCarViewDetailByIdDTO.setShipperTypeName(ConvertorUtil.getName(dicData, DataDictionaryConstant.SHIPPER_TYPE, String.valueOf(sendCarViewDetailByIdDTO.getShipperType())));
			sendCarViewDetailByIdDTO.setConsigneeTypeName(ConvertorUtil.getName(dicData, DataDictionaryConstant.CONSIGNEE_TYPE, String.valueOf(sendCarViewDetailByIdDTO.getConsigneeType())));
			sendCarViewDetailByIdDTO.setOrderTypeName(ConvertorUtil.getName(dicData, DataDictionaryConstant.ORDER_TYPE, String.valueOf(sendCarViewDetailByIdDTO.getOrderType())));
			list.add(sendCarViewDetailByIdDTO);
		}

		dto.setSendCarViewDetailByIdDTOS(list);

		return dto;
	}

	/**
	 * 已派车配载运单查询
	 *
	 * @param sendCarPageDetailVO
	 * @return
	 */
	@SuppressWarnings("resource")
	@Override
	public Page<SendCarPageDetailDTO> pageDetailSendCarData(SendCarPageDetailVO sendCarPageDetailVO) {
		ToolKits.isParamNull(sendCarPageDetailVO, "明细查询请求不为空");
		ToolKits.isParamNull(sendCarPageDetailVO.getPageNum(), "当前页码不为空");
		ToolKits.isParamNull(sendCarPageDetailVO.getPageSize(), "每页条数不为空");
		ToolKits.isParamNull(sendCarPageDetailVO.getLoadingBillId(), "派车单ID不为空");

		UserEntity user = PlgFxUsrUtils.getUserEntity();
		ToolKits.isParamNull(user, "当前人员没有操作权限");
		if (!user.getUserType().equals(BussinessConstant.USER_TYPE_ZY) && !user.getUserType().equals(BussinessConstant.USER_TYPE_CYS)) {
			ToolKits.isParamNull(user, "当前人员没有操作权限");
		}

		// 数据字典翻译数据集合
		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<SysRefdatadModel> dicData = convertorUtil.getDictionary(new String[] { DataDictionaryConstant.DELIVERY_METHOD_TYPE, // 配送方式
				DataDictionaryConstant.TRANSPORT_TYPE, // 运输类型(运输模式)
				DataDictionaryConstant.TEMPERATURE_REQUIREMENT, // 温度要求
				DataDictionaryConstant.SHIPPER_TYPE, // 发货方类型
				DataDictionaryConstant.CONSIGNEE_TYPE, // 收货方类型
				DataDictionaryConstant.ORDER_TYPE, // 订单类型
				DataDictionaryConstant.LINE_DIRECTION, // 线路方向
				DataDictionaryConstant.ORDER_BUSINESS_TYPE // 订单业务类型
		});
		List<SignconfigPopDTO> data8 = Lists.newArrayList();

		// 标记配置
		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(TmsLoadingBillDetailModel.class);
		Restriction r1 = Restrictions.eq("loadingBillId", sendCarPageDetailVO.getLoadingBillId());
		criteria.setRestriction(r1);
		criteria.setOrder(Order.newInstance().asc(new String[] { "shippingOrder" }));

		PageUtils.startPage(sendCarPageDetailVO.getPageNum(), sendCarPageDetailVO.getPageSize());
		List<TmsLoadingBillDetailModel> tmsLoadingBillDetailModels = tmsLoadingBillDetailMapper.findByCriteria(criteria);

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

		for (TmsLoadingBillDetailModel model : tmsLoadingBillDetailModels) {

			SendCarPageDetailDTO sendCarPageDetailDTO = new SendCarPageDetailDTO();
			BeanUtils.copyProperties(model, sendCarPageDetailDTO);

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

			StringBuffer consigneeProvinceCityDistrict = new StringBuffer();
			// 目的地
			if (ToolKits.isNotEmpty(model.getConsigneeProvinceName())) {
				consigneeProvinceCityDistrict.append(model.getConsigneeProvinceName());
			}
			if (ToolKits.isNotEmpty(model.getConsigneeCityName())) {
				consigneeProvinceCityDistrict.append(model.getConsigneeCityName());
			}
			if (ToolKits.isNotEmpty(model.getConsigneeDistrictName())) {
				consigneeProvinceCityDistrict.append(model.getConsigneeDistrictName());
			}
			sendCarPageDetailDTO.setConsigneeProvinceCityDistrict(consigneeProvinceCityDistrict.toString());
			// 始发地
			StringBuffer shipperProvinceCityDistrict = new StringBuffer();
			if (ToolKits.isNotEmpty(model.getShipperProvinceName())) {
				shipperProvinceCityDistrict.append(model.getShipperProvinceName());
			}
			if (ToolKits.isNotEmpty(model.getShipperCityName())) {
				shipperProvinceCityDistrict.append(model.getShipperCityName());
			}
			if (ToolKits.isNotEmpty(model.getShipperDistrictName())) {
				shipperProvinceCityDistrict.append(model.getShipperDistrictName());
			}
			sendCarPageDetailDTO.setShipperProvinceCityDistrict(shipperProvinceCityDistrict.toString());

			// 类型翻译
			sendCarPageDetailDTO.setOrderTypeName(ConvertorUtil.getName(dicData, DataDictionaryConstant.ORDER_TYPE, String.valueOf(sendCarPageDetailDTO.getOrderType())));
			sendCarPageDetailDTO.setOrderBusinessTypeName(ConvertorUtil.getName(dicData, DataDictionaryConstant.ORDER_BUSINESS_TYPE, String.valueOf(sendCarPageDetailDTO.getOrderBusinessType())));
			sendCarPageDetailDTO.setDeliveryMethodTypeName(ConvertorUtil.getName(dicData, DataDictionaryConstant.DELIVERY_METHOD_TYPE, String.valueOf(sendCarPageDetailDTO.getDeliveryMethodType())));
			sendCarPageDetailDTO.setTransportTypeName(ConvertorUtil.getName(dicData, DataDictionaryConstant.TRANSPORT_TYPE, String.valueOf(sendCarPageDetailDTO.getTransportType())));
			sendCarPageDetailDTO.setTemperatureRequirementName(ConvertorUtil.getName(dicData, DataDictionaryConstant.TEMPERATURE_REQUIREMENT, String.valueOf(sendCarPageDetailDTO.getTemperatureRequirement())));
			sendCarPageDetailDTO.setShipperTypeName(ConvertorUtil.getName(dicData, DataDictionaryConstant.SHIPPER_TYPE, String.valueOf(sendCarPageDetailDTO.getShipperType())));
			sendCarPageDetailDTO.setConsigneeTypeName(ConvertorUtil.getName(dicData, DataDictionaryConstant.CONSIGNEE_TYPE, String.valueOf(sendCarPageDetailDTO.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(sendCarPageDetailDTO.getOrderTypeName()) ? sendCarPageDetailDTO.getOrderTypeName() : "")) {
							sendCarPageDetailDTO.setBackground(ToolKits.isEmpty(signconfigPopDTO.getBackground()) ? "" : signconfigPopDTO.getBackground());
							sendCarPageDetailDTO.setColor(ToolKits.isEmpty(signconfigPopDTO.getColor()) ? "" : signconfigPopDTO.getColor());

							// 返回前端所需标记ID
							sendCarPageDetailDTO.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(sendCarPageDetailDTO.getOrderBusinessTypeName()) ? sendCarPageDetailDTO.getOrderBusinessTypeName() : "")) {
							sendCarPageDetailDTO.setBackground(ToolKits.isEmpty(signconfigPopDTO.getBackground()) ? "" : signconfigPopDTO.getBackground());
							sendCarPageDetailDTO.setColor(ToolKits.isEmpty(signconfigPopDTO.getColor()) ? "" : signconfigPopDTO.getColor());

							sendCarPageDetailDTO.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(sendCarPageDetailDTO.getTemperatureRequirementName()) ? sendCarPageDetailDTO.getTemperatureRequirementName() : "")) {
							sendCarPageDetailDTO.setBackground(ToolKits.isEmpty(signconfigPopDTO.getBackground()) ? "" : signconfigPopDTO.getBackground());
							sendCarPageDetailDTO.setColor(ToolKits.isEmpty(signconfigPopDTO.getColor()) ? "" : signconfigPopDTO.getColor());

							sendCarPageDetailDTO.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(sendCarPageDetailDTO.getDeliveryMethodTypeName()) ? sendCarPageDetailDTO.getDeliveryMethodTypeName() : "")) {
							sendCarPageDetailDTO.setBackground(ToolKits.isEmpty(signconfigPopDTO.getBackground()) ? "" : signconfigPopDTO.getBackground());
							sendCarPageDetailDTO.setColor(ToolKits.isEmpty(signconfigPopDTO.getColor()) ? "" : signconfigPopDTO.getColor());

							sendCarPageDetailDTO.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(model.getMemo()) ? model.getMemo() : "")) {
							sendCarPageDetailDTO.setBackground(ToolKits.isEmpty(signconfigPopDTO.getBackground()) ? "" : signconfigPopDTO.getBackground());
							sendCarPageDetailDTO.setColor(ToolKits.isEmpty(signconfigPopDTO.getColor()) ? "" : signconfigPopDTO.getColor());

							sendCarPageDetailDTO.setSignConfigId(signconfigPopDTO.getId());
							break Signconfig;
						}
					}
					break;
				}
			}

			list.add(sendCarPageDetailDTO);
		}

		// 分页重组
		Page<SendCarPageDetailDTO> page = PageUtils.getPage(list);
		if (tmsLoadingBillDetailModels instanceof com.github.pagehelper.Page) {
			com.github.pagehelper.Page<TmsLoadingBillDetailModel> p0 = (com.github.pagehelper.Page<TmsLoadingBillDetailModel>) tmsLoadingBillDetailModels;
			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;
	}

	/**
	 * 已派车配载运单添加
	 *
	 * @param sendCarAddDetailVO
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public List<ShipbillHeaderPageDTO> addDetailSendCarData(SendCarAddDetailVO sendCarAddDetailVO) {
		ToolKits.isParamNull(sendCarAddDetailVO.getLoadingBillId(), "派车单ID不为空");
		ToolKits.isParamNull(sendCarAddDetailVO.getShipbillIds(), "运单ID不为空");
		// 当前时间
		Date date = DateUtil.date();
		UserEntity user = PlgFxUsrUtils.getUserEntity();
		ToolKits.isParamNull(user, "当前人员没有操作权限");
		if (!user.getUserType().equals(BussinessConstant.USER_TYPE_ZY) && !user.getUserType().equals(BussinessConstant.USER_TYPE_CYS)) {
			ToolKits.isParamNull(user, "当前人员没有操作权限");
		}

		// 数据字典翻译数据集合
		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<SignconfigPopDTO> data9 = 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();
		}

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

		// 标记配置
		SignconfigPopVO signconfigPopVO = new SignconfigPopVO();
		RestMessage<List<SignconfigPopDTO>> restMessage9 = maindataTmsResource.getSignConfig(signconfigPopVO);
		if (!restMessage9.isSuccess()) {
			throw new RuntimeException("标记配置查询失败!");
		} else {
			data9 = restMessage9.getData();
		}

		TmsLoadingBillHeaderModel tmsLoadingBillHeaderModel = tmsLoadingBillHeaderMapper.findById(sendCarAddDetailVO.getLoadingBillId(), TmsLoadingBillHeaderModel.class);
		ToolKits.isParamNull(tmsLoadingBillHeaderModel, "派车单ID[" + sendCarAddDetailVO.getLoadingBillId() + "]有误");
		Assert.isTrue(ToolKits.isEmpty(tmsLoadingBillHeaderModel.getOldStatus()), "反审核派车单【" + tmsLoadingBillHeaderModel.getLoadingBillId() + "】不能添加运单！");

		List<TmsShipbillHeaderModel> tmsShipbillHeaderModels = tmsShipbillHeaderMapper.findByIds(TmsShipbillHeaderModel.class, sendCarAddDetailVO.getShipbillIds().toArray(), null);

		Criteria criteria = Criteria.forClass(TmsLoadingBillDetailModel.class);
		Restriction r1 = Restrictions.eq("loadingBillId", sendCarAddDetailVO.getLoadingBillId());
		Restriction r2 = Restrictions.in("shipbillId", sendCarAddDetailVO.getShipbillIds().toArray());
		criteria.setRestriction(Restrictions.and(r1, r2));
		List<TmsLoadingBillDetailModel> tmsLoadingBillDetailModelList = tmsLoadingBillDetailMapper.findByCriteria(criteria);
		if (ToolKits.isNotEmpty(tmsLoadingBillDetailModelList)) {
			throw new PrologException("运单ID[" + tmsLoadingBillDetailModelList.stream().map(TmsLoadingBillDetailModel::getShipbillId).collect(Collectors.joining(",")) + "]已被添加");
		}

		List<TmsLoadingBillDetailModel> tmsLoadingBillDetailModels = tmsLoadingBillDetailMapper.findByCriteria(criteria);
//		List<Integer> indexList = tmsLoadingBillDetailModels.stream().flatMap(tmsLoadingBillDetailModel ->
//				Stream.of(tmsLoadingBillDetailModel.getPickUpOrder(), tmsLoadingBillDetailModel.getShippingOrder())).
//				filter(ObjectUtil::isNotNull).collect(Collectors.toList());
		Integer index = maxStationOrderNumber(tmsLoadingBillDetailModels);
//		if (ToolKits.isEmpty(indexList)) {
//			index = 1;
//		} else {
//			index = Collections.max(indexList);
//		}

		// 客户数
		List<String> customerList = tmsLoadingBillDetailModels.stream().filter(o -> ToolKits.isNotEmpty(o.getConsigneeUnitName())).map(TmsLoadingBillDetailModel::getConsigneeUnitName).distinct().collect(Collectors.toList());

		// 站点数
		List<String> siteList = tmsLoadingBillDetailModels.stream().filter(o -> ToolKits.isNotEmpty(o.getConsigneeAddress())).map(TmsLoadingBillDetailModel::getConsigneeAddress).distinct().collect(Collectors.toList());

		// 明细保存集合
		List<TmsLoadingBillDetailModel> saveList = Lists.newArrayList();

		List<ShipbillHeaderPageDTO> dtoList = Lists.newArrayList();
		for (TmsShipbillHeaderModel tmsShipbillHeaderModel : tmsShipbillHeaderModels) {
			ShipbillHeaderPageDTO dto = new ShipbillHeaderPageDTO();
			BeanUtils.copyProperties(tmsShipbillHeaderModel, dto);

			dtoList.add(dto);

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

			// 类型翻译
			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.setStatusName(PublicMethods.change(data8, String.valueOf(dto.getStatus())));

			// 获取背景颜色和字体颜色
			Signconfig: for (SignconfigPopDTO signconfigPopDTO : data9) {
				// 标记类型匹配
				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(dto.getOrderTypeName()) ? dto.getOrderTypeName() : "")) {
							dto.setBackground(ToolKits.isEmpty(signconfigPopDTO.getBackground()) ? "" : signconfigPopDTO.getBackground());
							dto.setColor(ToolKits.isEmpty(signconfigPopDTO.getColor()) ? "" : signconfigPopDTO.getColor());

							// 返回前端所需标记ID
							dto.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(dto.getOrderBusinessTypeName()) ? dto.getOrderBusinessTypeName() : "")) {
							dto.setBackground(ToolKits.isEmpty(signconfigPopDTO.getBackground()) ? "" : signconfigPopDTO.getBackground());
							dto.setColor(ToolKits.isEmpty(signconfigPopDTO.getColor()) ? "" : signconfigPopDTO.getColor());

							// 返回前端所需标记ID
							dto.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(dto.getTemperatureRequirementName()) ? dto.getTemperatureRequirementName() : "")) {
							dto.setBackground(ToolKits.isEmpty(signconfigPopDTO.getBackground()) ? "" : signconfigPopDTO.getBackground());
							dto.setColor(ToolKits.isEmpty(signconfigPopDTO.getColor()) ? "" : signconfigPopDTO.getColor());

							// 返回前端所需标记ID
							dto.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(dto.getDeliveryMethodTypeName()) ? dto.getDeliveryMethodTypeName() : "")) {
							dto.setBackground(ToolKits.isEmpty(signconfigPopDTO.getBackground()) ? "" : signconfigPopDTO.getBackground());
							dto.setColor(ToolKits.isEmpty(signconfigPopDTO.getColor()) ? "" : signconfigPopDTO.getColor());

							// 返回前端所需标记ID
							dto.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(dto.getMemo()) ? dto.getMemo() : "")) {
							dto.setBackground(ToolKits.isEmpty(signconfigPopDTO.getBackground()) ? "" : signconfigPopDTO.getBackground());
							dto.setColor(ToolKits.isEmpty(signconfigPopDTO.getColor()) ? "" : signconfigPopDTO.getColor());

							// 返回前端所需标记ID
							dto.setSignConfigId(signconfigPopDTO.getId());

							break Signconfig;
						}
					}
					break;
				}
			}

			TmsLoadingBillDetailModel tmsLoadingBillDetailModel = new TmsLoadingBillDetailModel();
			BeanUtils.copyProperties(tmsShipbillHeaderModel, tmsLoadingBillDetailModel);

			ShipbillOperateLogSaveVO shipbillOperateLogSaveVO = new ShipbillOperateLogSaveVO();
			ShipbillNodeTrackingSaveVO shipbillNodeTrackingSaveVO = new ShipbillNodeTrackingSaveVO();
			if (user.getUserType().equals(BussinessConstant.USER_TYPE_ZY)) {
				// 修改装车单明细状态
				tmsLoadingBillDetailModel.setStatus(DataDictionaryConstant.SHIPBILL_STATUS_DISPATCH);
				// 修改运单状态
				tmsShipbillHeaderModel.setStatus(DataDictionaryConstant.SHIPBILL_STATUS_DISPATCH);
				// 日志状态
				shipbillOperateLogSaveVO.setOldStatus(DataDictionaryConstant.SHIPBILL_STATUS_YTJ);
				shipbillOperateLogSaveVO.setNewStatus(DataDictionaryConstant.SHIPBILL_STATUS_DISPATCH);
				// 节点状态
				shipbillNodeTrackingSaveVO.setStatus(DataDictionaryConstant.SHIPBILL_STATUS_DISPATCH);
			} else {
				// 修改装车单明细状态
				tmsLoadingBillDetailModel.setCarrierShipbillStatus(DataDictionaryConstant.CARRIER_SHIPBILL_STATUS_DISPATCHED);
				// 修改运单状态
				tmsShipbillHeaderModel.setCarrierShipbillStatus(DataDictionaryConstant.CARRIER_SHIPBILL_STATUS_DISPATCHED);
				// 日志状态
				shipbillOperateLogSaveVO.setOldStatus(DataDictionaryConstant.CARRIER_SHIPBILL_STATUS_AUDITED);
				shipbillOperateLogSaveVO.setNewStatus(DataDictionaryConstant.CARRIER_SHIPBILL_STATUS_DISPATCHED);
				// 节点状态
				shipbillNodeTrackingSaveVO.setStatus(DataDictionaryConstant.CARRIER_SHIPBILL_STATUS_DISPATCHED);

			}

			// 获取派车单明细ID
			RestMessage<String> restMessage = maindataTmsResource.getCodeNumberByCode(SeriaNnumberConstant.TMS_LOADING_BILL_DETAIL_ID, "L");
			if (!restMessage.isSuccess()) {
				throw new RuntimeException("生成派车单明细ID失败");
			}
			String id = restMessage.getData();
			tmsLoadingBillDetailModel.setCreateperson(user.getNickname());
			tmsLoadingBillDetailModel.setCreatetime(date);
			tmsLoadingBillDetailModel.setId(id);
			// 提货顺序
			index++;
			tmsLoadingBillDetailModel.setPickUpOrder(index);
			// 配送顺序
			index++;
			tmsLoadingBillDetailModel.setShippingOrder(index);
			tmsLoadingBillDetailModel.setLoadingBillId(sendCarAddDetailVO.getLoadingBillId());
			tmsLoadingBillDetailModel.setLoadingBillNo(sendCarAddDetailVO.getLoadingBillId());
			tmsLoadingBillDetailModel.setFlowConfig(tmsShipbillHeaderModel.getFlowConfig());
			saveList.add(tmsLoadingBillDetailModel);

			// 重量体积件数
			tmsLoadingBillHeaderModel.setTotalPcs(tmsLoadingBillHeaderModel.getTotalPcs().add(tmsLoadingBillDetailModel.getTotalPcs()));
			tmsLoadingBillHeaderModel.setTotalVolume(tmsLoadingBillHeaderModel.getTotalVolume().add(tmsLoadingBillDetailModel.getTotalVolume()));
			tmsLoadingBillHeaderModel.setTotalWeight(tmsLoadingBillHeaderModel.getTotalWeight().add(tmsLoadingBillDetailModel.getTotalWeight()));

			// 实际重量体积件数
			tmsLoadingBillHeaderModel.setActualTotalPcs(tmsLoadingBillHeaderModel.getActualTotalPcs().add(tmsLoadingBillDetailModel.getActualTotalPcs()));
			tmsLoadingBillHeaderModel.setActualTotalVolume(tmsLoadingBillHeaderModel.getActualTotalVolume().add(tmsLoadingBillDetailModel.getActualTotalVolume()));
			tmsLoadingBillHeaderModel.setActualTotalWeight(tmsLoadingBillHeaderModel.getActualTotalWeight().add(tmsLoadingBillDetailModel.getActualTotalWeight()));

			// 整件数拼箱数
			if (ToolKits.isNotEmpty(tmsLoadingBillDetailModel.getPackageWholePiece())) {
				tmsLoadingBillHeaderModel.setTotalWholePiece(tmsLoadingBillHeaderModel.getTotalWholePiece().subtract(tmsLoadingBillDetailModel.getPackageWholePiece()));
			}
			if (ToolKits.isNotEmpty(tmsLoadingBillDetailModel.getPackageLclPiece())) {
				tmsLoadingBillHeaderModel.setTotalLclPiece(tmsLoadingBillHeaderModel.getTotalLclPiece().subtract(tmsLoadingBillDetailModel.getPackageLclPiece()));
			}
			// 运单数
			tmsLoadingBillHeaderModel.setShipbillNumber(tmsLoadingBillHeaderModel.getShipbillNumber() + 1);

			// 客户数
			if (!customerList.contains(tmsShipbillHeaderModel.getConsigneeUnitName())) {
				tmsLoadingBillHeaderModel.setCustomerNumber(tmsLoadingBillHeaderModel.getCustomerNumber() + 1);
			}

			// 站点数
			if (!siteList.contains(tmsShipbillHeaderModel.getConsigneeAddress())) {
				tmsLoadingBillHeaderModel.setSiteNumber(tmsLoadingBillHeaderModel.getSiteNumber() + 1);
			}

			// 运单操作日志保存
			shipbillOperateLogSaveVO.setShipbillId(tmsLoadingBillDetailModel.getShipbillId());
			shipbillOperateLogSaveVO.setShipbillNo(tmsLoadingBillDetailModel.getShipbillNo());
			shipbillOperateLogSaveVO.setOperateEvent("添加到 派车单" + tmsLoadingBillDetailModel.getShipbillId());

			StringBuffer nodeEvent = new StringBuffer();
			nodeEvent.append(ToolKits.isEmpty(tmsLoadingBillHeaderModel.getDriverName()) ? "" : tmsLoadingBillHeaderModel.getDriverName() + " ");
			nodeEvent.append(ToolKits.isEmpty(tmsLoadingBillHeaderModel.getDeliverymanName()) ? "" : tmsLoadingBillHeaderModel.getDeliverymanName() + " ");
			nodeEvent.append(ToolKits.isEmpty(tmsLoadingBillHeaderModel.getVehiclePlateNumber()) ? "" : tmsLoadingBillHeaderModel.getVehiclePlateNumber() + " ");
			// 运单节点保存
			shipbillNodeTrackingSaveVO.setShipbillId(tmsShipbillHeaderModel.getShipbillId());
			shipbillNodeTrackingSaveVO.setShipbillNo(tmsShipbillHeaderModel.getShipbillNo());
			shipbillNodeTrackingSaveVO.setNodeEvent(nodeEvent.toString());

			// 保存操作
			tmsShipbillHeaderModel.setUpdateperson(user.getNickname());
			tmsShipbillHeaderModel.setUpdatetime(date);
			tmsShipbillHeaderMapper.update(tmsShipbillHeaderModel);
			shipbillOperateLogService.addShipbillOperateLogData(shipbillOperateLogSaveVO,user);
			shipbillNodeTrackingService.addShipbillNodeTrackingData(shipbillNodeTrackingSaveVO,user);

		}

		// 计算装载率
		if (ToolKits.isNotEmpty(tmsLoadingBillHeaderModel.getVehicleId())) {
			Map<String, String> map = this.calculateLoadingRate(tmsLoadingBillHeaderModel.getVehicleId(), tmsLoadingBillHeaderModel.getTotalWeight(), tmsLoadingBillHeaderModel.getTotalVolume());
			tmsLoadingBillHeaderModel.setVolumeLoadingRate(map.get("volume"));
			tmsLoadingBillHeaderModel.setWeightLoadingRate(map.get("weight"));
		}

		// 批量添加派车单明细
		tmsLoadingBillDetailMapper.saveBatch(saveList);

		// 修改派车单
		tmsLoadingBillHeaderModel.setUpdateperson(user.getNickname());
		tmsLoadingBillHeaderModel.setUpdatetime(date);
		tmsLoadingBillHeaderMapper.update(tmsLoadingBillHeaderModel);

		return dtoList;
	}

	/**
	 * 已派车配载运单剔除
	 * 
	 * @param sendCarDeleteDetailVO
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void deleteDetailSendCarData(SendCarDeleteDetailVO sendCarDeleteDetailVO) {
		ToolKits.isParamNull(sendCarDeleteDetailVO.getLoadingBillId(), "派车单ID不为空");
		ToolKits.isParamNull(sendCarDeleteDetailVO.getShipbillIds(), "运单ID不为空");

		UserEntity user = PlgFxUsrUtils.getUserEntity();
		ToolKits.isParamNull(user, "当前人员没有操作权限");
		if (!user.getUserType().equals(BussinessConstant.USER_TYPE_ZY) && !user.getUserType().equals(BussinessConstant.USER_TYPE_CYS)) {
			ToolKits.isParamNull(user, "当前人员没有操作权限");
		}
		TmsLoadingBillHeaderModel tmsLoadingBillHeaderModel = tmsLoadingBillHeaderMapper.findById(sendCarDeleteDetailVO.getLoadingBillId(), TmsLoadingBillHeaderModel.class);
		if (ToolKits.isEmpty(tmsLoadingBillHeaderModel)) {
			throw new PrologException(StrUtil.format("派车单{}不存在", sendCarDeleteDetailVO.getLoadingBillId()));
		}

		Assert.isTrue(ToolKits.isEmpty(tmsLoadingBillHeaderModel.getOldStatus()), "反审核派车单【" + tmsLoadingBillHeaderModel.getLoadingBillId() + "】不能剔除运单！");

		if (ToolKits.isEmpty(tmsLoadingBillHeaderModel.getStatus()) || DataDictionaryConstant.LOADING_BILL_STATUS_ZC_CONFIRM.intValue() < tmsLoadingBillHeaderModel.getStatus().intValue()) {
			throw new PrologException(StrUtil.format("派车单{}已启运，请不要剔除运单", sendCarDeleteDetailVO.getLoadingBillId()));
		}
		Date date = DateUtil.date();
		Criteria criteria = Criteria.forClass(TmsLoadingBillDetailModel.class);
		Restriction r1 = Restrictions.eq(TmsLoadingBillDetailModel::getLoadingBillId, sendCarDeleteDetailVO.getLoadingBillId());
		Restriction r2 = Restrictions.in(TmsLoadingBillDetailModel::getShipbillId, sendCarDeleteDetailVO.getShipbillIds().stream().toArray());
		criteria.setRestriction(Restrictions.and(r1, r2));
		List<TmsLoadingBillDetailModel> tmsLoadingBillDetailModels = tmsLoadingBillDetailMapper.findByCriteria(criteria);

		// 修改配送顺序以及总重量体积件数等数据
		for (TmsLoadingBillDetailModel tmsLoadingBillDetailModel : tmsLoadingBillDetailModels) {

			// 修改配送顺序
			r1 = Restrictions.eq("loadingBillId", tmsLoadingBillDetailModel.getLoadingBillId());
			r2 = Restrictions.ne("shipbillId", tmsLoadingBillDetailModel.getShipbillId());
			criteria.setRestriction(Restrictions.and(r1, r2));
			List<TmsLoadingBillDetailModel> tmsLoadingBillDetailModelList = tmsLoadingBillDetailMapper.findByCriteria(criteria);

			/*
			 * // 客户数 Integer customerNumber =
			 * tmsLoadingBillDetailModelList.stream().filter(o ->
			 * ToolKits.isNotEmpty(o.getConsigneeName())).map(TmsLoadingBillDetailModel::
			 * getConsigneeName).distinct().collect(Collectors.toList()).size();
			 * 
			 * // 站点数 Integer siteNumber = tmsLoadingBillDetailModelList.stream().filter(o
			 * ->
			 * ToolKits.isNotEmpty(o.getConsigneeAddress())).map(TmsLoadingBillDetailModel::
			 * getConsigneeAddress).distinct().collect(Collectors.toList()).size();
			 * 
			 * // 重量体积件数
			 * tmsLoadingBillHeaderModel.setTotalPcs(tmsLoadingBillHeaderModel.getTotalPcs()
			 * .subtract(tmsLoadingBillDetailModel.getTotalPcs()));
			 * tmsLoadingBillHeaderModel.setTotalVolume(tmsLoadingBillHeaderModel.
			 * getTotalVolume().subtract(tmsLoadingBillDetailModel.getTotalVolume()));
			 * tmsLoadingBillHeaderModel.setTotalWeight(tmsLoadingBillHeaderModel.
			 * getTotalWeight().subtract(tmsLoadingBillDetailModel.getTotalWeight()));
			 * 
			 * // 实际重量体积件数
			 * tmsLoadingBillHeaderModel.setActualTotalPcs(tmsLoadingBillHeaderModel.
			 * getActualTotalPcs().subtract(tmsLoadingBillDetailModel.getActualTotalPcs()));
			 * tmsLoadingBillHeaderModel.setActualTotalVolume(tmsLoadingBillHeaderModel.
			 * getActualTotalVolume().subtract(tmsLoadingBillDetailModel.
			 * getActualTotalVolume()));
			 * tmsLoadingBillHeaderModel.setActualTotalWeight(tmsLoadingBillHeaderModel.
			 * getActualTotalWeight().subtract(tmsLoadingBillDetailModel.
			 * getActualTotalWeight()));
			 * 
			 * // 整件数拼箱数 if
			 * (ToolKits.isNotEmpty(tmsLoadingBillDetailModel.getPackageWholePiece())) {
			 * tmsLoadingBillHeaderModel.setTotalWholePiece(tmsLoadingBillHeaderModel.
			 * getTotalWholePiece().subtract(tmsLoadingBillDetailModel.getPackageWholePiece(
			 * ))); } if
			 * (ToolKits.isNotEmpty(tmsLoadingBillDetailModel.getPackageLclPiece())) {
			 * tmsLoadingBillHeaderModel.setTotalLclPiece(tmsLoadingBillHeaderModel.
			 * getTotalLclPiece().subtract(tmsLoadingBillDetailModel.getPackageLclPiece()));
			 * }
			 * 
			 * // 运单数 tmsLoadingBillHeaderModel.setShipbillNumber(tmsLoadingBillHeaderModel.
			 * getShipbillNumber() - 1);
			 * 
			 * // 客户数 tmsLoadingBillHeaderModel.setCustomerNumber(customerNumber); // 站点数
			 * tmsLoadingBillHeaderModel.setSiteNumber(siteNumber);
			 */

			// 删除明细内容
			tmsLoadingBillDetailMapper.deleteById(tmsLoadingBillDetailModel.getId(), TmsLoadingBillDetailModel.class);

			// 运单操作日志保存
			ShipbillOperateLogSaveVO shipbillOperateLogSaveVO = new ShipbillOperateLogSaveVO();
			shipbillOperateLogSaveVO.setShipbillId(tmsLoadingBillDetailModel.getShipbillId());
			shipbillOperateLogSaveVO.setShipbillNo(tmsLoadingBillDetailModel.getShipbillNo());
			shipbillOperateLogSaveVO.setOperateEvent("从派车单" + tmsLoadingBillDetailModel.getShipbillId() + "中剔除");

			// 运单节点保存
			ShipbillNodeTrackingSaveVO shipbillNodeTrackingSaveVO = new ShipbillNodeTrackingSaveVO();
			shipbillNodeTrackingSaveVO.setShipbillId(tmsLoadingBillDetailModel.getShipbillId());
			shipbillNodeTrackingSaveVO.setShipbillNo(tmsLoadingBillDetailModel.getShipbillNo());

			shipbillNodeTrackingSaveVO.setNodeEvent("从派车单" + tmsLoadingBillHeaderModel.getLoadingBillId() + "中剔除");

			if (user.getUserType().equals(BussinessConstant.USER_TYPE_ZY)) {
				shipbillOperateLogSaveVO.setOldStatus(DataDictionaryConstant.SHIPBILL_STATUS_DISPATCH);
				shipbillOperateLogSaveVO.setNewStatus(DataDictionaryConstant.SHIPBILL_STATUS_REVIEW);
				shipbillNodeTrackingSaveVO.setStatus(DataDictionaryConstant.SHIPBILL_STATUS_REVIEW);
			} else {
				shipbillOperateLogSaveVO.setOldStatus(DataDictionaryConstant.CARRIER_SHIPBILL_STATUS_DISPATCHED);
				shipbillOperateLogSaveVO.setNewStatus(DataDictionaryConstant.CARRIER_SHIPBILL_STATUS_AUDITED);
				shipbillNodeTrackingSaveVO.setStatus(DataDictionaryConstant.CARRIER_SHIPBILL_STATUS_AUDITED);
			}

			// 保存操作
			shipbillOperateLogService.addShipbillOperateLogData(shipbillOperateLogSaveVO,user);
			shipbillNodeTrackingService.addShipbillNodeTrackingData(shipbillNodeTrackingSaveVO,user);

		}
		calculateLoadingData(tmsLoadingBillHeaderModel);

		// 计算装载率
		if (ToolKits.isNotEmpty(tmsLoadingBillHeaderModel.getVehicleId())) {
			Map<String, String> map = this.calculateLoadingRate(tmsLoadingBillHeaderModel.getVehicleId(), tmsLoadingBillHeaderModel.getTotalWeight(), tmsLoadingBillHeaderModel.getTotalVolume());
			tmsLoadingBillHeaderModel.setVolumeLoadingRate(map.get("volume"));
			tmsLoadingBillHeaderModel.setWeightLoadingRate(map.get("weight"));
		}

		// 修改汇总表
		tmsLoadingBillHeaderModel.setUpdatetime(date);
		tmsLoadingBillHeaderModel.setUpdateperson(user.getNickname());
		tmsLoadingBillHeaderMapper.update(tmsLoadingBillHeaderModel);

		// 运单状态回退
		criteria = Criteria.forClass(TmsShipbillHeaderModel.class);
		r1 = Restrictions.in("shipbillId", sendCarDeleteDetailVO.getShipbillIds().toArray());
		criteria.setRestriction(r1);

		Map<String, Object> map = Maps.newHashMap();
		map.put("updateperson", user.getNickname());
		map.put("updatetime", date);
		if (user.getUserType().equals(BussinessConstant.USER_TYPE_ZY)) {
			map.put("status", DataDictionaryConstant.SHIPBILL_STATUS_REVIEW);
		} else {
			map.put("carrierShipbillStatus", DataDictionaryConstant.CARRIER_SHIPBILL_STATUS_AUDITED);
		}

		tmsShipbillHeaderMapper.updateMapByCriteria(map, criteria);
	}

	/**
	 * 已派车配载运单移动
	 *
	 * @param sendCarMobileDetailVO
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void mobileDetailSendCarData(SendCarMobileDetailVO sendCarMobileDetailVO) {
		ToolKits.isParamNull(sendCarMobileDetailVO.getOriginalLoadingBillId(), "原派车单ID不为空");
		ToolKits.isParamNull(sendCarMobileDetailVO.getNowLoadingBillId(), "目标派车单ID不为空");
		ToolKits.isParamNull(sendCarMobileDetailVO.getShipbillIds(), "运单ID不为空");

		UserEntity user = PlgFxUsrUtils.getUserEntity();
		ToolKits.isParamNull(user, "当前人员没有操作权限");
		if (!user.getUserType().equals(BussinessConstant.USER_TYPE_ZY) && !user.getUserType().equals(BussinessConstant.USER_TYPE_CYS)) {
			ToolKits.isParamNull(user, "当前人员没有操作权限");
		}
		Date date = DateUtil.date();
		Criteria criteria = Criteria.forClass(TmsLoadingBillDetailModel.class);
		Restriction r1 = Restrictions.in("shipbillId", sendCarMobileDetailVO.getShipbillIds().toArray());
		criteria.setRestriction(r1);
		List<TmsLoadingBillDetailModel> tmsLoadingBillDetailModels = tmsLoadingBillDetailMapper.findByCriteria(criteria);

		// 原派车单
		TmsLoadingBillHeaderModel originalModel = tmsLoadingBillHeaderMapper.findById(sendCarMobileDetailVO.getOriginalLoadingBillId(), TmsLoadingBillHeaderModel.class);
		Assert.isTrue(ToolKits.isEmpty(originalModel.getOldStatus()), "反审核原派车单【" + originalModel.getLoadingBillId() + "】不能移动运单！");

		// 目标派车单
		TmsLoadingBillHeaderModel nowModel = tmsLoadingBillHeaderMapper.findById(sendCarMobileDetailVO.getNowLoadingBillId(), TmsLoadingBillHeaderModel.class);
		Assert.isTrue(ToolKits.isEmpty(nowModel.getOldStatus()), "反审核目标派车单【" + nowModel.getLoadingBillId() + "】不能移动运单！");

		criteria = Criteria.forClass(TmsLoadingBillDetailModel.class);
		r1 = Restrictions.eq("loadingBillId", sendCarMobileDetailVO.getNowLoadingBillId());
		criteria.setRestriction(r1);

		List<TmsLoadingBillDetailModel> tmsLoadingBillDetailNowModels = tmsLoadingBillDetailMapper.findByCriteria(criteria);
//		List<Integer> indexList = tmsLoadingBillDetailNowModels.stream().filter(o -> ToolKits.isNotEmpty(o.getShippingOrder())).map(TmsLoadingBillDetailModel::getShippingOrder).collect(Collectors.toList());
		Integer index = maxStationOrderNumber(tmsLoadingBillDetailNowModels);
//		if (ToolKits.isEmpty(indexList)) {
//			index = 1;
//		} else {
//			index = Collections.max(indexList);
//		}

		// 目标派车单客户集合
		List<String> customerList = tmsLoadingBillDetailNowModels.stream().filter(o -> ToolKits.isNotEmpty(o.getConsigneeName())).map(TmsLoadingBillDetailModel::getConsigneeName).distinct().collect(Collectors.toList());

		// 目标派车单站点集合
		List<String> siteList = tmsLoadingBillDetailNowModels.stream().filter(o -> ToolKits.isNotEmpty(o.getConsigneeAddress())).map(TmsLoadingBillDetailModel::getConsigneeAddress).distinct().collect(Collectors.toList());

		// 修改配送顺序以及总重量体积件数等数据
		for (TmsLoadingBillDetailModel tmsLoadingBillDetailModel : tmsLoadingBillDetailModels) {

			r1 = Restrictions.eq("loadingBillId", tmsLoadingBillDetailModel.getLoadingBillId());
			Restriction r2 = Restrictions.ne("shipbillId", tmsLoadingBillDetailModel.getShipbillId());
			criteria.setRestriction(Restrictions.and(r1, r2));
			List<TmsLoadingBillDetailModel> tmsLoadingBillDetailModelList = tmsLoadingBillDetailMapper.findByCriteria(criteria);
//			for (TmsLoadingBillDetailModel loadingBillDetailModel : tmsLoadingBillDetailModelList) {
//				if (loadingBillDetailModel.getShippingOrder() > tmsLoadingBillDetailModel.getShippingOrder()) {
//					loadingBillDetailModel.setShippingOrder(loadingBillDetailModel.getShippingOrder() - 1);
//				}
//				loadingBillDetailModel.setUpdateperson(user.getNickname());
//				loadingBillDetailModel.setUpdatetime(date);
//				tmsLoadingBillDetailMapper.update(loadingBillDetailModel);
//			}

			// 原派车单客户数
			Integer customerNumber = tmsLoadingBillDetailModelList.stream().filter(o -> ToolKits.isNotEmpty(o.getConsigneeName())).map(TmsLoadingBillDetailModel::getConsigneeName).distinct().collect(Collectors.toList()).size();

			// 原派车单站点数
			Integer siteNumber = tmsLoadingBillDetailModelList.stream().filter(o -> ToolKits.isNotEmpty(o.getConsigneeAddress())).map(TmsLoadingBillDetailModel::getConsigneeAddress).distinct().collect(Collectors.toList()).size();

			// 原派车单重量体积件数
			originalModel.setTotalPcs(originalModel.getTotalPcs().subtract(tmsLoadingBillDetailModel.getTotalPcs()));
			originalModel.setTotalVolume(originalModel.getTotalVolume().subtract(tmsLoadingBillDetailModel.getTotalVolume()));
			originalModel.setTotalWeight(originalModel.getTotalWeight().subtract(tmsLoadingBillDetailModel.getTotalWeight()));

			// 原派车单实际重量体积件数
			originalModel.setActualTotalPcs(originalModel.getActualTotalPcs().subtract(tmsLoadingBillDetailModel.getActualTotalPcs()));
			originalModel.setActualTotalVolume(originalModel.getActualTotalVolume().subtract(tmsLoadingBillDetailModel.getActualTotalVolume()));
			originalModel.setActualTotalWeight(originalModel.getActualTotalWeight().subtract(tmsLoadingBillDetailModel.getActualTotalWeight()));

			// 原派车单整件数拼箱数
			if (ToolKits.isNotEmpty(tmsLoadingBillDetailModel.getPackageWholePiece())) {
				originalModel.setTotalWholePiece(originalModel.getTotalWholePiece().subtract(tmsLoadingBillDetailModel.getPackageWholePiece()));
			}
			if (ToolKits.isNotEmpty(tmsLoadingBillDetailModel.getPackageLclPiece())) {
				originalModel.setTotalLclPiece(originalModel.getTotalLclPiece().subtract(tmsLoadingBillDetailModel.getPackageLclPiece()));
			}
			// 原派车单运单数
			originalModel.setShipbillNumber(originalModel.getShipbillNumber() - 1);

			// 原派车单客户数
			originalModel.setCustomerNumber(customerNumber);
			// 原派车单站点数
			originalModel.setSiteNumber(siteNumber);

			// 目标派车单重量体积件数
			nowModel.setTotalPcs(nowModel.getTotalPcs().add(tmsLoadingBillDetailModel.getTotalPcs()));
			nowModel.setTotalVolume(nowModel.getTotalVolume().add(tmsLoadingBillDetailModel.getTotalVolume()));
			nowModel.setTotalWeight(nowModel.getTotalWeight().add(tmsLoadingBillDetailModel.getTotalWeight()));

			// 目标派车单实际重量体积件数
			nowModel.setActualTotalPcs(nowModel.getActualTotalPcs().add(tmsLoadingBillDetailModel.getActualTotalPcs()));
			nowModel.setActualTotalVolume(nowModel.getActualTotalVolume().add(tmsLoadingBillDetailModel.getActualTotalVolume()));
			nowModel.setActualTotalWeight(nowModel.getActualTotalWeight().add(tmsLoadingBillDetailModel.getActualTotalWeight()));

			// 目标派车单整件数拼箱数
			if (ToolKits.isNotEmpty(tmsLoadingBillDetailModel.getPackageWholePiece())) {
				nowModel.setTotalWholePiece(nowModel.getTotalWholePiece().add(tmsLoadingBillDetailModel.getPackageWholePiece()));
			}
			if (ToolKits.isNotEmpty(tmsLoadingBillDetailModel.getPackageLclPiece())) {
				nowModel.setTotalLclPiece(nowModel.getTotalLclPiece().add(tmsLoadingBillDetailModel.getPackageLclPiece()));
			}
			// 目标派车单运单数
			nowModel.setShipbillNumber(nowModel.getShipbillNumber() + 1);

			// 目标派车单客户数
			if (!customerList.contains(tmsLoadingBillDetailModel.getConsigneeName())) {
				nowModel.setCustomerNumber(nowModel.getCustomerNumber() + 1);
			}

			// 目标派车单站点数
			if (!siteList.contains(tmsLoadingBillDetailModel.getConsigneeAddress())) {
				nowModel.setSiteNumber(nowModel.getSiteNumber() + 1);
			}

			// 修改明细内容
			Map<String, Object> map = Maps.newHashMap();
			map.put("updateperson", user.getNickname());
			map.put("updatetime", date);
			map.put("loadingBillId", sendCarMobileDetailVO.getNowLoadingBillId());
			map.put("loadingBillNo", sendCarMobileDetailVO.getNowLoadingBillId());
			// 修改提货顺序
			index++;
			map.put("pickUpOrder", index);
			// 修改配送顺序
			index++;
			map.put("shippingOrder", index);

			tmsLoadingBillDetailMapper.updateMapById(tmsLoadingBillDetailModel.getId(), map, TmsLoadingBillDetailModel.class);

			ShipbillOperateLogSaveVO shipbillOperateLogSaveVO = new ShipbillOperateLogSaveVO();
			ShipbillNodeTrackingSaveVO shipbillNodeTrackingSaveVO = new ShipbillNodeTrackingSaveVO();
			if (user.getUserType().equals(BussinessConstant.USER_TYPE_ZY)) {
				shipbillOperateLogSaveVO.setOldStatus(DataDictionaryConstant.SHIPBILL_STATUS_DISPATCH);
				shipbillOperateLogSaveVO.setNewStatus(DataDictionaryConstant.SHIPBILL_STATUS_DISPATCH);
				shipbillNodeTrackingSaveVO.setStatus(DataDictionaryConstant.SHIPBILL_STATUS_DISPATCH);
			} else if (user.getUserType().equals(BussinessConstant.USER_TYPE_CYS)) {
				shipbillOperateLogSaveVO.setOldStatus(DataDictionaryConstant.CARRIER_SHIPBILL_STATUS_DISPATCHED);
				shipbillOperateLogSaveVO.setNewStatus(DataDictionaryConstant.CARRIER_SHIPBILL_STATUS_DISPATCHED);
				shipbillNodeTrackingSaveVO.setStatus(DataDictionaryConstant.CARRIER_SHIPBILL_STATUS_DISPATCHED);
			}
			// 运单操作日志保存
			shipbillOperateLogSaveVO.setShipbillId(tmsLoadingBillDetailModel.getShipbillId());
			shipbillOperateLogSaveVO.setShipbillNo(tmsLoadingBillDetailModel.getShipbillNo());
			shipbillOperateLogSaveVO.setOperateEvent(DataDictionaryConstant.SHIPBILL_NODE_STATUSNAME_YD + sendCarMobileDetailVO.getNowLoadingBillId());
			shipbillOperateLogService.addShipbillOperateLogData(shipbillOperateLogSaveVO,user);

			StringBuffer nodeEvent = new StringBuffer(DataDictionaryConstant.SHIPBILL_NODE_STATUSNAME_YD + sendCarMobileDetailVO.getNowLoadingBillId());
			nodeEvent.append(" ");
			if (DataDictionaryConstant.LINE_CARRIER_TYPE_CYF.equals(nowModel.getCarrierType())) {
				nodeEvent.append(nowModel.getCarrierName());
			} else {
				nodeEvent.append(ToolKits.isEmpty(nowModel.getDriverName()) ? "" : nowModel.getDriverName() + " ");
				nodeEvent.append(ToolKits.isEmpty(nowModel.getDeliverymanName()) ? "" : nowModel.getDeliverymanName() + " ");
				nodeEvent.append(ToolKits.isEmpty(nowModel.getVehiclePlateNumber()) ? "" : nowModel.getVehiclePlateNumber() + " ");
			}

			// 运单节点保存
			shipbillNodeTrackingSaveVO.setShipbillId(tmsLoadingBillDetailModel.getShipbillId());
			shipbillNodeTrackingSaveVO.setShipbillNo(tmsLoadingBillDetailModel.getShipbillNo());
			shipbillNodeTrackingSaveVO.setNodeEvent(nodeEvent.toString());
			shipbillNodeTrackingService.addShipbillNodeTrackingData(shipbillNodeTrackingSaveVO,user);

		}

		// 原派车单计算装载率
		if (ToolKits.isNotEmpty(originalModel.getVehicleId())) {
			Map<String, String> map = this.calculateLoadingRate(originalModel.getVehicleId(), originalModel.getTotalWeight(), originalModel.getTotalVolume());
			originalModel.setVolumeLoadingRate(map.get("volume"));
			originalModel.setWeightLoadingRate(map.get("weight"));
		}

		// 目标派车单计算装载率
		if (ToolKits.isNotEmpty(nowModel.getVehicleId())) {
			Map<String, String> map = this.calculateLoadingRate(nowModel.getVehicleId(), nowModel.getTotalWeight(), nowModel.getTotalVolume());
			nowModel.setVolumeLoadingRate(map.get("volume"));
			nowModel.setWeightLoadingRate(map.get("weight"));
		}

		// 修改汇总表
		originalModel.setUpdateperson(user.getNickname());
		originalModel.setUpdatetime(date);
		tmsLoadingBillHeaderMapper.update(originalModel);
		tmsLoadingBillHeaderMapper.update(nowModel);
	}

	/**
	 * 已派车配载商品查询
	 *
	 * @param sendCarItemDetailVO
	 * @return
	 */
	@SuppressWarnings("resource")
	@Override
	public Page<SendCarItemPageDTO> itemDetailSendCarData(SendCarItemDetailVO sendCarItemDetailVO) {
		ToolKits.isParamNull(sendCarItemDetailVO.getLoadingBillId(), "派车单ID不为空");
		ToolKits.isParamNull(sendCarItemDetailVO.getPageNum(), "当前页码不为空");
		ToolKits.isParamNull(sendCarItemDetailVO.getPageSize(), "每页条数不为空");

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

		// 数据字典翻译数据集合
		List<Map<String, Object>> data1 = Lists.newArrayList();
		List<Map<String, Object>> data2 = Lists.newArrayList();

		// 包装类型
		RestMessage<List<Map<String, Object>>> restMessage1 = maindataTmsResource.getDropDownById(DataDictionaryConstant.PACK_TYPE, null, null, null);
		if (!restMessage1.isSuccess()) {
			throw new RuntimeException("订单类型翻译失败!");
		} else {
			data1 = restMessage1.getData();
		}
		// 货物温层
		RestMessage<List<Map<String, Object>>> restMessage2 = maindataTmsResource.getDropDownById(DataDictionaryConstant.CARGO_THERMOSPHERE, null, null, null);
		if (!restMessage2.isSuccess()) {
			throw new RuntimeException("货物温层翻译失败!");
		} else {
			data2 = restMessage2.getData();
		}

		Criteria criteria = Criteria.forClass(TmsLoadingBillDetailModel.class);
		Restriction r1 = Restrictions.eq("loadingBillId", sendCarItemDetailVO.getLoadingBillId());
		criteria.setRestriction(r1);
		List<TmsLoadingBillDetailModel> tmsLoadingBillDetailModels = tmsLoadingBillDetailMapper.findByCriteria(criteria);
		List<String> shipbillIds = tmsLoadingBillDetailModels.stream().filter(o -> ToolKits.isNotEmpty(o.getShipbillId())).map(TmsLoadingBillDetailModel::getShipbillId).distinct().collect(Collectors.toList());

		// 根据运单ID查询明细数据
		criteria = Criteria.forClass(TmsShipbillDetailModel.class);
		r1 = Restrictions.in("shipbillId", shipbillIds.toArray());
		criteria.setRestriction(r1);

		PageUtils.startPage(sendCarItemDetailVO.getPageNum(), sendCarItemDetailVO.getPageSize());
		List<TmsShipbillDetailModel> tmsShipbillDetailModels = tmsShipbillDetailMapper.findByCriteria(criteria);

		// 返回数据集
		List<SendCarItemPageDTO> list = Lists.newArrayList();

		for (TmsShipbillDetailModel tmsShipbillDetailModel : tmsShipbillDetailModels) {
			SendCarItemPageDTO dto = new SendCarItemPageDTO();
			BeanUtils.copyProperties(tmsShipbillDetailModel, dto);

			// 数据字典翻译
			dto.setPackTypeName(PublicMethods.change(data1, String.valueOf(dto.getPackType())));
			dto.setCargoThermosphereName(PublicMethods.change(data2, String.valueOf(dto.getCargoThermosphere())));

			list.add(dto);
		}

		// 分页重组
		Page<SendCarItemPageDTO> page = PageUtils.getPage(list);
		if (tmsShipbillDetailModels instanceof com.github.pagehelper.Page) {
			com.github.pagehelper.Page<TmsShipbillDetailModel> p0 = (com.github.pagehelper.Page<TmsShipbillDetailModel>) tmsShipbillDetailModels;
			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;
	}

	/**
	 * 已派车配载包裹查询
	 *
	 * @param sendCarPackageDetailVO
	 * @return
	 */
	@SuppressWarnings("resource")
	@Override
	public Page<SendCarPackagePageDTO> packageDetailSendCarData(SendCarPackageDetailVO sendCarPackageDetailVO) {
		ToolKits.isParamNull(sendCarPackageDetailVO.getLoadingBillId(), "派车单ID不为空");
		ToolKits.isParamNull(sendCarPackageDetailVO.getPageNum(), "当前页码不为空");
		ToolKits.isParamNull(sendCarPackageDetailVO.getPageSize(), "每页条数不为空");

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

		// 数据字典翻译数据集合
		List<Map<String, Object>> data1 = Lists.newArrayList();

		// 包裹类型
		RestMessage<List<Map<String, Object>>> restMessage1 = maindataTmsResource.getDropDownById(DataDictionaryConstant.PACKAGE_TYPE, null, null, null);
		if (!restMessage1.isSuccess()) {
			throw new RuntimeException("包裹类型翻译失败!");
		} else {
			data1 = restMessage1.getData();
		}

		Criteria criteria = Criteria.forClass(TmsLoadingBillDetailModel.class);
		Restriction r1 = Restrictions.eq("loadingBillId", sendCarPackageDetailVO.getLoadingBillId());
		criteria.setRestriction(r1);
		List<TmsLoadingBillDetailModel> tmsLoadingBillDetailModels = tmsLoadingBillDetailMapper.findByCriteria(criteria);
		List<String> shipbillIds = tmsLoadingBillDetailModels.stream().filter(o -> ToolKits.isNotEmpty(o.getShipbillId())).map(TmsLoadingBillDetailModel::getShipbillId).distinct().collect(Collectors.toList());

		// 根据运单ID查询明细数据
		criteria = Criteria.forClass(TmsShipbillPackageModel.class);
		r1 = Restrictions.in("shipbillId", shipbillIds.toArray());
		criteria.setRestriction(r1);

		PageUtils.startPage(sendCarPackageDetailVO.getPageNum(), sendCarPackageDetailVO.getPageSize());
		List<TmsShipbillPackageModel> tmsShipbillPackageModels = tmsShipbillPackageMapper.findByCriteria(criteria);

		// 返回数据集
		List<SendCarPackagePageDTO> list = Lists.newArrayList();

		for (TmsShipbillPackageModel tmsShipbillPackageModel : tmsShipbillPackageModels) {
			SendCarPackagePageDTO dto = new SendCarPackagePageDTO();
			BeanUtils.copyProperties(tmsShipbillPackageModel, dto);

			// 数据字典翻译
			dto.setPackageTypeName(PublicMethods.change(data1, String.valueOf(dto.getPackageType())));

			// 设备类型翻译
			if (ToolKits.isNotEmpty(tmsShipbillPackageModel.getDeviceId())) {
				RestMessage<DeviceByOneDTO> deviceByOneDTORestMessage = maindataTmsResource.deviceGetOne(tmsShipbillPackageModel.getDeviceId());
				if (!deviceByOneDTORestMessage.isSuccess()) {
					throw new RuntimeException("获取设备失败!");
				}
				DeviceByOneDTO data = deviceByOneDTORestMessage.getData();
				ToolKits.isParamNull(data, "获取设备为空");

				dto.setDeviceTypeName(data.getTypeName());
			}

			list.add(dto);
		}

		// 分页重组
		Page<SendCarPackagePageDTO> page = PageUtils.getPage(list);
		if (tmsShipbillPackageModels instanceof com.github.pagehelper.Page) {
			com.github.pagehelper.Page<TmsShipbillPackageModel> p0 = (com.github.pagehelper.Page<TmsShipbillPackageModel>) tmsShipbillPackageModels;
			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;
	}

	/**
	 * 已派车修改
	 *
	 * @param sendCarUpdateVO
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void updateSendCarData(SendCarUpdateVO sendCarUpdateVO) {
		ToolKits.isParamNull(sendCarUpdateVO.getLoadingBillId(), "派车单ID不为空");

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

		// 修改派车单
		TmsLoadingBillHeaderModel tmsLoadingBillHeaderModel = tmsLoadingBillHeaderMapper.findById(sendCarUpdateVO.getLoadingBillId(), TmsLoadingBillHeaderModel.class);
		ToolKits.isParamNull(tmsLoadingBillHeaderModel, "派车单ID[" + sendCarUpdateVO.getLoadingBillId() + "]有误,查询为空!");

		if (tmsLoadingBillHeaderModel.getStatus().intValue() > DataDictionaryConstant.LOADING_BILL_STATUS_WSH.intValue()) {
			throw new RuntimeException("派车单[" + sendCarUpdateVO.getLoadingBillId() + "]已审核,不能修改!");
		}

		List<SendCarUpdateDetailVO> sendCarUpdateDetailVOS = sendCarUpdateVO.getSendCarUpdateDetailVOS();

		// 判断配送顺序是否重复
		if (sendCarUpdateDetailVOS.stream().distinct().collect(Collectors.toList()).size() != sendCarUpdateDetailVOS.size()) {
			throw new RuntimeException("配送顺序不可重复!");
		}
		// 判断配送顺序是否小于0
		if (sendCarUpdateDetailVOS.stream().filter(o -> ToolKits.isNotEmpty(o.getShippingOrder()) && o.getShippingOrder() < 0).collect(Collectors.toList()).size() > 0) {
			throw new RuntimeException("配送顺序不可小于0!");
		}

		// 修改配送顺序
		for (SendCarUpdateDetailVO sendCarUpdateDetailVO : sendCarUpdateDetailVOS) {
			TmsLoadingBillDetailModel tmsLoadingBillDetailModel = tmsLoadingBillDetailMapper.findById(sendCarUpdateDetailVO.getId(), TmsLoadingBillDetailModel.class);
			ToolKits.isParamNull(tmsLoadingBillDetailModel, "明细ID[" + sendCarUpdateDetailVO.getId() + "]有误,查询为空!");

			tmsLoadingBillDetailModel.setShippingOrder(sendCarUpdateDetailVO.getShippingOrder());
			tmsLoadingBillDetailModel.setUpdatetime(date);
			tmsLoadingBillDetailModel.setUpdateperson(user.getNickname());

			// 车辆设备
			if (tmsLoadingBillDetailModel.getTemperatureRequirement().intValue() > DataDictionaryConstant.TEMPERATURE_REQUIREMENT_CW.intValue()) {
				tmsLoadingBillDetailModel.setContainerId(sendCarUpdateVO.getContainerId());
				tmsLoadingBillDetailModel.setContainerCode(sendCarUpdateVO.getContainerCode());
				tmsLoadingBillDetailModel.setContainerName(sendCarUpdateVO.getContainerName());
			}
			tmsLoadingBillDetailModel.setVehicleDeviceId(sendCarUpdateVO.getVehicleDeviceId());
			tmsLoadingBillDetailModel.setVehicleDeviceCode(sendCarUpdateVO.getVehicleDeviceCode());
			tmsLoadingBillDetailModel.setVehicleDeviceName(sendCarUpdateVO.getVehicleDeviceName());
			tmsLoadingBillDetailMapper.update(tmsLoadingBillDetailModel);

		}

		BeanUtils.copyProperties(sendCarUpdateVO, tmsLoadingBillHeaderModel);

		// 解析司机名称
		String driverName = this.getFirstStr(sendCarUpdateVO.getDriverName());
		// 解析送货员
		String deliverymanName = this.getFirstStr(sendCarUpdateVO.getDeliverymanName());

		// 解析司机ID
		String driverId = this.getFirstStr(String.valueOf(sendCarUpdateVO.getDriverId()));
		// 解析司机编号
		String driverCode = this.getFirstStr(sendCarUpdateVO.getDriverCode());
		// 解析司机手机号
		String phoneNumber = this.getFirstStr(sendCarUpdateVO.getDriverPhoneNumber());
		// 司机信息
		tmsLoadingBillHeaderModel.setDriverId(driverId == null ? null : Long.valueOf(driverId));
		tmsLoadingBillHeaderModel.setDriverCode(driverCode == null ? null : driverCode);
		tmsLoadingBillHeaderModel.setDriverName(driverName == null ? null : driverName);
		tmsLoadingBillHeaderModel.setDriverPhoneNumber(phoneNumber == null ? null : phoneNumber);
		// 副司机信息
		String viceDriverId = this.subArrToString(String.valueOf(sendCarUpdateVO.getDriverId()));
		tmsLoadingBillHeaderModel.setViceDriverId(viceDriverId == null ? null : viceDriverId);
		String viceDriverCode = this.subArrToString(sendCarUpdateVO.getDriverCode());
		tmsLoadingBillHeaderModel.setViceDriverCode(viceDriverCode == null ? null : viceDriverCode);
		String viceDriverName = this.subArrToString(sendCarUpdateVO.getDriverName());
		tmsLoadingBillHeaderModel.setViceDriverName(viceDriverName == null ? null : viceDriverName);
		String vicephoneNumber = this.subArrToString(sendCarUpdateVO.getDriverPhoneNumber());
		tmsLoadingBillHeaderModel.setViceDriverPhoneNumber(vicephoneNumber == null ? null : vicephoneNumber);
		// 送货员信息
		// 解析送货员ID
		String deliverymanId = this.getFirstStr(sendCarUpdateVO.getDeliverymanId());
		// 解析送货员编号
		String deliverymanCode = this.getFirstStr(sendCarUpdateVO.getDeliverymanCode());
		// 解析送货员手机号
		String deliverymanPhoneNumber = this.getFirstStr(sendCarUpdateVO.getDeliverymanPhoneNumber());
		tmsLoadingBillHeaderModel.setDeliverymanId(deliverymanId == null ? null : Long.valueOf(deliverymanId));
		tmsLoadingBillHeaderModel.setDeliverymanCode(deliverymanCode == null ? null : deliverymanCode);
		tmsLoadingBillHeaderModel.setDeliverymanName(deliverymanName == null ? null : deliverymanName);
		tmsLoadingBillHeaderModel.setDeliverymanPhoneNumber(deliverymanPhoneNumber == null ? null : deliverymanPhoneNumber);
		// 副送货员信息
		String viceDeliverymanId = this.subArrToString(sendCarUpdateVO.getDeliverymanId());
		tmsLoadingBillHeaderModel.setViceDriverId(viceDeliverymanId == null ? null : viceDeliverymanId);
		String viceDeliverymanCode = this.subArrToString(sendCarUpdateVO.getDeliverymanCode());
		tmsLoadingBillHeaderModel.setViceDriverCode(viceDeliverymanCode == null ? null : viceDeliverymanCode);
		String viceDeliverymanName = this.subArrToString(sendCarUpdateVO.getDeliverymanName());
		tmsLoadingBillHeaderModel.setViceDeliverymanName(viceDeliverymanName == null ? null : viceDeliverymanName);
		String viceDeliverymanphoneNumber = this.subArrToString(sendCarUpdateVO.getDeliverymanPhoneNumber());
		tmsLoadingBillHeaderModel.setViceDeliverymanPhoneNumber(viceDeliverymanphoneNumber == null ? null : viceDeliverymanphoneNumber);

		// 重新计算装载率
		Map<String, String> map = this.calculateLoadingRate(sendCarUpdateVO.getVehicleId(), tmsLoadingBillHeaderModel.getTotalWeight(), tmsLoadingBillHeaderModel.getTotalVolume());

		tmsLoadingBillHeaderModel.setWeightLoadingRate(map.get("weight"));
		tmsLoadingBillHeaderModel.setVolumeLoadingRate(map.get("volume"));
		tmsLoadingBillHeaderModel.setUpdatetime(date);
		tmsLoadingBillHeaderModel.setUpdateperson(user.getNickname());
		tmsLoadingBillHeaderModel.setVehicleTypeCategory(sendCarUpdateVO.getVehicleTypeCategory());
		tmsLoadingBillHeaderModel.setVehicleDeviceId(sendCarUpdateVO.getVehicleDeviceId());
		tmsLoadingBillHeaderModel.setVehicleDeviceCode(sendCarUpdateVO.getVehicleDeviceCode());
		tmsLoadingBillHeaderModel.setVehicleDeviceName(sendCarUpdateVO.getVehicleDeviceName());
		tmsLoadingBillHeaderModel.setVehicleAffiliationId(sendCarUpdateVO.getVehicleAffiliationId());
		tmsLoadingBillHeaderModel.setVehicleAffiliationCode(sendCarUpdateVO.getVehicleAffiliationCode());
		tmsLoadingBillHeaderModel.setVehicleAffiliationName(sendCarUpdateVO.getVehicleAffiliationName());
		tmsLoadingBillHeaderModel.setContainerId(sendCarUpdateVO.getContainerId());
		tmsLoadingBillHeaderModel.setContainerCode(sendCarUpdateVO.getContainerCode());
		tmsLoadingBillHeaderModel.setContainerName(sendCarUpdateVO.getContainerName());
		tmsLoadingBillHeaderMapper.update(tmsLoadingBillHeaderModel);
	}

	/**
	 * 已派车修改—运单添加
	 *
	 * @param sendCarUpdateAddDetailVO
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public List<ShipbillHeaderPageDTO> updateAddDetailSendCarData(SendCarUpdateAddDetailVO sendCarUpdateAddDetailVO) {
		ToolKits.isParamNull(sendCarUpdateAddDetailVO.getLoadingBillId(), "派车单ID不为空");
		ToolKits.isParamNull(sendCarUpdateAddDetailVO.getShipbillIds(), "运单ID不为空");

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

		// 数据字典翻译数据集合
		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<SignconfigPopDTO> data9 = 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();
		}

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

		// 标记配置
		SignconfigPopVO signconfigPopVO = new SignconfigPopVO();
		RestMessage<List<SignconfigPopDTO>> restMessage9 = maindataTmsResource.getSignConfig(signconfigPopVO);
		if (!restMessage9.isSuccess()) {
			throw new RuntimeException("标记配置查询失败!");
		} else {
			data9 = restMessage9.getData();
		}

		TmsLoadingBillHeaderModel tmsLoadingBillHeaderModel = tmsLoadingBillHeaderMapper.findById(sendCarUpdateAddDetailVO.getLoadingBillId(), TmsLoadingBillHeaderModel.class);
		ToolKits.isParamNull(tmsLoadingBillHeaderModel, "派车单ID[" + sendCarUpdateAddDetailVO.getLoadingBillId() + "]有误");
		Assert.isTrue(ToolKits.isEmpty(tmsLoadingBillHeaderModel.getOldStatus()), "反审核派车单【" + tmsLoadingBillHeaderModel.getLoadingBillId() + "】不能添加运单！");

		List<TmsShipbillHeaderModel> tmsShipbillHeaderModels = tmsShipbillHeaderMapper.findByIds(TmsShipbillHeaderModel.class, sendCarUpdateAddDetailVO.getShipbillIds().toArray(), null);

		Criteria criteria = Criteria.forClass(TmsLoadingBillDetailModel.class);
		Restriction r1 = Restrictions.eq("loadingBillId", sendCarUpdateAddDetailVO.getLoadingBillId());
		Restriction r2 = Restrictions.in("shipbillId", sendCarUpdateAddDetailVO.getShipbillIds().toArray());
		criteria.setRestriction(Restrictions.and(r1, r2));
		List<TmsLoadingBillDetailModel> tmsLoadingBillDetailModelList = tmsLoadingBillDetailMapper.findByCriteria(criteria);
		if (ToolKits.isNotEmpty(tmsLoadingBillDetailModelList)) {
			throw new PrologException("运单ID[" + tmsLoadingBillDetailModelList.stream().map(TmsLoadingBillDetailModel::getShipbillId).collect(Collectors.joining(",")) + "]已被添加");
		}

		criteria.setRestriction(r1);
		List<TmsLoadingBillDetailModel> tmsLoadingBillDetailModels = tmsLoadingBillDetailMapper.findByCriteria(criteria);
//		List<Integer> indexList = tmsLoadingBillDetailModels.stream().filter(o -> ToolKits.isNotEmpty(o.getShippingOrder())).map(TmsLoadingBillDetailModel::getShippingOrder).collect(Collectors.toList());
		Integer index = maxStationOrderNumber(tmsLoadingBillDetailModels);
//		if (ToolKits.isEmpty(indexList)) {
//			index = 1;
//		} else {
//			index = Collections.max(indexList);
//		}

		// 客户数
		List<String> customerList = tmsLoadingBillDetailModels.stream().filter(o -> ToolKits.isNotEmpty(o.getConsigneeName())).map(TmsLoadingBillDetailModel::getConsigneeName).distinct().collect(Collectors.toList());

		// 站点数
		List<String> siteList = tmsLoadingBillDetailModels.stream().filter(o -> ToolKits.isNotEmpty(o.getConsigneeAddress())).map(TmsLoadingBillDetailModel::getConsigneeAddress).distinct().collect(Collectors.toList());

		// 明细保存集合
		List<TmsLoadingBillDetailModel> saveList = Lists.newArrayList();

		List<ShipbillHeaderPageDTO> dtoList = Lists.newArrayList();
		for (TmsShipbillHeaderModel tmsShipbillHeaderModel : tmsShipbillHeaderModels) {
			ShipbillHeaderPageDTO dto = new ShipbillHeaderPageDTO();
			BeanUtils.copyProperties(tmsShipbillHeaderModel, dto);

			dtoList.add(dto);

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

			// 类型翻译
			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.setStatusName(PublicMethods.change(data8, String.valueOf(dto.getStatus())));

			// 获取背景颜色和字体颜色
			Signconfig: for (SignconfigPopDTO signconfigPopDTO : data9) {
				// 标记类型匹配
				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(dto.getOrderTypeName()) ? dto.getOrderTypeName() : "")) {
							dto.setBackground(ToolKits.isEmpty(signconfigPopDTO.getBackground()) ? "" : signconfigPopDTO.getBackground());
							dto.setColor(ToolKits.isEmpty(signconfigPopDTO.getColor()) ? "" : signconfigPopDTO.getColor());

							// 返回前端所需标记ID
							dto.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(dto.getOrderBusinessTypeName()) ? dto.getOrderBusinessTypeName() : "")) {
							dto.setBackground(ToolKits.isEmpty(signconfigPopDTO.getBackground()) ? "" : signconfigPopDTO.getBackground());
							dto.setColor(ToolKits.isEmpty(signconfigPopDTO.getColor()) ? "" : signconfigPopDTO.getColor());

							// 返回前端所需标记ID
							dto.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(dto.getTemperatureRequirementName()) ? dto.getTemperatureRequirementName() : "")) {
							dto.setBackground(ToolKits.isEmpty(signconfigPopDTO.getBackground()) ? "" : signconfigPopDTO.getBackground());
							dto.setColor(ToolKits.isEmpty(signconfigPopDTO.getColor()) ? "" : signconfigPopDTO.getColor());

							// 返回前端所需标记ID
							dto.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(dto.getDeliveryMethodTypeName()) ? dto.getDeliveryMethodTypeName() : "")) {
							dto.setBackground(ToolKits.isEmpty(signconfigPopDTO.getBackground()) ? "" : signconfigPopDTO.getBackground());
							dto.setColor(ToolKits.isEmpty(signconfigPopDTO.getColor()) ? "" : signconfigPopDTO.getColor());

							// 返回前端所需标记ID
							dto.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(dto.getMemo()) ? dto.getMemo() : "")) {
							dto.setBackground(ToolKits.isEmpty(signconfigPopDTO.getBackground()) ? "" : signconfigPopDTO.getBackground());
							dto.setColor(ToolKits.isEmpty(signconfigPopDTO.getColor()) ? "" : signconfigPopDTO.getColor());

							// 返回前端所需标记ID
							dto.setSignConfigId(signconfigPopDTO.getId());

							break Signconfig;
						}
					}
					break;
				}
			}

			TmsLoadingBillDetailModel tmsLoadingBillDetailModel = new TmsLoadingBillDetailModel();
			BeanUtils.copyProperties(tmsShipbillHeaderModel, tmsLoadingBillDetailModel);

			// 获取派车单明细ID
			RestMessage<String> restMessage = maindataTmsResource.getCodeNumberByCode(SeriaNnumberConstant.TMS_LOADING_BILL_DETAIL_ID, "L");
			if (!restMessage.isSuccess()) {
				throw new RuntimeException("生成派车单明细ID失败");
			}
			String id = restMessage.getData();

			tmsLoadingBillDetailModel.setId(id);
			// 提货顺序
			index++;
			tmsLoadingBillDetailModel.setPickUpOrder(index);
			// 配送顺序
			index++;
			tmsLoadingBillDetailModel.setShippingOrder(index);
			tmsLoadingBillDetailModel.setLoadingBillId(sendCarUpdateAddDetailVO.getLoadingBillId());
			tmsLoadingBillDetailModel.setLoadingBillNo(sendCarUpdateAddDetailVO.getLoadingBillId());
			tmsLoadingBillDetailModel.setFlowConfig(tmsShipbillHeaderModel.getFlowConfig());
			saveList.add(tmsLoadingBillDetailModel);

			// 重量体积件数
			tmsLoadingBillHeaderModel.setTotalPcs(tmsLoadingBillHeaderModel.getTotalPcs().add(tmsLoadingBillDetailModel.getTotalPcs()));
			tmsLoadingBillHeaderModel.setTotalVolume(tmsLoadingBillHeaderModel.getTotalVolume().add(tmsLoadingBillDetailModel.getTotalVolume()));
			tmsLoadingBillHeaderModel.setTotalWeight(tmsLoadingBillHeaderModel.getTotalWeight().add(tmsLoadingBillDetailModel.getTotalWeight()));

			// 实际重量体积件数
			tmsLoadingBillHeaderModel.setActualTotalPcs(tmsLoadingBillHeaderModel.getActualTotalPcs().add(tmsLoadingBillDetailModel.getActualTotalPcs()));
			tmsLoadingBillHeaderModel.setActualTotalVolume(tmsLoadingBillHeaderModel.getActualTotalVolume().add(tmsLoadingBillDetailModel.getActualTotalVolume()));
			tmsLoadingBillHeaderModel.setActualTotalWeight(tmsLoadingBillHeaderModel.getActualTotalWeight().add(tmsLoadingBillDetailModel.getActualTotalWeight()));

			// 整件数拼箱数
			if (ToolKits.isNotEmpty(tmsLoadingBillDetailModel.getPackageWholePiece())) {
				tmsLoadingBillHeaderModel.setTotalWholePiece(tmsLoadingBillHeaderModel.getTotalWholePiece().subtract(tmsLoadingBillDetailModel.getPackageWholePiece()));
			}
			if (ToolKits.isNotEmpty(tmsLoadingBillDetailModel.getPackageLclPiece())) {
				tmsLoadingBillHeaderModel.setTotalLclPiece(tmsLoadingBillHeaderModel.getTotalLclPiece().subtract(tmsLoadingBillDetailModel.getPackageLclPiece()));
			}
			// 运单数
			tmsLoadingBillHeaderModel.setShipbillNumber(tmsLoadingBillHeaderModel.getShipbillNumber() + 1);

			// 客户数
			if (!customerList.contains(tmsShipbillHeaderModel.getConsigneeName())) {
				tmsLoadingBillHeaderModel.setCustomerNumber(tmsLoadingBillHeaderModel.getCustomerNumber() + 1);
			}

			// 站点数
			if (!siteList.contains(tmsShipbillHeaderModel.getConsigneeAddress())) {
				tmsLoadingBillHeaderModel.setSiteNumber(tmsLoadingBillHeaderModel.getSiteNumber() + 1);
			}

			// 运单操作日志保存
			ShipbillOperateLogSaveVO shipbillOperateLogSaveVO = new ShipbillOperateLogSaveVO();
			shipbillOperateLogSaveVO.setShipbillId(tmsLoadingBillDetailModel.getShipbillId());
			shipbillOperateLogSaveVO.setShipbillNo(tmsLoadingBillDetailModel.getShipbillNo());
			shipbillOperateLogSaveVO.setOperateEvent("添加到 派车单" + tmsLoadingBillDetailModel.getShipbillId());

			StringBuffer nodeEvent = new StringBuffer();
			nodeEvent.append(ToolKits.isEmpty(tmsLoadingBillHeaderModel.getDriverName()) ? "" : tmsLoadingBillHeaderModel.getDriverName() + " ");
			nodeEvent.append(ToolKits.isEmpty(tmsLoadingBillHeaderModel.getDeliverymanName()) ? "" : tmsLoadingBillHeaderModel.getDeliverymanName() + " ");
			nodeEvent.append(ToolKits.isEmpty(tmsLoadingBillHeaderModel.getVehiclePlateNumber()) ? "" : tmsLoadingBillHeaderModel.getVehiclePlateNumber() + " ");
			// 运单节点保存
			ShipbillNodeTrackingSaveVO shipbillNodeTrackingSaveVO = new ShipbillNodeTrackingSaveVO();
			shipbillNodeTrackingSaveVO.setShipbillId(tmsShipbillHeaderModel.getShipbillId());
			shipbillNodeTrackingSaveVO.setShipbillNo(tmsShipbillHeaderModel.getShipbillNo());
			shipbillNodeTrackingSaveVO.setNodeEvent(nodeEvent.toString());

			if (user.getUserType().equals(BussinessConstant.USER_TYPE_ZY)) {
				// 修改运单状态
				tmsShipbillHeaderModel.setStatus(DataDictionaryConstant.SHIPBILL_STATUS_DISPATCH);
				// 日志状态
				shipbillOperateLogSaveVO.setOldStatus(DataDictionaryConstant.SHIPBILL_STATUS_YTJ);
				shipbillOperateLogSaveVO.setNewStatus(DataDictionaryConstant.SHIPBILL_STATUS_DISPATCH);
				// 节点状态
				shipbillNodeTrackingSaveVO.setStatus(DataDictionaryConstant.SHIPBILL_STATUS_DISPATCH);
			} else {
				// 修改运单状态
				tmsShipbillHeaderModel.setCarrierShipbillStatus(DataDictionaryConstant.CARRIER_SHIPBILL_STATUS_DISPATCHED);
				// 日志状态
				shipbillOperateLogSaveVO.setOldStatus(DataDictionaryConstant.CARRIER_SHIPBILL_STATUS_AUDITED);
				shipbillOperateLogSaveVO.setNewStatus(DataDictionaryConstant.CARRIER_SHIPBILL_STATUS_DISPATCHED);
				// 节点状态
				shipbillNodeTrackingSaveVO.setStatus(DataDictionaryConstant.CARRIER_SHIPBILL_STATUS_DISPATCHED);

			}
			// 保存操作
			tmsShipbillHeaderModel.setUpdateperson(user.getNickname());
			tmsShipbillHeaderModel.setUpdatetime(DateUtil.date());
			tmsShipbillHeaderMapper.update(tmsShipbillHeaderModel);
			shipbillOperateLogService.addShipbillOperateLogData(shipbillOperateLogSaveVO,user);
			shipbillNodeTrackingService.addShipbillNodeTrackingData(shipbillNodeTrackingSaveVO,user);
		}

		// 计算装载率
		if (ToolKits.isNotEmpty(tmsLoadingBillHeaderModel.getVehicleId())) {
			Map<String, String> map = this.calculateLoadingRate(tmsLoadingBillHeaderModel.getVehicleId(), tmsLoadingBillHeaderModel.getTotalWeight(), tmsLoadingBillHeaderModel.getTotalVolume());
			tmsLoadingBillHeaderModel.setVolumeLoadingRate(map.get("volume"));
			tmsLoadingBillHeaderModel.setWeightLoadingRate(map.get("weight"));
		}

		// 批量添加派车单明细
		tmsLoadingBillDetailMapper.saveBatch(saveList);

		// 修改派车单
		tmsLoadingBillHeaderModel.setUpdateperson(user.getNickname());
		tmsLoadingBillHeaderModel.setUpdatetime(DateUtil.date());
		tmsLoadingBillHeaderMapper.update(tmsLoadingBillHeaderModel);

		return dtoList;
	}

	/**
	 * 已派车修改—运单剔除
	 *
	 * @param sendCarUpdateDeleteDetailVO
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void updateDeleteDetailSendCarData(SendCarUpdateDeleteDetailVO sendCarUpdateDeleteDetailVO) {
		ToolKits.isParamNull(sendCarUpdateDeleteDetailVO.getLoadingBillId(), "派车单ID不为空");
		ToolKits.isParamNull(sendCarUpdateDeleteDetailVO.getShipbillIds(), "运单ID不为空");

		UserEntity user = PlgFxUsrUtils.getUserEntity();
		ToolKits.isParamNull(user, "当前人员没有操作权限");
		if (!user.getUserType().equals(BussinessConstant.USER_TYPE_ZY) && !user.getUserType().equals(BussinessConstant.USER_TYPE_CYS)) {
			ToolKits.isParamNull(user, "当前人员没有操作权限");
		}

		TmsLoadingBillHeaderModel tmsLoadingBillHeaderModel = tmsLoadingBillHeaderMapper.findById(sendCarUpdateDeleteDetailVO.getLoadingBillId(), TmsLoadingBillHeaderModel.class);
		if (ToolKits.isEmpty(tmsLoadingBillHeaderModel)) {
			throw new PrologException(StrUtil.format("派车单{}不存在", sendCarUpdateDeleteDetailVO.getLoadingBillId()));
		}
		Assert.isTrue(ToolKits.isEmpty(tmsLoadingBillHeaderModel.getOldStatus()), "反审核派车单【" + tmsLoadingBillHeaderModel.getLoadingBillId() + "】不能剔除运单！");

		if (ToolKits.isEmpty(tmsLoadingBillHeaderModel.getStatus()) || DataDictionaryConstant.LOADING_BILL_STATUS_ZC_CONFIRM.intValue() < tmsLoadingBillHeaderModel.getStatus().intValue()) {
			throw new PrologException(StrUtil.format("派车单{}已启运，请不要剔除运单", sendCarUpdateDeleteDetailVO.getLoadingBillId()));
		}

		Criteria criteria = Criteria.forClass(TmsLoadingBillDetailModel.class);
		Restriction r1 = Restrictions.eq(TmsLoadingBillDetailModel::getLoadingBillId, sendCarUpdateDeleteDetailVO.getLoadingBillId());
		Restriction r2 = Restrictions.in("shipbillId", sendCarUpdateDeleteDetailVO.getShipbillIds().toArray());
		criteria.setRestriction(Restrictions.and(r1, r2));
		List<TmsLoadingBillDetailModel> tmsLoadingBillDetailModels = tmsLoadingBillDetailMapper.findByCriteria(criteria);

		// 修改配送顺序以及总重量体积件数等数据
		for (TmsLoadingBillDetailModel tmsLoadingBillDetailModel : tmsLoadingBillDetailModels) {

			// 修改配送顺序
			r1 = Restrictions.eq("loadingBillId", tmsLoadingBillDetailModel.getLoadingBillId());
			r2 = Restrictions.ne("shipbillId", tmsLoadingBillDetailModel.getShipbillId());
			criteria.setRestriction(Restrictions.and(r1, r2));
			List<TmsLoadingBillDetailModel> tmsLoadingBillDetailModelList = tmsLoadingBillDetailMapper.findByCriteria(criteria);
//			for (TmsLoadingBillDetailModel loadingBillDetailModel : tmsLoadingBillDetailModelList) {
//				if (loadingBillDetailModel.getShippingOrder() > tmsLoadingBillDetailModel.getShippingOrder()) {
//					loadingBillDetailModel.setShippingOrder(loadingBillDetailModel.getShippingOrder() - 1);
//				}
//				tmsLoadingBillDetailMapper.update(loadingBillDetailModel);
//			}

			/*
			 * // 客户数 Integer customerNumber =
			 * tmsLoadingBillDetailModelList.stream().filter(o ->
			 * ToolKits.isNotEmpty(o.getConsigneeName())).map(TmsLoadingBillDetailModel::
			 * getConsigneeName).distinct().collect(Collectors.toList()).size();
			 * 
			 * // 站点数 Integer siteNumber = tmsLoadingBillDetailModelList.stream().filter(o
			 * ->
			 * ToolKits.isNotEmpty(o.getConsigneeAddress())).map(TmsLoadingBillDetailModel::
			 * getConsigneeAddress).distinct().collect(Collectors.toList()).size();
			 * 
			 * // 重量体积件数
			 * tmsLoadingBillHeaderModel.setTotalPcs(tmsLoadingBillHeaderModel.getTotalPcs()
			 * .subtract(tmsLoadingBillDetailModel.getTotalPcs()));
			 * tmsLoadingBillHeaderModel.setTotalVolume(tmsLoadingBillHeaderModel.
			 * getTotalVolume().subtract(tmsLoadingBillDetailModel.getTotalVolume()));
			 * tmsLoadingBillHeaderModel.setTotalWeight(tmsLoadingBillHeaderModel.
			 * getTotalWeight().subtract(tmsLoadingBillDetailModel.getTotalWeight()));
			 * 
			 * // 实际重量体积件数
			 * tmsLoadingBillHeaderModel.setActualTotalPcs(tmsLoadingBillHeaderModel.
			 * getActualTotalPcs().subtract(tmsLoadingBillDetailModel.getActualTotalPcs()));
			 * tmsLoadingBillHeaderModel.setActualTotalVolume(tmsLoadingBillHeaderModel.
			 * getActualTotalVolume().subtract(tmsLoadingBillDetailModel.
			 * getActualTotalVolume()));
			 * tmsLoadingBillHeaderModel.setActualTotalWeight(tmsLoadingBillHeaderModel.
			 * getActualTotalWeight().subtract(tmsLoadingBillDetailModel.
			 * getActualTotalWeight()));
			 * 
			 * // 整件数拼箱数 if
			 * (ToolKits.isNotEmpty(tmsLoadingBillDetailModel.getPackageWholePiece())) {
			 * tmsLoadingBillHeaderModel.setTotalWholePiece(tmsLoadingBillHeaderModel.
			 * getTotalWholePiece().subtract(tmsLoadingBillDetailModel.getPackageWholePiece(
			 * ))); } if
			 * (ToolKits.isNotEmpty(tmsLoadingBillDetailModel.getPackageLclPiece())) {
			 * tmsLoadingBillHeaderModel.setTotalLclPiece(tmsLoadingBillHeaderModel.
			 * getTotalLclPiece().subtract(tmsLoadingBillDetailModel.getPackageLclPiece()));
			 * } // 运单数
			 * tmsLoadingBillHeaderModel.setShipbillNumber(tmsLoadingBillHeaderModel.
			 * getShipbillNumber() - 1);
			 * 
			 * // 客户数 tmsLoadingBillHeaderModel.setCustomerNumber(customerNumber); // 站点数
			 * tmsLoadingBillHeaderModel.setSiteNumber(siteNumber);
			 */

			// 删除明细内容
			tmsLoadingBillDetailMapper.deleteById(tmsLoadingBillDetailModel.getId(), TmsLoadingBillDetailModel.class);

			// 运单操作日志保存
			ShipbillOperateLogSaveVO shipbillOperateLogSaveVO = new ShipbillOperateLogSaveVO();
			shipbillOperateLogSaveVO.setShipbillId(tmsLoadingBillDetailModel.getShipbillId());
			shipbillOperateLogSaveVO.setShipbillNo(tmsLoadingBillDetailModel.getShipbillNo());
			shipbillOperateLogSaveVO.setOperateEvent("从派车单" + tmsLoadingBillDetailModel.getShipbillId() + "中剔除");

			// 运单节点保存
			ShipbillNodeTrackingSaveVO shipbillNodeTrackingSaveVO = new ShipbillNodeTrackingSaveVO();
			shipbillNodeTrackingSaveVO.setShipbillId(tmsLoadingBillDetailModel.getShipbillId());
			shipbillNodeTrackingSaveVO.setShipbillNo(tmsLoadingBillDetailModel.getShipbillNo());

			shipbillNodeTrackingSaveVO.setNodeEvent("从派车单" + tmsLoadingBillHeaderModel.getLoadingBillId() + "中剔除");

			if (user.getUserType().equals(BussinessConstant.USER_TYPE_ZY)) {
				shipbillOperateLogSaveVO.setOldStatus(DataDictionaryConstant.SHIPBILL_STATUS_DISPATCH);
				shipbillOperateLogSaveVO.setNewStatus(DataDictionaryConstant.SHIPBILL_STATUS_REVIEW);
				shipbillNodeTrackingSaveVO.setStatus(DataDictionaryConstant.SHIPBILL_STATUS_REVIEW);
			} else {
				shipbillOperateLogSaveVO.setOldStatus(DataDictionaryConstant.CARRIER_SHIPBILL_STATUS_DISPATCHED);
				shipbillOperateLogSaveVO.setNewStatus(DataDictionaryConstant.CARRIER_SHIPBILL_STATUS_AUDITED);
				shipbillNodeTrackingSaveVO.setStatus(DataDictionaryConstant.CARRIER_SHIPBILL_STATUS_AUDITED);
			}

			// 保存操作
			shipbillOperateLogService.addShipbillOperateLogData(shipbillOperateLogSaveVO,user);
			shipbillNodeTrackingService.addShipbillNodeTrackingData(shipbillNodeTrackingSaveVO,user);
		}
		calculateLoadingData(tmsLoadingBillHeaderModel);
		// 计算装载率
		if (ToolKits.isNotEmpty(tmsLoadingBillHeaderModel.getVehicleId())) {
			Map<String, String> map = this.calculateLoadingRate(tmsLoadingBillHeaderModel.getVehicleId(), tmsLoadingBillHeaderModel.getTotalWeight(), tmsLoadingBillHeaderModel.getTotalVolume());
			tmsLoadingBillHeaderModel.setVolumeLoadingRate(map.get("volume"));
			tmsLoadingBillHeaderModel.setWeightLoadingRate(map.get("weight"));
		}

		// 修改汇总表
		tmsLoadingBillHeaderMapper.update(tmsLoadingBillHeaderModel);

		// 运单状态回退
		criteria = Criteria.forClass(TmsShipbillHeaderModel.class);
		r1 = Restrictions.in("shipbillId", sendCarUpdateDeleteDetailVO.getShipbillIds().toArray());
		criteria.setRestriction(r1);

		Map<String, Object> map = Maps.newHashMap();
		if (user.getUserType().equals(BussinessConstant.USER_TYPE_ZY)) {
			map.put("status", DataDictionaryConstant.SHIPBILL_STATUS_REVIEW);
		} else {
			map.put("carrierShipbillStatus", DataDictionaryConstant.CARRIER_SHIPBILL_STATUS_AUDITED);
		}
		tmsShipbillHeaderMapper.updateMapByCriteria(map, criteria);
	}

	/**
	 * 已派车修改—运单移动
	 *
	 * @param sendCarUpdateMobileDetailVO
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void updateMobileDetailSendCarData(SendCarUpdateMobileDetailVO sendCarUpdateMobileDetailVO) {
		ToolKits.isParamNull(sendCarUpdateMobileDetailVO.getOriginalLoadingBillId(), "原派车单ID不为空");
		ToolKits.isParamNull(sendCarUpdateMobileDetailVO.getNowLoadingBillId(), "目标派车单ID不为空");
		ToolKits.isParamNull(sendCarUpdateMobileDetailVO.getShipbillIds(), "运单ID不为空");

		UserEntity user = PlgFxUsrUtils.getUserEntity();
		ToolKits.isParamNull(user, "当前人员没有操作权限");
		if (!user.getUserType().equals(BussinessConstant.USER_TYPE_ZY) && !user.getUserType().equals(BussinessConstant.USER_TYPE_CYS)) {
			ToolKits.isParamNull(user, "当前人员没有操作权限");
		}

		Criteria criteria = Criteria.forClass(TmsLoadingBillDetailModel.class);
		Restriction r1 = Restrictions.in("shipbillId", sendCarUpdateMobileDetailVO.getShipbillIds().toArray());
		criteria.setRestriction(r1);
		List<TmsLoadingBillDetailModel> tmsLoadingBillDetailModels = tmsLoadingBillDetailMapper.findByCriteria(criteria);

		// 原派车单
		TmsLoadingBillHeaderModel originalModel = tmsLoadingBillHeaderMapper.findById(sendCarUpdateMobileDetailVO.getOriginalLoadingBillId(), TmsLoadingBillHeaderModel.class);
		Assert.isTrue(ToolKits.isEmpty(originalModel.getOldStatus()), "反审核原派车单【" + originalModel.getLoadingBillId() + "】不能移动运单！");

		// 目标派车单
		TmsLoadingBillHeaderModel nowModel = tmsLoadingBillHeaderMapper.findById(sendCarUpdateMobileDetailVO.getNowLoadingBillId(), TmsLoadingBillHeaderModel.class);
		Assert.isTrue(ToolKits.isEmpty(nowModel.getOldStatus()), "反审核目标派车单【" + nowModel.getLoadingBillId() + "】不能移动运单！");

		criteria = Criteria.forClass(TmsLoadingBillDetailModel.class);
		r1 = Restrictions.eq("loadingBillId", sendCarUpdateMobileDetailVO.getNowLoadingBillId());
		criteria.setRestriction(r1);

		List<TmsLoadingBillDetailModel> tmsLoadingBillDetailNowModels = tmsLoadingBillDetailMapper.findByCriteria(criteria);
//		List<Integer> indexList = tmsLoadingBillDetailNowModels.stream().filter(o -> ToolKits.isNotEmpty(o.getShippingOrder())).map(TmsLoadingBillDetailModel::getShippingOrder).collect(Collectors.toList());
		Integer index = maxStationOrderNumber(tmsLoadingBillDetailNowModels);
//		if (ToolKits.isEmpty(indexList)) {
//			index = 1;
//		} else {
//			index = Collections.max(indexList);
//		}

		// 目标派车单客户集合
		List<String> customerList = tmsLoadingBillDetailNowModels.stream().filter(o -> ToolKits.isNotEmpty(o.getConsigneeName())).map(TmsLoadingBillDetailModel::getConsigneeName).distinct().collect(Collectors.toList());

		// 目标派车单站点集合
		List<String> siteList = tmsLoadingBillDetailNowModels.stream().filter(o -> ToolKits.isNotEmpty(o.getConsigneeAddress())).map(TmsLoadingBillDetailModel::getConsigneeAddress).distinct().collect(Collectors.toList());

		// 修改配送顺序以及总重量体积件数等数据
		for (TmsLoadingBillDetailModel tmsLoadingBillDetailModel : tmsLoadingBillDetailModels) {

			r1 = Restrictions.eq("loadingBillId", tmsLoadingBillDetailModel.getLoadingBillId());
			Restriction r2 = Restrictions.ne("shipbillId", tmsLoadingBillDetailModel.getShipbillId());
			criteria.setRestriction(Restrictions.and(r1, r2));
			List<TmsLoadingBillDetailModel> tmsLoadingBillDetailModelList = tmsLoadingBillDetailMapper.findByCriteria(criteria);
//			for (TmsLoadingBillDetailModel loadingBillDetailModel : tmsLoadingBillDetailModelList) {
//				if (loadingBillDetailModel.getShippingOrder() > tmsLoadingBillDetailModel.getShippingOrder()) {
//					loadingBillDetailModel.setShippingOrder(loadingBillDetailModel.getShippingOrder() - 1);
//				}
//				tmsLoadingBillDetailMapper.update(loadingBillDetailModel);
//			}

			// 原派车单客户数
			Integer customerNumber = tmsLoadingBillDetailModelList.stream().filter(o -> ToolKits.isNotEmpty(o.getConsigneeName())).map(TmsLoadingBillDetailModel::getConsigneeName).distinct().collect(Collectors.toList()).size();

			// 原派车单站点数
			Integer siteNumber = tmsLoadingBillDetailModelList.stream().filter(o -> ToolKits.isNotEmpty(o.getConsigneeAddress())).map(TmsLoadingBillDetailModel::getConsigneeAddress).distinct().collect(Collectors.toList()).size();

			// 原派车单重量体积件数
			originalModel.setTotalPcs(originalModel.getTotalPcs().subtract(tmsLoadingBillDetailModel.getTotalPcs()));
			originalModel.setTotalVolume(originalModel.getTotalVolume().subtract(tmsLoadingBillDetailModel.getTotalVolume()));
			originalModel.setTotalWeight(originalModel.getTotalWeight().subtract(tmsLoadingBillDetailModel.getTotalWeight()));

			// 原派车单实际重量体积件数
			originalModel.setActualTotalPcs(originalModel.getActualTotalPcs().subtract(tmsLoadingBillDetailModel.getActualTotalPcs()));
			originalModel.setActualTotalVolume(originalModel.getActualTotalVolume().subtract(tmsLoadingBillDetailModel.getActualTotalVolume()));
			originalModel.setActualTotalWeight(originalModel.getActualTotalWeight().subtract(tmsLoadingBillDetailModel.getActualTotalWeight()));

			// 原派车单整件数拼箱数
			if (ToolKits.isNotEmpty(tmsLoadingBillDetailModel.getPackageWholePiece())) {
				originalModel.setTotalWholePiece(originalModel.getTotalWholePiece().subtract(tmsLoadingBillDetailModel.getPackageWholePiece()));
			}
			if (ToolKits.isNotEmpty(tmsLoadingBillDetailModel.getPackageLclPiece())) {
				originalModel.setTotalLclPiece(originalModel.getTotalLclPiece().subtract(tmsLoadingBillDetailModel.getPackageLclPiece()));
			}
			// 原派车单运单数
			originalModel.setShipbillNumber(originalModel.getShipbillNumber() - 1);

			// 原派车单客户数
			originalModel.setCustomerNumber(customerNumber);
			// 原派车单站点数
			originalModel.setSiteNumber(siteNumber);

			// 目标派车单重量体积件数
			nowModel.setTotalPcs(nowModel.getTotalPcs().add(tmsLoadingBillDetailModel.getTotalPcs()));
			nowModel.setTotalVolume(nowModel.getTotalVolume().add(tmsLoadingBillDetailModel.getTotalVolume()));
			nowModel.setTotalWeight(nowModel.getTotalWeight().add(tmsLoadingBillDetailModel.getTotalWeight()));

			// 目标派车单实际重量体积件数
			nowModel.setActualTotalPcs(nowModel.getActualTotalPcs().add(tmsLoadingBillDetailModel.getActualTotalPcs()));
			nowModel.setActualTotalVolume(nowModel.getActualTotalVolume().add(tmsLoadingBillDetailModel.getActualTotalVolume()));
			nowModel.setActualTotalWeight(nowModel.getActualTotalWeight().add(tmsLoadingBillDetailModel.getActualTotalWeight()));

			// 目标派车单整件数拼箱数
			if (ToolKits.isNotEmpty(tmsLoadingBillDetailModel.getPackageWholePiece())) {
				nowModel.setTotalWholePiece(nowModel.getTotalWholePiece().add(tmsLoadingBillDetailModel.getPackageWholePiece()));
			}
			if (ToolKits.isNotEmpty(tmsLoadingBillDetailModel.getPackageLclPiece())) {
				nowModel.setTotalLclPiece(nowModel.getTotalLclPiece().add(tmsLoadingBillDetailModel.getPackageLclPiece()));
			}

			// 目标派车单运单数
			nowModel.setShipbillNumber(nowModel.getShipbillNumber() + 1);

			// 目标派车单客户数
			if (!customerList.contains(tmsLoadingBillDetailModel.getConsigneeName())) {
				nowModel.setCustomerNumber(nowModel.getCustomerNumber() + 1);
			}

			// 目标派车单站点数
			if (!siteList.contains(tmsLoadingBillDetailModel.getConsigneeAddress())) {
				nowModel.setSiteNumber(nowModel.getSiteNumber() + 1);
			}

			// 修改明细内容
			Map<String, Object> map = Maps.newHashMap();
			map.put("loadingBillId", sendCarUpdateMobileDetailVO.getNowLoadingBillId());
			map.put("loadingBillNo", sendCarUpdateMobileDetailVO.getNowLoadingBillId());
			// 修改提货顺序
			index++;
			map.put("pickUpOrder", index);
			// 修改配送顺序
			index++;
			map.put("shippingOrder", index);

			tmsLoadingBillDetailMapper.updateMapById(tmsLoadingBillDetailModel.getId(), map, TmsLoadingBillDetailModel.class);

			// 运单操作日志保存
			ShipbillOperateLogSaveVO shipbillOperateLogSaveVO = new ShipbillOperateLogSaveVO();
			shipbillOperateLogSaveVO.setShipbillId(tmsLoadingBillDetailModel.getShipbillId());
			shipbillOperateLogSaveVO.setShipbillNo(tmsLoadingBillDetailModel.getShipbillNo());
			shipbillOperateLogSaveVO.setOperateEvent(DataDictionaryConstant.SHIPBILL_NODE_STATUSNAME_YD + sendCarUpdateMobileDetailVO.getNowLoadingBillId());
			shipbillOperateLogSaveVO.setOldStatus(DataDictionaryConstant.SHIPBILL_STATUS_DISPATCH);
			shipbillOperateLogSaveVO.setNewStatus(DataDictionaryConstant.SHIPBILL_STATUS_DISPATCH);
			shipbillOperateLogService.addShipbillOperateLogData(shipbillOperateLogSaveVO,user);

			StringBuffer nodeEvent = new StringBuffer();
			if (user.getUserType().equals(BussinessConstant.USER_TYPE_ZY)) {
				nodeEvent.append(nowModel.getCarrierName());
			} else {
				nodeEvent.append(ToolKits.isEmpty(nowModel.getDriverName()) ? "" : nowModel.getDriverName() + " ");
				nodeEvent.append(ToolKits.isEmpty(nowModel.getDeliverymanName()) ? "" : nowModel.getDeliverymanName() + " ");
				nodeEvent.append(ToolKits.isEmpty(nowModel.getVehiclePlateNumber()) ? "" : nowModel.getVehiclePlateNumber() + " ");
			}
			// 运单节点保存
			ShipbillNodeTrackingSaveVO shipbillNodeTrackingSaveVO = new ShipbillNodeTrackingSaveVO();
			shipbillNodeTrackingSaveVO.setShipbillId(tmsLoadingBillDetailModel.getShipbillId());
			shipbillNodeTrackingSaveVO.setShipbillNo(tmsLoadingBillDetailModel.getShipbillNo());
			shipbillNodeTrackingSaveVO.setStatus(DataDictionaryConstant.SHIPBILL_STATUS_REVIEW);
			shipbillNodeTrackingSaveVO.setNodeEvent(nodeEvent.toString());
			shipbillNodeTrackingService.addShipbillNodeTrackingData(shipbillNodeTrackingSaveVO,user);

		}

		// 原派车单计算装载率
		if (ToolKits.isNotEmpty(originalModel.getVehicleId())) {
			Map<String, String> map = this.calculateLoadingRate(originalModel.getVehicleId(), originalModel.getTotalWeight(), originalModel.getTotalVolume());
			originalModel.setVolumeLoadingRate(map.get("volume"));
			originalModel.setWeightLoadingRate(map.get("weight"));
		}

		// 目标派车单计算装载率
		if (ToolKits.isNotEmpty(nowModel.getVehicleId())) {
			Map<String, String> map = this.calculateLoadingRate(nowModel.getVehicleId(), nowModel.getTotalWeight(), nowModel.getTotalVolume());
			nowModel.setVolumeLoadingRate(map.get("volume"));
			nowModel.setWeightLoadingRate(map.get("weight"));
		}

		// 修改汇总表
		tmsLoadingBillHeaderMapper.update(originalModel);
		tmsLoadingBillHeaderMapper.update(nowModel);
	}

	/**
	 * 已派车运单弹窗
	 *
	 * @param sendCarShipbillPopVO
	 * @return
	 */
	@SuppressWarnings("resource")
	@Override
	public Page<SendCarShipbillPopDTODTO> shipbillPopData(SendCarShipbillPopVO sendCarShipbillPopVO) {
		ToolKits.isParamNull(sendCarShipbillPopVO, "待调度分页查询请求不为空");
		ToolKits.isParamNull(sendCarShipbillPopVO.getPageNum(), "当前页码不为空");
		ToolKits.isParamNull(sendCarShipbillPopVO.getPageSize(), "每页条数不为空");

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

		if (!user.getUserType().equals(BussinessConstant.USER_TYPE_ZY) && !user.getUserType().equals(BussinessConstant.USER_TYPE_CYS)) {
			ToolKits.isParamNull(user, "当前人员没有操作权限");
		}

		// 数据字典翻译数据集合
		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(TmsShipbillHeaderModel.class);
		Restriction r1 = ToolKits.isEmpty(sendCarShipbillPopVO.getCargoOwnerName()) ? null : Restrictions.like("cargoOwnerName", "%" + sendCarShipbillPopVO.getCargoOwnerName() + "%");
		Restriction r2 = ToolKits.isEmpty(sendCarShipbillPopVO.getOrderNo()) ? null : Restrictions.like("orderNo", "%" + sendCarShipbillPopVO.getOrderNo() + "%");
		Restriction r3 = ToolKits.isEmpty(sendCarShipbillPopVO.getShipbillNo()) ? null : Restrictions.like("shipbillNo", "%" + sendCarShipbillPopVO.getShipbillNo() + "%");
		Restriction r4 = ToolKits.isEmpty(sendCarShipbillPopVO.getOrderBusinessType()) ? null : Restrictions.eq("orderBusinessType", sendCarShipbillPopVO.getOrderBusinessType());
		Restriction r5 = ToolKits.isEmpty(sendCarShipbillPopVO.getOrderDateStart()) ? null : Restrictions.ge("orderDate", sendCarShipbillPopVO.getOrderDateStart());
		Restriction r6 = ToolKits.isEmpty(sendCarShipbillPopVO.getOrderDateEnd()) ? null : Restrictions.le("orderDate", sendCarShipbillPopVO.getOrderDateEnd());
		Restriction r7 = ToolKits.isEmpty(sendCarShipbillPopVO.getShipperName()) ? null : Restrictions.like("shipperName", "%" + sendCarShipbillPopVO.getShipperName() + "%");
		Restriction r8 = ToolKits.isEmpty(sendCarShipbillPopVO.getConsigneeName()) ? null : Restrictions.like("consigneeName", "%" + sendCarShipbillPopVO.getConsigneeName() + "%");

		Restriction r22 = Restrictions.eq("deliveryMethodType", DataDictionaryConstant.DELIVERY_METHOD_TYPE_SEND);
		Restriction r14 = Restrictions.eq("enterpriseId", user.getEnterpriseId());

		Restriction r15 = null;
		Restriction r23 = null;
		Restriction r13 = null;
		if (user.getUserType().equals(BussinessConstant.USER_TYPE_ZY)) {// 自有账号
			// 拆单状态 0未拆单
			Restriction r27 = Restrictions.eq("splitOrderStatus", DataDictionaryConstant.SPLIT_ORDER_STATUS_UN);
			// 承运商拆单类型 1未拆单
			Restriction r28 = Restrictions.eq("carrierSplitOrderType", DataDictionaryConstant.CARRIER_SPLIT_ORDER_TYPE_UN);
			Restriction r29 = Restrictions.and(r27, r28);
			// 承运商拆单类型 2拆分主单
			Restriction r30 = Restrictions.eq("carrierSplitOrderType", DataDictionaryConstant.CARRIER_SPLIT_ORDER_TYPE_SPLIT_MASTER);
			// 承运商拆单类型 2中转主单
			Restriction r31 = Restrictions.eq("carrierSplitOrderType", DataDictionaryConstant.CARRIER_SPLIT_ORDER_TYPE_TRANSIT_MASTER);
			r13 = Restrictions.or(r29, r30, r31);
			// 判断是否为部门权限
			r23 = Restrictions.eq("status", DataDictionaryConstant.SHIPBILL_STATUS_REVIEW);
			if (user.getOwnedAllDataAuthFlag().equals(BussinessConstant.USER_DEPARTMENT_AUTH_Y)) {
				r15 = Restrictions.in("departmentId", user.getDepts().stream().toArray(String[]::new));
			} else {
				Restriction r16 = Restrictions.in("departmentId", user.getDepts().stream().toArray(String[]::new));
				Restriction r17 = Restrictions.in("cargoOwnerId", user.getConsignors().stream().toArray(Long[]::new));
				Restriction r18 = Restrictions.in("consigneeUnitId", user.getWarehouses().stream().toArray(Long[]::new));
				Restriction r19 = Restrictions.in("consigneeUnitId", user.getSuppliers().stream().toArray(Long[]::new));
				Restriction r20 = Restrictions.in("consigneeUnitId", user.getCustomers().stream().toArray(Long[]::new));
				Restriction r21 = Restrictions.or(r18, r19, r20);
				r15 = Restrictions.and(r16, r17, r21);
			}
		} else {// 非自有账号
			r13 = Restrictions.eq("carrierSplitOrderStatus", DataDictionaryConstant.CARRIER_SPLIT_ORDER_STATUS_UN);
			Restriction r16 = Restrictions.eq("carrierId", user.getEnterpriseId());
			Restriction r17 = Restrictions.eq("status", DataDictionaryConstant.SHIPBILL_STATUS_DISPATCH_CHECK);
			Restriction r18 = Restrictions.eq("carrierShipbillStatus", DataDictionaryConstant.CARRIER_SHIPBILL_STATUS_AUDITED);
			r15 = Restrictions.and(r16, r17, r18);
		}

		criteria.setRestriction(Restrictions.and(r1, r2, r3, r4, r5, r6, r7, r8, r13, r14, r15, r22, r23));
		criteria.setOrder(Order.newInstance().desc(new String[] { "updatetime" }));

		PageUtils.startPage(sendCarShipbillPopVO.getPageNum(), sendCarShipbillPopVO.getPageSize());
		List<TmsShipbillHeaderModel> tmsShipbillHeaderModels = tmsShipbillHeaderMapper.findByCriteria(criteria);

		// 响应对象集合
		List<SendCarShipbillPopDTODTO> sendCarShipbillPopDTODTOS = Lists.newArrayList();

		for (TmsShipbillHeaderModel tmsShipbillHeaderModel : tmsShipbillHeaderModels) {
			SendCarShipbillPopDTODTO sendCarShipbillPopDTODTO = new SendCarShipbillPopDTODTO();
			BeanUtils.copyProperties(tmsShipbillHeaderModel, sendCarShipbillPopDTODTO);
			// 收货方位置(经纬度判断)
			if (ToolKits.isNotEmpty(tmsShipbillHeaderModel.getConsigneeLongitude()) && ToolKits.isNotEmpty(tmsShipbillHeaderModel.getConsigneeLatitude())) {
				sendCarShipbillPopDTODTO.setConsigneePositioning(StatusConstant.POSITIONING_YDW);
			} else {
				sendCarShipbillPopDTODTO.setConsigneePositioning(StatusConstant.POSITIONING_WDW);
			}
			// 发货方位置(经纬度判断)
			if (ToolKits.isNotEmpty(tmsShipbillHeaderModel.getShipperLongitude()) && ToolKits.isNotEmpty(tmsShipbillHeaderModel.getShipperLatitude())) {
				sendCarShipbillPopDTODTO.setShipperPositioning(StatusConstant.POSITIONING_YDW);
			} else {
				sendCarShipbillPopDTODTO.setShipperPositioning(StatusConstant.POSITIONING_WDW);
			}

			StringBuffer consigneeProvinceCityDistrict = new StringBuffer();
			// 目的地
			if (ToolKits.isNotEmpty(tmsShipbillHeaderModel.getConsigneeProvinceName())) {
				consigneeProvinceCityDistrict.append(tmsShipbillHeaderModel.getConsigneeProvinceName());
			}
			if (ToolKits.isNotEmpty(tmsShipbillHeaderModel.getConsigneeCityName())) {
				consigneeProvinceCityDistrict.append(tmsShipbillHeaderModel.getConsigneeCityName());
			}
			if (ToolKits.isNotEmpty(tmsShipbillHeaderModel.getConsigneeDistrictName())) {
				consigneeProvinceCityDistrict.append(tmsShipbillHeaderModel.getConsigneeDistrictName());
			}
			sendCarShipbillPopDTODTO.setConsigneeProvinceCityDistrict(consigneeProvinceCityDistrict.toString());
			// 始发地
			StringBuffer shipperProvinceCityDistrict = new StringBuffer();
			if (ToolKits.isNotEmpty(tmsShipbillHeaderModel.getShipperProvinceName())) {
				shipperProvinceCityDistrict.append(tmsShipbillHeaderModel.getShipperProvinceName());
			}
			if (ToolKits.isNotEmpty(tmsShipbillHeaderModel.getShipperCityName())) {
				shipperProvinceCityDistrict.append(tmsShipbillHeaderModel.getShipperCityName());
			}
			if (ToolKits.isNotEmpty(tmsShipbillHeaderModel.getShipperDistrictName())) {
				shipperProvinceCityDistrict.append(tmsShipbillHeaderModel.getShipperDistrictName());
			}
			sendCarShipbillPopDTODTO.setShipperProvinceCityDistrict(shipperProvinceCityDistrict.toString());

			// 类型翻译
			sendCarShipbillPopDTODTO.setOrderTypeName(PublicMethods.change(data1, String.valueOf(sendCarShipbillPopDTODTO.getOrderType())));
			sendCarShipbillPopDTODTO.setOrderBusinessTypeName(PublicMethods.change(data2, String.valueOf(sendCarShipbillPopDTODTO.getOrderBusinessType())));
			sendCarShipbillPopDTODTO.setDeliveryMethodTypeName(PublicMethods.change(data3, String.valueOf(sendCarShipbillPopDTODTO.getDeliveryMethodType())));
			sendCarShipbillPopDTODTO.setTransportTypeName(PublicMethods.change(data4, String.valueOf(sendCarShipbillPopDTODTO.getTransportType())));
			sendCarShipbillPopDTODTO.setTemperatureRequirementName(PublicMethods.change(data5, String.valueOf(sendCarShipbillPopDTODTO.getTemperatureRequirement())));
			sendCarShipbillPopDTODTO.setShipperTypeName(PublicMethods.change(data6, String.valueOf(sendCarShipbillPopDTODTO.getShipperType())));
			sendCarShipbillPopDTODTO.setConsigneeTypeName(PublicMethods.change(data7, String.valueOf(sendCarShipbillPopDTODTO.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(sendCarShipbillPopDTODTO.getOrderTypeName()) ? sendCarShipbillPopDTODTO.getOrderTypeName() : "")) {
							sendCarShipbillPopDTODTO.setBackground(ToolKits.isEmpty(signconfigPopDTO.getBackground()) ? "" : signconfigPopDTO.getBackground());
							sendCarShipbillPopDTODTO.setColor(ToolKits.isEmpty(signconfigPopDTO.getColor()) ? "" : signconfigPopDTO.getColor());

							sendCarShipbillPopDTODTO.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(sendCarShipbillPopDTODTO.getOrderBusinessTypeName()) ? sendCarShipbillPopDTODTO.getOrderBusinessTypeName() : "")) {
							sendCarShipbillPopDTODTO.setBackground(ToolKits.isEmpty(signconfigPopDTO.getBackground()) ? "" : signconfigPopDTO.getBackground());
							sendCarShipbillPopDTODTO.setColor(ToolKits.isEmpty(signconfigPopDTO.getColor()) ? "" : signconfigPopDTO.getColor());

							sendCarShipbillPopDTODTO.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(sendCarShipbillPopDTODTO.getTemperatureRequirementName()) ? sendCarShipbillPopDTODTO.getTemperatureRequirementName() : "")) {
							sendCarShipbillPopDTODTO.setBackground(ToolKits.isEmpty(signconfigPopDTO.getBackground()) ? "" : signconfigPopDTO.getBackground());
							sendCarShipbillPopDTODTO.setColor(ToolKits.isEmpty(signconfigPopDTO.getColor()) ? "" : signconfigPopDTO.getColor());

							sendCarShipbillPopDTODTO.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(sendCarShipbillPopDTODTO.getDeliveryMethodTypeName()) ? sendCarShipbillPopDTODTO.getDeliveryMethodTypeName() : "")) {
							sendCarShipbillPopDTODTO.setBackground(ToolKits.isEmpty(signconfigPopDTO.getBackground()) ? "" : signconfigPopDTO.getBackground());
							sendCarShipbillPopDTODTO.setColor(ToolKits.isEmpty(signconfigPopDTO.getColor()) ? "" : signconfigPopDTO.getColor());

							sendCarShipbillPopDTODTO.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(sendCarShipbillPopDTODTO.getMemo()) ? sendCarShipbillPopDTODTO.getMemo() : "")) {
							sendCarShipbillPopDTODTO.setBackground(ToolKits.isEmpty(signconfigPopDTO.getBackground()) ? "" : signconfigPopDTO.getBackground());
							sendCarShipbillPopDTODTO.setColor(ToolKits.isEmpty(signconfigPopDTO.getColor()) ? "" : signconfigPopDTO.getColor());

							sendCarShipbillPopDTODTO.setSignConfigId(signconfigPopDTO.getId());

							break Signconfig;
						}
					}
					break;
				}
			}

			sendCarShipbillPopDTODTOS.add(sendCarShipbillPopDTODTO);
		}

		// 分页重组
		Page<SendCarShipbillPopDTODTO> page = PageUtils.getPage(sendCarShipbillPopDTODTOS);
		if (tmsShipbillHeaderModels instanceof com.github.pagehelper.Page) {
			com.github.pagehelper.Page<TmsShipbillHeaderModel> p0 = (com.github.pagehelper.Page<TmsShipbillHeaderModel>) tmsShipbillHeaderModels;
			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;
	}

	/**
	 * 拼接
	 *
	 * @param str1
	 * @param str2
	 * @return
	 */
	private String splicing(String str1, String str2) {
		String str = null;
		StringBuffer stringBuffer = new StringBuffer();
		if (ToolKits.isNotEmpty(str1)) {
			stringBuffer.append(str1);
			stringBuffer.append(",");
		}
		if (ToolKits.isNotEmpty(str2)) {
			stringBuffer.append(str2);
		} else {
			if (stringBuffer.length() > 0) {
				str = stringBuffer.toString().substring(0, stringBuffer.length() - 1);
			} else {
				return null;
			}
		}
		str = stringBuffer.toString();
		return str;
	}

	/**
	 * 计算装载率
	 *
	 * @param id
	 * @param weight
	 * @param volume
	 * @return
	 */
	private Map<String, String> calculateLoadingRate(Long id, BigDecimal weight, BigDecimal volume) {

		VehicleCheckVO vehicleCheckVO = new VehicleCheckVO();
		vehicleCheckVO.setVehicleId(id);

		RestMessage<VehicleCheckDTO> data = maindataTmsResource.getVehicle(vehicleCheckVO);
		if (!data.isSuccess()) {
			throw new RuntimeException("获取车辆失败");
		}
		VehicleCheckDTO vehicleCheckDTO = data.getData();

		StringBuffer weightStr = new StringBuffer();
		StringBuffer volumeStr = new StringBuffer();

		if (ToolKits.isNotEmpty(weight)) {
			BigDecimal divide = ToolKits.isEmpty(vehicleCheckDTO.getWeight()) ? BigDecimal.ZERO : weight.divide(vehicleCheckDTO.getWeight(), 2, BigDecimal.ROUND_HALF_UP);
			BigDecimal multiply = divide.multiply(new BigDecimal("100"));
			weightStr.append(multiply.intValue());
			weightStr.append("%");
		}
		if (ToolKits.isNotEmpty(volume)) {
			BigDecimal divide = ToolKits.isEmpty(vehicleCheckDTO.getVolume()) ? BigDecimal.ZERO : volume.divide(vehicleCheckDTO.getVolume(), 2, BigDecimal.ROUND_HALF_UP);
			BigDecimal multiply = divide.multiply(new BigDecimal("100"));
			volumeStr.append(multiply.intValue());
			volumeStr.append("%");
		}

		Map<String, String> map = Maps.newHashMap();
		map.put("weight", weightStr.toString());
		map.put("volume", volumeStr.toString());

		return map;
	}

	/**
	 * 计算派车单统计数据
	 *
	 * @param tmsLoadingBillHeaderModel
	 * @return
	 */
	private void calculateLoadingData(TmsLoadingBillHeaderModel tmsLoadingBillHeaderModel) {
		// 重新计算
		Criteria criteria = Criteria.forClass(TmsLoadingBillDetailModel.class);
		Restriction r1 = Restrictions.eq(TmsLoadingBillDetailModel::getLoadingBillId, tmsLoadingBillHeaderModel.getLoadingBillId());
		criteria.setRestriction(Restrictions.and(r1));
		List<TmsLoadingBillDetailModel> tmsLoadingBillDetailModelList = tmsLoadingBillDetailMapper.findByCriteria(criteria);
		if (ToolKits.isEmpty(tmsLoadingBillDetailModelList)) {
			// 货主数
			tmsLoadingBillHeaderModel.setCargoOwnerNumber(Long.valueOf(0));
			// 客户数
			tmsLoadingBillHeaderModel.setCustomerNumber(0);
			// 运单数
			tmsLoadingBillHeaderModel.setShipbillNumber(0);
			// 总提货点数
			tmsLoadingBillHeaderModel.setPickupStations(Long.valueOf(0));
			// 总配送点数
			tmsLoadingBillHeaderModel.setDeliveryStations(Long.valueOf(0));
			// 总站数
			tmsLoadingBillHeaderModel.setTotalStations(Long.valueOf(0));
			tmsLoadingBillHeaderModel.setSiteNumber(tmsLoadingBillHeaderModel.getTotalStations().intValue());
			// 冷链运单数
			tmsLoadingBillHeaderModel.setColdShipbillNumber(Long.valueOf(0));

			// 紧急加急运单数
			tmsLoadingBillHeaderModel.setUrgentShipbillNumber(Long.valueOf(0));

			// 商品/包裹 总件数
			tmsLoadingBillHeaderModel.setTotalPcs(BigDecimal.ZERO);
			tmsLoadingBillHeaderModel.setTotalLclPiece(BigDecimal.ZERO);
			tmsLoadingBillHeaderModel.setTotalWholePiece(BigDecimal.ZERO);
			// 商品/包裹 总重量
			tmsLoadingBillHeaderModel.setTotalWeight(BigDecimal.ZERO);
			// 商品/包裹 总体积
			tmsLoadingBillHeaderModel.setTotalVolume(BigDecimal.ZERO);

			tmsLoadingBillHeaderModel.setActualTotalPcs(tmsLoadingBillHeaderModel.getTotalPcs());
			tmsLoadingBillHeaderModel.setActualTotalWeight(tmsLoadingBillHeaderModel.getTotalWeight());
			tmsLoadingBillHeaderModel.setActualTotalVolume(tmsLoadingBillHeaderModel.getTotalVolume());
			;
			tmsLoadingBillHeaderModel.setTotalMileage(BigDecimal.ZERO);
		} else {
			// 货主数
			tmsLoadingBillHeaderModel.setCargoOwnerNumber(Long.valueOf(tmsLoadingBillDetailModelList.stream().map(TmsLoadingBillDetailModel::getCargoOwnerName).distinct().collect(Collectors.toList()).size()));
			// 客户数
			tmsLoadingBillHeaderModel.setCustomerNumber(tmsLoadingBillDetailModelList.stream().map(TmsLoadingBillDetailModel::getConsigneeUnitName).distinct().collect(Collectors.toList()).size());
			// 运单数
			tmsLoadingBillHeaderModel.setShipbillNumber(tmsLoadingBillDetailModelList.size());
			// 总提货点数
			tmsLoadingBillHeaderModel.setPickupStations(Long.valueOf(tmsLoadingBillDetailModelList.stream().map(TmsLoadingBillDetailModel::getShipperAddress).distinct().collect(Collectors.toList()).size()));
			// 总配送点数
			tmsLoadingBillHeaderModel.setDeliveryStations(Long.valueOf(tmsLoadingBillDetailModelList.stream().map(TmsLoadingBillDetailModel::getConsigneeAddress).distinct().collect(Collectors.toList()).size()));
			// 总站数
			tmsLoadingBillHeaderModel.setTotalStations(tmsLoadingBillHeaderModel.getPickupStations().longValue() + tmsLoadingBillHeaderModel.getDeliveryStations().longValue());
			tmsLoadingBillHeaderModel.setSiteNumber(tmsLoadingBillHeaderModel.getTotalStations().intValue());
			// 冷链运单数
			long coldChainShipbillQty = tmsLoadingBillDetailModelList.stream().filter(s -> ToolKits.isNotEmpty(s.getTemperatureRequirement()) && s.getTemperatureRequirement().intValue() > 1).collect(Collectors.toList()).size();
			tmsLoadingBillHeaderModel.setColdShipbillNumber(coldChainShipbillQty);

			// 紧急加急运单数
			long urgentShipbillQty = tmsLoadingBillDetailModelList.stream().filter(s -> ToolKits.isNotEmpty(s.getOrderType()) && s.getOrderType().intValue() > 1).collect(Collectors.toList()).size();
			tmsLoadingBillHeaderModel.setUrgentShipbillNumber(urgentShipbillQty);

			BigDecimal pcs1 = tmsLoadingBillDetailModelList.stream().filter(dto -> ToolKits.isNotEmpty(dto.getTotalPcs())).map(TmsLoadingBillDetailModel::getTotalPcs).reduce(BigDecimal.ZERO, BigDecimal::add);
			BigDecimal pcs2 = tmsLoadingBillDetailModelList.stream().filter(dto -> ToolKits.isNotEmpty(dto.getPackageLclPiece())).map(TmsLoadingBillDetailModel::getPackageLclPiece).reduce(BigDecimal.ZERO, BigDecimal::add);
			BigDecimal pcs3 = tmsLoadingBillDetailModelList.stream().filter(dto -> ToolKits.isNotEmpty(dto.getPackageWholePiece())).map(TmsLoadingBillDetailModel::getPackageWholePiece).reduce(BigDecimal.ZERO, BigDecimal::add);
			BigDecimal weigth1 = tmsLoadingBillDetailModelList.stream().filter(dto -> ToolKits.isNotEmpty(dto.getTotalWeight())).map(TmsLoadingBillDetailModel::getTotalWeight).reduce(BigDecimal.ZERO, BigDecimal::add);
			BigDecimal weigth2 = tmsLoadingBillDetailModelList.stream().filter(dto -> ToolKits.isNotEmpty(dto.getPackageTotalWeight())).map(TmsLoadingBillDetailModel::getPackageTotalWeight).reduce(BigDecimal.ZERO, BigDecimal::add);
			BigDecimal volume1 = tmsLoadingBillDetailModelList.stream().filter(dto -> ToolKits.isNotEmpty(dto.getTotalVolume())).map(TmsLoadingBillDetailModel::getTotalVolume).reduce(BigDecimal.ZERO, BigDecimal::add);
			BigDecimal volume2 = tmsLoadingBillDetailModelList.stream().filter(dto -> ToolKits.isNotEmpty(dto.getPackageTotalVolume())).map(TmsLoadingBillDetailModel::getPackageTotalVolume).reduce(BigDecimal.ZERO, BigDecimal::add);

			// 商品/包裹 总件数
			tmsLoadingBillHeaderModel.setTotalPcs(pcs1);
			tmsLoadingBillHeaderModel.setTotalLclPiece(pcs2);
			tmsLoadingBillHeaderModel.setTotalWholePiece(pcs3);
			// 商品/包裹 总重量
			tmsLoadingBillHeaderModel.setTotalWeight(weigth1.add(weigth2));
			// 商品/包裹 总体积
			tmsLoadingBillHeaderModel.setTotalVolume(volume1.add(volume2));

			tmsLoadingBillHeaderModel.setActualTotalPcs(tmsLoadingBillHeaderModel.getTotalPcs());
			tmsLoadingBillHeaderModel.setActualTotalWeight(tmsLoadingBillHeaderModel.getTotalWeight());
			tmsLoadingBillHeaderModel.setActualTotalVolume(tmsLoadingBillHeaderModel.getTotalVolume());
		}
	}

	/**
	 * 获得第一个字符
	 *
	 * @param str
	 * @return
	 */
	public String getFirstStr(String str) {
		if (ToolKits.isEmpty(str)) {
			return null;
		}
		String[] arr1 = str.split(",");
		return arr1[0];
	}

	/**
	 * 去掉数组第一个元素
	 *
	 * @param str
	 * @return
	 */
	public String subArrToString(String str) {
		if (ToolKits.isEmpty(str)) {
			return null;
		}
		String[] arr1 = str.split(",");
		if (null == arr1) {
			return null;
		} else if (1 == arr1.length) {
			return null;
		} else if (1 < arr1.length) {
			String[] arr2 = (String[]) ArrayUtils.subarray(arr1, 1, arr1.length);
			return Arrays.stream(arr2).collect(Collectors.joining(","));
		}
		return null;
	}

	/**
	 * 调度单审核信息查询
	 *
	 * @param approvalInfoVO
	 * @return
	 */
	public DispatchCkApprovalSCDTO getApprovalInfoData(DispatchApprovalInfoVO approvalInfoVO) {
		ToolKits.isParamNull(approvalInfoVO, "调度单审核信息查询请求不为空");
		ToolKits.isParamNull(approvalInfoVO.getLoadingBillId(), "派车单ID不为空");
		ToolKits.isParamNull(approvalInfoVO.getApprovalBusinessId(), "审批业务ID不为空");

		UserEntity user = PlgFxUsrUtils.getUserEntity();
		ToolKits.isParamNull(user, "当前人员没有操作权限");
		DispatchCkApprovalSCDTO approvalSCDTO = new DispatchCkApprovalSCDTO();
		// 数据字典翻译数据集合
		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();
		// 承运方类型
		RestMessage<List<Map<String, Object>>> restMessage9 = maindataTmsResource.getDropDownById(DataDictionaryConstant.LINE_CARRIER_TYPE, null, null, null);
		if (!restMessage9.isSuccess()) {
			throw new RuntimeException("承运方类型翻译失败");
		} else {
			data9 = restMessage9.getData();
		}

		TmsLoadingBillHeaderModel loadingBillHeaderModel = tmsLoadingBillHeaderMapper.findById(approvalInfoVO.getLoadingBillId(), TmsLoadingBillHeaderModel.class);
		if (ToolKits.isEmpty(loadingBillHeaderModel)) {
			throw new PrologException("调度单【" + approvalInfoVO.getLoadingBillId() + "】信息不存在");
		}
		// 设定调度单信息
		BeanUtils.copyProperties(loadingBillHeaderModel, approvalSCDTO);
		approvalSCDTO.setCarrierTypeName(PublicMethods.change(data9, String.valueOf(loadingBillHeaderModel.getCarrierType())));

		// 查询明细内容
		Criteria criteria = Criteria.forClass(TmsLoadingBillDetailModel.class);
		Restriction r1 = Restrictions.eq(TmsLoadingBillDetailModel::getLoadingBillId, approvalInfoVO.getLoadingBillId());
		criteria.setRestriction(r1);
		List<TmsLoadingBillDetailModel> tmsLoadingBillDetailModels = tmsLoadingBillDetailMapper.findByCriteria(criteria);
		if (ToolKits.isEmpty(tmsLoadingBillDetailModels)) {
			throw new PrologException("调度单【" + approvalInfoVO.getLoadingBillId() + "】的明细信息不存在");
		}

		List<ShipbillInfoDTO> shipbillInfoDTOS = 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();
		}
		// 运单状态
		RestMessage<List<Map<String, Object>>> restMessage8 = maindataTmsResource.getDropDownById(DataDictionaryConstant.SHIPBILL_STATUS, null, null, null);
		if (!restMessage8.isSuccess()) {
			throw new RuntimeException("运单状态翻译失败!");
		} else {
			data8 = restMessage8.getData();
		}

		// 运单信息
		for (TmsLoadingBillDetailModel detailModel : tmsLoadingBillDetailModels) {
			ShipbillInfoDTO shipbillInfoDTO = new ShipbillInfoDTO();
			BeanUtils.copyProperties(detailModel, shipbillInfoDTO);

			shipbillInfoDTO.setOrderTypeName(PublicMethods.change(data1, String.valueOf(detailModel.getOrderType())));
			shipbillInfoDTO.setOrderBusinessTypeName(PublicMethods.change(data2, String.valueOf(detailModel.getOrderBusinessType())));
			shipbillInfoDTO.setDeliveryMethodTypeName(PublicMethods.change(data3, String.valueOf(detailModel.getDeliveryMethodType())));
			shipbillInfoDTO.setTransportTypeName(PublicMethods.change(data4, String.valueOf(detailModel.getTransportType())));
			shipbillInfoDTO.setTemperatureRequirementName(PublicMethods.change(data5, String.valueOf(detailModel.getTemperatureRequirement())));
			shipbillInfoDTO.setShipperTypeName(PublicMethods.change(data6, String.valueOf(detailModel.getShipperType())));
			shipbillInfoDTO.setConsigneeTypeName(PublicMethods.change(data7, String.valueOf(detailModel.getConsigneeType())));
			shipbillInfoDTO.setStatusName(PublicMethods.change(data8, String.valueOf(detailModel.getStatus())));
			shipbillInfoDTOS.add(shipbillInfoDTO);
		}
		approvalSCDTO.setShipbillInfoDTOList(shipbillInfoDTOS);

		RestMessage<List<ApprovalLogDTO>> resourceBusLog = maindataTmsResource.getBusLog(approvalInfoVO.getApprovalBusinessId());
		if (!resourceBusLog.isSuccess()) {
			throw new PrologException("调用审批日志服务失败!");
		}
		approvalSCDTO.setShipbillApprovalLogDTOList(resourceBusLog.getData());

		RestMessage<List<ApprovalNodeSelDTO>> resourceBusDetail = maindataTmsResource.getBusDetail(approvalInfoVO.getApprovalBusinessId());
		if (!resourceBusLog.isSuccess()) {
			throw new PrologException("调用审批节点服务失败!");
		}
		approvalSCDTO.setShipbillApprovalNodeDTOList(resourceBusDetail.getData());

		return approvalSCDTO;
	}

	/**
	 * 调度单审批作废
	 *
	 * @param approvalInvalidVO
	 */
	public void dispatchApprovalInvalidData(DispatchCkApprovalInvalidVO approvalInvalidVO) {
		ToolKits.isParamNull(approvalInvalidVO, "调度单审批作废请求不为空");
		ToolKits.isParamNull(approvalInvalidVO.getLoadingBillId(), "派车单ID不为空");
		ToolKits.isParamNull(approvalInvalidVO.getApprovalBusinessId(), "审批业务ID不为空");

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

		// 审核业务作废
		RestMessage<Object> restMessage = maindataTmsResource.approvalInvalidExecute(approvalInvalidVO.getApprovalBusinessId());
		if (!restMessage.isSuccess()) {
			throw new RuntimeException("调用审核作废失败");
		}
		Date date = DateUtils.nowDate();
		Map<String, Object> map = Maps.newHashMap();
		map.put("status", DataDictionaryConstant.LOADING_BILL_STATUS_WSH);
		map.put("updatetime", date);
		map.put("updateperson", user.getNickname());
		// 调度单状态更新
		tmsLoadingBillHeaderMapper.updateMapById(approvalInvalidVO.getLoadingBillId(), map, TmsLoadingBillHeaderModel.class);

		// 调度单明细更新
		// 查询明细内容
		Criteria criteria = Criteria.forClass(TmsLoadingBillDetailModel.class);
		Restriction r1 = Restrictions.eq(TmsLoadingBillDetailModel::getLoadingBillId, approvalInvalidVO.getLoadingBillId());
		criteria.setRestriction(r1);
		List<TmsLoadingBillDetailModel> tmsLoadingBillDetailModels = tmsLoadingBillDetailMapper.findByCriteria(criteria);

		if (ToolKits.isEmpty(tmsLoadingBillDetailModels)) {
			throw new PrologException("调度单【" + approvalInvalidVO.getLoadingBillId() + "】的明细信息不存在");
		}

		Map<String, Object> mapUpdateLoadingDetail = Maps.newHashMap();
		mapUpdateLoadingDetail.put("updatetime", date);
		mapUpdateLoadingDetail.put("updateperson", user.getNickname());

		Map<String, Object> mapUpdateShipbillHeader = Maps.newHashMap();
		mapUpdateShipbillHeader.put("updatetime", date);
		mapUpdateShipbillHeader.put("updateperson", user.getNickname());

		for (TmsLoadingBillDetailModel detailModel : tmsLoadingBillDetailModels) {
			// 自有账号
			mapUpdateLoadingDetail.put("status", DataDictionaryConstant.SHIPBILL_STATUS_DISPATCH);
			mapUpdateShipbillHeader.put("status", DataDictionaryConstant.SHIPBILL_STATUS_DISPATCH);
			// 更改运单状态
			tmsShipbillHeaderMapper.updateMapById(detailModel.getShipbillId(), mapUpdateShipbillHeader, TmsShipbillHeaderModel.class);
			// 更新派车单明细状态
			tmsLoadingBillDetailMapper.updateMapById(detailModel.getId(), mapUpdateLoadingDetail, TmsLoadingBillDetailModel.class);
		}
	}

	/**
	 * 调度单审批流撤回
	 *
	 * @param approvalRetractVO
	 */
	public void dispatchApprovalRetractData(DispatchApprovalRetractVO approvalRetractVO) {

		ToolKits.isParamNull(approvalRetractVO, "调度单审批撤回请求不为空");
		ToolKits.isParamNull(approvalRetractVO.getLoadingBillId(), "派车单ID不为空");
		ToolKits.isParamNull(approvalRetractVO.getApprovalBusinessId(), "审批业务ID不为空");

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

		// 审核业务撤回
		RestMessage<Object> restMessage = maindataTmsResource.approvalRetractExecute(approvalRetractVO.getApprovalBusinessId());
		if (!restMessage.isSuccess()) {
			throw new RuntimeException("调用审核撤回失败");
		}
	}

	/**
	 * 调度单审批流提交
	 *
	 * @param approvalSubmitVO
	 */
	public void dispatchApprovalSubmitData(DispatchApprovalSubmitVO approvalSubmitVO) {
		ToolKits.isParamNull(approvalSubmitVO, "调度单审批提交请求不为空");
		ToolKits.isParamNull(approvalSubmitVO.getLoadingBillId(), "派车单ID不为空");
		ToolKits.isParamNull(approvalSubmitVO.getApprovalBusinessId(), "审批业务ID不为空");

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

		// 提交当前审批
		RestMessage<Object> restMessage1 = maindataTmsResource.approvalSubmitExecute(approvalSubmitVO.getApprovalBusinessId());
		if (!restMessage1.isSuccess()) {
			throw new RuntimeException("调用审批提交失败");
		}
	}

	/**
	 * 调度单审批流审核
	 *
	 * @param approvalVO
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void dispatchApprovalData(DispatchApprovalVO approvalVO) {
		ToolKits.isParamNull(approvalVO, "调度单审核请求不为空");
		ToolKits.isParamNull(approvalVO.getApprovalObjectId(), "运单ID不为空");
		ToolKits.isParamNull(approvalVO.getApprovalBusinessId(), "审批业务ID不为空");
		ToolKits.isParamNull(approvalVO.getApprovalObjectName(), "审批对象名称不为空");
		ToolKits.isParamNull(approvalVO.getApprovalId(), "审批流程ID不为空");
		ToolKits.isParamNull(approvalVO.getNextApproverNodeId(), "下一审批节点ID不为空");
		ToolKits.isParamNull(approvalVO.getNextApprovalOrder(), "下一节点顺序不为空");

		ToolKits.isParamNull(approvalVO.getResult(), "审批结果不为空");

		if (!approvalVO.getResult().equals(DataDictionaryConstant.NODE_APPROVAL_RESULT_PASS)) {
			ToolKits.isParamNull(approvalVO.getApprovalOpinion(), "驳回意见不为空");
		}

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

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

		TmsLoadingBillHeaderModel loadingBillHeaderModel = tmsLoadingBillHeaderMapper.findById(approvalVO.getApprovalObjectId(), TmsLoadingBillHeaderModel.class);
		if (ToolKits.isEmpty(loadingBillHeaderModel)) {
			throw new PrologException("调度单【" + approvalVO.getApprovalObjectId() + "】不存在");
		}
		if (!loadingBillHeaderModel.getStatus().equals(DataDictionaryConstant.LOADING_BILL_STATUS_DIS_APPROVAL)) {
			throw new PrologException("运单【" + approvalVO.getApprovalObjectId() + "】已审批");
		}

		// 封装审核所需数据
		ApprovalBusinessNodeVO approvalBusinessNodeVO = new ApprovalBusinessNodeVO();
		approvalBusinessNodeVO.setApprovalObjectName(approvalVO.getApprovalObjectName());
		approvalBusinessNodeVO.setApprovalBusinessId(approvalVO.getApprovalBusinessId());
		approvalBusinessNodeVO.setApprovalId(approvalVO.getApprovalId());
		approvalBusinessNodeVO.setNextApprovalNodeId(approvalVO.getNextApproverNodeId());
		approvalBusinessNodeVO.setNextApprovalOrder(approvalVO.getNextApprovalOrder());
		approvalBusinessNodeVO.setNextApproverRoleId(approvalVO.getNextApproverRoleId());
		approvalBusinessNodeVO.setNextApproverRoleName(approvalVO.getNextApproverRoleName());
		approvalBusinessNodeVO.setNextApproverUserId(approvalVO.getNextApproverUserId());
		approvalBusinessNodeVO.setNextApproverUserName(approvalVO.getNextApproverUserName());
		approvalBusinessNodeVO.setApproverPersonId(user.getUserid());
		approvalBusinessNodeVO.setApproverPersonName(user.getNickname());
		approvalBusinessNodeVO.setApprovalOpinion(ToolKits.isEmpty(approvalVO.getApprovalOpinion()) ? "" : approvalVO.getApprovalOpinion());
		approvalBusinessNodeVO.setApprovalTime(date);
		approvalBusinessNodeVO.setResult(approvalVO.getResult());

		approvalBusinessNodeVO.setApproverPersonRoleId(user.getRoles().stream().map(role -> String.valueOf(role)).collect(Collectors.joining(",")));
		approvalBusinessNodeVO.setApproverPersonRoleName("");

		// 节点审批者类型 数据字典 NODE_APPROVER_TYPE 1 角色 2 用户
		approvalBusinessNodeVO.setNodeApproverType(approvalVO.getNodeApproverType());
		// 审批方式 数据字典 NODE_APPROVAL_TYPE: 1 会签 2 或签
		approvalBusinessNodeVO.setNodeApprovalType(approvalVO.getNodeApprovalType());

		// 流程节点审批
		RestMessage<Boolean> restMessage1 = maindataTmsResource.nodeApprovalExecute(approvalBusinessNodeVO);
		if (!restMessage1.isSuccess()) {
			throw new RuntimeException("调用审核失败");
		}
		Boolean isFinish = restMessage1.getData();

		// 判断是否已结束流程
		if (isFinish) {
			// 流程结束
			Criteria criteria = Criteria.forClass(TmsLoadingBillDetailModel.class);
			Restriction r1 = Restrictions.eq("loadingBillId", loadingBillHeaderModel.getLoadingBillId());
			criteria.setRestriction(r1);
			List<TmsLoadingBillDetailModel> tmsLoadingBillDetailModels = tmsLoadingBillDetailMapper.findByCriteria(criteria);

			if (ToolKits.isEmpty(tmsLoadingBillDetailModels)) {
				throw new PrologException("调度单【" + approvalVO.getApprovalObjectId() + "】的明细信息不存在");
			}

			int shipperTypeCnt = 0;
			int consigneeType = 0;
			List<String> receiveObjs = Lists.newArrayList();
			for (TmsLoadingBillDetailModel detailModel : tmsLoadingBillDetailModels) {
				if (DataDictionaryConstant.SHIPPER_TYPE_CK.equals(detailModel.getShipperType())) {
					shipperTypeCnt++;
				}
				if (DataDictionaryConstant.CONSIGNEE_TYPE_CK.equals(detailModel.getConsigneeType())) {
					consigneeType++;
				}
				ShipbillNodeTrackingSaveVO shipbillNodeTrackingSaveVO = new ShipbillNodeTrackingSaveVO();
				ShipbillOperateLogSaveVO shipbillOperateLogSaveVO = new ShipbillOperateLogSaveVO();
				Map<String, Object> mapUpdateShipbillHeader = Maps.newHashMap();
				Map<String, Object> mapUpdateLoadingDetail = Maps.newHashMap();

				mapUpdateShipbillHeader.put("updateperson", user.getNickname());
				mapUpdateShipbillHeader.put("updatetime", date);
				mapUpdateLoadingDetail.put("updateperson", user.getNickname());
				mapUpdateLoadingDetail.put("updatetime", date);
				if (DataDictionaryConstant.LINE_CARRIER_TYPE_SJ.equals(loadingBillHeaderModel.getCarrierType())) {
					// 调度司机
					// 判定下一步流程
					int status = businessFlowUtil.judgmentNextFlowSts(detailModel.getFlowConfig(), DataDictionaryConstant.FLOW_CONFIG_CHECK);
					mapUpdateLoadingDetail.put("status", status);
					mapUpdateShipbillHeader.put("status", status);
					shipbillNodeTrackingSaveVO.setStatus(status);
					shipbillOperateLogSaveVO.setOldStatus(DataDictionaryConstant.SHIPBILL_STATUS_DISPATCH);
					shipbillOperateLogSaveVO.setNewStatus(status);

					shipbillNodeTrackingSaveVO.setNodeEvent(DataDictionaryConstant.SHIPBILL_NODE_STATUSNAME_PC);
					shipbillOperateLogSaveVO.setOperateEvent(DataDictionaryConstant.SHIPBILL_NODE_STATUSNAME_PC);
				} else {
					if (ToolKits.isNotEmpty(detailModel.getCarrierFlowConfig())) {

						int status = DataDictionaryConstant.SHIPBILL_STATUS_DISPATCH_CHECK;

						mapUpdateLoadingDetail.put("status", status);
						mapUpdateShipbillHeader.put("status", status);
						mapUpdateLoadingDetail.put("carrierShipbillStatus", DataDictionaryConstant.CARRIER_SHIPBILL_STATUS_WAIT_RECEIVE);
						mapUpdateShipbillHeader.put("carrierShipbillStatus", DataDictionaryConstant.CARRIER_SHIPBILL_STATUS_WAIT_RECEIVE);

						shipbillNodeTrackingSaveVO.setStatus(status);
						shipbillNodeTrackingSaveVO.setNodeEvent(DataDictionaryConstant.SHIPBILL_NODE_STATUSNAME_TY);
						shipbillOperateLogSaveVO.setOperateEvent(DataDictionaryConstant.SHIPBILL_NODE_STATUSNAME_TY);
						shipbillOperateLogSaveVO.setOldStatus(DataDictionaryConstant.SHIPBILL_STATUS_DISPATCH);
						shipbillOperateLogSaveVO.setNewStatus(status);

						// 承运商是否开启接单拒绝
						if (!detailModel.getCarrierFlowConfig().contains(DataDictionaryConstant.FLOW_CONFIG_REJECT_RECEIVE)) {
							receiveObjs.add(detailModel.getShipbillId());
						}
					} else {
						// 判定下一步流程
						int status = businessFlowUtil.judgmentNextFlowSts(detailModel.getFlowConfig(), DataDictionaryConstant.FLOW_CONFIG_CHECK);
						mapUpdateLoadingDetail.put("status", status);
						mapUpdateShipbillHeader.put("status", status);
						mapUpdateLoadingDetail.put("carrierShipbillStatus", DataDictionaryConstant.CARRIER_SHIPBILL_STATUS_DISPATCHED_CHECK);
						mapUpdateShipbillHeader.put("carrierShipbillStatus", DataDictionaryConstant.CARRIER_SHIPBILL_STATUS_DISPATCHED_CHECK);

						shipbillNodeTrackingSaveVO.setStatus(status);
						shipbillNodeTrackingSaveVO.setNodeEvent(DataDictionaryConstant.SHIPBILL_NODE_STATUSNAME_TY);
						shipbillOperateLogSaveVO.setOperateEvent(DataDictionaryConstant.SHIPBILL_NODE_STATUSNAME_TY);
						shipbillOperateLogSaveVO.setOldStatus(DataDictionaryConstant.SHIPBILL_STATUS_DISPATCH);
						shipbillOperateLogSaveVO.setNewStatus(status);
					}
				}

				// 更改运单状态
				tmsShipbillHeaderMapper.updateMapById(detailModel.getShipbillId(), mapUpdateShipbillHeader, TmsShipbillHeaderModel.class);
				// 更新派车单明细状态
				tmsLoadingBillDetailMapper.updateMapById(detailModel.getId(), mapUpdateLoadingDetail, TmsLoadingBillDetailModel.class);
				// 新增节点信息
				shipbillNodeTrackingSaveVO.setShipbillId(detailModel.getShipbillId());
				shipbillNodeTrackingSaveVO.setShipbillNo(detailModel.getShipbillNo());
				shipbillNodeTrackingService.addShipbillNodeTrackingData(shipbillNodeTrackingSaveVO,user);

				// 新增日志信息
				shipbillOperateLogSaveVO.setShipbillId(detailModel.getShipbillId());
				shipbillOperateLogSaveVO.setShipbillNo(detailModel.getShipbillNo());
				shipbillOperateLogSaveVO.setOperateEvent(DataDictionaryConstant.SHIPBILL_NODE_STATUSNAME_PC);
				shipbillOperateLogService.addShipbillOperateLogData(shipbillOperateLogSaveVO,user);

				// 更新运输记录表的调度审核时间
				Criteria criteriaTransLog = Criteria.forClass(TmsShipbillTransLogModel.class);
				Restriction r3 = Restrictions.eq(TmsShipbillTransLogModel::getShipbillId, detailModel.getShipbillId());
				Restriction r4 = Restrictions.eq(TmsShipbillTransLogModel::getEnterpriseId, user.getEnterpriseId());
				criteriaTransLog.setRestriction(Restrictions.and(r3, r4));

				Map<String, Object> mapUpdate = Maps.newHashMap();
				mapUpdate.put("updateperson", user.getNickname());
				mapUpdate.put("updatetime", date);
				mapUpdate.put("disCheckDt", date);
				tmsShipbillTransportLogMapper.updateMapByCriteria(mapUpdate, criteriaTransLog);
			}
			// 更改派车单状态
			// 装车单类型
			if (shipperTypeCnt == tmsLoadingBillDetailModels.size()) {
				loadingBillHeaderModel.setLoadingBillType(DataDictionaryConstant.LOADING_BILL_TYPE_CK);
			} else if (consigneeType == tmsLoadingBillDetailModels.size()) {
				loadingBillHeaderModel.setLoadingBillType(DataDictionaryConstant.LOADING_BILL_TYPE_RK);
			} else {
				loadingBillHeaderModel.setLoadingBillType(DataDictionaryConstant.LOADING_BILL_TYPE_QT);
			}
			loadingBillHeaderModel.setUpdateperson(user.getNickname());
			loadingBillHeaderModel.setUpdatetime(date);
			loadingBillHeaderModel.setStatus(DataDictionaryConstant.LOADING_BILL_STATUS_YSH);
			tmsLoadingBillHeaderMapper.update(loadingBillHeaderModel);
			MessageTypeEnum messageTypeEnum = MessageTypeEnum.SELF_DISPATCH_AUDIT;
			if (user.getUserType().equals(BussinessConstant.USER_TYPE_CYS)) {
				messageTypeEnum = MessageTypeEnum.CARRIER_DISPATCH_AUDIT;
			}
			MessageUtil.addMessage(new SendMessageDTO(MessageOrderTypeEnum.LOADING_NO.getCode(), messageTypeEnum.getCode(), Lists.newArrayList(loadingBillHeaderModel.getLoadingBillId())));
			// 承运商自动接单
			if (ToolKits.isNotEmpty(receiveObjs)) {
				trailerService.autoReceiveShipbillData(receiveObjs, date, user);
			}

		}
	}

	// 调度审核匹配审批流程
	public Boolean approvalOpen(TmsLoadingBillHeaderModel loadingBillHeaderModel, TmsShipbillHeaderModel model, Integer approvalFlowType, UserEntity user) {
		// 封装判断所需数据
		ApprovalOpenVO approvalOpenVO = new ApprovalOpenVO();
		approvalOpenVO.setApprovalFlowType(approvalFlowType);
		approvalOpenVO.setApprovalObjectId(loadingBillHeaderModel.getLoadingBillId());
		approvalOpenVO.setApprovalObjectCode(loadingBillHeaderModel.getLoadingBillNo());
		approvalOpenVO.setApprovalObjectName(loadingBillHeaderModel.getLoadingBillNo());
		approvalOpenVO.setInitiatedUserId(user.getUserid());
		approvalOpenVO.setInitiatedUserName(user.getNickname());

		// 配送方式
		approvalOpenVO.setDeliveryMethodType(model.getDeliveryMethodType());
		// 发货方类型
		approvalOpenVO.setShipperType(model.getShipperType());
		// 发货方单位ID
		approvalOpenVO.setShipperUnitId(model.getShipperUnitId());
		// 收货方类型
		approvalOpenVO.setConsigneeType(model.getConsigneeType());
		// 收货方单位ID
		approvalOpenVO.setConsigneeUnitId(model.getConsigneeUnitId());
		// 订单类型
		approvalOpenVO.setOrderType(model.getOrderType());
		// 订单业务类型
		approvalOpenVO.setOrderBusinessType(model.getOrderBusinessType());
		// 运输模式
		approvalOpenVO.setTransportType(model.getTransportType());
		// 温度要求
		approvalOpenVO.setTemperatureRequirement(model.getTemperatureRequirement());
		// 货主ID
		approvalOpenVO.setCargoOwnerId(model.getCargoOwnerId());
		// 部门ID
		approvalOpenVO.setDepartmentId(model.getDepartmentId());

		RestMessage<Boolean> restMessage1 = maindataTmsResource.openExecute(approvalOpenVO);
		if (!restMessage1.isSuccess()) {
			throw new RuntimeException("调用maindata服务是否开启审批流接口失败:" + restMessage1.getMessage());
		}
		return restMessage1.getData();
	}

	/**
	 * 获取最大站点顺序
	 * 
	 * @param tmsLoadingBillDetailModels
	 * @return
	 */
	private Integer maxStationOrderNumber(List<TmsLoadingBillDetailModel> tmsLoadingBillDetailModels) {
		List<Integer> indexList = tmsLoadingBillDetailModels.stream().flatMap(tmsLoadingBillDetailModel -> Stream.of(tmsLoadingBillDetailModel.getPickUpOrder(), tmsLoadingBillDetailModel.getShippingOrder())).filter(ObjectUtil::isNotNull).collect(Collectors.toList());
		if (ToolKits.isEmpty(indexList)) {
			return 1;
		} else {
			return Collections.max(indexList);
		}
	}

	/**
	 * 派车单站点信息查询
	 *
	 * @param vo
	 */
	@Override
	public List<LoadingSiteInfoDTO> loadingSiteQuery(LoadingSiteInfoQueryVO vo) {
		ToolKits.isParamNull(vo, "派车单站点信息查询请求不为空");

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

		List<LoadingSiteInfoDTO> tmpList = Lists.newArrayList();

		// 查询明细内容
		Criteria criteria = Criteria.forClass(TmsLoadingBillDetailModel.class);
		Restriction r1 = ToolKits.isEmpty(vo.getLoadingBillId()) ? null : Restrictions.eq(TmsLoadingBillDetailModel::getLoadingBillId, vo.getLoadingBillId());
		Restriction r2 = ToolKits.isEmpty(vo.getShipbillIdList()) ? null : Restrictions.in(TmsLoadingBillDetailModel::getShipbillId, vo.getShipbillIdList().stream().toArray());
		criteria.setRestriction(Restrictions.and(r1, r2));

		List<TmsLoadingBillDetailModel> loadingBillDetailModels = tmsLoadingBillDetailMapper.findByCriteria(criteria);
		if (ToolKits.isEmpty(loadingBillDetailModels)) {
			return tmpList;
		}
		Map<String, List<TmsLoadingBillDetailModel>> shipperMap = Maps.newHashMap();
		Map<String, List<TmsLoadingBillDetailModel>> consigneeMap = Maps.newHashMap();
		shipperMap = loadingBillDetailModels.stream().filter(l -> ToolKits.isNotEmpty(l.getShipperName())).collect(Collectors.groupingBy(TmsLoadingBillDetailModel::getShipperName));
		consigneeMap = loadingBillDetailModels.stream().filter(l -> ToolKits.isNotEmpty(l.getConsigneeName())).collect(Collectors.groupingBy(TmsLoadingBillDetailModel::getConsigneeName));

		Boolean isFinished = Boolean.TRUE;
		if (loadingBillDetailModels.stream().anyMatch(l -> !DataDictionaryConstant.SHIPBILL_STATUS_END.equals(l.getStatus()))) {
			isFinished = Boolean.FALSE;
		}
		// 提货站点
		for (String key : shipperMap.keySet()) {
			LoadingSiteInfoDTO siteInfoDTO = new LoadingSiteInfoDTO();
			List<TmsLoadingBillDetailModel> oneShipperLoadingDetails = shipperMap.get(key);
			if (ToolKits.isEmpty(oneShipperLoadingDetails)) {
				continue;
			}
			// 运单数
			siteInfoDTO.setShipbillQty(oneShipperLoadingDetails.size());

			BigDecimal pcs1 = oneShipperLoadingDetails.stream().filter(dto -> ToolKits.isNotEmpty(dto.getTotalPcs())).map(TmsLoadingBillDetailModel::getTotalPcs).reduce(BigDecimal.ZERO, BigDecimal::add);
			BigDecimal pcs2 = oneShipperLoadingDetails.stream().filter(dto -> ToolKits.isNotEmpty(dto.getPackageLclPiece())).map(TmsLoadingBillDetailModel::getPackageLclPiece).reduce(BigDecimal.ZERO, BigDecimal::add);
			BigDecimal pcs3 = oneShipperLoadingDetails.stream().filter(dto -> ToolKits.isNotEmpty(dto.getPackageWholePiece())).map(TmsLoadingBillDetailModel::getPackageWholePiece).reduce(BigDecimal.ZERO, BigDecimal::add);
			BigDecimal weigth1 = oneShipperLoadingDetails.stream().filter(dto -> ToolKits.isNotEmpty(dto.getTotalWeight())).map(TmsLoadingBillDetailModel::getTotalWeight).reduce(BigDecimal.ZERO, BigDecimal::add);
			BigDecimal weigth2 = oneShipperLoadingDetails.stream().filter(dto -> ToolKits.isNotEmpty(dto.getPackageTotalWeight())).map(TmsLoadingBillDetailModel::getPackageTotalWeight).reduce(BigDecimal.ZERO, BigDecimal::add);
			BigDecimal volume1 = oneShipperLoadingDetails.stream().filter(dto -> ToolKits.isNotEmpty(dto.getTotalVolume())).map(TmsLoadingBillDetailModel::getTotalVolume).reduce(BigDecimal.ZERO, BigDecimal::add);
			BigDecimal volume2 = oneShipperLoadingDetails.stream().filter(dto -> ToolKits.isNotEmpty(dto.getPackageTotalVolume())).map(TmsLoadingBillDetailModel::getPackageTotalVolume).reduce(BigDecimal.ZERO, BigDecimal::add);

			// 商品/包裹 总件数
			siteInfoDTO.setTotalPieceQty(pcs1.add(pcs2.add(pcs3)).intValue());
			// 商品/包裹 总重量
			siteInfoDTO.setTotalWeightQty(weigth1.add(weigth2).intValue());
			// 商品/包裹 总体积
			siteInfoDTO.setTotalVolumeQty(volume1.add(volume2).intValue());

			TmsLoadingBillDetailModel detailModel = oneShipperLoadingDetails.get(0);
			siteInfoDTO.setSiteOrder(detailModel.getPickUpOrder());
			siteInfoDTO.setSiteTypeName("提货点");
			siteInfoDTO.setSiteName(detailModel.getShipperName());
			siteInfoDTO.setLatitude(detailModel.getShipperLatitude());
			siteInfoDTO.setLongitude(detailModel.getShipperLongitude());
			// 预计提货时间
			Optional<TmsLoadingBillDetailModel> maxStartTime = oneShipperLoadingDetails.stream().filter(s -> ToolKits.isNotEmpty(s.getEstimatedPickupStartTime())).max(Comparator.comparing(TmsLoadingBillDetailModel::getEstimatedPickupStartTime));
			if (maxStartTime.isPresent()) {
				siteInfoDTO.setEstimatedTime(maxStartTime.get().getEstimatedPickupStartTime());
			}
			Optional<TmsLoadingBillDetailModel> minEndTime = oneShipperLoadingDetails.stream().filter(s -> ToolKits.isNotEmpty(s.getEstimatedPickupEndTime())).min(Comparator.comparing(TmsLoadingBillDetailModel::getEstimatedPickupEndTime));
			Date endTime = null;
			if (minEndTime.isPresent()) {
				endTime = minEndTime.get().getEstimatedPickupEndTime();
			}
			List<String> shipbillIds = oneShipperLoadingDetails.stream().map(TmsLoadingBillDetailModel::getShipbillId).collect(Collectors.toList());

			Criteria criteriaShipbillHeaderModel = Criteria.forClass(TmsShipbillHeaderModel.class);
			Restriction r3 = Restrictions.in(TmsShipbillTransLogModel::getShipbillId, shipbillIds.stream().toArray());
			criteriaShipbillHeaderModel.setRestriction(Restrictions.and(r3));
			List<TmsShipbillHeaderModel> headerModelList = tmsShipbillHeaderMapper.findByCriteria(criteriaShipbillHeaderModel);
			if (ToolKits.isNotEmpty(headerModelList)) {
				List<Date> minTime = headerModelList.stream().filter(s -> ToolKits.isNotEmpty(s.getDepartureTime())).map(TmsShipbillHeaderModel::getDepartureTime).collect(Collectors.toList());
				if (ToolKits.isNotEmpty(minTime)) {
					// 实际提货时间
					siteInfoDTO.setActualTime(minTime.get(0));
				}
			}
			if (ToolKits.isNotEmpty(siteInfoDTO.getEstimatedTime()) && ToolKits.isNotEmpty(siteInfoDTO.getActualTime())) {
				if (siteInfoDTO.getActualTime().before(siteInfoDTO.getEstimatedTime())) {
					long time = DateUtil.between(siteInfoDTO.getActualTime(), siteInfoDTO.getEstimatedTime(), DateUnit.MINUTE);
					siteInfoDTO.setTimeDescription(StrUtil.format("早到{}分钟", time));
				}
			}
			if (ToolKits.isNotEmpty(endTime) && ToolKits.isNotEmpty(siteInfoDTO.getActualTime())) {
				if (siteInfoDTO.getActualTime().after(endTime)) {
					long time = DateUtil.between(siteInfoDTO.getActualTime(), endTime, DateUnit.MINUTE);
					siteInfoDTO.setTimeDescription(StrUtil.format("晚到{}分钟", time));
				}
			}
			siteInfoDTO.setTemperature(detailModel.getDepartureTemperature());
			if (Boolean.TRUE.equals(isFinished)) {
				siteInfoDTO.setStatusName("已完成");
			} else {
				siteInfoDTO.setStatusName("在途");
			}
			tmpList.add(siteInfoDTO);
		}
		// 送货站点
		for (String key : consigneeMap.keySet()) {
			LoadingSiteInfoDTO siteInfoDTO = new LoadingSiteInfoDTO();
			List<TmsLoadingBillDetailModel> oneConsigneeLoadingDetails = consigneeMap.get(key);
			if (ToolKits.isEmpty(oneConsigneeLoadingDetails)) {
				continue;
			}
			// 运单数
			siteInfoDTO.setShipbillQty(oneConsigneeLoadingDetails.size());

			BigDecimal pcs1 = oneConsigneeLoadingDetails.stream().filter(dto -> ToolKits.isNotEmpty(dto.getTotalPcs())).map(TmsLoadingBillDetailModel::getTotalPcs).reduce(BigDecimal.ZERO, BigDecimal::add);
			BigDecimal pcs2 = oneConsigneeLoadingDetails.stream().filter(dto -> ToolKits.isNotEmpty(dto.getPackageLclPiece())).map(TmsLoadingBillDetailModel::getPackageLclPiece).reduce(BigDecimal.ZERO, BigDecimal::add);
			BigDecimal pcs3 = oneConsigneeLoadingDetails.stream().filter(dto -> ToolKits.isNotEmpty(dto.getPackageWholePiece())).map(TmsLoadingBillDetailModel::getPackageWholePiece).reduce(BigDecimal.ZERO, BigDecimal::add);
			BigDecimal weigth1 = oneConsigneeLoadingDetails.stream().filter(dto -> ToolKits.isNotEmpty(dto.getTotalWeight())).map(TmsLoadingBillDetailModel::getTotalWeight).reduce(BigDecimal.ZERO, BigDecimal::add);
			BigDecimal weigth2 = oneConsigneeLoadingDetails.stream().filter(dto -> ToolKits.isNotEmpty(dto.getPackageTotalWeight())).map(TmsLoadingBillDetailModel::getPackageTotalWeight).reduce(BigDecimal.ZERO, BigDecimal::add);
			BigDecimal volume1 = oneConsigneeLoadingDetails.stream().filter(dto -> ToolKits.isNotEmpty(dto.getTotalVolume())).map(TmsLoadingBillDetailModel::getTotalVolume).reduce(BigDecimal.ZERO, BigDecimal::add);
			BigDecimal volume2 = oneConsigneeLoadingDetails.stream().filter(dto -> ToolKits.isNotEmpty(dto.getPackageTotalVolume())).map(TmsLoadingBillDetailModel::getPackageTotalVolume).reduce(BigDecimal.ZERO, BigDecimal::add);

			// 商品/包裹 总件数
			siteInfoDTO.setTotalPieceQty(pcs1.add(pcs2.add(pcs3)).intValue());
			// 商品/包裹 总重量
			siteInfoDTO.setTotalWeightQty(weigth1.add(weigth2).intValue());
			// 商品/包裹 总体积
			siteInfoDTO.setTotalVolumeQty(volume1.add(volume2).intValue());

			TmsLoadingBillDetailModel detailModel = oneConsigneeLoadingDetails.get(0);
			siteInfoDTO.setSiteOrder(detailModel.getShippingOrder());
			siteInfoDTO.setSiteTypeName("送货点");
			siteInfoDTO.setSiteName(detailModel.getConsigneeName());
			siteInfoDTO.setLatitude(detailModel.getConsigneeLatitude());
			siteInfoDTO.setLongitude(detailModel.getConsigneeLongitude());
			// 预计送达时间
			Optional<TmsLoadingBillDetailModel> maxStartTime = oneConsigneeLoadingDetails.stream().filter(s -> ToolKits.isNotEmpty(s.getEstimatedDeliveryStartTime())).max(Comparator.comparing(TmsLoadingBillDetailModel::getEstimatedDeliveryStartTime));
			if (maxStartTime.isPresent()) {
				siteInfoDTO.setEstimatedTime(maxStartTime.get().getEstimatedDeliveryStartTime());
			}
			Optional<TmsLoadingBillDetailModel> minEndTime = oneConsigneeLoadingDetails.stream().filter(s -> ToolKits.isNotEmpty(s.getEstimatedDeliveryEndTime())).min(Comparator.comparing(TmsLoadingBillDetailModel::getEstimatedDeliveryEndTime));
			Date endTime = null;
			if (minEndTime.isPresent()) {
				endTime = minEndTime.get().getEstimatedDeliveryEndTime();
			}
			List<String> shipbillIds = oneConsigneeLoadingDetails.stream().map(TmsLoadingBillDetailModel::getShipbillId).collect(Collectors.toList());

			Criteria criteriaShipbillHeaderModel = Criteria.forClass(TmsShipbillHeaderModel.class);
			Restriction r3 = Restrictions.in(TmsShipbillTransLogModel::getShipbillId, shipbillIds.stream().toArray());
			criteriaShipbillHeaderModel.setRestriction(Restrictions.and(r3));
			List<TmsShipbillHeaderModel> headerModelList = tmsShipbillHeaderMapper.findByCriteria(criteriaShipbillHeaderModel);
			if (ToolKits.isNotEmpty(headerModelList)) {
				List<Date> minTime = headerModelList.stream().filter(s -> ToolKits.isNotEmpty(s.getDeliveryTime())).map(TmsShipbillHeaderModel::getDeliveryTime).collect(Collectors.toList());
				if (ToolKits.isNotEmpty(minTime)) {
					// 实际送达时间
					siteInfoDTO.setActualTime(minTime.get(0));
				}
			}
			if (ToolKits.isNotEmpty(siteInfoDTO.getEstimatedTime()) && ToolKits.isNotEmpty(siteInfoDTO.getActualTime())) {
				if (siteInfoDTO.getActualTime().before(siteInfoDTO.getEstimatedTime())) {
					long time = DateUtil.between(siteInfoDTO.getActualTime(), siteInfoDTO.getEstimatedTime(), DateUnit.MINUTE);
					siteInfoDTO.setTimeDescription(StrUtil.format("早到{}分钟", time));
				}
			}
			if (ToolKits.isNotEmpty(endTime) && ToolKits.isNotEmpty(siteInfoDTO.getActualTime())) {
				if (siteInfoDTO.getActualTime().after(endTime)) {
					long time = DateUtil.between(siteInfoDTO.getActualTime(), endTime, DateUnit.MINUTE);
					siteInfoDTO.setTimeDescription(StrUtil.format("晚到{}分钟", time));
				}
			}
			siteInfoDTO.setTemperature(detailModel.getDeliveryTemperature());
			if (Boolean.TRUE.equals(isFinished)) {
				siteInfoDTO.setStatusName("已完成");
			} else {
				siteInfoDTO.setStatusName("在途");
			}
			tmpList.add(siteInfoDTO);
		}
		if (ToolKits.isEmpty(tmpList)) {
			return tmpList;
		}
		List<LoadingSiteInfoDTO> rsList = Lists.newArrayList();
		List<LoadingSiteInfoDTO> orders = tmpList.stream().filter(l -> ToolKits.isNotEmpty(l.getSiteOrder())).sorted(Comparator.comparing(LoadingSiteInfoDTO::getSiteOrder)).collect(Collectors.toList());
		if (ToolKits.isNotEmpty(orders)) {
			rsList.addAll(orders);
		}
		List<LoadingSiteInfoDTO> noOrders = tmpList.stream().filter(l -> ToolKits.isEmpty(l.getSiteOrder())).collect(Collectors.toList());
		if (ToolKits.isNotEmpty(noOrders)) {
			rsList.addAll(noOrders);
		}
		return rsList;
	}

	/**
	 * 反审核
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void undoAuditSendCarData(List<String> loadingBillIds) {
		ToolKits.isParamNull(loadingBillIds, "请选择需要反审核的派车单");

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

		if (!user.getUserType().equals(BussinessConstant.USER_TYPE_ZY) && !user.getUserType().equals(BussinessConstant.USER_TYPE_CYS)) {
			ToolKits.isParamNull(user, "当前人员没有操作权限");
		}

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

		for (String loadingBillId : loadingBillIds) {
			// 派车单对象
			TmsLoadingBillHeaderModel loadingBillHeaderModel = tmsLoadingBillHeaderMapper.findById(loadingBillId, TmsLoadingBillHeaderModel.class);

			// 反审核只能处理审核后的派车单包含审核
			Assert.isTrue(loadingBillHeaderModel.getStatus().intValue() >= DataDictionaryConstant.LOADING_BILL_STATUS_YSH.intValue(), "派车单【" + loadingBillId + "】不为已审核及之后的状态，不可反审核！");

			// 送达后（包括部分送达）的派车单不可反审核
			Assert.isTrue(loadingBillHeaderModel.getStatus().intValue() < DataDictionaryConstant.LOADING_BILL_STATUS_SD_PART.intValue(), "派车单【" + loadingBillId + "】已送达，不可反审核！");

			// 查询对应的派车单明细
			Criteria criteria = Criteria.forClass(TmsLoadingBillDetailModel.class);
			Restriction r1 = Restrictions.eq(TmsLoadingBillDetailModel::getLoadingBillId, loadingBillId);
			criteria.setRestriction(Restrictions.and(r1));
			List<TmsLoadingBillDetailModel> loadingBillDetailModels = tmsLoadingBillDetailMapper.findByCriteria(criteria);
			Assert.isTrue(loadingBillDetailModels.size() > 0, "派车单【" + loadingBillId + "】明细为空，反审核失败！");
			for (TmsLoadingBillDetailModel loadingBillDetailModel : loadingBillDetailModels) {
				// 运单节点记录
				ShipbillNodeTrackingSaveVO shipbillNodeTrackingSaveVO = new ShipbillNodeTrackingSaveVO();
				shipbillNodeTrackingSaveVO.setShipbillId(loadingBillDetailModel.getShipbillId());
				shipbillNodeTrackingSaveVO.setShipbillNo(loadingBillDetailModel.getShipbillNo());
				shipbillNodeTrackingSaveVO.setStatus(loadingBillDetailModel.getStatus());
				shipbillNodeTrackingSaveVO.setNodeEvent("运单反审核操作");
				shipbillNodeTrackingSaveVO.setCarrierShipbillStatus(loadingBillDetailModel.getCarrierShipbillStatus());
				shipbillNodeTrackingSaveVO.setNodeDate(date);
				shipbillNodeTrackingService.addShipbillNodeTrackingData(shipbillNodeTrackingSaveVO,user);

				// 运单操作日志
				ShipbillOperateLogSaveVO shipbillOperateLogSaveVO = new ShipbillOperateLogSaveVO();
				shipbillOperateLogSaveVO.setShipbillId(loadingBillDetailModel.getShipbillId());
				shipbillOperateLogSaveVO.setShipbillNo(loadingBillDetailModel.getShipbillNo());
				shipbillOperateLogSaveVO.setOperateDate(date);
				shipbillOperateLogSaveVO.setOperateEvent("运单反审核操作");
				shipbillOperateLogSaveVO.setOldStatus(loadingBillDetailModel.getStatus());
				shipbillOperateLogSaveVO.setNewStatus(loadingBillDetailModel.getStatus());
				shipbillOperateLogSaveVO.setOldCarrierShipbillStatus(loadingBillDetailModel.getCarrierShipbillStatus());
				shipbillOperateLogSaveVO.setNewCarrierShipbillStatus(loadingBillDetailModel.getCarrierShipbillStatus());
				shipbillOperateLogService.addShipbillOperateLogData(shipbillOperateLogSaveVO,user);
			}

			loadingBillHeaderModel.setOldStatus(loadingBillHeaderModel.getStatus());
			loadingBillHeaderModel.setStatus(DataDictionaryConstant.LOADING_BILL_STATUS_WSH);
			loadingBillHeaderModel.setUpdateperson(user.getNickname());
			loadingBillHeaderModel.setUpdatetime(date);
			tmsLoadingBillHeaderMapper.update(loadingBillHeaderModel);
		}
	}

}
