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

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.concurrent.CompletableFuture;
import java.util.function.BiFunction;
import java.util.stream.Collectors;

import com.prolog.rdc.tms.constant.enums.intelligent.IntelligentLockEnum;
import org.apache.commons.lang.ArrayUtils;
import org.apache.ibatis.plugin.PluginException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.web.bind.annotation.RequestBody;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.netflix.hystrix.strategy.concurrency.HystrixRequestContext;
import com.prolog.common.util.DateUtils;
import com.prolog.common.util.ToolKits;
import com.prolog.framework.authority.util.HystrixVarUtil;
import com.prolog.framework.common.message.RestMessage;
import com.prolog.framework.core.exception.BizException;
import com.prolog.framework.core.exception.ParameterException;
import com.prolog.framework.core.exception.PrologException;
import com.prolog.framework.core.pojo.Page;
import com.prolog.framework.core.restriction.Criteria;
import com.prolog.framework.core.restriction.Order;
import com.prolog.framework.core.restriction.Restriction;
import com.prolog.framework.core.restriction.Restrictions;
import com.prolog.framework.dao.util.PageUtils;
import com.prolog.product.core.framework.entity.UserEntity;
import com.prolog.product.core.framework.util.PlgFxUsrUtils;
import com.prolog.rdc.tms.constant.BussinessConstant;
import com.prolog.rdc.tms.constant.DataDictionaryConstant;
import com.prolog.rdc.tms.constant.SeriaNnumberConstant;
import com.prolog.rdc.tms.constant.StatusConstant;
import com.prolog.rdc.tms.constant.enums.DriverReceiveStatusEnum;
import com.prolog.rdc.tms.constant.enums.ShipBillTypeEnum;
import com.prolog.rdc.tms.constant.enums.SignInStatusEnum;
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.TmsShipbillOperateLogMapper;
import com.prolog.rdc.tms.dao.mapper.TmsShipbillPackageDetailMapper;
import com.prolog.rdc.tms.dao.mapper.TmsShipbillPackageMapper;
import com.prolog.rdc.tms.dao.mapper.TmsShipbillTransportLogMapper;
import com.prolog.rdc.tms.dao.mapper.TmsTransPlanBillDetailMapper;
import com.prolog.rdc.tms.dao.mapper.TmsTransPlanBillHeaderMapper;
import com.prolog.rdc.tms.model.dto.CalculateMileageDTO;
import com.prolog.rdc.tms.model.dto.LineSiteMapDTO;
import com.prolog.rdc.tms.model.dto.PendingDispatchAddressPageDTO;
import com.prolog.rdc.tms.model.dto.PendingDispatchDetailDTO;
import com.prolog.rdc.tms.model.dto.PendingDispatchExportDetailDataDTO;
import com.prolog.rdc.tms.model.dto.PendingDispatchPackageDTO;
import com.prolog.rdc.tms.model.dto.PendingDispatchPackageDetailDTO;
import com.prolog.rdc.tms.model.dto.PendingDispatchPageDTO;
import com.prolog.rdc.tms.model.dto.PendingDispatchPrintDetailDTO;
import com.prolog.rdc.tms.model.dto.PendingDispatchPrintHeadDTO;
import com.prolog.rdc.tms.model.dto.PendingDispatchShipbillQtyByLineDTO;
import com.prolog.rdc.tms.model.dto.PendingDispatchShipbillQtyDTO;
import com.prolog.rdc.tms.model.dto.PendingDispatchViewDTO;
import com.prolog.rdc.tms.model.dto.PendingDispatchViewDetailDTO;
import com.prolog.rdc.tms.model.dto.PendingDispatchViewPackageDTO;
import com.prolog.rdc.tms.model.dto.ShipbillHotMapDTO;
import com.prolog.rdc.tms.model.dto.ShipbillLineMapDTO;
import com.prolog.rdc.tms.model.dto.ShipbillMapDTO;
import com.prolog.rdc.tms.model.dto.SmartSplitDTO;
import com.prolog.rdc.tms.model.dto.SysGroupCfgDtlDTO;
import com.prolog.rdc.tms.model.dto.SysGroupCfgHdrDTO;
import com.prolog.rdc.tms.model.dto.SysGroupLoadingQueryDTO;
import com.prolog.rdc.tms.model.dto.SysGroupQueryDTO;
import com.prolog.rdc.tms.model.dto.SysGroupQueryRsDTO;
import com.prolog.rdc.tms.model.dto.SysGroupShipbillQueryDTO;
import com.prolog.rdc.tms.model.dto.TmsLineSiteDTO;
import com.prolog.rdc.tms.model.dto.TransferDtDTO;
import com.prolog.rdc.tms.model.dto.basicConfigure.ShipbillFitBusinessFlowDTO;
import com.prolog.rdc.tms.model.dto.basicConfigure.ShipbillMatchCarrierDTO;
import com.prolog.rdc.tms.model.dto.basicConfigure.ShipbillMatchLineDTO;
import com.prolog.rdc.tms.model.dto.basicConfigure.SignconfigPopDTO;
import com.prolog.rdc.tms.model.dto.basicConfigure.StrategySplitMatchingDTO;
import com.prolog.rdc.tms.model.dto.basicConfigure.StrategyTransferMatchingDTO;
import com.prolog.rdc.tms.model.dto.basicConfigure.StrategyTransferStationDTO;
import com.prolog.rdc.tms.model.dto.basicData.CarrierCheckDTO;
import com.prolog.rdc.tms.model.dto.basicData.ItemCheckDTO;
import com.prolog.rdc.tms.model.dto.basicData.StationDistanceDTO;
import com.prolog.rdc.tms.model.dto.basicData.TmsBaseBranchDTO;
import com.prolog.rdc.tms.model.dto.basicData.TmsLineMapDTO;
import com.prolog.rdc.tms.model.dto.basicData.TmsLineWaySiteDTO;
import com.prolog.rdc.tms.model.dto.basicData.TmsTransferStationByViewDTO;
import com.prolog.rdc.tms.model.dto.fleetManagement.VehicleAndDriverDTO;
import com.prolog.rdc.tms.model.dto.fleetManagement.VehiclePopupDTO;
import com.prolog.rdc.tms.model.dto.message.SendMessageDTO;
import com.prolog.rdc.tms.model.dto.planMng.PlanBillDetailDTO;
import com.prolog.rdc.tms.model.dto.planMng.PlanBillLoadingDTO;
import com.prolog.rdc.tms.model.dto.planMng.PlanGroupQueryDTO;
import com.prolog.rdc.tms.model.dto.planMng.PlanGroupQueryRsDTO;
import com.prolog.rdc.tms.model.entity.ShipbillNodeTracking;
import com.prolog.rdc.tms.model.entity.SysParamConfigModel;
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.TmsShipbillOperateLogModel;
import com.prolog.rdc.tms.model.entity.TmsShipbillPackageModel;
import com.prolog.rdc.tms.model.entity.TmsShipbillPkgDetailModel;
import com.prolog.rdc.tms.model.entity.TmsShipbillTransLogModel;
import com.prolog.rdc.tms.model.entity.TmsTransPlanBillDetailModel;
import com.prolog.rdc.tms.model.entity.TmsTransPlanBillHeaderModel;
import com.prolog.rdc.tms.model.enums.MessageOrderTypeEnum;
import com.prolog.rdc.tms.model.enums.MessageTypeEnum;
import com.prolog.rdc.tms.model.vo.CalculateMileageVO;
import com.prolog.rdc.tms.model.vo.DetailItemPageVO;
import com.prolog.rdc.tms.model.vo.DetailItemSplitVO;
import com.prolog.rdc.tms.model.vo.GroupPendingDispatchReviewVO;
import com.prolog.rdc.tms.model.vo.GroupPendingDispatchVO;
import com.prolog.rdc.tms.model.vo.LoadingBillDetailVO;
import com.prolog.rdc.tms.model.vo.LoadingBillHeaderVO;
import com.prolog.rdc.tms.model.vo.PendingDispatchAddressPageVO;
import com.prolog.rdc.tms.model.vo.PendingDispatchAdvQueryVO;
import com.prolog.rdc.tms.model.vo.PendingDispatchDetailByPackageVO;
import com.prolog.rdc.tms.model.vo.PendingDispatchExportAllDataVO;
import com.prolog.rdc.tms.model.vo.PendingDispatchExportCurrenPageDataVO;
import com.prolog.rdc.tms.model.vo.PendingDispatchPackageByDetailVO;
import com.prolog.rdc.tms.model.vo.PendingDispatchPageVO;
import com.prolog.rdc.tms.model.vo.PendingDispatchParseAddressVO;
import com.prolog.rdc.tms.model.vo.PendingDispatchReviewVO;
import com.prolog.rdc.tms.model.vo.PendingDispatchVO;
import com.prolog.rdc.tms.model.vo.RevokeVO;
import com.prolog.rdc.tms.model.vo.ShipbillNodeTrackingSaveNewVO;
import com.prolog.rdc.tms.model.vo.ShipbillNodeTrackingSaveVO;
import com.prolog.rdc.tms.model.vo.ShipbillOperateLogSaveNewVO;
import com.prolog.rdc.tms.model.vo.ShipbillOperateLogSaveVO;
import com.prolog.rdc.tms.model.vo.SmartSplitStrategyVO;
import com.prolog.rdc.tms.model.vo.SmartSplitVO;
import com.prolog.rdc.tms.model.vo.SplitGoodsDetailVO;
import com.prolog.rdc.tms.model.vo.SplitGoodsListVO;
import com.prolog.rdc.tms.model.vo.SplitVO;
import com.prolog.rdc.tms.model.vo.SysGroupCfgVO;
import com.prolog.rdc.tms.model.vo.SysGroupQueryVO;
import com.prolog.rdc.tms.model.vo.TransitDetailInfoVO;
import com.prolog.rdc.tms.model.vo.TransitVO;
import com.prolog.rdc.tms.model.vo.ZoneVO;
import com.prolog.rdc.tms.model.vo.basicConfigure.ApprovalOpenVO;
import com.prolog.rdc.tms.model.vo.basicConfigure.BusinessFlowShipbillVO;
import com.prolog.rdc.tms.model.vo.basicConfigure.ShipbillMatchCarrierVO;
import com.prolog.rdc.tms.model.vo.basicConfigure.ShipbillMatchLineVO;
import com.prolog.rdc.tms.model.vo.basicConfigure.SignconfigPopVO;
import com.prolog.rdc.tms.model.vo.basicConfigure.StrategySplitMatchingVO;
import com.prolog.rdc.tms.model.vo.basicConfigure.StrategyTransferMatchingVO;
import com.prolog.rdc.tms.model.vo.basicData.ItemCheckVO;
import com.prolog.rdc.tms.model.vo.basicData.StationDistanceVO;
import com.prolog.rdc.tms.model.vo.basicData.TmsTransferStationVO;
import com.prolog.rdc.tms.model.vo.fleetManagement.VehicleAndVehicleVO;
import com.prolog.rdc.tms.model.vo.fleetManagement.VehiclePopupVO;
import com.prolog.rdc.tms.model.vo.planMng.PlanBillDetailQueryVO;
import com.prolog.rdc.tms.model.vo.planMng.PlanBillLoadingVO;
import com.prolog.rdc.tms.model.vo.planMng.PlanDispatchVO;
import com.prolog.rdc.tms.model.vo.planMng.PlanGroupQueryVO;
import com.prolog.rdc.tms.rmi.feign.MaindataFeign;
import com.prolog.rdc.tms.service.LoadingBillService;
import com.prolog.rdc.tms.service.PendingDispatchService;
import com.prolog.rdc.tms.service.SendCarService;
import com.prolog.rdc.tms.service.ShipbillNodeTrackingService;
import com.prolog.rdc.tms.service.ShipbillOperateLogService;
import com.prolog.rdc.tms.service.SysGroupCfgService;
import com.prolog.rdc.tms.service.TrailerService;
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.date.TimeInterval;
import cn.hutool.core.exceptions.ExceptionUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;

/**
 * 调度管理-待调度实现层
 *
 * @author lhb
 * @since 2022-04-13 14:45:00
 */
@Service
@Slf4j
public class PendingDispatchServiceImpl implements PendingDispatchService {

	@Autowired
	private TmsShipbillHeaderMapper tmsShipbillHeaderMapper;

	@Autowired
	private TmsShipbillDetailMapper tmsShipbillDetailMapper;

	@Autowired
	private TmsShipbillPackageMapper tmsShipbillPackageMapper;

	@Autowired
	private TmsShipbillPackageDetailMapper tmsShipbillPackageDetailMapper;

	@Autowired
	private MaindataFeign maindataTmsResource;

	@Autowired
	private ShipbillNodeTrackingService shipbillNodeTrackingService;

	@Autowired
	private ShipbillOperateLogService shipbillOperateLogService;

	@Autowired
	private TmsLoadingBillHeaderMapper tmsLoadingBillHeaderMapper;

	@Autowired
	private TmsLoadingBillDetailMapper tmsLoadingBillDetailMapper;

	@Autowired
	private TmsShipbillOperateLogMapper tmsShipbillOperateLogMapper;

	@Autowired
	private TmsShipbillNodeTrackingMapper tmsShipbillNodeTrackingMapper;

	@Autowired
	private TrailerService trailerService;

	@Autowired
	private SendCarService sendCarService;

	@Autowired
	private TmsShipbillTransportLogMapper tmsShipbillTransportLogMapper;

	@Autowired
	private LoadingBillService loadingBillService;

	@Autowired
	private ConvertorUtil convertorUtil;

	@Autowired
	private SysGroupCfgService sysGroupCfgService;

	@Autowired
	@Qualifier("messageAndImportExecutor")
	private ThreadPoolTaskExecutor executor;

	@Autowired
	private DataSourceTransactionManager dataSourceTransactionManager;

	@Autowired
	private TmsTransPlanBillHeaderMapper tmsTransPlanBillHeaderMapper;

	@Autowired
	private TmsTransPlanBillDetailMapper tmsTransPlanBillDetailMapper;

	/**
	 * 待调度分页查询
	 *
	 * @param pendingDispatchPageVO
	 * @return
	 */
	@SuppressWarnings("resource")
	@Override
	public Page<PendingDispatchPageDTO> pagePendingDispatchData(PendingDispatchPageVO pendingDispatchPageVO) {
		ToolKits.isParamNull(pendingDispatchPageVO, "待调度分页查询请求不为空");
		ToolKits.isParamNull(pendingDispatchPageVO.getPageNum(), "当前页码不为空");
		ToolKits.isParamNull(pendingDispatchPageVO.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, "当前人员没有操作权限");
		}
		if (ToolKits.isNotEmpty(pendingDispatchPageVO.getCargoOwnerIds())) {
			String[] ids = pendingDispatchPageVO.getCargoOwnerIds().split(",");
			pendingDispatchPageVO.setCargoOwnerIdList(Arrays.stream(ids).map(id -> Long.valueOf(id)).collect(Collectors.toList()));
		}
		if (ToolKits.isNotEmpty(pendingDispatchPageVO.getLineIds())) {
			String[] ids = pendingDispatchPageVO.getLineIds().split(",");
			pendingDispatchPageVO.setLineIdList(Arrays.stream(ids).map(id -> Long.valueOf(id)).collect(Collectors.toList()));
		}
		List<ZoneVO> shipperAdministrativeAreas = pendingDispatchPageVO.getShipperAdministrativeAreas();
		if (ToolKits.isNotEmpty(shipperAdministrativeAreas)) {
			List<String> provinceList = parseCode(shipperAdministrativeAreas, "province");
			if (ToolKits.isNotEmpty(provinceList)) {
				pendingDispatchPageVO.setShipperProvinceList(provinceList);
			}
			List<String> cityList = parseCode(shipperAdministrativeAreas, "city");
			if (ToolKits.isNotEmpty(cityList)) {
				pendingDispatchPageVO.setShipperCityList(cityList);
			}
			List<String> districtList = parseCode(shipperAdministrativeAreas, "district");
			if (ToolKits.isNotEmpty(districtList)) {
				pendingDispatchPageVO.setShipperDistrictList(districtList);
			}
		}
		List<ZoneVO> consigneeAdministrativeAreas = pendingDispatchPageVO.getAdministrativeAreas();
		if (ToolKits.isNotEmpty(consigneeAdministrativeAreas)) {
			List<String> provinceList = parseCode(consigneeAdministrativeAreas, "province");
			if (ToolKits.isNotEmpty(provinceList)) {
				pendingDispatchPageVO.setConsigneeProvinceList(provinceList);
			}
			List<String> cityList = parseCode(consigneeAdministrativeAreas, "city");
			if (ToolKits.isNotEmpty(cityList)) {
				pendingDispatchPageVO.setConsigneeCityList(cityList);
			}
			List<String> districtList = parseCode(consigneeAdministrativeAreas, "district");
			if (ToolKits.isNotEmpty(districtList)) {
				pendingDispatchPageVO.setConsigneeDistrictList(districtList);
			}
		}
		// 数据字典翻译数据集合
		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(TmsShipbillHeaderModel.class);
		Restriction r1 = ToolKits.isEmpty(pendingDispatchPageVO.getCargoOwnerIdList()) ? null : Restrictions.in("cargoOwnerId", pendingDispatchPageVO.getCargoOwnerIdList().stream().toArray(Long[]::new));
		Restriction r2 = ToolKits.isEmpty(pendingDispatchPageVO.getOrderNo()) ? null : Restrictions.like("orderNo", "%" + pendingDispatchPageVO.getOrderNo() + "%");
		Restriction r3 = ToolKits.isEmpty(pendingDispatchPageVO.getShipbillNo()) ? null : Restrictions.like("shipbillNo", "%" + pendingDispatchPageVO.getShipbillNo() + "%");
		Restriction r4 = ToolKits.isEmpty(pendingDispatchPageVO.getOrderBusinessType()) ? null : Restrictions.eq("orderBusinessType", pendingDispatchPageVO.getOrderBusinessType());
		Restriction r5 = ToolKits.isEmpty(pendingDispatchPageVO.getEstimatedPickupStartTime()) ? null : Restrictions.ge("estimatedPickupStartTime", pendingDispatchPageVO.getEstimatedPickupStartTime());
		Restriction r6 = ToolKits.isEmpty(pendingDispatchPageVO.getEstimatedPickupEndTime()) ? null : Restrictions.le("estimatedPickupEndTime", pendingDispatchPageVO.getEstimatedPickupEndTime());
		Restriction r7 = ToolKits.isEmpty(pendingDispatchPageVO.getEstimatedDeliveryStartTime()) ? null : Restrictions.ge("estimatedDeliveryStartTime", pendingDispatchPageVO.getEstimatedDeliveryStartTime());
		Restriction r8 = ToolKits.isEmpty(pendingDispatchPageVO.getEstimatedDeliveryEndTime()) ? null : Restrictions.le("estimatedDeliveryEndTime", pendingDispatchPageVO.getEstimatedDeliveryEndTime());
		Restriction r9 = ToolKits.isEmpty(pendingDispatchPageVO.getLineIdList()) ? null : Restrictions.in("lineId", pendingDispatchPageVO.getLineIdList().stream().toArray(Long[]::new));

		Restriction r10 = ToolKits.isEmpty(pendingDispatchPageVO.getShipperProvinceList()) ? null : Restrictions.in(TmsShipbillHeaderModel::getShipperProvince, pendingDispatchPageVO.getShipperProvinceList().stream().toArray(String[]::new));
		Restriction r44 = ToolKits.isEmpty(pendingDispatchPageVO.getShipperCityList()) ? null : Restrictions.in(TmsShipbillHeaderModel::getShipperCity, pendingDispatchPageVO.getShipperCityList().stream().toArray(String[]::new));
		Restriction r45 = ToolKits.isEmpty(pendingDispatchPageVO.getShipperDistrictList()) ? null : Restrictions.in(TmsShipbillHeaderModel::getShipperDistrict, pendingDispatchPageVO.getShipperDistrictList().stream().toArray(String[]::new));
		Restriction r55 = Restrictions.or(r10, r44, r45);

		Restriction r11 = ToolKits.isEmpty(pendingDispatchPageVO.getConsigneeProvinceList()) ? null : Restrictions.in(TmsShipbillHeaderModel::getConsigneeProvince, pendingDispatchPageVO.getConsigneeProvinceList().stream().toArray(String[]::new));
		Restriction r46 = ToolKits.isEmpty(pendingDispatchPageVO.getConsigneeCityList()) ? null : Restrictions.in(TmsShipbillHeaderModel::getConsigneeCity, pendingDispatchPageVO.getConsigneeCityList().stream().toArray(String[]::new));
		Restriction r47 = ToolKits.isEmpty(pendingDispatchPageVO.getConsigneeDistrictList()) ? null : Restrictions.in(TmsShipbillHeaderModel::getConsigneeDistrict, pendingDispatchPageVO.getConsigneeDistrictList().stream().toArray(String[]::new));
		Restriction r57 = Restrictions.or(r11, r46, r47);

		Restriction r48 = ToolKits.isEmpty(pendingDispatchPageVO.getLineDirection()) ? null : Restrictions.eq(TmsShipbillHeaderModel::getLineDirection, pendingDispatchPageVO.getLineDirection());
		Restriction r58 = ToolKits.isEmpty(pendingDispatchPageVO.getRecordTagWord()) ? null : Restrictions.like(TmsShipbillHeaderModel::getRecordTagWord, "%" + pendingDispatchPageVO.getRecordTagWord() + "%");

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

		Restriction r15 = null;
		Restriction r23 = 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 r33 = Restrictions.in(TmsShipbillHeaderModel::getShipperUnitId, user.getWarehouses().stream().toArray(Long[]::new));
				Restriction r34 = Restrictions.in(TmsShipbillHeaderModel::getShipperUnitId, user.getSuppliers().stream().toArray(Long[]::new));
				Restriction r35 = Restrictions.in(TmsShipbillHeaderModel::getShipperUnitId, user.getCustomers().stream().toArray(Long[]::new));

				Restriction r21 = Restrictions.or(r18, r19, r20, r33, r34, r35);
				r15 = Restrictions.and(r16, r17, r21);
			}
		} else {
			// 非自有账号
			r13 = Restrictions.eq("carrierSplitOrderStatus", DataDictionaryConstant.CARRIER_SPLIT_ORDER_STATUS_UN);
			Restriction r16 = Restrictions.eq("carrierId", Long.valueOf(user.getLoginUserCompanyInfo().getId()));
			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);
		}

		Restriction r17 = null;
		if (ToolKits.isNotEmpty(pendingDispatchPageVO.getShipperLocation()) && pendingDispatchPageVO.getShipperLocation().intValue() == 0) {
			Restriction r18 = Restrictions.isnull("shipperLongitude");
			Restriction r19 = Restrictions.isnull("shipperLatitude");
			r17 = Restrictions.or(r18, r19);
		} else if (ToolKits.isNotEmpty(pendingDispatchPageVO.getShipperLocation()) && pendingDispatchPageVO.getShipperLocation().intValue() == 1) {
			Restriction r18 = Restrictions.isNotNull("shipperLongitude");
			Restriction r19 = Restrictions.isNotNull("shipperLatitude");
			r17 = Restrictions.and(r18, r19);
		}
		Restriction r20 = null;
		if (ToolKits.isNotEmpty(pendingDispatchPageVO.getConsigneeLocation()) && pendingDispatchPageVO.getConsigneeLocation().intValue() == 0) {
			Restriction r18 = Restrictions.isnull("consigneeLongitude");
			Restriction r19 = Restrictions.isnull("consigneeLatitude");
			r20 = Restrictions.or(r18, r19);
		} else if (ToolKits.isNotEmpty(pendingDispatchPageVO.getConsigneeLocation()) && pendingDispatchPageVO.getConsigneeLocation().intValue() == 1) {
			Restriction r18 = Restrictions.isNotNull("consigneeLongitude");
			Restriction r19 = Restrictions.isNotNull("consigneeLatitude");
			r20 = Restrictions.and(r18, r19);
		}

		Restriction r59 = ToolKits.isEmpty(pendingDispatchPageVO.getOrderDateStart()) ? null : Restrictions.ge(TmsShipbillHeaderModel::getOrderDate, pendingDispatchPageVO.getOrderDateStart());
		Restriction r60 = ToolKits.isEmpty(pendingDispatchPageVO.getOrderDateEnd()) ? null : Restrictions.le(TmsShipbillHeaderModel::getOrderDate, pendingDispatchPageVO.getOrderDateEnd());

		Restriction r61 = ToolKits.isEmpty(pendingDispatchPageVO.getCreateDateStart()) ? null : Restrictions.ge(TmsShipbillHeaderModel::getCreatetime, pendingDispatchPageVO.getCreateDateStart());
		Restriction r62 = ToolKits.isEmpty(pendingDispatchPageVO.getCreateDateEnd()) ? null : Restrictions.le(TmsShipbillHeaderModel::getCreatetime, pendingDispatchPageVO.getCreateDateEnd());
		Restriction r63 = Restrictions.gt(TmsShipbillHeaderModel::getTotalPcs, BigDecimal.valueOf(0));

		Restriction r64 = ToolKits.isEmpty(pendingDispatchPageVO.getCreateperson()) ? null : Restrictions.in(TmsShipbillHeaderModel::getCreateperson, pendingDispatchPageVO.getCreateperson().split(","));
		Restriction r65 = ToolKits.isEmpty(pendingDispatchPageVO.getConsigneeType()) ? null : Restrictions.eq(TmsShipbillHeaderModel::getConsigneeType, pendingDispatchPageVO.getConsigneeType());
		Restriction r66 = ToolKits.isEmpty(pendingDispatchPageVO.getConsigneeId()) ? null : Restrictions.in(TmsShipbillHeaderModel::getConsigneeId, pendingDispatchPageVO.getConsigneeId().split(","));
		Restriction r67 = ToolKits.isEmpty(pendingDispatchPageVO.getConsigneeStationId()) ? null : Restrictions.in(TmsShipbillHeaderModel::getConsigneeStationId, pendingDispatchPageVO.getConsigneeStationId().split(","));
		Restriction r68 = ToolKits.isEmpty(pendingDispatchPageVO.getConsigneeAddress()) ? null : Restrictions.likeAll(TmsShipbillHeaderModel::getConsigneeAddress, pendingDispatchPageVO.getConsigneeAddress());
		Restriction r69 = Restrictions.eq(TmsShipbillHeaderModel::getIntelligentLock, 0);
		Restriction r70 = ToolKits.isEmpty(pendingDispatchPageVO.getCarriersId()) ? null : Restrictions.eq(TmsShipbillHeaderModel::getCarriersId, pendingDispatchPageVO.getCarriersId());

		criteria.setRestriction(Restrictions.and(r1, r2, r3, r4, r5, r6, r7, r8, r9, r55, r57, r48, r58, r12, r13, r14, r15, r22, r23, r17, r20, r59, r60, r61, r62, r63, r64, r65, r66, r67, r68, r69,r70));
		criteria.setOrder(Order.newInstance().desc(new String[] { "updatetime" }));

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

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

		for (TmsShipbillHeaderModel tmsShipbillHeaderModel : tmsShipbillHeaderModels) {
			PendingDispatchPageDTO pendingDispatchPageDTO = new PendingDispatchPageDTO();
			BeanUtils.copyProperties(tmsShipbillHeaderModel, pendingDispatchPageDTO);
			// 收货方位置(经纬度判断)
			if (ToolKits.isNotEmpty(tmsShipbillHeaderModel.getConsigneeLongitude()) && ToolKits.isNotEmpty(tmsShipbillHeaderModel.getConsigneeLatitude())) {
				pendingDispatchPageDTO.setConsigneePositioning(StatusConstant.POSITIONING_YDW);
			} else {
				pendingDispatchPageDTO.setConsigneePositioning(StatusConstant.POSITIONING_WDW);
			}
			// 发货方位置(经纬度判断)
			if (ToolKits.isNotEmpty(tmsShipbillHeaderModel.getShipperLongitude()) && ToolKits.isNotEmpty(tmsShipbillHeaderModel.getShipperLatitude())) {
				pendingDispatchPageDTO.setShipperPositioning(StatusConstant.POSITIONING_YDW);
			} else {
				pendingDispatchPageDTO.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());
			}
			pendingDispatchPageDTO.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());
			}
			pendingDispatchPageDTO.setShipperProvinceCityDistrict(shipperProvinceCityDistrict.toString());

			// 类型翻译
			pendingDispatchPageDTO.setOrderTypeName(ConvertorUtil.getName(dicData, DataDictionaryConstant.ORDER_TYPE, String.valueOf(pendingDispatchPageDTO.getOrderType())));
			pendingDispatchPageDTO.setOrderBusinessTypeName(ConvertorUtil.getName(dicData, DataDictionaryConstant.ORDER_BUSINESS_TYPE, String.valueOf(pendingDispatchPageDTO.getOrderBusinessType())));
			pendingDispatchPageDTO.setDeliveryMethodTypeName(ConvertorUtil.getName(dicData, DataDictionaryConstant.DELIVERY_METHOD_TYPE, String.valueOf(pendingDispatchPageDTO.getDeliveryMethodType())));
			pendingDispatchPageDTO.setTransportTypeName(ConvertorUtil.getName(dicData, DataDictionaryConstant.TRANSPORT_TYPE, String.valueOf(pendingDispatchPageDTO.getTransportType())));
			pendingDispatchPageDTO.setTemperatureRequirementName(ConvertorUtil.getName(dicData, DataDictionaryConstant.TEMPERATURE_REQUIREMENT, String.valueOf(pendingDispatchPageDTO.getTemperatureRequirement())));
			pendingDispatchPageDTO.setShipperTypeName(ConvertorUtil.getName(dicData, DataDictionaryConstant.SHIPPER_TYPE, String.valueOf(pendingDispatchPageDTO.getShipperType())));
			pendingDispatchPageDTO.setConsigneeTypeName(ConvertorUtil.getName(dicData, DataDictionaryConstant.CONSIGNEE_TYPE, String.valueOf(pendingDispatchPageDTO.getConsigneeType())));
			pendingDispatchPageDTO.setLineDirectionName(ConvertorUtil.getName(dicData, DataDictionaryConstant.LINE_DIRECTION, String.valueOf(pendingDispatchPageDTO.getLineDirection())));
			// 获取背景颜色和字体颜色
			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(pendingDispatchPageDTO.getOrderTypeName()) ? pendingDispatchPageDTO.getOrderTypeName() : "")) {
							pendingDispatchPageDTO.setBackground(ToolKits.isEmpty(signconfigPopDTO.getBackground()) ? "" : signconfigPopDTO.getBackground());
							pendingDispatchPageDTO.setColor(ToolKits.isEmpty(signconfigPopDTO.getColor()) ? "" : signconfigPopDTO.getColor());

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

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

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

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

							pendingDispatchPageDTO.setSignConfigId(signconfigPopDTO.getId());

							break Signconfig;
						}
					}
					break;
				}
			}

			pendingDispatchPageDTOs.add(pendingDispatchPageDTO);
		}

		// 分页重组
		Page<PendingDispatchPageDTO> page = PageUtils.getPage(pendingDispatchPageDTOs);
		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 advancedQueryVO
	 * @return
	 */
	@SuppressWarnings("resource")
	public Page<PendingDispatchPageDTO> pageAdvanced(PendingDispatchAdvQueryVO 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.DELIVERY_METHOD_TYPE, // 配送方式
				DataDictionaryConstant.TRANSPORT_TYPE, // 运输类型(运输模式)
				DataDictionaryConstant.TEMPERATURE_REQUIREMENT, // 温度要求
				DataDictionaryConstant.SHIPPER_TYPE, // 发货方类型
				DataDictionaryConstant.CONSIGNEE_TYPE, // 收货方类型
				DataDictionaryConstant.ORDER_TYPE, // 订单类型
				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();
		}

		// 添加查询条件
		advancedQueryVO.setEnterpriseId(user.getEnterpriseId());
		advancedQueryVO.setDeliveryMethodType(DataDictionaryConstant.DELIVERY_METHOD_TYPE_SEND);
		advancedQueryVO.setSplitOrderStatus(DataDictionaryConstant.SPLIT_ORDER_STATUS_UN);
		if (ObjectUtil.equal(user.getUserType(), BussinessConstant.USER_TYPE_ZY)) {
			// 自有账号
			advancedQueryVO.setStatus(DataDictionaryConstant.SHIPBILL_STATUS_REVIEW);
			advancedQueryVO.setDepts(user.getDepts().stream().toArray(String[]::new));
			if (BussinessConstant.USER_DEPARTMENT_AUTH_Y.equals(user.getOwnedAllDataAuthFlag())) {
				advancedQueryVO.setIsDept("YES");
			} else {
				advancedQueryVO.setIsDept("NO");
				// 其它权限
				// 货主
				advancedQueryVO.setConsignors(user.getConsignors().stream().toArray(Long[]::new));
				// 客户
				advancedQueryVO.setCustomers(user.getCustomers().stream().toArray(Long[]::new));
				// 供应商
				advancedQueryVO.setSuppliers(user.getSuppliers().stream().toArray(Long[]::new));
				// 仓库
				advancedQueryVO.setWsarehouses(user.getWarehouses().stream().toArray(Long[]::new));
			}
		} else if (ObjectUtil.equal(user.getUserType(), BussinessConstant.USER_TYPE_CYS)) {// 承运商账号
			// 承运商账号 单位ID
			advancedQueryVO.setUnitId(Long.valueOf(user.getLoginUserCompanyInfo().getId()));
			// 承运商运单状态
			Integer[] carrierStsList = new Integer[] { DataDictionaryConstant.CARRIER_SHIPBILL_STATUS_AUDITED };
			advancedQueryVO.setCarrierStatusList(carrierStsList);
		} else {
			throw new PrologException("当前人员没有操作权限！");
		}
		// 获取高级查询配置
		String conditions = null;
		RestMessage<String> restMessageAdvancedCfg = maindataTmsResource.getQueryConfiguration(DataDictionaryConstant.BIZ_TYPE_PENDING_DISPATCH);
		if (!restMessageAdvancedCfg.isSuccess()) {
			// throw new RuntimeException("订单类型翻译失败!");
		} else {
			conditions = restMessageAdvancedCfg.getData();
		}
		advancedQueryVO.setSql(conditions);

		PageUtils.startPage(advancedQueryVO.getPageNum(), advancedQueryVO.getPageSize());
		List<PendingDispatchPageDTO> tmsShipbillHeaderModels = tmsShipbillHeaderMapper.pendingDispatchAdvancedQuery(advancedQueryVO);

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

		for (PendingDispatchPageDTO tmsShipbillHeaderModel : tmsShipbillHeaderModels) {
			PendingDispatchPageDTO pendingDispatchPageDTO = new PendingDispatchPageDTO();
			BeanUtils.copyProperties(tmsShipbillHeaderModel, pendingDispatchPageDTO);
			// 收货方位置(经纬度判断)
			if (ToolKits.isNotEmpty(tmsShipbillHeaderModel.getConsigneeLongitude()) && ToolKits.isNotEmpty(tmsShipbillHeaderModel.getConsigneeLatitude())) {
				pendingDispatchPageDTO.setConsigneePositioning(StatusConstant.POSITIONING_YDW);
			} else {
				pendingDispatchPageDTO.setConsigneePositioning(StatusConstant.POSITIONING_WDW);
			}
			// 发货方位置(经纬度判断)
			if (ToolKits.isNotEmpty(tmsShipbillHeaderModel.getShipperLongitude()) && ToolKits.isNotEmpty(tmsShipbillHeaderModel.getShipperLatitude())) {
				pendingDispatchPageDTO.setShipperPositioning(StatusConstant.POSITIONING_YDW);
			} else {
				pendingDispatchPageDTO.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());
			}
			pendingDispatchPageDTO.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());
			}
			pendingDispatchPageDTO.setShipperProvinceCityDistrict(shipperProvinceCityDistrict.toString());

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

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

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

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

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

							pendingDispatchPageDTO.setSignConfigId(signconfigPopDTO.getId());

							break Signconfig;
						}
					}
					break;
				}
			}

			pendingDispatchPageDTOs.add(pendingDispatchPageDTO);
		}

		// 分页重组
		Page<PendingDispatchPageDTO> page = PageUtils.getPage(pendingDispatchPageDTOs);
		if (tmsShipbillHeaderModels instanceof com.github.pagehelper.Page) {
			com.github.pagehelper.Page<PendingDispatchPageDTO> p0 = (com.github.pagehelper.Page<PendingDispatchPageDTO>) 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 detailItemPageVO
	 * @return
	 */
	@SuppressWarnings("resource")
	@Override
	public Page<PendingDispatchDetailDTO> listShipbillDetailData(DetailItemPageVO detailItemPageVO) {
		ToolKits.isParamNull(detailItemPageVO, "商品信息查询查询不为空");
		ToolKits.isParamNull(detailItemPageVO.getShipbillId(), "运单ID不为空");
		ToolKits.isParamNull(detailItemPageVO.getPageNum(), "当前页码不为空");
		ToolKits.isParamNull(detailItemPageVO.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(TmsShipbillDetailModel.class);
		Restriction r1 = Restrictions.eq("shipbillId", detailItemPageVO.getShipbillId());
		Restriction r2 = Restrictions.eq("enterpriseId", user.getEnterpriseId());
		criteria.setRestriction(Restrictions.and(r1, r2));
		criteria.setOrder(Order.newInstance().desc(new String[] { "updatetime" }));

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

		// 响应对象集合
		List<PendingDispatchDetailDTO> pendingDispatchDetailDTOs = new ArrayList<PendingDispatchDetailDTO>();

		if (ToolKits.isNotEmpty(tmsShipbillDetailModels)) {
			for (TmsShipbillDetailModel tmsShipbillDetailModel : tmsShipbillDetailModels) {
				// 响应对象
				PendingDispatchDetailDTO pendingDispatchDetailDTO = new PendingDispatchDetailDTO();
				BeanUtils.copyProperties(tmsShipbillDetailModel, pendingDispatchDetailDTO);
				pendingDispatchDetailDTO.setPackTypeName(PublicMethods.change(data1, String.valueOf(pendingDispatchDetailDTO.getPackType())));
				pendingDispatchDetailDTO.setCargoThermosphereName(PublicMethods.change(data2, String.valueOf(pendingDispatchDetailDTO.getCargoThermosphere())));

				pendingDispatchDetailDTOs.add(pendingDispatchDetailDTO);
			}
		}

		// 分页重组
		Page<PendingDispatchDetailDTO> page = PageUtils.getPage(pendingDispatchDetailDTOs);
		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 detailItemSplitVO
	 * @return
	 */
	public List<PendingDispatchDetailDTO> splitListShipbillDetail(DetailItemSplitVO detailItemSplitVO) {
		ToolKits.isParamNull(detailItemSplitVO, "商品信息查询查询不为空");
		ToolKits.isParamNull(detailItemSplitVO.getShipbillId(), "运单ID不为空");

		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(TmsShipbillDetailModel.class);
		Restriction r1 = Restrictions.eq("shipbillId", detailItemSplitVO.getShipbillId());
		Restriction r2 = Restrictions.eq("enterpriseId", user.getEnterpriseId());
		criteria.setRestriction(Restrictions.and(r1, r2));
		criteria.setOrder(Order.newInstance().desc(new String[] { "updatetime" }));

		List<TmsShipbillDetailModel> tmsShipbillDetailModels = tmsShipbillDetailMapper.findByCriteria(criteria);

		// 响应对象集合
		List<PendingDispatchDetailDTO> pendingDispatchDetailDTOs = new ArrayList<PendingDispatchDetailDTO>();

		if (ToolKits.isNotEmpty(tmsShipbillDetailModels)) {
			for (TmsShipbillDetailModel tmsShipbillDetailModel : tmsShipbillDetailModels) {
				// 响应对象
				PendingDispatchDetailDTO pendingDispatchDetailDTO = new PendingDispatchDetailDTO();
				BeanUtils.copyProperties(tmsShipbillDetailModel, pendingDispatchDetailDTO);
				pendingDispatchDetailDTO.setPackTypeName(PublicMethods.change(data1, String.valueOf(pendingDispatchDetailDTO.getPackType())));
				pendingDispatchDetailDTO.setCargoThermosphereName(PublicMethods.change(data2, String.valueOf(pendingDispatchDetailDTO.getCargoThermosphere())));

				pendingDispatchDetailDTOs.add(pendingDispatchDetailDTO);
			}
		}
		return pendingDispatchDetailDTOs;
	}

	/**
	 * 待调度包裹信息查询
	 *
	 * @param detailItemPageVO
	 * @return
	 */
	@SuppressWarnings("resource")
	@Override
	public Page<PendingDispatchPackageDTO> listShipbillPackageData(DetailItemPageVO detailItemPageVO) {
		ToolKits.isParamNull(detailItemPageVO, "包裹信息查询不为空");
		ToolKits.isParamNull(detailItemPageVO.getShipbillId(), "运单ID不为空");
		ToolKits.isParamNull(detailItemPageVO.getPageNum(), "当前页码不为空");
		ToolKits.isParamNull(detailItemPageVO.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.PACKAGE_TYPE, null, null, null);
		if (!restMessage1.isSuccess()) {
			throw new RuntimeException("包裹类型翻译失败!");
		} else {
			data1 = restMessage1.getData();
		}

		// 设备类型
		RestMessage<List<Map<String, Object>>> restMessage2 = maindataTmsResource.getDropDownById(DataDictionaryConstant.DEVICE_COMPANY, null, null, null);
		if (!restMessage2.isSuccess()) {
			throw new RuntimeException("设备类型翻译失败!");
		} else {
			data2 = restMessage2.getData();
		}

		// 添加查询条件
		Criteria criteria = Criteria.forClass(TmsShipbillPackageModel.class);
		Restriction r1 = Restrictions.eq("shipbillId", detailItemPageVO.getShipbillId());
		Restriction r2 = Restrictions.eq("enterpriseId", user.getEnterpriseId());
		criteria.setRestriction(Restrictions.and(r1, r2));
		criteria.setOrder(Order.newInstance().desc(new String[] { "updatetime" }));

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

		// 响应对象集合
		List<PendingDispatchPackageDTO> pendingDispatchPackageDTOs = new ArrayList<PendingDispatchPackageDTO>();

		if (ToolKits.isNotEmpty(tmsShipbillPackageModels)) {
			for (TmsShipbillPackageModel tmsShipbillPackageModel : tmsShipbillPackageModels) {
				// 响应对象
				PendingDispatchPackageDTO pendingDispatchPackageDTO = new PendingDispatchPackageDTO();
				BeanUtils.copyProperties(tmsShipbillPackageModel, pendingDispatchPackageDTO);
				pendingDispatchPackageDTO.setPackageTypeName(PublicMethods.change(data1, String.valueOf(tmsShipbillPackageModel.getPackageType())));
				pendingDispatchPackageDTO.setDeviceCompanyName(PublicMethods.change(data2, String.valueOf(tmsShipbillPackageModel.getDeviceCompany())));

				pendingDispatchPackageDTOs.add(pendingDispatchPackageDTO);
			}
		}
		// 分页重组
		Page<PendingDispatchPackageDTO> page = PageUtils.getPage(pendingDispatchPackageDTOs);
		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 vo
	 * @return
	 */
	@Override
	public PendingDispatchShipbillQtyDTO goodsQtyStatistics(SysGroupQueryVO vo) {
		ToolKits.isParamNull(vo, "运单货量统计请求不为空");

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

		vo.setUserType(user.getUserType());
		vo.setEnterpriseId(user.getEnterpriseId());
		if (ObjectUtil.equal(user.getUserType(), BussinessConstant.USER_TYPE_ZY)) {// 自有账号
			vo.setDepts(ToolKits.isEmpty(user.getDepts()) ? null : user.getDepts().stream().toArray(String[]::new));
			if (BussinessConstant.USER_DEPARTMENT_AUTH_Y.equals(user.getOwnedAllDataAuthFlag())) {// 部门权限
				vo.setIsDept("YES");
			} else {// 业务员权限
				vo.setIsDept("NO");
				// 货主
				vo.setConsignors(ToolKits.isEmpty(user.getConsignors()) ? null : user.getConsignors().stream().toArray(Long[]::new));
				// 客户
				vo.setCustomers(ToolKits.isEmpty(user.getCustomers()) ? null : user.getCustomers().stream().toArray(Long[]::new));
				// 供应商
				vo.setSuppliers(ToolKits.isEmpty(user.getSuppliers()) ? null : user.getSuppliers().stream().toArray(Long[]::new));
				// 仓库
				vo.setWsarehouses(ToolKits.isEmpty(user.getWarehouses()) ? null : user.getWarehouses().stream().toArray(Long[]::new));
			}
		} else if (ObjectUtil.equal(user.getUserType(), BussinessConstant.USER_TYPE_CYS)) {// 承运商账号
			vo.setCarrierId(Long.valueOf(user.getLoginUserCompanyInfo().getId()));
		}
		PendingDispatchShipbillQtyDTO rsDTO = new PendingDispatchShipbillQtyDTO();

		List<ShipbillLineMapDTO> shipbillQueryDTOS = tmsShipbillHeaderMapper.shipbillLineMapSiteQuery(vo);

		if (ToolKits.isNotEmpty(shipbillQueryDTOS)) {
			// 货主数
			rsDTO.setCargoOwnerQty(shipbillQueryDTOS.stream().map(ShipbillLineMapDTO::getCargoOwnerName).distinct().collect(Collectors.toList()).size());
			// 运单数
			rsDTO.setShipbillQty(shipbillQueryDTOS.size());
			// 收货方数
			rsDTO.setConsigneeQty(shipbillQueryDTOS.stream().map(ShipbillLineMapDTO::getConsigneeUnitName).distinct().collect(Collectors.toList()).size());
			// 总提货点数
			rsDTO.setTotalPickUpSiteQty(shipbillQueryDTOS.stream().map(ShipbillLineMapDTO::getShipperAddress).distinct().collect(Collectors.toList()).size());
			// 总配送点数
			rsDTO.setTotalDeliverySiteQty(shipbillQueryDTOS.stream().map(ShipbillLineMapDTO::getConsigneeAddress).distinct().collect(Collectors.toList()).size());
			// 总站数
			rsDTO.setTotalSitQty(rsDTO.getTotalPickUpSiteQty().intValue() + rsDTO.getTotalDeliverySiteQty().intValue());
			// 冷链运单数
			long coldChainShipbillQty = shipbillQueryDTOS.stream().filter(s -> ToolKits.isNotEmpty(s.getTemperatureRequirement()) && s.getTemperatureRequirement().intValue() > 1).collect(Collectors.toList()).size();
			rsDTO.setColdChainShipbillQty(Integer.valueOf(new Long(coldChainShipbillQty).intValue()));

			// 紧急加急运单数
			long urgentShipbillQty = shipbillQueryDTOS.stream().filter(s -> ToolKits.isNotEmpty(s.getOrderType()) && s.getOrderType().intValue() > 1).collect(Collectors.toList()).size();
			rsDTO.setUrgentShipbillQty(Integer.valueOf(new Long(urgentShipbillQty).intValue()));

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

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

			// 根据站点计算总里程
			if (shipbillQueryDTOS.stream().anyMatch(shipbill->ToolKits.isEmpty(shipbill.getShipperDeliveryOrder()) || ToolKits.isEmpty(shipbill.getConsigneeDeliveryOrder())
					|| ToolKits.isEmpty(shipbill.getConsigneeStationName()) || ToolKits.isEmpty(shipbill.getShipperStationName()))) {
				log.info("运单货量统计时,站点信息不全{}未获取到总里程",shipbillQueryDTOS);
				return rsDTO;
			}
		}
		return rsDTO;
	}

	/**
	 * 运单地图-线路货量统计
	 *
	 * @param vo
	 * @return
	 */
	@Override
	public List<PendingDispatchShipbillQtyByLineDTO> lineQtyStatistics(SysGroupQueryVO vo) {

		ToolKits.isParamNull(vo, "线路货量统计请求不为空");

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

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

		vo.setUserType(user.getUserType());
		vo.setEnterpriseId(user.getEnterpriseId());
		if (ObjectUtil.equal(user.getUserType(), BussinessConstant.USER_TYPE_ZY)) {// 自有账号
			vo.setDepts(ToolKits.isEmpty(user.getDepts()) ? null : user.getDepts().stream().toArray(String[]::new));
			if (BussinessConstant.USER_DEPARTMENT_AUTH_Y.equals(user.getOwnedAllDataAuthFlag())) {// 部门权限
				vo.setIsDept("YES");
			} else {// 业务员权限
				vo.setIsDept("NO");
				// 货主
				vo.setConsignors(ToolKits.isEmpty(user.getConsignors()) ? null : user.getConsignors().stream().toArray(Long[]::new));
				// 客户
				vo.setCustomers(ToolKits.isEmpty(user.getCustomers()) ? null : user.getCustomers().stream().toArray(Long[]::new));
				// 供应商
				vo.setSuppliers(ToolKits.isEmpty(user.getSuppliers()) ? null : user.getSuppliers().stream().toArray(Long[]::new));
				// 仓库
				vo.setWsarehouses(ToolKits.isEmpty(user.getWarehouses()) ? null : user.getWarehouses().stream().toArray(Long[]::new));
			}
		} else if (ObjectUtil.equal(user.getUserType(), BussinessConstant.USER_TYPE_CYS)) {// 承运商账号
			vo.setCarrierId(Long.valueOf(user.getLoginUserCompanyInfo().getId()));
		}

		List<PendingDispatchShipbillQtyByLineDTO> lineShipbillQtyDTOS = Lists.newArrayList();

		List<ShipbillLineMapDTO> shipbillQueryDTOS = tmsShipbillHeaderMapper.shipbillLineMapSiteQuery(vo);

		if (ToolKits.isNotEmpty(shipbillQueryDTOS)) {
			shipbillQueryDTOS = shipbillQueryDTOS.stream().filter(shipbill -> ToolKits.isNotEmpty(shipbill.getLineId())).collect(Collectors.toList());
			Map<Long, List<ShipbillLineMapDTO>> lineShipbillMap = Maps.newHashMap();
			lineShipbillMap = shipbillQueryDTOS.stream().collect(Collectors.groupingBy(ShipbillLineMapDTO::getLineId));
			for (Object obj : lineShipbillMap.keySet()) {
				PendingDispatchShipbillQtyByLineDTO lineDTO = new PendingDispatchShipbillQtyByLineDTO();
				List<ShipbillLineMapDTO> oneLineShipbillDTO = lineShipbillMap.get(obj);

				lineDTO.setLineId(oneLineShipbillDTO.get(0).getLineId());
				lineDTO.setLineName(oneLineShipbillDTO.get(0).getLineName());
				// 货主数
				lineDTO.setCargoOwnerQty(oneLineShipbillDTO.stream().map(ShipbillLineMapDTO::getCargoOwnerName).distinct().collect(Collectors.toList()).size());
				// 运单数
				lineDTO.setShipbillQty(oneLineShipbillDTO.size());
				// 收货方数
				lineDTO.setConsigneeQty(oneLineShipbillDTO.stream().map(ShipbillLineMapDTO::getConsigneeUnitName).distinct().collect(Collectors.toList()).size());
				// 总提货点数
				lineDTO.setTotalPickUpSiteQty(oneLineShipbillDTO.stream().map(ShipbillLineMapDTO::getShipperAddress).distinct().collect(Collectors.toList()).size());
				// 总配送点数
				lineDTO.setTotalDeliverySiteQty(oneLineShipbillDTO.stream().map(ShipbillLineMapDTO::getConsigneeAddress).distinct().collect(Collectors.toList()).size());
				// 总站数
				lineDTO.setTotalSitQty(lineDTO.getTotalPickUpSiteQty().intValue() + lineDTO.getTotalDeliverySiteQty().intValue());
				// 冷链运单数
				long coldChainShipbillQty = oneLineShipbillDTO.stream().filter(s -> ToolKits.isNotEmpty(s.getTemperatureRequirement()) && s.getTemperatureRequirement().intValue() > 1).collect(Collectors.toList()).size();
				lineDTO.setColdChainShipbillQty(Integer.valueOf(new Long(coldChainShipbillQty).intValue()));

				// 紧急加急运单数
				long urgentShipbillQty = oneLineShipbillDTO.stream().filter(s -> ToolKits.isNotEmpty(s.getOrderType()) && s.getOrderType().intValue() > 1).collect(Collectors.toList()).size();
				lineDTO.setUrgentShipbillQty(Integer.valueOf(new Long(urgentShipbillQty).intValue()));

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

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

				lineShipbillQtyDTOS.add(lineDTO);
			}
		}
		return lineShipbillQtyDTOS;
	}

	public void dispatchForThread(PendingDispatchVO vo, UserEntity user, Date date, String... isAudit) {
		if (ToolKits.isNotEmpty(isAudit) && "Y".equals(isAudit[0])) {
			autoDispatch(vo, user, date, "",isAudit);
		} else {
			autoDispatch(vo, user, date,"");
		}
	}

	/**
	 * 自动调度
	 *
	 * @param vo
	 * @return
	 */
	@Override
	public void autoDispatch(PendingDispatchVO vo, UserEntity user, Date date, String isPlanDis,String... isAudit) {
		ToolKits.isParamNull(vo, "运单调度请求不为空");
		ToolKits.isParamNull(vo.getLoadingBillDetailVO(), "运单调度明细不为空");
		ToolKits.isParamNull(vo.getLoadingBillHeaderVO(), "运单调度承运方不为空");
		log.info("调度:" + JSON.toJSONString(vo));
		// 装车单汇总
		LoadingBillHeaderVO headerVO = vo.getLoadingBillHeaderVO();
		// 调到给司机时，若司机未事先录入系统，自动将司机、车辆信息录入系统
		if (DataDictionaryConstant.LINE_CARRIER_TYPE_SJ.equals(headerVO.getCarrierType()) && ToolKits.isEmpty(headerVO.getDriverId())) {
			// 校验司机车辆信息
			VehicleAndVehicleVO vehicleAndVehicleVO = new VehicleAndVehicleVO();
			vehicleAndVehicleVO.setDriverName(headerVO.getDriverName());
			vehicleAndVehicleVO.setPhoneNumber(headerVO.getDriverPhoneNumber());
			vehicleAndVehicleVO.setVehiclePlateNumber(headerVO.getVehiclePlateNumber());
			vehicleAndVehicleVO.setVehicleAscription(headerVO.getVehicleAscription());
			RestMessage<VehicleAndDriverDTO> restMessage = maindataTmsResource.vehicleAutomaticExecute(vehicleAndVehicleVO);
			if (!restMessage.isSuccess()) {
				throw new ParameterException("司机车辆信息校验失败:" + restMessage.getMessage());
			}
			// 车辆司机信息
			VehicleAndDriverDTO vehicleAndDriverDTO = restMessage.getData();
			// 司机信息
			headerVO.setDriverId(String.valueOf(vehicleAndDriverDTO.getDriver().getDriverId()));
			headerVO.setDriverCode(vehicleAndDriverDTO.getDriver().getDriverCode());
			headerVO.setDriverName(vehicleAndDriverDTO.getDriver().getDriverName());
			headerVO.setDriverPhoneNumber(vehicleAndDriverDTO.getDriver().getDriverPhoneNumber());
			headerVO.setCarrierId(vehicleAndDriverDTO.getDriver().getAffiliationId());
			headerVO.setCarrierCode(vehicleAndDriverDTO.getDriver().getAffiliationCode());
			headerVO.setCarrierName(vehicleAndDriverDTO.getDriver().getAffiliationName());

			// 车辆信息
			headerVO.setVehicleId(vehicleAndDriverDTO.getVehicle().getVehicleId());
			headerVO.setVehicleCode(vehicleAndDriverDTO.getVehicle().getVehicleCode());
			headerVO.setVehicleName(vehicleAndDriverDTO.getVehicle().getVehicleName());
			headerVO.setVehiclePlateNumber(vehicleAndDriverDTO.getVehicle().getVehiclePlateNumber());
		}
		Map<String, List<TmsShipbillHeaderModel>> shipbillHeaderMap = Maps.newHashMap();
		// 装车单明细
		List<LoadingBillDetailVO> detailVOS = vo.getLoadingBillDetailVO();
		if (ToolKits.isEmpty(detailVOS)) {
			throw new PrologException("运单调度请求不为空");
		}
		List<String> shipbillIds = detailVOS.stream().map(LoadingBillDetailVO::getShipbillId).collect(Collectors.toList());
		if (ToolKits.isEmpty(shipbillIds)) {
			throw new PrologException("运单ID不为空");
		}
		List<TmsShipbillHeaderModel> shipbillHeaderModels = tmsShipbillHeaderMapper.findByIds(TmsShipbillHeaderModel.class, shipbillIds.stream().toArray(), null);
		if (ToolKits.isEmpty(shipbillHeaderModels)) {
			throw new PrologException(String.format("运单不存在[%s]", shipbillIds.stream().collect(Collectors.joining(","))));
		}

		if (shipbillHeaderModels.stream().map(TmsShipbillHeaderModel::getCarriersId).distinct().collect(Collectors.toList()).size() > 1) {
			throw new PrologException(StrUtil.format("运单{}存在多个承运商,请重新勾选运单", shipbillIds.stream().collect(Collectors.joining(","))));
		}
		if (shipbillHeaderModels.size() > 1) {
			RestMessage<SysParamConfigModel> restMessageShipbillId = maindataTmsResource.getValue(DataDictionaryConstant.LOADING_BILL_CREATE_RULE);
			if (!restMessageShipbillId.isSuccess()) {
				throw new RuntimeException("获取多个发货地址调度单生成方式的系统参数失败!");
			}
			SysParamConfigModel sysParamConfigModel = restMessageShipbillId.getData();
			if (DataDictionaryConstant.LOADING_BILL_CREATE_RULE_MANY.equals(sysParamConfigModel.getValue())) {
				shipbillHeaderMap = shipbillHeaderModels.stream().collect(Collectors.groupingBy(TmsShipbillHeaderModel::getShipperAddress));

			} else {
				shipbillHeaderMap.put("one_loadingBillHeader", shipbillHeaderModels);
			}
		} else {
			shipbillHeaderMap.put("one_loadingBillHeader", shipbillHeaderModels);
		}
		if (ToolKits.isEmpty(shipbillHeaderMap)) {
			throw new PrologException("运单调度明细不为空");
		}
		List<String> ids = Lists.newArrayList();
		for (Object obj : shipbillHeaderMap.keySet()) {
			List<TmsShipbillHeaderModel> shipbillHeaderModelList = shipbillHeaderMap.get(obj);
			// 装车单汇总保存
			// 获取装车单ID
			RestMessage<String> restMessage1 = maindataTmsResource.getCodeNumberByCode(SeriaNnumberConstant.TMS_LOADING_BILL_HEADER_ID, "L");
			if (!restMessage1.isSuccess()) {
				throw new RuntimeException("生成装车单ID失败");
			}

			String loadingBillId = restMessage1.getData();
			TmsLoadingBillHeaderModel loadingBillHeaderModel = new TmsLoadingBillHeaderModel();
			BeanUtils.copyProperties(headerVO, loadingBillHeaderModel);

			if (user.getUserType().equals(BussinessConstant.USER_TYPE_ZY)) {
				loadingBillHeaderModel.setScheduleType(DataDictionaryConstant.SCHEDULE_TYPE_ZY);
			} else {
				loadingBillHeaderModel.setScheduleType(DataDictionaryConstant.SCHEDULE_TYPE_CYS);
			}
			loadingBillHeaderModel.setCarrierId(headerVO.getCarrierId());
			loadingBillHeaderModel.setLoadingBillId(loadingBillId);
			loadingBillHeaderModel.setLoadingBillNo(loadingBillId);
			loadingBillHeaderModel.setStatus(DataDictionaryConstant.LOADING_BILL_STATUS_WSH);
			loadingBillHeaderModel.setEnterpriseId(user.getEnterpriseId());
			loadingBillHeaderModel.setEnterpriseName(user.getEnterpriseName());
			loadingBillHeaderModel.setCreateperson(user.getNickname());
			loadingBillHeaderModel.setCreatetime(date);
			loadingBillHeaderModel.setUpdateperson(user.getNickname());
			loadingBillHeaderModel.setUpdatetime(date);

			loadingBillHeaderModel.setLoadingBillDate(date);
			// 解析司机名称
			String driverName = this.getFirstStr(headerVO.getDriverName());
			// 解析送货员
			String deliverymanName = this.getFirstStr(headerVO.getDeliverymanName());
			if (DataDictionaryConstant.LINE_CARRIER_TYPE_SJ.equals(headerVO.getCarrierType())) {
				// 解析司机ID
				String driverId = this.getFirstStr(headerVO.getDriverId());
				// 解析司机编号
				String driverCode = this.getFirstStr(headerVO.getDriverCode());
				// 解析司机手机号
				String phoneNumber = this.getFirstStr(headerVO.getDriverPhoneNumber());
				// 司机信息
				loadingBillHeaderModel.setDriverId(StrUtil.isBlank(driverId) ? null : Long.valueOf(driverId));
				loadingBillHeaderModel.setDriverCode(StrUtil.isBlank(driverCode) ? null : driverCode);
				loadingBillHeaderModel.setDriverName(StrUtil.isBlank(driverName) ? null : driverName);
				loadingBillHeaderModel.setDriverPhoneNumber(StrUtil.isBlank(phoneNumber) ? null : phoneNumber);
				// 副司机信息
				String viceDriverId = this.subArrToString(String.valueOf(headerVO.getDriverId()));
				loadingBillHeaderModel.setViceDriverId(StrUtil.isBlank(viceDriverId) ? null : viceDriverId);
				String viceDriverCode = this.subArrToString(headerVO.getDriverCode());
				loadingBillHeaderModel.setViceDriverCode(StrUtil.isBlank(viceDriverCode) ? null : viceDriverCode);
				String viceDriverName = this.subArrToString(headerVO.getDriverName());
				loadingBillHeaderModel.setViceDriverName(StrUtil.isBlank(viceDriverName) ? null : viceDriverName);
				String vicephoneNumber = this.subArrToString(headerVO.getDriverPhoneNumber());
				loadingBillHeaderModel.setViceDriverPhoneNumber(StrUtil.isBlank(vicephoneNumber) ? null : vicephoneNumber);
				// 送货员信息
				// 解析送货员ID
				String deliverymanId = this.getFirstStr(headerVO.getDeliverymanId());
				// 解析送货员编号
				String deliverymanCode = this.getFirstStr(headerVO.getDeliverymanCode());
				// 解析送货员手机号
				String deliverymanPhoneNumber = this.getFirstStr(headerVO.getDeliverymanPhoneNumber());
				loadingBillHeaderModel.setDeliverymanId(StrUtil.isBlank(deliverymanId) ? null : Long.valueOf(deliverymanId));
				loadingBillHeaderModel.setDeliverymanCode(StrUtil.isBlank(deliverymanCode) ? null : deliverymanCode);
				loadingBillHeaderModel.setDeliverymanName(StrUtil.isBlank(deliverymanName) ? null : deliverymanName);
				loadingBillHeaderModel.setDeliverymanPhoneNumber(StrUtil.isBlank(deliverymanPhoneNumber) ? null : deliverymanPhoneNumber);
				// 副送货员信息
				String viceDeliverymanId = this.subArrToString(headerVO.getDeliverymanId());
				loadingBillHeaderModel.setViceDriverId(StrUtil.isBlank(viceDeliverymanId) ? null : viceDeliverymanId);
				String viceDeliverymanCode = this.subArrToString(headerVO.getDeliverymanCode());
				loadingBillHeaderModel.setViceDriverCode(StrUtil.isBlank(viceDeliverymanCode) ? null : viceDeliverymanCode);
				String viceDeliverymanName = this.subArrToString(headerVO.getDeliverymanName());
				loadingBillHeaderModel.setViceDeliverymanName(StrUtil.isBlank(viceDeliverymanName) ? null : viceDeliverymanName);
				String viceDeliverymanphoneNumber = this.subArrToString(headerVO.getDeliverymanPhoneNumber());
				loadingBillHeaderModel.setViceDeliverymanPhoneNumber(StrUtil.isBlank(viceDeliverymanphoneNumber) ? null : viceDeliverymanphoneNumber);
			}

			loadingBillHeaderModel.setTotalPcs(BigDecimal.ZERO);
			loadingBillHeaderModel.setTotalVolume(BigDecimal.ZERO);
			loadingBillHeaderModel.setTotalWeight(BigDecimal.ZERO);
			loadingBillHeaderModel.setActualTotalPcs(BigDecimal.ZERO);
			loadingBillHeaderModel.setActualTotalVolume(BigDecimal.ZERO);
			loadingBillHeaderModel.setActualTotalWeight(BigDecimal.ZERO);

			Integer totalWholePiece = 0;
			Integer totalLclPiece = 0;
			boolean autoDispatchCheck = false;

			// 总货主数
			long cargoOwnerNumber = 0;
			cargoOwnerNumber = shipbillHeaderModelList.stream().map(TmsShipbillHeaderModel::getCargoOwnerName).distinct().collect(Collectors.toList()).size();
			// 冷链运单数
			long coldShipbillNumber = 0;
			coldShipbillNumber = shipbillHeaderModelList.stream().filter(s -> ToolKits.isNotEmpty(s.getTemperatureRequirement()) && s.getTemperatureRequirement().intValue() > 1).collect(Collectors.toList()).size();
			// 紧急加急运单数
			long urgentShipbillNumber = 0;
			urgentShipbillNumber = shipbillHeaderModelList.stream().filter(s -> ToolKits.isNotEmpty(s.getOrderType()) && s.getOrderType().intValue() > 1).collect(Collectors.toList()).size();
			// 总提货点数
			long pickupStations = 0;
			pickupStations = shipbillHeaderModelList.stream().map(TmsShipbillHeaderModel::getShipperAddress).distinct().collect(Collectors.toList()).size();
			// 总配送点数
			long deliveryStations = 0;
			deliveryStations = shipbillHeaderModelList.stream().map(TmsShipbillHeaderModel::getConsigneeAddress).distinct().collect(Collectors.toList()).size();

			for (TmsShipbillHeaderModel tmsShipbillHeaderModel : shipbillHeaderModelList) {
				// 装车单明细保存
				// 获取装车单明细ID
				RestMessage<String> restMessage2 = maindataTmsResource.getCodeNumberByCode(SeriaNnumberConstant.TMS_LOADING_BILL_DETAIL_ID, "L");
				if (!restMessage2.isSuccess()) {
					throw new RuntimeException("生成装车单明细ID失败");
				}
				String loadingBillDetailId = restMessage2.getData();
				TmsLoadingBillDetailModel loadingBillDetailModel = new TmsLoadingBillDetailModel();
				BeanUtils.copyProperties(tmsShipbillHeaderModel, loadingBillDetailModel);

				ShipbillNodeTracking shipbillNodeTrackingSaveVO = new ShipbillNodeTracking();
				TmsShipbillOperateLogModel shipbillOperateLogSaveVO = new TmsShipbillOperateLogModel();
				// 节点内容
				StringBuffer nodeEvent = new StringBuffer();
				if (user.getUserType().equals(BussinessConstant.USER_TYPE_ZY)) {
					// 自有账号
					if (!DataDictionaryConstant.SHIPBILL_STATUS_REVIEW.equals(tmsShipbillHeaderModel.getStatus())) {
						throw new PrologException("运单【" + tmsShipbillHeaderModel.getShipbillNo() + "】非待调度状态,调度失败");
					}
					loadingBillDetailModel.setStatus(DataDictionaryConstant.SHIPBILL_STATUS_DISPATCH);
					tmsShipbillHeaderModel.setStatus(DataDictionaryConstant.SHIPBILL_STATUS_DISPATCH);
					shipbillNodeTrackingSaveVO.setStatus(DataDictionaryConstant.SHIPBILL_STATUS_DISPATCH);
					shipbillOperateLogSaveVO.setOldStatus(DataDictionaryConstant.SHIPBILL_STATUS_REVIEW);
					shipbillOperateLogSaveVO.setNewStatus(DataDictionaryConstant.SHIPBILL_STATUS_DISPATCH);
					nodeEvent.append(DataDictionaryConstant.SHIPBILL_NODE_STATUSNAME_DI);

					// 判定是否调度后审核
					if (ToolKits.isNotEmpty(isAudit) && "Y".equals(isAudit[0])) {
						// 调度并审核
						autoDispatchCheck = true;
					} else {
						if (!autoDispatchCheck && tmsShipbillHeaderModel.getFlowConfig().contains(DataDictionaryConstant.FLOW_CONFIG_DISPATCH_CHECK)) {
							autoDispatchCheck = true;
						}
					}
				} else if (user.getUserType().equals(BussinessConstant.USER_TYPE_CYS)) {
					// 承运商账号
					if (!DataDictionaryConstant.CARRIER_SHIPBILL_STATUS_AUDITED.equals(tmsShipbillHeaderModel.getCarrierShipbillStatus())) {
						throw new PrologException("运单【" + tmsShipbillHeaderModel.getShipbillNo() + "】非待调度状态,调度失败");
					}
					if (DataDictionaryConstant.SHIPBILL_STATUS_DISPATCH_CHECK.intValue() > tmsShipbillHeaderModel.getStatus().intValue()) {
						throw new PrologException("运单【" + tmsShipbillHeaderModel.getShipbillNo() + "】非待调度状态,调度失败");
					}
					loadingBillDetailModel.setCarrierShipbillStatus(DataDictionaryConstant.CARRIER_SHIPBILL_STATUS_DISPATCHED);
					tmsShipbillHeaderModel.setCarrierShipbillStatus(DataDictionaryConstant.CARRIER_SHIPBILL_STATUS_DISPATCHED);
					shipbillNodeTrackingSaveVO.setStatus(DataDictionaryConstant.CARRIER_SHIPBILL_STATUS_DISPATCHED);
					shipbillOperateLogSaveVO.setOldStatus(DataDictionaryConstant.CARRIER_SHIPBILL_STATUS_AUDITED);
					shipbillOperateLogSaveVO.setNewStatus(DataDictionaryConstant.CARRIER_SHIPBILL_STATUS_DISPATCHED);
					nodeEvent.append(DataDictionaryConstant.CARRIER_SHIPBILL_NODE_STATUSNAME_DI);
					// 判定是否调度后审核
					if (ToolKits.isNotEmpty(isAudit) && "Y".equals(isAudit[0])) {
						// 调度并审核
						autoDispatchCheck = true;
					} else {
						if (!autoDispatchCheck && tmsShipbillHeaderModel.getCarrierFlowConfig().contains(DataDictionaryConstant.FLOW_CONFIG_DISPATCH_CHECK)) {
							autoDispatchCheck = true;
						}
					}
				}
				loadingBillDetailModel.setId(loadingBillDetailId);
				loadingBillDetailModel.setLoadingBillId(loadingBillId);
				loadingBillDetailModel.setLoadingBillNo(loadingBillId);
				loadingBillDetailModel.setEnterpriseId(user.getEnterpriseId());
				loadingBillDetailModel.setEnterpriseName(user.getEnterpriseName());
				loadingBillDetailModel.setCreateperson(user.getNickname());
				loadingBillDetailModel.setCreatetime(date);
				loadingBillDetailModel.setUpdateperson(user.getNickname());
				loadingBillDetailModel.setUpdatetime(date);

				loadingBillDetailModel.setCarrierType(headerVO.getCarrierType());

				loadingBillDetailModel.setSource(tmsShipbillHeaderModel.getSource());
				nodeEvent.append(" ");
				if (DataDictionaryConstant.LINE_CARRIER_TYPE_CYF.equals(headerVO.getCarrierType())) {
					// 承运商
					nodeEvent.append(ToolKits.isEmpty(headerVO.getCarrierName()) ? "" : headerVO.getCarrierName());
					ShipbillFitBusinessFlowDTO flowData = shipbillMatchBusinessFlow(tmsShipbillHeaderModel, 1);
					tmsShipbillHeaderModel.setCarrierFlowConfig(flowData.getFlowConfig());

					tmsShipbillHeaderModel.setCarrierId(headerVO.getCarrierId());
					tmsShipbillHeaderModel.setCarrierCode(headerVO.getCarrierCode());
					tmsShipbillHeaderModel.setCarrierName(headerVO.getCarrierName());

					loadingBillDetailModel.setCarrierId(headerVO.getCarrierId());
					loadingBillDetailModel.setCarrierCode(headerVO.getCarrierCode());
					loadingBillDetailModel.setCarrierName(headerVO.getCarrierName());
				} else if (DataDictionaryConstant.LINE_CARRIER_TYPE_SJ.equals(headerVO.getCarrierType())) {
					// 司机
					nodeEvent.append(ToolKits.isEmpty(driverName) ? "" : driverName);
					nodeEvent.append(" ");
					// 送货员名称
					nodeEvent.append(ToolKits.isEmpty(deliverymanName) ? "" : deliverymanName);
					nodeEvent.append(" ");
					// 车牌号
					nodeEvent.append(ToolKits.isEmpty(headerVO.getVehiclePlateNumber()) ? "" : headerVO.getVehiclePlateNumber());
				}
				// 保存调度单明细
				loadingBillDetailModel.setFlowConfig(tmsShipbillHeaderModel.getFlowConfig());
				loadingBillDetailModel.setCarrierFlowConfig(tmsShipbillHeaderModel.getCarrierFlowConfig());

				// 车辆类别
				loadingBillDetailModel.setVehicleTypeCategory(headerVO.getVehicleTypeCategory());
				tmsShipbillHeaderModel.setVehicleTypeCategory(headerVO.getVehicleTypeCategory());
				// 车辆设备
				tmsShipbillHeaderModel.setVehicleDeviceId(headerVO.getVehicleDeviceId());
				tmsShipbillHeaderModel.setVehicleDeviceCode(headerVO.getVehicleDeviceCode());
				tmsShipbillHeaderModel.setVehicleDeviceName(headerVO.getVehicleDeviceName());

				loadingBillDetailModel.setVehicleDeviceId(headerVO.getVehicleDeviceId());
				loadingBillDetailModel.setVehicleDeviceCode(headerVO.getVehicleDeviceCode());
				loadingBillDetailModel.setVehicleDeviceName(headerVO.getVehicleDeviceName());
				if (tmsShipbillHeaderModel.getTemperatureRequirement().intValue() > DataDictionaryConstant.TEMPERATURE_REQUIREMENT_CW.intValue()) {
					// 容器
					loadingBillDetailModel.setContainerId(headerVO.getContainerId());
					loadingBillDetailModel.setContainerCode(headerVO.getContainerCode());
					loadingBillDetailModel.setContainerName(headerVO.getContainerName());

					tmsShipbillHeaderModel.setContainerId(headerVO.getContainerId());
					tmsShipbillHeaderModel.setContainerCode(headerVO.getContainerCode());
					tmsShipbillHeaderModel.setContainerName(headerVO.getContainerName());
				}
				List<LoadingBillDetailVO> details = detailVOS.stream().filter(d -> d.getShipbillId().equals(tmsShipbillHeaderModel.getShipbillId())).collect(Collectors.toList());
				if (ToolKits.isNotEmpty(details) && ToolKits.isNotEmpty(details.get(0).getShippingOrder())) {
					loadingBillDetailModel.setShippingOrder(details.get(0).getShippingOrder());
				}
				if (ToolKits.isNotEmpty(details) && ToolKits.isNotEmpty(details.get(0).getPickUpOrder())) {
					loadingBillDetailModel.setPickUpOrder(details.get(0).getPickUpOrder());
				}
				tmsLoadingBillDetailMapper.save(loadingBillDetailModel);
				// 运单调度
				tmsShipbillHeaderModel.setUpdateperson(user.getNickname());
				tmsShipbillHeaderModel.setUpdatetime(date);

				tmsShipbillHeaderModel.setCarrierType(headerVO.getCarrierType());
				tmsShipbillHeaderMapper.update(tmsShipbillHeaderModel);
				// 运单节点保存
				shipbillNodeTrackingSaveVO.setShipbillId(tmsShipbillHeaderModel.getShipbillId());
				shipbillNodeTrackingSaveVO.setShipbillNo(tmsShipbillHeaderModel.getShipbillNo());
				shipbillNodeTrackingSaveVO.setNodeEvent(nodeEvent.toString());
				// 获取节点ID
				RestMessage<String> restMessage = maindataTmsResource.getCodeNumberByCode(SeriaNnumberConstant.TMS_SHIPBILL_NODE_TRACKING_ID, "L");
				if (!restMessage.isSuccess()) {
					throw new RuntimeException("生成节点ID失败");
				}
				String id = restMessage.getData();
				shipbillNodeTrackingSaveVO.setId(id);
				shipbillNodeTrackingSaveVO.setUserId(user.getUserid());
				shipbillNodeTrackingSaveVO.setUserName(user.getNickname());
				shipbillNodeTrackingSaveVO.setEnterpriseId(user.getEnterpriseId());
				shipbillNodeTrackingSaveVO.setEnterpriseName(user.getEnterpriseName());
				shipbillNodeTrackingSaveVO.setCreateperson(user.getNickname());
				shipbillNodeTrackingSaveVO.setCreatetime(date);
				shipbillNodeTrackingSaveVO.setUpdateperson(user.getNickname());
				shipbillNodeTrackingSaveVO.setUpdatetime(date);
				shipbillNodeTrackingSaveVO.setNodeDate(date);
				tmsShipbillNodeTrackingMapper.save(shipbillNodeTrackingSaveVO);

				// 运单日志保存
				shipbillOperateLogSaveVO.setShipbillId(tmsShipbillHeaderModel.getShipbillId());
				shipbillOperateLogSaveVO.setShipbillNo(tmsShipbillHeaderModel.getShipbillNo());
				shipbillOperateLogSaveVO.setOperateEvent(nodeEvent.toString());
				// 获取日志ID
				RestMessage<String> restMessageLog = maindataTmsResource.getCodeNumberByCode(SeriaNnumberConstant.TMS_SHIPBILL_OPERATE_LOG_ID, "L");
				if (!restMessageLog.isSuccess()) {
					throw new RuntimeException("生成日志ID失败");
				}
				String idLog = restMessageLog.getData();

				// 日志记录
				shipbillOperateLogSaveVO.setId(idLog);
				shipbillOperateLogSaveVO.setOperateDate(date);
				shipbillOperateLogSaveVO.setUserId(user.getUserid());
				shipbillOperateLogSaveVO.setUserName(user.getNickname());
				shipbillOperateLogSaveVO.setEnterpriseId(user.getEnterpriseId());
				shipbillOperateLogSaveVO.setEnterpriseName(user.getEnterpriseName());
				shipbillOperateLogSaveVO.setCreateperson(user.getNickname());
				shipbillOperateLogSaveVO.setCreatetime(date);
				shipbillOperateLogSaveVO.setUpdateperson(user.getNickname());
				shipbillOperateLogSaveVO.setUpdatetime(date);
				tmsShipbillOperateLogMapper.save(shipbillOperateLogSaveVO);

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

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

				totalWholePiece = totalWholePiece + (ToolKits.isEmpty(tmsShipbillHeaderModel.getPackageWholePiece()) ? 0 : tmsShipbillHeaderModel.getPackageWholePiece().intValue());
				totalLclPiece = totalLclPiece + (ToolKits.isEmpty(tmsShipbillHeaderModel.getPackageLclPiece()) ? 0 : tmsShipbillHeaderModel.getPackageLclPiece().intValue());

				loadingBillHeaderModel.setTotalPcs(loadingBillHeaderModel.getTotalPcs().add(tmsShipbillHeaderModel.getTotalPcs()));
				loadingBillHeaderModel.setTotalVolume(loadingBillHeaderModel.getTotalVolume().add(tmsShipbillHeaderModel.getTotalVolume()));
				loadingBillHeaderModel.setTotalWeight(loadingBillHeaderModel.getTotalWeight().add(tmsShipbillHeaderModel.getTotalWeight()));
				loadingBillHeaderModel.setActualTotalPcs(loadingBillHeaderModel.getActualTotalPcs().add(tmsShipbillHeaderModel.getActualTotalPcs()));
				loadingBillHeaderModel.setActualTotalVolume(loadingBillHeaderModel.getActualTotalVolume().add(tmsShipbillHeaderModel.getActualTotalVolume()));
				loadingBillHeaderModel.setActualTotalWeight(loadingBillHeaderModel.getActualTotalWeight().add(tmsShipbillHeaderModel.getActualTotalWeight()));
			}
			// 总整件数
			loadingBillHeaderModel.setTotalWholePiece(BigDecimal.valueOf(totalWholePiece));
			// 总拼箱数
			loadingBillHeaderModel.setTotalLclPiece(BigDecimal.valueOf(totalLclPiece));

			loadingBillHeaderModel.setColdShipbillNumber(coldShipbillNumber);
			loadingBillHeaderModel.setCargoOwnerNumber(cargoOwnerNumber);
			loadingBillHeaderModel.setUrgentShipbillNumber(urgentShipbillNumber);
			loadingBillHeaderModel.setShipbillNumber(shipbillHeaderModelList.size());

			loadingBillHeaderModel.setPickupStations(pickupStations);
			loadingBillHeaderModel.setDeliveryStations(deliveryStations);
			loadingBillHeaderModel.setTotalStations(pickupStations + deliveryStations);

			loadingBillHeaderModel.setVehicleTypeCategory(headerVO.getVehicleTypeCategory());
			loadingBillHeaderModel.setVehicleAffiliationId(headerVO.getVehicleAffiliationId());
			loadingBillHeaderModel.setVehicleAffiliationCode(headerVO.getVehicleAffiliationCode());
			loadingBillHeaderModel.setVehicleAffiliationName(headerVO.getVehicleAffiliationName());

			loadingBillHeaderModel.setVehicleDeviceId(headerVO.getVehicleDeviceId());
			loadingBillHeaderModel.setVehicleDeviceCode(headerVO.getVehicleDeviceCode());
			loadingBillHeaderModel.setVehicleDeviceName(headerVO.getVehicleDeviceName());
			loadingBillHeaderModel.setScanStatus(DataDictionaryConstant.SCAN_STATUS_INIT);

			loadingBillHeaderModel.setContainerId(headerVO.getContainerId());
			loadingBillHeaderModel.setContainerCode(headerVO.getContainerCode());
			loadingBillHeaderModel.setContainerName(headerVO.getContainerName());
			loadingBillHeaderModel.setMemo(headerVO.getMemo());
			// 总里程 根据站点间的距离计算
			loadingBillHeaderModel.setTotalMileage(headerVO.getTotalMileage());
			// 地图总里程 页面上根据地图计算
			loadingBillHeaderModel.setTotalMileageMap(headerVO.getTotalMileageMap());
			loadingBillHeaderModel.setDeliveryLines(headerVO.getDeliveryLines());

			if (DataDictionaryConstant.LINE_CARRIER_TYPE_SJ.equals(loadingBillHeaderModel.getCarrierType())) {
				loadingBillHeaderModel.setCarrierSysFlag(DataDictionaryConstant.CARRIER_SYS_FLAG_INNER);
			} else {
				if (ToolKits.isNotEmpty(headerVO.getCarrierSysFlag())) {
					loadingBillHeaderModel.setCarrierSysFlag(headerVO.getCarrierSysFlag());
				} else {
					RestMessage<CarrierCheckDTO> restMessageCarrierInfo = maindataTmsResource.getCarrierExecute(loadingBillHeaderModel.getCarrierId());
					if (!restMessageCarrierInfo.isSuccess()) {
						throw new RuntimeException("调用承运商信息查询服务失败");
					}
					CarrierCheckDTO CarrierInfo = restMessageCarrierInfo.getData();
					loadingBillHeaderModel.setCarrierSysFlag(CarrierInfo.getCarrierSysFlag());
				}
			}
			loadingBillHeaderModel.setVehicleAscription(headerVO.getVehicleAscription());
			tmsLoadingBillHeaderMapper.save(loadingBillHeaderModel);
			// 更新站点数
			loadingBillService.updateStationByLoadingBillId(loadingBillHeaderModel.getLoadingBillId());
			MessageTypeEnum messageTypeEnum = MessageTypeEnum.SELF_DISPATCH;
			if (user.getUserType().equals(BussinessConstant.USER_TYPE_CYS)) {
				messageTypeEnum = MessageTypeEnum.CARRIER_DISPATCH;
			}
			MessageUtil.addMessage(new SendMessageDTO(MessageOrderTypeEnum.LOADING_NO.getCode(), messageTypeEnum.getCode(), Lists.newArrayList(loadingBillId)));
			// 调度后自动审核
			if (autoDispatchCheck) {
				ids.add(loadingBillId);
			}
		}
		if (BussinessConstant.USER_TYPE_ZY.equals(user.getUserType()) && ToolKits.isEmpty(isPlanDis)) {
			try {
				updatePlanBill(shipbillIds, user);
			} catch (Exception e) {
				log.info(ExceptionUtil.stacktraceToString(e));
			}
		}

		if (ToolKits.isNotEmpty(ids)) {
			if (DataDictionaryConstant.LINE_CARRIER_TYPE_SJ.equals(headerVO.getCarrierType())) {
				// 调用派车单审核
				sendCarService.autoSendcarAuditData(ids, user, date);
			} else {
				// 调用托运单审核
				trailerService.autoTrailerAuditData(ids, user, date);
			}
		}
	}

	public void updatePlanBill(List<String> shipbillIds,UserEntity user) {
		Criteria criteriaPlanBillDetail = Criteria.forClass(TmsTransPlanBillDetailModel.class);
		Restriction r1 = Restrictions.in(TmsTransPlanBillDetailModel::getShipbillId, shipbillIds.stream().toArray());
		Restriction r2 = Restrictions.eq(TmsTransPlanBillDetailModel::getStatus, 10);
		criteriaPlanBillDetail.setRestriction(Restrictions.and(r1,r2));
		List<TmsTransPlanBillDetailModel> planBillDetailModels = tmsTransPlanBillDetailMapper.findByCriteria(criteriaPlanBillDetail);
		if (ToolKits.isEmpty(planBillDetailModels)) {
			return;
		}
		Map<String, Object> mapUpdate = Maps.newHashMap();
		mapUpdate.put("updateperson", user.getNickname());
		mapUpdate.put("updatetime", DateUtils.nowDate());
		mapUpdate.put("status", 20);
		tmsTransPlanBillDetailMapper.updateMapByCriteria(mapUpdate,criteriaPlanBillDetail);

		List<String> planBillIds = planBillDetailModels.stream().map(TmsTransPlanBillDetailModel::getPlanBillId).distinct().collect(Collectors.toList());

		planBillIds.stream().forEach(planBillId->{
			Restriction r3 = Restrictions.eq(TmsTransPlanBillDetailModel::getPlanBillId, planBillId);
			criteriaPlanBillDetail.setRestriction(Restrictions.and(r3));
			List<TmsTransPlanBillDetailModel> detailModels = tmsTransPlanBillDetailMapper.findByCriteria(criteriaPlanBillDetail);
			List<String> otherShipBillIds = detailModels.stream().filter(shipBill->!shipbillIds.contains(shipBill.getShipbillId())).map(TmsTransPlanBillDetailModel::getShipbillId).collect(Collectors.toList());
			if (ToolKits.isNotEmpty(otherShipBillIds)) {
				List<TmsShipbillHeaderModel> headerModels = tmsShipbillHeaderMapper.findByIds(TmsShipbillHeaderModel.class,otherShipBillIds.stream().toArray(),null);
			    if (headerModels.stream().allMatch(model->model.getStatus().intValue() > 30 ||
						DataDictionaryConstant.SPLIT_ORDER_TYPE_UN.equals(model.getSplitOrderStatus()))) {
					tmsTransPlanBillHeaderMapper.updateMapById(planBillId,mapUpdate,TmsTransPlanBillHeaderModel.class);
				} else {
					mapUpdate.put("status", 15);
					tmsTransPlanBillHeaderMapper.updateMapById(planBillId,mapUpdate,TmsTransPlanBillHeaderModel.class);
				}
			} else {
				tmsTransPlanBillHeaderMapper.updateMapById(planBillId,mapUpdate,TmsTransPlanBillHeaderModel.class);
			}
		});
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void dispatch(PendingDispatchVO vo) {
		ToolKits.isParamNull(vo, "运单调度请求不为空");

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

	/**
	 * 调度并审核
	 *
	 * @param vo
	 * @return
	 */
	@Transactional(rollbackFor = Exception.class)
	@Override
	public void dispatchReview(PendingDispatchVO vo) {
		ToolKits.isParamNull(vo, "运单调度请求不为空");
		ToolKits.isParamNull(vo.getLoadingBillHeaderVO(), "运单调度承运方不为空");
		ToolKits.isParamNull(vo.getLoadingBillDetailVO(), "运单调度明细不为空");

		UserEntity user = PlgFxUsrUtils.getUserEntity();
		ToolKits.isParamNull(user, "当前人员没有操作权限");
		Date date = DateUtils.nowDate();
		// 装车单汇总
		PendingDispatchVO dispatchVO = new PendingDispatchVO();
		dispatchVO.setLoadingBillHeaderVO(vo.getLoadingBillHeaderVO());
		dispatchVO.setLoadingBillDetailVO(vo.getLoadingBillDetailVO());
		autoDispatch(dispatchVO, user, date, "","Y");
	}

	/**
	 * 获取调度单号
	 *
	 * @param
	 * @return
	 */
	public String getDispatchNumber() {
		RestMessage<String> restMessage1 = maindataTmsResource.getCodeNumberByCode(SeriaNnumberConstant.TMS_LOADING_BILL_HEADER_ID, "L");
		if (!restMessage1.isSuccess()) {
			throw new RuntimeException("生成调度单号失败");
		}
		return restMessage1.getData();
	}

	/**
	 * 分组调度
	 *
	 * @param groupPendingDispatchVOs
	 * @return
	 */
	@Override
	public void groupDispatch(List<GroupPendingDispatchVO> groupPendingDispatchVOs) {
		ToolKits.isParamNull(groupPendingDispatchVOs, "运单调度请求不为空");
		UserEntity user = PlgFxUsrUtils.getUserEntity();
		ToolKits.isParamNull(user, "当前人员没有操作权限");
		// 当前时间
		Date date = DateUtil.date();
		TimeInterval timer = DateUtil.timer();
		String userkey = HystrixVarUtil.getUserKey();
		log.info("【分组调度】userkey=" + userkey);
		for (GroupPendingDispatchVO vo : groupPendingDispatchVOs) {
			// 装车单汇总
			if (ToolKits.isEmpty(vo.getLoadingBillHeaderVO()) || ToolKits.isEmpty(vo.getLoadingBillDetailVO())) {
				continue;
			}
			PendingDispatchVO dispatchVO = new PendingDispatchVO();
			dispatchVO.setLoadingBillHeaderVO(vo.getLoadingBillHeaderVO());
			dispatchVO.setLoadingBillDetailVO(vo.getLoadingBillDetailVO());
			executor.submit(() -> {
				DefaultTransactionDefinition defaultTransactionDefinition = new DefaultTransactionDefinition();
				defaultTransactionDefinition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
				TransactionStatus transaction = dataSourceTransactionManager.getTransaction(defaultTransactionDefinition);
				try {
					HystrixRequestContext.initializeContext();
					HystrixVarUtil.setUserKey(userkey);
					dispatchForThread(dispatchVO, user, date);
					dataSourceTransactionManager.commit(transaction);
				} catch (Exception e) {
					List<String> shipbills = vo.getLoadingBillDetailVO().stream().map(LoadingBillDetailVO::getShipbillId).collect(Collectors.toList());
					log.error("分组调度失败={}", JSON.toJSONString(shipbills.stream().collect(Collectors.joining(","))), e);
					dataSourceTransactionManager.rollback(transaction);
				}
			});
		}
		log.warn("分组调度时间=======" + timer.interval());
	}

	/**
	 * 分组调度并审核
	 *
	 * @param groupDispatchReviewVOs
	 * @return
	 */
	@Override
	public void groupDispatchReview(List<GroupPendingDispatchReviewVO> groupDispatchReviewVOs) {
		ToolKits.isParamNull(groupDispatchReviewVOs, "运单调度请求不为空");

		UserEntity user = PlgFxUsrUtils.getUserEntity();
		ToolKits.isParamNull(user, "当前人员没有操作权限");
		// 当前时间
		Date date = DateUtil.date();
		TimeInterval timer = DateUtil.timer();
		String userkey = HystrixVarUtil.getUserKey();
		log.info("【分组调度并审核】userkey=" + userkey);
		for (GroupPendingDispatchReviewVO vo : groupDispatchReviewVOs) {
			// 装车单汇总
			if (ToolKits.isEmpty(vo.getLoadingBillHeaderVO()) || ToolKits.isEmpty(vo.getLoadingBillDetailVO())) {
				continue;
			}
			PendingDispatchVO dispatchVO = new PendingDispatchVO();
			dispatchVO.setLoadingBillHeaderVO(vo.getLoadingBillHeaderVO());
			dispatchVO.setLoadingBillDetailVO(vo.getLoadingBillDetailVO());
			executor.submit(() -> {
				DefaultTransactionDefinition defaultTransactionDefinition = new DefaultTransactionDefinition();
				defaultTransactionDefinition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
				TransactionStatus transaction = dataSourceTransactionManager.getTransaction(defaultTransactionDefinition);
				try {
					HystrixRequestContext.initializeContext();
					HystrixVarUtil.setUserKey(userkey);
					dispatchForThread(dispatchVO, user, date, "Y");
					dataSourceTransactionManager.commit(transaction);
				} catch (Exception e) {
					List<String> shipbills = vo.getLoadingBillDetailVO().stream().map(LoadingBillDetailVO::getShipbillId).collect(Collectors.toList());
					log.error("分组调度失败={}", JSON.toJSONString(shipbills.stream().collect(Collectors.joining(","))), e);
					dataSourceTransactionManager.rollback(transaction);
				}
			});
		}
		log.warn("分组调度并审核时间=======" + timer.interval());
	}

	/**
	 * 系统分组-查询
	 *
	 * @param vo
	 * @return
	 */
	@Override
	public SysGroupQueryRsDTO sysGroupNewQuery(SysGroupQueryVO vo) {
		ToolKits.isParamNull(vo, "系统分组查询请求不为空");
		UserEntity user = PlgFxUsrUtils.getUserEntity();
		ToolKits.isParamNull(user, "当前人员没有操作权限");
		TimeInterval timer = DateUtil.timer();

		SysGroupQueryRsDTO sysGroupQueryRsDTO = new SysGroupQueryRsDTO();
		if (ToolKits.isNotEmpty(vo.getCargoOwnerIds())) {
			String[] ids = vo.getCargoOwnerIds().split(",");
			vo.setCargoOwnerIdList(Arrays.stream(ids).map(id -> Long.valueOf(id)).collect(Collectors.toList()));
		}
		if (ToolKits.isNotEmpty(vo.getLineIds())) {
			String[] ids = vo.getLineIds().split(",");
			vo.setLineIdList(Arrays.stream(ids).map(id -> Long.valueOf(id)).collect(Collectors.toList()));
		}
		List<ZoneVO> shipperAdministrativeAreas = vo.getShipperAdministrativeAreas();
		if (ToolKits.isNotEmpty(shipperAdministrativeAreas)) {
			List<String> provinceList = parseCode(shipperAdministrativeAreas, "province");
			if (ToolKits.isNotEmpty(provinceList)) {
				vo.setShipperProvinceList(provinceList);
			}
			List<String> cityList = parseCode(shipperAdministrativeAreas, "city");
			if (ToolKits.isNotEmpty(cityList)) {
				vo.setShipperCityList(cityList);
			}
			List<String> districtList = parseCode(shipperAdministrativeAreas, "district");
			if (ToolKits.isNotEmpty(districtList)) {
				vo.setShipperDistrictList(districtList);
			}
		}
		List<ZoneVO> consigneeAdministrativeAreas = vo.getAdministrativeAreas();
		if (ToolKits.isNotEmpty(consigneeAdministrativeAreas)) {
			List<String> provinceList = parseCode(consigneeAdministrativeAreas, "province");
			if (ToolKits.isNotEmpty(provinceList)) {
				vo.setConsigneeProvinceList(provinceList);
			}
			List<String> cityList = parseCode(consigneeAdministrativeAreas, "city");
			if (ToolKits.isNotEmpty(cityList)) {
				vo.setConsigneeCityList(cityList);
			}
			List<String> districtList = parseCode(consigneeAdministrativeAreas, "district");
			if (ToolKits.isNotEmpty(districtList)) {
				vo.setConsigneeDistrictList(districtList);
			}
		}
		vo.setUserType(user.getUserType());
		vo.setEnterpriseId(user.getEnterpriseId());
		if (ObjectUtil.equal(user.getUserType(), BussinessConstant.USER_TYPE_ZY)) {// 自有账号
			vo.setDepts(ToolKits.isEmpty(user.getDepts()) ? null : user.getDepts().stream().toArray(String[]::new));
			if (BussinessConstant.USER_DEPARTMENT_AUTH_Y.equals(user.getOwnedAllDataAuthFlag())) {// 部门权限
				vo.setIsDept("YES");
			} else {// 业务员权限
				vo.setIsDept("NO");
				// 货主
				vo.setConsignors(ToolKits.isEmpty(user.getConsignors()) ? null : user.getConsignors().stream().toArray(Long[]::new));
				// 客户
				vo.setCustomers(ToolKits.isEmpty(user.getCustomers()) ? null : user.getCustomers().stream().toArray(Long[]::new));
				// 供应商
				vo.setSuppliers(ToolKits.isEmpty(user.getSuppliers()) ? null : user.getSuppliers().stream().toArray(Long[]::new));
				// 仓库
				vo.setWsarehouses(ToolKits.isEmpty(user.getWarehouses()) ? null : user.getWarehouses().stream().toArray(Long[]::new));
			}
		} else if (ObjectUtil.equal(user.getUserType(), BussinessConstant.USER_TYPE_CYS)) {// 承运商账号
			vo.setCarrierId(Long.valueOf(user.getLoginUserCompanyInfo().getId()));
		}
		List<String> groupDimensions = vo.getGroupDimensionList();
		List<SysGroupQueryDTO> sysGroupQueryList = Lists.newArrayList();
		// 数据字典翻译数据集合
		List<SysRefdatadModel> dicData = convertorUtil.getDictionary(new String[] { DataDictionaryConstant.TEMPERATURE_REQUIREMENT, // 温度要求
				DataDictionaryConstant.GROUP_DISPATCH_NEW, // 分组调度
				DataDictionaryConstant.LINE_DIRECTION, // 线路方向
				DataDictionaryConstant.ORDER_BUSINESS_TYPE // 订单业务类型
		});
		String groupItems = null;
		List<SysRefdatadModel> groupByItems = dicData.stream().filter(data -> DataDictionaryConstant.GROUP_DISPATCH_NEW.equals(data.getObjectcode())).collect(Collectors.toList());
		if (ToolKits.isNotEmpty(groupDimensions)) {
			// 页面勾选的分组项目
			groupByItems = groupByItems.stream().filter(item -> groupDimensions.contains(item.getCode())).collect(Collectors.toList());
			groupByItems = groupByItems.stream().sorted(Comparator.comparing(SysRefdatadModel::getSortnum)).collect(Collectors.toList());
			String groupItem = groupByItems.stream().map(SysRefdatadModel::getCode).collect(Collectors.joining(","));
			groupItems = "t1." + groupByItems.stream().map(SysRefdatadModel::getCode).collect(Collectors.joining(",t1."));
			String groupItemName = groupByItems.stream().map(SysRefdatadModel::getName).collect(Collectors.joining(" "));
			vo.setQueryGroupItems(groupItems + ",");
			vo.setGroupByItems(groupItems);
			sysGroupQueryList = tmsShipbillHeaderMapper.sysGroupQuery(vo);
			sysGroupQueryList.stream().forEach(oneDTO -> {
				setGroupInfo(oneDTO, dicData,groupItemName);
				oneDTO.setGroupDimensionList(groupDimensions);
				oneDTO.setGroupNumber(0);
				oneDTO.setGroupItem(groupItem);
				if (ToolKits.isNotEmpty(oneDTO.getTotalPickUpSiteQty())) {
					oneDTO.setTotalSitQty(oneDTO.getTotalPickUpSiteQty());
				} else {
					oneDTO.setTotalSitQty(0);
				}
				if (ToolKits.isNotEmpty(oneDTO.getTotalDeliverySiteQty())) {
					oneDTO.setTotalSitQty(oneDTO.getTotalSitQty().intValue() + oneDTO.getTotalDeliverySiteQty().intValue());
				}
			});
			String[] groupItemNames = groupItemName.split(" ");
			sysGroupQueryRsDTO.setGroupItemNames(Arrays.stream(groupItemNames).collect(Collectors.toList()));

		} else if (ToolKits.isNotEmpty(vo.getGroupConfigName())) {
			if (ToolKits.isEmpty(vo.getGroupConfigName()) || ToolKits.isEmpty(vo.getGroupNumber())) {
				throw new PrologException("分组配置信息不能为空");
			}
			// 设置的分组项目
			SysGroupCfgVO cfgVO = new SysGroupCfgVO();
			cfgVO.setGroupName(vo.getGroupConfigName());
			cfgVO.setGroupNumber(vo.getGroupNumber());
			List<SysGroupCfgHdrDTO> groupCfgHdrDTOS = sysGroupCfgService.queryGroupCfg(cfgVO);
			if (ToolKits.isEmpty(groupCfgHdrDTOS)) {
				throw new PrologException("用户的分组设置不存在");
			}
			if (ToolKits.isEmpty(vo.getGroupConfigName()) && ToolKits.isNotEmpty(groupCfgHdrDTOS) && groupCfgHdrDTOS.size() > 1) {
				throw new PrologException("默认分组设置【" + groupCfgHdrDTOS.stream().map(SysGroupCfgHdrDTO::getGroupName).collect(Collectors.joining(",")) + "】存在多个");
			}
			List<SysGroupCfgDtlDTO> groupCfgDtlDTOList = groupCfgHdrDTOS.get(0).getGroupCfgDtlDTOList();
			if (ToolKits.isEmpty(groupCfgDtlDTOList)) {
				throw new PrologException("分组设置的分组项目不存在");
			}

			if (ToolKits.isEmpty(groupCfgHdrDTOS.get(0).getTotalLevel())) {
				throw new PrologException("分组设置不正确,请重新设置");
			}
			sysGroupQueryRsDTO.setGroupCfgDTOS(groupCfgDtlDTOList);
			sysGroupQueryRsDTO.setGroupItemNames(groupCfgHdrDTOS.get(0).getGroupItemNames());
			// 下一个分组顺序
			Integer nextGroupNumber = 0;
			Integer cfgNumber = groupCfgDtlDTOList.get(0).getGroupNumber();
			if (cfgNumber.intValue() < groupCfgHdrDTOS.get(0).getTotalLevel().intValue()) {
				nextGroupNumber = cfgNumber.intValue() + 1;
			}
			// 分组调度查
			groupItems = groupCfgDtlDTOList.get(0).getGroupItem();
			String finalGroupItems = groupItems;
			groupByItems = groupByItems.stream().filter(item -> finalGroupItems.contains(item.getCode())).collect(Collectors.toList());
			groupItems = groupItems.replaceAll(",", ",t1.");
			groupItems = "t1." + groupItems;
			vo.setQueryGroupItems(groupItems + ",");
			vo.setGroupByItems(groupItems);
			sysGroupQueryList = tmsShipbillHeaderMapper.sysGroupQuery(vo);
			Integer finalNextGroupNumber = nextGroupNumber;
			String groupItem = groupByItems.stream().map(SysRefdatadModel::getCode).collect(Collectors.joining(" "));
			String groupItemName = groupByItems.stream().map(SysRefdatadModel::getName).collect(Collectors.joining(" "));
			sysGroupQueryList.stream().forEach(oneDTO -> {
				setGroupInfo(oneDTO, dicData,groupItemName);
				oneDTO.setGroupConfigName(groupCfgHdrDTOS.get(0).getGroupName());
				oneDTO.setGroupNumber(finalNextGroupNumber);
				oneDTO.setGroupItem(groupItem);
				if (ToolKits.isNotEmpty(oneDTO.getTotalPickUpSiteQty())) {
					oneDTO.setTotalSitQty(oneDTO.getTotalPickUpSiteQty());
				} else {
					oneDTO.setTotalSitQty(0);
				}
				if (ToolKits.isNotEmpty(oneDTO.getTotalDeliverySiteQty())) {
					oneDTO.setTotalSitQty(oneDTO.getTotalSitQty().intValue() + oneDTO.getTotalDeliverySiteQty().intValue());
				}
			});
		} else {
			throw new PrologException("分组配置或者类型条件,请选择一个");
		}
		sysGroupQueryRsDTO.setGroupQueryDTOS(sysGroupQueryList);
		log.warn("分组查询时间=======" + timer.interval());
		return sysGroupQueryRsDTO;
	}

	public void setGroupInfo(SysGroupQueryDTO groupQueryDTO, List<SysRefdatadModel> dicData,String groupItemName) {
		// 分组名称
		List<String> groupNames = Lists.newArrayList();
		Field[] fields = groupQueryDTO.getClass().getFields();
		for (Field field : fields) {
			try {
				Object val = field.get(groupQueryDTO);
				if (ToolKits.isNotEmpty(val) && "orderBusinessType".equals(field.getName())) {
					groupNames.add(ConvertorUtil.getName(dicData, DataDictionaryConstant.ORDER_BUSINESS_TYPE, String.valueOf(val)));
				} else if (ToolKits.isNotEmpty(val) && "temperatureRequirement".equals(field.getName())) {
					groupNames.add(ConvertorUtil.getName(dicData, DataDictionaryConstant.TEMPERATURE_REQUIREMENT, String.valueOf(val)));
				}  else if (ToolKits.isNotEmpty(val) && "lineDirection".equals(field.getName())) {
					groupNames.add(ConvertorUtil.getName(dicData, DataDictionaryConstant.LINE_DIRECTION, String.valueOf(val)));
				}  else if (ToolKits.isNotEmpty(val)) {
					groupNames.add((String) val);
				}
			} catch (Exception e) {}
		}

		if (ToolKits.isNotEmpty(groupNames)) {
			groupQueryDTO.setGroupName(groupNames.stream().collect(Collectors.joining(",")));
		} else {
			groupQueryDTO.setGroupName(groupItemName);
		}
		groupQueryDTO.setGroupItemName(groupItemName);

		groupQueryDTO.setId(ToolKits.getUUID());

		String shipbillIds = groupQueryDTO.getShipbillIds();
		if (ToolKits.isEmpty(shipbillIds)) {
			return;
		}
		List<SysGroupShipbillQueryDTO> sysGroupShipQueryList = tmsShipbillHeaderMapper.sysGroupShipbillsQuery(Arrays.stream(shipbillIds.split(",")).collect(Collectors.toList()));
		if (ToolKits.isEmpty(sysGroupShipQueryList)) {
			return;
		}
		// 货主数
		groupQueryDTO.setCargoOwnerQty(sysGroupShipQueryList.stream().map(SysGroupShipbillQueryDTO::getCargoOwnerName).distinct().collect(Collectors.toList()).size());
		// 运单数
		groupQueryDTO.setShipbillQty(sysGroupShipQueryList.size());
		// 收货方数
		groupQueryDTO.setConsigneeQty(sysGroupShipQueryList.stream().map(SysGroupShipbillQueryDTO::getConsigneeUnitName).distinct().collect(Collectors.toList()).size());
		// 总提货点数
		groupQueryDTO.setTotalPickUpSiteQty(sysGroupShipQueryList.stream().map(SysGroupShipbillQueryDTO::getShipperAddress).distinct().collect(Collectors.toList()).size());
		// 总配送点数
		groupQueryDTO.setTotalDeliverySiteQty(sysGroupShipQueryList.stream().map(SysGroupShipbillQueryDTO::getConsigneeAddress).distinct().collect(Collectors.toList()).size());
		// 总站数
		groupQueryDTO.setTotalSitQty(groupQueryDTO.getTotalPickUpSiteQty().intValue() + groupQueryDTO.getTotalDeliverySiteQty().intValue());
		// 冷链运单数
		long coldChainShipbillQty = sysGroupShipQueryList.stream().filter(s -> ToolKits.isNotEmpty(s.getTemperatureRequirement()) && s.getTemperatureRequirement().intValue() > 1).collect(Collectors.toList()).size();
		groupQueryDTO.setColdChainShipbillQty(Integer.valueOf(new Long(coldChainShipbillQty).intValue()));

		// 紧急加急运单数
		long urgentShipbillQty = sysGroupShipQueryList.stream().filter(s -> ToolKits.isNotEmpty(s.getOrderType()) && s.getOrderType().intValue() > 1).collect(Collectors.toList()).size();
		groupQueryDTO.setUrgentShipbillQty(Integer.valueOf(new Long(urgentShipbillQty).intValue()));

		BigDecimal pcs1 = sysGroupShipQueryList.stream().filter(dto -> ToolKits.isNotEmpty(dto.getTotalPcs())).map(SysGroupShipbillQueryDTO::getTotalPcs).reduce(BigDecimal.ZERO, BigDecimal::add);
		BigDecimal pcs2 = sysGroupShipQueryList.stream().filter(dto -> ToolKits.isNotEmpty(dto.getPackageLclPiece())).map(SysGroupShipbillQueryDTO::getPackageLclPiece).reduce(BigDecimal.ZERO, BigDecimal::add);
		groupQueryDTO.setTotalLclPieceQty(pcs2.intValue());

		BigDecimal pcs3 = sysGroupShipQueryList.stream().filter(dto -> ToolKits.isNotEmpty(dto.getPackageWholePiece())).map(SysGroupShipbillQueryDTO::getPackageWholePiece).reduce(BigDecimal.ZERO, BigDecimal::add);
		groupQueryDTO.setTotalWholePieceQty(pcs3.intValue());

		BigDecimal weigth1 = sysGroupShipQueryList.stream().filter(dto -> ToolKits.isNotEmpty(dto.getTotalWeight())).map(SysGroupShipbillQueryDTO::getTotalWeight).reduce(BigDecimal.ZERO, BigDecimal::add);
		BigDecimal weigth2 = sysGroupShipQueryList.stream().filter(dto -> ToolKits.isNotEmpty(dto.getPackageTotalWeight())).map(SysGroupShipbillQueryDTO::getPackageTotalWeight).reduce(BigDecimal.ZERO, BigDecimal::add);
		BigDecimal volume1 = sysGroupShipQueryList.stream().filter(dto -> ToolKits.isNotEmpty(dto.getTotalVolume())).map(SysGroupShipbillQueryDTO::getTotalVolume).reduce(BigDecimal.ZERO, BigDecimal::add);
		BigDecimal volume2 = sysGroupShipQueryList.stream().filter(dto -> ToolKits.isNotEmpty(dto.getPackageTotalVolume())).map(SysGroupShipbillQueryDTO::getPackageTotalVolume).reduce(BigDecimal.ZERO, BigDecimal::add);

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

		// 标记语
		if (sysGroupShipQueryList.stream().filter(dto->ToolKits.isNotEmpty(dto.getRecordTagWord())).map(SysGroupShipbillQueryDTO::getRecordTagWord).distinct().collect(Collectors.toList()).size() == 1) {
			groupQueryDTO.setRecordTagWord(sysGroupShipQueryList.get(0).getRecordTagWord());
		}
		// 配送顺序
		if (sysGroupShipQueryList.stream().filter(dto->ToolKits.isNotEmpty(dto.getConsigneeDeliveryOrder())).map(SysGroupShipbillQueryDTO::getConsigneeDeliveryOrder).distinct().collect(Collectors.toList()).size() == 1) {
			groupQueryDTO.setShippingOrder(sysGroupShipQueryList.get(0).getConsigneeDeliveryOrder());
		}
	}

	/**
	 * 调度前运单地图站点信息查询
	 *
	 * @param vo
	 */
	public ShipbillMapDTO shipbillMapSiteQuery(SysGroupQueryVO vo) {
		ToolKits.isParamNull(vo, "运单地图站点信息查询请求不为空");

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

		if (ToolKits.isNotEmpty(vo.getCargoOwnerIds())) {
			String[] ids = vo.getCargoOwnerIds().split(",");
			vo.setCargoOwnerIdList(Arrays.stream(ids).map(id -> Long.valueOf(id)).collect(Collectors.toList()));
		}
		if (ToolKits.isNotEmpty(vo.getLineIds())) {
			String[] ids = vo.getLineIds().split(",");
			vo.setLineIdList(Arrays.stream(ids).map(id -> Long.valueOf(id)).collect(Collectors.toList()));
		}
		List<ZoneVO> shipperAdministrativeAreas = vo.getShipperAdministrativeAreas();
		if (ToolKits.isNotEmpty(shipperAdministrativeAreas)) {
			List<String> provinceList = parseCode(shipperAdministrativeAreas, "province");
			if (ToolKits.isNotEmpty(provinceList)) {
				vo.setShipperProvinceList(provinceList);
			}
			List<String> cityList = parseCode(shipperAdministrativeAreas, "city");
			if (ToolKits.isNotEmpty(cityList)) {
				vo.setShipperCityList(cityList);
			}
			List<String> districtList = parseCode(shipperAdministrativeAreas, "district");
			if (ToolKits.isNotEmpty(districtList)) {
				vo.setShipperDistrictList(districtList);
			}
		}
		List<ZoneVO> consigneeAdministrativeAreas = vo.getAdministrativeAreas();
		if (ToolKits.isNotEmpty(consigneeAdministrativeAreas)) {
			List<String> provinceList = parseCode(consigneeAdministrativeAreas, "province");
			if (ToolKits.isNotEmpty(provinceList)) {
				vo.setConsigneeProvinceList(provinceList);
			}
			List<String> cityList = parseCode(consigneeAdministrativeAreas, "city");
			if (ToolKits.isNotEmpty(cityList)) {
				vo.setConsigneeCityList(cityList);
			}
			List<String> districtList = parseCode(consigneeAdministrativeAreas, "district");
			if (ToolKits.isNotEmpty(districtList)) {
				vo.setConsigneeDistrictList(districtList);
			}
		}
		vo.setUserType(user.getUserType());
		vo.setEnterpriseId(user.getEnterpriseId());
		if (ObjectUtil.equal(user.getUserType(), BussinessConstant.USER_TYPE_ZY)) {// 自有账号
			vo.setDepts(ToolKits.isEmpty(user.getDepts()) ? null : user.getDepts().stream().toArray(String[]::new));
			if (BussinessConstant.USER_DEPARTMENT_AUTH_Y.equals(user.getOwnedAllDataAuthFlag())) {// 部门权限
				vo.setIsDept("YES");
			} else {// 业务员权限
				vo.setIsDept("NO");
				// 货主
				vo.setConsignors(ToolKits.isEmpty(user.getConsignors()) ? null : user.getConsignors().stream().toArray(Long[]::new));
				// 客户
				vo.setCustomers(ToolKits.isEmpty(user.getCustomers()) ? null : user.getCustomers().stream().toArray(Long[]::new));
				// 供应商
				vo.setSuppliers(ToolKits.isEmpty(user.getSuppliers()) ? null : user.getSuppliers().stream().toArray(Long[]::new));
				// 仓库
				vo.setWsarehouses(ToolKits.isEmpty(user.getWarehouses()) ? null : user.getWarehouses().stream().toArray(Long[]::new));
			}
		} else if (ObjectUtil.equal(user.getUserType(), BussinessConstant.USER_TYPE_CYS)) {// 承运商账号
			vo.setCarrierId(Long.valueOf(user.getLoginUserCompanyInfo().getId()));
		}

		List<ShipbillLineMapDTO> shipbillQueryDTOS = tmsShipbillHeaderMapper.shipbillLineMapSiteQuery(vo);
		List<LineSiteMapDTO> siteQueryDTOS = Lists.newArrayList();
		if (ToolKits.isNotEmpty(shipbillQueryDTOS)) {
			// 没有匹配到线路的运单
			List<ShipbillLineMapDTO> noLineShipbills = shipbillQueryDTOS.stream().filter(s -> ToolKits.isEmpty(s.getLineId())).collect(Collectors.toList());
			for (ShipbillLineMapDTO shipbillQueryDTO : noLineShipbills) {
				LineSiteMapDTO siteQueryDTO = new LineSiteMapDTO();
				List<TmsLineSiteDTO> siteDTOs = Lists.newArrayList();
				// 发货方信息
				TmsLineSiteDTO shipperSiteDTO = new TmsLineSiteDTO();
				shipperSiteDTO.setSiteOrder(1);
				shipperSiteDTO.setAddress(shipbillQueryDTO.getShipperAddress());
				shipperSiteDTO.setBranchId(shipbillQueryDTO.getShipperUnitId());
				shipperSiteDTO.setBranchCode(shipbillQueryDTO.getShipperUnitCode());
				shipperSiteDTO.setBranchName(shipbillQueryDTO.getShipperUnitName());
				shipperSiteDTO.setSiteTypeName("提");
				shipperSiteDTO.setLongitude(shipbillQueryDTO.getShipperLongitude());
				shipperSiteDTO.setLatitude(shipbillQueryDTO.getShipperLatitude());
				shipperSiteDTO.setIsLineSite("0");

				siteDTOs.add(shipperSiteDTO);

				// 收货方信息
				TmsLineSiteDTO consigneeSiteDTO = new TmsLineSiteDTO();
				consigneeSiteDTO.setSiteOrder(2);
				consigneeSiteDTO.setAddress(shipbillQueryDTO.getConsigneeAddress());
				consigneeSiteDTO.setConsigneeUnitId(shipbillQueryDTO.getConsigneeUnitId());
				consigneeSiteDTO.setConsigneeUnitCode(shipbillQueryDTO.getConsigneeUnitCode());
				consigneeSiteDTO.setConsigneeUnitName(shipbillQueryDTO.getConsigneeUnitName());
				consigneeSiteDTO.setConsigneeId(shipbillQueryDTO.getConsigneeId());
				consigneeSiteDTO.setConsigneeCode(shipbillQueryDTO.getConsigneeCode());
				consigneeSiteDTO.setConsigneeName(shipbillQueryDTO.getConsigneeName());
				consigneeSiteDTO.setSiteTypeName("送");
				consigneeSiteDTO.setLongitude(shipbillQueryDTO.getConsigneeLongitude());
				consigneeSiteDTO.setLatitude(shipbillQueryDTO.getConsigneeLatitude());
				consigneeSiteDTO.setIsLineSite("0");

				siteDTOs.add(consigneeSiteDTO);

				siteQueryDTO.setSiteDTOs(siteDTOs);
				siteQueryDTOS.add(siteQueryDTO);
			}
			// 匹配到线路的运单
			Map<Long, List<ShipbillLineMapDTO>> lineShipbillMap = Maps.newHashMap();
			List<ShipbillLineMapDTO> hasLineShipbills = shipbillQueryDTOS.stream().filter(s -> ToolKits.isNotEmpty(s.getLineId())).collect(Collectors.toList());
			if (ToolKits.isNotEmpty(hasLineShipbills)) {
				lineShipbillMap = hasLineShipbills.stream().collect(Collectors.groupingBy(ShipbillLineMapDTO::getLineId));

				List<Long> lineIds = lineShipbillMap.keySet().stream().collect(Collectors.toList());
				RestMessage<List<TmsLineMapDTO>> restMessageLineSite = maindataTmsResource.lineSites(lineIds);
				if (!restMessageLineSite.isSuccess()) {
					throw new RuntimeException("线路站点查询请求服务失败!");
				}
				List<TmsLineMapDTO> lineMapDTOS = restMessageLineSite.getData();
				for (Long lineId : lineShipbillMap.keySet()) {
					List<ShipbillLineMapDTO> shipbillList = lineShipbillMap.get(lineId);
					List<Long> shipperUnitIds = shipbillList.stream().map(ShipbillLineMapDTO::getShipperUnitId).collect(Collectors.toList());
					List<Long> consigneeUnitIds = shipbillList.stream().map(ShipbillLineMapDTO::getConsigneeUnitId).collect(Collectors.toList());
					List<Long> consigneeIds = shipbillList.stream().map(ShipbillLineMapDTO::getConsigneeId).collect(Collectors.toList());

					List<TmsLineMapDTO> oneLineSites = lineMapDTOS.stream().filter(lId -> lineId.equals(lId.getLineId())).collect(Collectors.toList());
					if (ToolKits.isEmpty(oneLineSites)) {
						continue;
					}
					TmsLineMapDTO lineMapDTO = oneLineSites.get(0);
					LineSiteMapDTO lineSiteDTO = new LineSiteMapDTO();
					lineSiteDTO.setLineId(lineMapDTO.getLineId());
					lineSiteDTO.setLineCode(lineMapDTO.getLineCode());
					lineSiteDTO.setLineName(lineMapDTO.getLineName());
					lineSiteDTO.setTotalMileage(lineMapDTO.getTotalMileage());
					lineSiteDTO.setPickUpSiteNumber(lineMapDTO.getPickUpSiteNumber());
					lineSiteDTO.setDeliverySiteNumber(lineMapDTO.getDeliverySiteNumber());
					lineSiteDTO.setTotalStations(lineMapDTO.getTotalStations());

					List<TmsLineWaySiteDTO> siteDTOs = lineMapDTO.getSiteDTOs();
					// 提货站点
					List<TmsLineWaySiteDTO> pickUpSiteDTOs = siteDTOs.stream().filter(site -> ToolKits.isNotEmpty(site.getSiteTypeName()) && site.getSiteTypeName().equals("提货")).collect(Collectors.toList());
					// 送货站点
					List<TmsLineWaySiteDTO> deliverySiteDTOs = siteDTOs.stream().filter(site -> ToolKits.isNotEmpty(site.getSiteTypeName()) && site.getSiteTypeName().equals("送货")).collect(Collectors.toList());
					List<TmsLineSiteDTO> shipperLineSiteDTOS = Lists.newArrayList();
					for (TmsLineWaySiteDTO waySiteDTO : pickUpSiteDTOs) {
						if (shipperUnitIds.contains(waySiteDTO.getBranchId())) {
							TmsLineSiteDTO shipperSiteDTO = new TmsLineSiteDTO();
							shipperSiteDTO.setSiteOrder(waySiteDTO.getSiteOrder());
							shipperSiteDTO.setAddress(waySiteDTO.getAddress());
							shipperSiteDTO.setBranchId(waySiteDTO.getBranchId());
							shipperSiteDTO.setBranchCode(waySiteDTO.getBranchCode());
							shipperSiteDTO.setBranchName(waySiteDTO.getBranchName());
							shipperSiteDTO.setSiteTypeName("提");
							shipperSiteDTO.setLongitude(waySiteDTO.getLongitude());
							shipperSiteDTO.setLatitude(waySiteDTO.getLatitude());
							shipperSiteDTO.setIsLineSite("1");
							shipperLineSiteDTOS.add(shipperSiteDTO);
						}
					}
					for (TmsLineWaySiteDTO waySiteDTO : deliverySiteDTOs) {
						if (consigneeUnitIds.contains(waySiteDTO.getCustomerId()) && consigneeIds.contains(waySiteDTO.getConsigneeId())) {
							TmsLineSiteDTO shipperSiteDTO = new TmsLineSiteDTO();
							shipperSiteDTO.setSiteOrder(waySiteDTO.getSiteOrder());
							shipperSiteDTO.setAddress(waySiteDTO.getAddress());
							shipperSiteDTO.setConsigneeUnitId(waySiteDTO.getCustomerId());
							shipperSiteDTO.setConsigneeUnitCode(waySiteDTO.getCustomerCode());
							shipperSiteDTO.setConsigneeUnitName(waySiteDTO.getCustomerName());
							shipperSiteDTO.setConsigneeId(waySiteDTO.getConsigneeId());
							shipperSiteDTO.setConsigneeCode(waySiteDTO.getConsigneeCode());
							shipperSiteDTO.setConsigneeName(waySiteDTO.getConsigneeName());
							shipperSiteDTO.setSiteTypeName("送");
							shipperSiteDTO.setLongitude(waySiteDTO.getLongitude());
							shipperSiteDTO.setLatitude(waySiteDTO.getLatitude());
							shipperSiteDTO.setIsLineSite("1");
							shipperLineSiteDTOS.add(shipperSiteDTO);
						}
					}
					lineSiteDTO.setSiteDTOs(shipperLineSiteDTOS);
					siteQueryDTOS.add(lineSiteDTO);
				}
			}
			// 调度前运单地图站点信息
			shipbillMapDTO.setLineSiteMapDTOS(siteQueryDTOS);

			// 运单货量
			PendingDispatchShipbillQtyDTO rsDTO = new PendingDispatchShipbillQtyDTO();
			// 货主数
			rsDTO.setCargoOwnerQty(shipbillQueryDTOS.stream().map(ShipbillLineMapDTO::getCargoOwnerName).distinct().collect(Collectors.toList()).size());
			// 运单数
			rsDTO.setShipbillQty(shipbillQueryDTOS.size());
			// 收货方数
			rsDTO.setConsigneeQty(shipbillQueryDTOS.stream().map(ShipbillLineMapDTO::getConsigneeUnitName).distinct().collect(Collectors.toList()).size());
			// 总提货点数
			rsDTO.setTotalPickUpSiteQty(shipbillQueryDTOS.stream().map(ShipbillLineMapDTO::getShipperAddress).distinct().collect(Collectors.toList()).size());
			// 总配送点数
			rsDTO.setTotalDeliverySiteQty(shipbillQueryDTOS.stream().map(ShipbillLineMapDTO::getConsigneeAddress).distinct().collect(Collectors.toList()).size());
			// 总站数
			rsDTO.setTotalSitQty(rsDTO.getTotalPickUpSiteQty().intValue() + rsDTO.getTotalDeliverySiteQty().intValue());
			// 冷链运单数
			long coldChainShipbillQty = shipbillQueryDTOS.stream().filter(s -> ToolKits.isNotEmpty(s.getTemperatureRequirement()) && s.getTemperatureRequirement().intValue() > 1).collect(Collectors.toList()).size();
			rsDTO.setColdChainShipbillQty(Integer.valueOf(new Long(coldChainShipbillQty).intValue()));

			// 紧急加急运单数
			long urgentShipbillQty = shipbillQueryDTOS.stream().filter(s -> ToolKits.isNotEmpty(s.getOrderType()) && s.getOrderType().intValue() > 1).collect(Collectors.toList()).size();
			rsDTO.setUrgentShipbillQty(Integer.valueOf(new Long(urgentShipbillQty).intValue()));

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

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

			shipbillMapDTO.setShipbillQtyDTO(rsDTO);

			// 运单线路货量
			List<PendingDispatchShipbillQtyByLineDTO> lineShipbillQtyDTOS = Lists.newArrayList();
			lineShipbillMap.entrySet().stream().forEach(entry -> {
				PendingDispatchShipbillQtyByLineDTO lineDTO = new PendingDispatchShipbillQtyByLineDTO();
				lineDTO.setLineId(entry.getValue().get(0).getLineId());
				lineDTO.setLineName(entry.getValue().get(0).getLineName());
				// 货主数
				lineDTO.setCargoOwnerQty(entry.getValue().stream().map(ShipbillLineMapDTO::getCargoOwnerName).distinct().collect(Collectors.toList()).size());
				// 运单数
				lineDTO.setShipbillQty(entry.getValue().size());
				// 收货方数
				lineDTO.setConsigneeQty(entry.getValue().stream().map(ShipbillLineMapDTO::getConsigneeUnitName).distinct().collect(Collectors.toList()).size());
				// 总提货点数
				lineDTO.setTotalPickUpSiteQty(entry.getValue().stream().map(ShipbillLineMapDTO::getShipperAddress).distinct().collect(Collectors.toList()).size());
				// 总配送点数
				lineDTO.setTotalDeliverySiteQty(entry.getValue().stream().map(ShipbillLineMapDTO::getConsigneeAddress).distinct().collect(Collectors.toList()).size());
				// 总站数
				lineDTO.setTotalSitQty(lineDTO.getTotalPickUpSiteQty().intValue() + lineDTO.getTotalDeliverySiteQty().intValue());
				// 冷链运单数
				long coldChainShipbillQty2 = entry.getValue().stream().filter(s -> ToolKits.isNotEmpty(s.getTemperatureRequirement()) && s.getTemperatureRequirement().intValue() > 1).collect(Collectors.toList()).size();
				lineDTO.setColdChainShipbillQty(Integer.valueOf(new Long(coldChainShipbillQty2).intValue()));

				// 紧急加急运单数
				long urgentShipbillQty2 = entry.getValue().stream().filter(s -> ToolKits.isNotEmpty(s.getOrderType()) && s.getOrderType().intValue() > 1).collect(Collectors.toList()).size();
				lineDTO.setUrgentShipbillQty(Integer.valueOf(new Long(urgentShipbillQty2).intValue()));

				BigDecimal pcs11 = entry.getValue().stream().filter(dto -> ToolKits.isNotEmpty(dto.getTotalPcs())).map(ShipbillLineMapDTO::getTotalPcs).reduce(BigDecimal.ZERO, BigDecimal::add);
				BigDecimal pcs21 = entry.getValue().stream().filter(dto -> ToolKits.isNotEmpty(dto.getPackageLclPiece())).map(ShipbillLineMapDTO::getPackageLclPiece).reduce(BigDecimal.ZERO, BigDecimal::add);
				BigDecimal pcs31 = entry.getValue().stream().filter(dto -> ToolKits.isNotEmpty(dto.getPackageWholePiece())).map(ShipbillLineMapDTO::getPackageWholePiece).reduce(BigDecimal.ZERO, BigDecimal::add);
				BigDecimal weigth11 = entry.getValue().stream().filter(dto -> ToolKits.isNotEmpty(dto.getTotalWeight())).map(ShipbillLineMapDTO::getTotalWeight).reduce(BigDecimal.ZERO, BigDecimal::add);
				BigDecimal weigth21 = entry.getValue().stream().filter(dto -> ToolKits.isNotEmpty(dto.getPackageTotalWeight())).map(ShipbillLineMapDTO::getPackageTotalWeight).reduce(BigDecimal.ZERO, BigDecimal::add);
				BigDecimal volume11 = entry.getValue().stream().filter(dto -> ToolKits.isNotEmpty(dto.getTotalVolume())).map(ShipbillLineMapDTO::getTotalVolume).reduce(BigDecimal.ZERO, BigDecimal::add);
				BigDecimal volume21 = entry.getValue().stream().filter(dto -> ToolKits.isNotEmpty(dto.getPackageTotalVolume())).map(ShipbillLineMapDTO::getPackageTotalVolume).reduce(BigDecimal.ZERO, BigDecimal::add);

				// 商品/包裹 总件数
				lineDTO.setTotalPieceQty(pcs11.add(pcs21.add(pcs31)).intValue());
				// 商品/包裹 总重量
				lineDTO.setTotalWeightQty(weigth11.add(weigth21));
				// 商品/包裹 总体积
				lineDTO.setTotalVolumeQty(volume11.add(volume21));

				lineShipbillQtyDTOS.add(lineDTO);
			});
			shipbillMapDTO.setShipbillQtyByLineDTOS(lineShipbillQtyDTOS);
		}
		return shipbillMapDTO;
	}

	/**
	 * 热力图站点信息查询
	 *
	 * @param vo
	 */
	public List<ShipbillHotMapDTO> shipbillHotMapSiteQuery(SysGroupQueryVO vo) {
		ToolKits.isParamNull(vo, "热力图查询请求不为空");
		UserEntity user = PlgFxUsrUtils.getUserEntity();
		ToolKits.isParamNull(user, "当前人员没有操作权限");

		if (ToolKits.isNotEmpty(vo.getCargoOwnerIds())) {
			String[] ids = vo.getCargoOwnerIds().split(",");
			vo.setCargoOwnerIdList(Arrays.stream(ids).map(id -> Long.valueOf(id)).collect(Collectors.toList()));
		}
		if (ToolKits.isNotEmpty(vo.getLineIds())) {
			String[] ids = vo.getLineIds().split(",");
			vo.setLineIdList(Arrays.stream(ids).map(id -> Long.valueOf(id)).collect(Collectors.toList()));
		}
		List<ZoneVO> shipperAdministrativeAreas = vo.getShipperAdministrativeAreas();
		if (ToolKits.isNotEmpty(shipperAdministrativeAreas)) {
			List<String> provinceList = parseCode(shipperAdministrativeAreas, "province");
			if (ToolKits.isNotEmpty(provinceList)) {
				vo.setShipperProvinceList(provinceList);
			}
			List<String> cityList = parseCode(shipperAdministrativeAreas, "city");
			if (ToolKits.isNotEmpty(cityList)) {
				vo.setShipperCityList(cityList);
			}
			List<String> districtList = parseCode(shipperAdministrativeAreas, "district");
			if (ToolKits.isNotEmpty(districtList)) {
				vo.setShipperDistrictList(districtList);
			}
		}
		List<ZoneVO> consigneeAdministrativeAreas = vo.getAdministrativeAreas();
		if (ToolKits.isNotEmpty(consigneeAdministrativeAreas)) {
			List<String> provinceList = parseCode(consigneeAdministrativeAreas, "province");
			if (ToolKits.isNotEmpty(provinceList)) {
				vo.setConsigneeProvinceList(provinceList);
			}
			List<String> cityList = parseCode(consigneeAdministrativeAreas, "city");
			if (ToolKits.isNotEmpty(cityList)) {
				vo.setConsigneeCityList(cityList);
			}
			List<String> districtList = parseCode(consigneeAdministrativeAreas, "district");
			if (ToolKits.isNotEmpty(districtList)) {
				vo.setConsigneeDistrictList(districtList);
			}
		}
		vo.setUserType(user.getUserType());
		vo.setEnterpriseId(user.getEnterpriseId());
		if (ObjectUtil.equal(user.getUserType(), BussinessConstant.USER_TYPE_ZY)) {// 自有账号
			vo.setDepts(ToolKits.isEmpty(user.getDepts()) ? null : user.getDepts().stream().toArray(String[]::new));
			if (BussinessConstant.USER_DEPARTMENT_AUTH_Y.equals(user.getOwnedAllDataAuthFlag())) {// 部门权限
				vo.setIsDept("YES");
			} else {// 业务员权限
				vo.setIsDept("NO");
				// 货主
				vo.setConsignors(ToolKits.isEmpty(user.getConsignors()) ? null : user.getConsignors().stream().toArray(Long[]::new));
				// 客户
				vo.setCustomers(ToolKits.isEmpty(user.getCustomers()) ? null : user.getCustomers().stream().toArray(Long[]::new));
				// 供应商
				vo.setSuppliers(ToolKits.isEmpty(user.getSuppliers()) ? null : user.getSuppliers().stream().toArray(Long[]::new));
				// 仓库
				vo.setWsarehouses(ToolKits.isEmpty(user.getWarehouses()) ? null : user.getWarehouses().stream().toArray(Long[]::new));
			}
		} else if (ObjectUtil.equal(user.getUserType(), BussinessConstant.USER_TYPE_CYS)) {// 承运商账号
			vo.setCarrierId(Long.valueOf(user.getLoginUserCompanyInfo().getId()));
		}
		return tmsShipbillHeaderMapper.shipbillHotMapSiteQuery(vo);
	}

	/**
	 * 运单线路站点信息查询
	 *
	 * @param vo
	 */
	public List<SysGroupShipbillQueryDTO> shipbillSiteQuery(SysGroupQueryVO vo) {
		ToolKits.isParamNull(vo, "运单线路站点信息查询请求不为空");
		return sysGroupShipbillQuery(vo);
	}

	/**
	 * 系统分组-运单查询
	 *
	 * @param vo
	 * @return
	 */
	public List<SysGroupShipbillQueryDTO> sysGroupShipbillQuery(SysGroupQueryVO vo) {
		ToolKits.isParamNull(vo, "系统分组-运单查询请求不为空");
		TimeInterval timer = DateUtil.timer();
		// 数据字典翻译数据集合
		List<SysRefdatadModel> dicData = convertorUtil.getDictionary(new String[] { DataDictionaryConstant.TEMPERATURE_REQUIREMENT, // 温度要求
				DataDictionaryConstant.ORDER_TYPE, // 订单类型
				DataDictionaryConstant.SHIPPER_TYPE, // 发货方类型
				DataDictionaryConstant.CONSIGNEE_TYPE, // 收货方类型
				DataDictionaryConstant.ORDER_BUSINESS_TYPE // 订单业务类型
		});
		// 添加查询条件
		List<SysGroupShipbillQueryDTO> sysGroupShipQueryList = tmsShipbillHeaderMapper.sysGroupShipbillsQuery(vo.getShipbillIdList());
		// 响应对象集合
		if (ToolKits.isNotEmpty(sysGroupShipQueryList)) {
			sysGroupShipQueryList.stream().forEach(shipbill -> {
				StringBuffer consigneeProvinceCityDistrict = new StringBuffer();
				// 目的地
				consigneeProvinceCityDistrict.append(ToolKits.isEmpty(shipbill.getConsigneeProvinceName()) ? "" : shipbill.getConsigneeProvinceName());
				consigneeProvinceCityDistrict.append(ToolKits.isEmpty(shipbill.getConsigneeCityName()) ? "" : shipbill.getConsigneeCityName());
				consigneeProvinceCityDistrict.append(ToolKits.isEmpty(shipbill.getConsigneeDistrictName()) ? "" : shipbill.getConsigneeDistrictName());
				shipbill.setConsigneeProvinceCityDistrict(consigneeProvinceCityDistrict.toString());
				// 始发地
				StringBuffer shipperProvinceCityDistrict = new StringBuffer();
				shipperProvinceCityDistrict.append(ToolKits.isEmpty(shipbill.getShipperProvinceName()) ? "" : shipbill.getShipperProvinceName());
				shipperProvinceCityDistrict.append(ToolKits.isEmpty(shipbill.getShipperCityName()) ? "" : shipbill.getShipperCityName());
				shipperProvinceCityDistrict.append(ToolKits.isEmpty(shipbill.getShipperDistrictName()) ? "" : shipbill.getShipperDistrictName());
				shipbill.setShipperProvinceCityDistrict(shipperProvinceCityDistrict.toString());

				// 类型翻译
				shipbill.setOrderTypeName(ConvertorUtil.getName(dicData, DataDictionaryConstant.ORDER_TYPE, String.valueOf(shipbill.getOrderType())));
				shipbill.setOrderBusinessTypeName(ConvertorUtil.getName(dicData, DataDictionaryConstant.ORDER_BUSINESS_TYPE, String.valueOf(shipbill.getOrderBusinessType())));
				shipbill.setTemperatureRequirementName(ConvertorUtil.getName(dicData, DataDictionaryConstant.TEMPERATURE_REQUIREMENT, String.valueOf(shipbill.getTemperatureRequirement())));
				shipbill.setShipperTypeName(ConvertorUtil.getName(dicData, DataDictionaryConstant.SHIPPER_TYPE, String.valueOf(shipbill.getShipperType())));
				shipbill.setConsigneeTypeName(ConvertorUtil.getName(dicData, DataDictionaryConstant.CONSIGNEE_TYPE, String.valueOf(shipbill.getConsigneeType())));
				shipbill.setId(ToolKits.getUUID());
			});
		}
		log.warn("分组运单查询时间=======" + timer.interval());
		return sysGroupShipQueryList;
	}

	/**
	 * 系统分组-配载单信息查询
	 *
	 * @param vo
	 * @return
	 */
	public SysGroupLoadingQueryDTO sysGroupLoadingQuery(SysGroupQueryVO vo) {
		ToolKits.isParamNull(vo, "系统分组-配载单信息查询请求不为空");
		TimeInterval timer = DateUtil.timer();

		CompletableFuture<SysGroupLoadingQueryDTO> future1 = CompletableFuture.supplyAsync(() -> {
			return this.shipbillAndQtyQuery(vo);
		}, executor);

		CompletableFuture<ShipbillMatchCarrierDTO> future2 = CompletableFuture.supplyAsync(() -> {
			HystrixRequestContext.initializeContext();
			return this.queryDispatchStrategyData(vo.getShipbillIdList());
		}, executor);

		CompletableFuture<SysGroupLoadingQueryDTO> future3 = future1.thenCombineAsync(future2, new BiFunction<SysGroupLoadingQueryDTO, ShipbillMatchCarrierDTO, SysGroupLoadingQueryDTO>() {
			@Override
			public SysGroupLoadingQueryDTO apply(SysGroupLoadingQueryDTO loadingQueryDTO, ShipbillMatchCarrierDTO matchCarrierDTO) {
				SysGroupLoadingQueryDTO rsDTO = loadingQueryDTO;
				rsDTO.setShipbillMatchCarrierDTO(matchCarrierDTO);
				return rsDTO;
			}
		}, executor);
		SysGroupLoadingQueryDTO loadingQueryDTO = future3.join();
		log.warn("系统分组 配载单查询时间=======" + timer.interval());
		return loadingQueryDTO;
	}

	public SysGroupLoadingQueryDTO shipbillAndQtyQuery(SysGroupQueryVO vo) {
		ToolKits.isParamNull(vo, "系统分组-运单查询请求不为空");
		SysGroupLoadingQueryDTO loadingQueryDTO = new SysGroupLoadingQueryDTO();
		TimeInterval timer = DateUtil.timer();
		// 数据字典翻译数据集合
		List<SysRefdatadModel> dicData = convertorUtil.getDictionary(new String[] { DataDictionaryConstant.TEMPERATURE_REQUIREMENT, // 温度要求
				DataDictionaryConstant.ORDER_TYPE, // 订单类型
				DataDictionaryConstant.SHIPPER_TYPE, // 发货方类型
				DataDictionaryConstant.CONSIGNEE_TYPE, // 收货方类型
				DataDictionaryConstant.ORDER_BUSINESS_TYPE // 订单业务类型
		});
		// 添加查询条件
		List<SysGroupShipbillQueryDTO> sysGroupShipQueryList = tmsShipbillHeaderMapper.sysGroupShipbillsQuery(vo.getShipbillIdList());
		PendingDispatchShipbillQtyDTO qtyDTO = new PendingDispatchShipbillQtyDTO();
		// 响应对象集合
		if (ToolKits.isNotEmpty(sysGroupShipQueryList)) {
			sysGroupShipQueryList.stream().forEach(shipbill -> {
				StringBuffer consigneeProvinceCityDistrict = new StringBuffer();
				// 目的地
				consigneeProvinceCityDistrict.append(ToolKits.isEmpty(shipbill.getConsigneeProvinceName()) ? "" : shipbill.getConsigneeProvinceName());
				consigneeProvinceCityDistrict.append(ToolKits.isEmpty(shipbill.getConsigneeCityName()) ? "" : shipbill.getConsigneeCityName());
				consigneeProvinceCityDistrict.append(ToolKits.isEmpty(shipbill.getConsigneeDistrictName()) ? "" : shipbill.getConsigneeDistrictName());
				shipbill.setConsigneeProvinceCityDistrict(consigneeProvinceCityDistrict.toString());
				// 始发地
				StringBuffer shipperProvinceCityDistrict = new StringBuffer();
				shipperProvinceCityDistrict.append(ToolKits.isEmpty(shipbill.getShipperProvinceName()) ? "" : shipbill.getShipperProvinceName());
				shipperProvinceCityDistrict.append(ToolKits.isEmpty(shipbill.getShipperCityName()) ? "" : shipbill.getShipperCityName());
				shipperProvinceCityDistrict.append(ToolKits.isEmpty(shipbill.getShipperDistrictName()) ? "" : shipbill.getShipperDistrictName());
				shipbill.setShipperProvinceCityDistrict(shipperProvinceCityDistrict.toString());

				// 类型翻译
				shipbill.setOrderTypeName(ConvertorUtil.getName(dicData, DataDictionaryConstant.ORDER_TYPE, String.valueOf(shipbill.getOrderType())));
				shipbill.setOrderBusinessTypeName(ConvertorUtil.getName(dicData, DataDictionaryConstant.ORDER_BUSINESS_TYPE, String.valueOf(shipbill.getOrderBusinessType())));
				shipbill.setTemperatureRequirementName(ConvertorUtil.getName(dicData, DataDictionaryConstant.TEMPERATURE_REQUIREMENT, String.valueOf(shipbill.getTemperatureRequirement())));
				shipbill.setShipperTypeName(ConvertorUtil.getName(dicData, DataDictionaryConstant.SHIPPER_TYPE, String.valueOf(shipbill.getShipperType())));
				shipbill.setConsigneeTypeName(ConvertorUtil.getName(dicData, DataDictionaryConstant.CONSIGNEE_TYPE, String.valueOf(shipbill.getConsigneeType())));
				shipbill.setId(ToolKits.getUUID());
			});

			// 货主数
			qtyDTO.setCargoOwnerQty(sysGroupShipQueryList.stream().map(SysGroupShipbillQueryDTO::getCargoOwnerName).distinct().collect(Collectors.toList()).size());
			// 运单数
			qtyDTO.setShipbillQty(sysGroupShipQueryList.size());
			// 收货方数
			qtyDTO.setConsigneeQty(sysGroupShipQueryList.stream().map(SysGroupShipbillQueryDTO::getConsigneeUnitName).distinct().collect(Collectors.toList()).size());
			// 总提货点数
			qtyDTO.setTotalPickUpSiteQty(sysGroupShipQueryList.stream().map(SysGroupShipbillQueryDTO::getShipperAddress).distinct().collect(Collectors.toList()).size());
			// 总配送点数
			qtyDTO.setTotalDeliverySiteQty(sysGroupShipQueryList.stream().map(SysGroupShipbillQueryDTO::getConsigneeAddress).distinct().collect(Collectors.toList()).size());
			// 总站数
			qtyDTO.setTotalSitQty(qtyDTO.getTotalPickUpSiteQty().intValue() + qtyDTO.getTotalDeliverySiteQty().intValue());
			// 冷链运单数
			long coldChainShipbillQty = sysGroupShipQueryList.stream().filter(s -> ToolKits.isNotEmpty(s.getTemperatureRequirement()) && s.getTemperatureRequirement().intValue() > 1).collect(Collectors.toList()).size();
			qtyDTO.setColdChainShipbillQty(Integer.valueOf(new Long(coldChainShipbillQty).intValue()));

			// 紧急加急运单数
			long urgentShipbillQty = sysGroupShipQueryList.stream().filter(s -> ToolKits.isNotEmpty(s.getOrderType()) && s.getOrderType().intValue() > 1).collect(Collectors.toList()).size();
			qtyDTO.setUrgentShipbillQty(Integer.valueOf(new Long(urgentShipbillQty).intValue()));

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

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

		log.warn("分组运单查询时间=======" + timer.interval());
		return loadingQueryDTO;
	}

	/**
	 * 待调度中转
	 *
	 * @param transitVO
	 * @return
	 */
	@Transactional(rollbackFor = Exception.class)
	@Override
	public void transit(TransitVO transitVO) {
		ToolKits.isParamNull(transitVO, "待调度中转请求不为空");

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

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

		List<TransitDetailInfoVO> transitDetailInfoVOLists = transitVO.getTransitDetailInfoVOList();
		ToolKits.isParamNull(transitDetailInfoVOLists, "待调度中转信息不为空");
		// STD-DEVELOP20220823 lhb 承运商拆分完善 20220916 start
		// 原装车明细更新
		Map<String, Object> mapUpdate = Maps.newHashMap();
		mapUpdate.put("updateperson", user.getNickname());
		mapUpdate.put("updatetime", date);
		// STD-DEVELOP20220823 lhb 承运商拆分完善 20220916 end
		for (String shipbillId : transitVO.getShipbillIdList()) {
			// 原运单更新
			TmsShipbillHeaderModel tmsShipbillHeaderModel = tmsShipbillHeaderMapper.findById(shipbillId, TmsShipbillHeaderModel.class);

			if (user.getUserType().equals(BussinessConstant.USER_TYPE_ZY)) {
				if (!DataDictionaryConstant.SHIPBILL_STATUS_REVIEW.equals(tmsShipbillHeaderModel.getStatus())) {
					throw new PrologException("运单【" + tmsShipbillHeaderModel.getShipbillNo() + "】非待调度状态,中转失败");
				}
				if (!DataDictionaryConstant.SPLIT_ORDER_STATUS_UN.equals(tmsShipbillHeaderModel.getSplitOrderStatus())) {
					throw new PrologException("运单【" + tmsShipbillHeaderModel.getShipbillNo() + "】已拆单,中转失败");
				}
				// 中转拆分状态
				tmsShipbillHeaderModel.setSplitOrderStatus(DataDictionaryConstant.SPLIT_ORDER_STATUS_ED);
				// 原始主单被中转时，拆单类型更新为4中转主单，子单被中转时，不更新拆单类型
				if (ToolKits.isEmpty(tmsShipbillHeaderModel.getSplitOrderType()) || DataDictionaryConstant.SPLIT_ORDER_TYPE_UN.equals(tmsShipbillHeaderModel.getSplitOrderType())) {
					tmsShipbillHeaderModel.setSplitOrderType(DataDictionaryConstant.SPLIT_ORDER_TYPE_TRANSIT_MASTER);
				}
			} else if (user.getUserType().equals(BussinessConstant.USER_TYPE_CYS)) {
				if (!DataDictionaryConstant.CARRIER_SHIPBILL_STATUS_AUDITED.equals(tmsShipbillHeaderModel.getCarrierShipbillStatus())) {
					throw new PrologException("运单【" + tmsShipbillHeaderModel.getShipbillNo() + "】非待调度状态,中转失败");
				}
				if (!DataDictionaryConstant.CARRIER_SPLIT_ORDER_STATUS_UN.equals(tmsShipbillHeaderModel.getCarrierSplitOrderStatus())) {
					throw new PrologException("运单【" + tmsShipbillHeaderModel.getShipbillNo() + "】已拆单,中转失败");
				}
				// 中转拆分状态
				tmsShipbillHeaderModel.setCarrierSplitOrderStatus(DataDictionaryConstant.CARRIER_SPLIT_ORDER_STATUS_ED);

				// 原始主单被中转时，拆单类型更新为4中转主单，子单被中转时，不更新拆单类型
				if (ToolKits.isEmpty(tmsShipbillHeaderModel.getCarrierSplitOrderType()) || DataDictionaryConstant.CARRIER_SPLIT_ORDER_TYPE_UN.equals(tmsShipbillHeaderModel.getCarrierSplitOrderType())) {
					tmsShipbillHeaderModel.setCarrierSplitOrderType(DataDictionaryConstant.CARRIER_SPLIT_ORDER_TYPE_TRANSIT_MASTER);
				}

				// STD-DEVELOP20220823 lhb 承运商拆分完善 20220916 start
				// 更新装车单明细
				mapUpdate.put("carrierSplitOrderStatus", DataDictionaryConstant.CARRIER_SPLIT_ORDER_STATUS_ED);
				if (ToolKits.isEmpty(tmsShipbillHeaderModel.getCarrierSplitOrderType()) || DataDictionaryConstant.CARRIER_SPLIT_ORDER_TYPE_UN.equals(tmsShipbillHeaderModel.getCarrierSplitOrderType())) {
					mapUpdate.put("carrierSplitOrderType", DataDictionaryConstant.CARRIER_SPLIT_ORDER_TYPE_TRANSIT_MASTER);
				}

				Criteria criteriaDetail = Criteria.forClass(TmsLoadingBillDetailModel.class);
				Restriction r21 = Restrictions.eq(TmsLoadingBillDetailModel::getCarrierShipbillStatus, DataDictionaryConstant.CARRIER_SHIPBILL_STATUS_AUDITED);
				Restriction r22 = Restrictions.eq(TmsLoadingBillDetailModel::getShipbillId, shipbillId);
				criteriaDetail.setRestriction(Restrictions.and(r21, r22));
				tmsLoadingBillDetailMapper.updateMapByCriteria(mapUpdate, criteriaDetail);
				// STD-DEVELOP20220823 lhb 承运商拆分完善 20220916 end
			} else {
				throw new ParameterException("当前人员没有操作权限");
			}

			tmsShipbillHeaderModel.setUpdateperson(user.getNickname());
			tmsShipbillHeaderModel.setUpdatetime(date);
			tmsShipbillHeaderMapper.update(tmsShipbillHeaderModel);

			// 原运单日志保存
			ShipbillOperateLogSaveVO shipbillOperateLogSaveVO = new ShipbillOperateLogSaveVO();
			shipbillOperateLogSaveVO.setShipbillId(tmsShipbillHeaderModel.getShipbillId());
			shipbillOperateLogSaveVO.setShipbillNo(tmsShipbillHeaderModel.getShipbillNo());
			shipbillOperateLogSaveVO.setOperateEvent(DataDictionaryConstant.SHIPBILL_EVENT_NAME_TRANSIT);
			shipbillOperateLogSaveVO.setOldStatus(DataDictionaryConstant.SHIPBILL_STATUS_REVIEW);
			shipbillOperateLogSaveVO.setNewStatus(DataDictionaryConstant.SHIPBILL_STATUS_REVIEW);
			shipbillOperateLogService.addShipbillOperateLogData(shipbillOperateLogSaveVO);

			// 原运单明细
			// 添加查询条件
			Criteria criteria = Criteria.forClass(TmsShipbillDetailModel.class);
			Restriction r1 = Restrictions.eq("shipbillId", shipbillId);
			Restriction r2 = Restrictions.eq("enterpriseId", user.getEnterpriseId());
			criteria.setRestriction(Restrictions.and(r1, r2));
			List<TmsShipbillDetailModel> tmsShipbillDetailModels = tmsShipbillDetailMapper.findByCriteria(criteria);

			// 中转信息
			int index = 0;
			// 中转成多个子单
			List<String> newShipbillIds = new ArrayList<>();
			RestMessage<SysParamConfigModel> restMessageShipbillId = maindataTmsResource.getValue(DataDictionaryConstant.SHIPBILL_ID_CREATE_RULE);
			if (!restMessageShipbillId.isSuccess()) {
				throw new RuntimeException("获取运单ID生成规则的系统参数失败!");
			}
			SysParamConfigModel sysParamConfigModel = restMessageShipbillId.getData();
			for (TransitDetailInfoVO vo : transitDetailInfoVOLists) {
				String subShipbillId = "";
				// 运单ID生成规则
				if (DataDictionaryConstant.SHIPBILL_ID_CREATE_RULE_AUTO.equals(sysParamConfigModel.getValue())) {
					// 获取运单汇总ID
					RestMessage<String> restMessageAutoCreateShipbillId = maindataTmsResource.getCodeNumberByCode(SeriaNnumberConstant.TMS_SHIPBILL_HEADER_ID, "L");
					if (!restMessageAutoCreateShipbillId.isSuccess()) {
						throw new RuntimeException("生成运单汇总ID失败");
					}
					subShipbillId = restMessageAutoCreateShipbillId.getData();
				} else {
					StringBuffer buffNo1 = new StringBuffer(shipbillId);
					buffNo1.append(DataDictionaryConstant.SUB_SHIPBILL_NO);
					buffNo1.append(index + 1);
					subShipbillId = buffNo1.toString();
				}
				newShipbillIds.add(subShipbillId);
				// 保存中转子单的运单汇总
				TmsShipbillHeaderModel subTmsShipbillHeaderModel = new TmsShipbillHeaderModel();
				BeanUtils.copyProperties(tmsShipbillHeaderModel, subTmsShipbillHeaderModel);

				subTmsShipbillHeaderModel.setShipbillId(subShipbillId);
				subTmsShipbillHeaderModel.setShipbillNo(subShipbillId);
				if (user.getUserType().equals(BussinessConstant.USER_TYPE_ZY)) {
					// 拆单状态 0未拆单
					subTmsShipbillHeaderModel.setSplitOrderStatus(DataDictionaryConstant.SPLIT_ORDER_STATUS_UN);
					// 拆单类型 3拆段子单
					subTmsShipbillHeaderModel.setSplitOrderType(DataDictionaryConstant.SPLIT_ORDER_TYPE_TRANSIT_SUB);
				} else {
					// 拆单状态 0未拆单
					subTmsShipbillHeaderModel.setCarrierSplitOrderStatus(DataDictionaryConstant.CARRIER_SPLIT_ORDER_STATUS_UN);
					// 拆单类型 3拆段子单
					subTmsShipbillHeaderModel.setCarrierSplitOrderType(DataDictionaryConstant.CARRIER_SPLIT_ORDER_TYPE_TRANSIT_SUB);
				}
				// 父级运单ID
				subTmsShipbillHeaderModel.setFatherShipbillId(tmsShipbillHeaderModel.getShipbillId());
				// 父级运单编号
				subTmsShipbillHeaderModel.setFatherShipbillNo(tmsShipbillHeaderModel.getShipbillNo());
				// 原始运单ID
				String originalShipbillId = StrUtil.isBlank(tmsShipbillHeaderModel.getOriginalShipbillId()) ? tmsShipbillHeaderModel.getShipbillId() : tmsShipbillHeaderModel.getOriginalShipbillId();
				subTmsShipbillHeaderModel.setOriginalShipbillId(originalShipbillId);
				// 原始运单编号
				String originalShipbillNo = StrUtil.isBlank(tmsShipbillHeaderModel.getOriginalShipbillNo()) ? tmsShipbillHeaderModel.getShipbillNo() : tmsShipbillHeaderModel.getOriginalShipbillNo();
				subTmsShipbillHeaderModel.setOriginalShipbillNo(originalShipbillNo);
				if (vo.getTransitNumber().intValue() == 1) {
					// 第一段的中转站
					// 预计提货开始时间
					subTmsShipbillHeaderModel.setEstimatedPickupStartTime(tmsShipbillHeaderModel.getEstimatedPickupStartTime());
					// 预计提货结束时间
					subTmsShipbillHeaderModel.setEstimatedPickupEndTime(tmsShipbillHeaderModel.getEstimatedPickupEndTime());
					// 预计送达开始时间
					subTmsShipbillHeaderModel.setEstimatedDeliveryStartTime(vo.getEstimatedDeliveryStartTime());
					// 预计送达结束时间
					subTmsShipbillHeaderModel.setEstimatedDeliveryEndTime(vo.getEstimatedDeliveryEndTime());
					// 时效 送达时间 - 提货时间
					subTmsShipbillHeaderModel.setTransportAging(tmsShipbillHeaderModel.getEstimatedPickupEndTime() == null ? null : getTransportAging(tmsShipbillHeaderModel.getEstimatedPickupEndTime(), vo.getEstimatedDeliveryEndTime()));
				} else {
					// 中间段的中转站
					TransitDetailInfoVO lastTransDetailInfo = transitDetailInfoVOLists.get(index - 1);
					// 上一站的出发时间 -> 预计提货开始时间
					subTmsShipbillHeaderModel.setEstimatedPickupStartTime(lastTransDetailInfo.getEstimatedSendStartTime());
					// 预计提货结束时间
					subTmsShipbillHeaderModel.setEstimatedPickupEndTime(lastTransDetailInfo.getEstimatedSendEndTime());
					// 预计送达开始时间
					subTmsShipbillHeaderModel.setEstimatedDeliveryStartTime(vo.getEstimatedDeliveryStartTime());
					// 预计送达结束时间
					subTmsShipbillHeaderModel.setEstimatedDeliveryEndTime(vo.getEstimatedDeliveryEndTime());
					// 时效 送达时间 - 提货时间
					subTmsShipbillHeaderModel.setTransportAging(lastTransDetailInfo.getEstimatedSendEndTime() == null ? null : getTransportAging(lastTransDetailInfo.getEstimatedSendEndTime(), vo.getEstimatedDeliveryEndTime()));

					// 发货方单位ID
					subTmsShipbillHeaderModel.setShipperUnitId(lastTransDetailInfo.getId());
					// 发货方单位编码
					subTmsShipbillHeaderModel.setShipperUnitCode(lastTransDetailInfo.getCode());
					// 发货方单位名称
					subTmsShipbillHeaderModel.setShipperUnitName(lastTransDetailInfo.getName());
					// 发货方联系人
					subTmsShipbillHeaderModel.setShipperContact(lastTransDetailInfo.getContact());
					// 发货方手机号
					subTmsShipbillHeaderModel.setShipperPhoneNumber(lastTransDetailInfo.getPhoneNumber());
					// 发货方座机号
					subTmsShipbillHeaderModel.setShipperLandlineNumber(lastTransDetailInfo.getLandlineNumber());
					// 发货方邮箱
					subTmsShipbillHeaderModel.setShipperEmail(lastTransDetailInfo.getEmail());
					// 发货方省编码
					subTmsShipbillHeaderModel.setShipperProvince(lastTransDetailInfo.getProvince());
					// 发货方省名称
					subTmsShipbillHeaderModel.setShipperProvinceName(lastTransDetailInfo.getProvinceName());
					// 发货方市编码
					subTmsShipbillHeaderModel.setShipperCity(lastTransDetailInfo.getCity());
					// 发货方市名称
					subTmsShipbillHeaderModel.setShipperCityName(lastTransDetailInfo.getCityName());
					// 发货方区/县编码
					subTmsShipbillHeaderModel.setShipperDistrict(lastTransDetailInfo.getDistrict());
					// 发货方区/县名称
					subTmsShipbillHeaderModel.setShipperDistrictName(lastTransDetailInfo.getDistrictName());
					// 发货方详细地址
					subTmsShipbillHeaderModel.setShipperAddress(lastTransDetailInfo.getAddress());
					// 发货方经度
					subTmsShipbillHeaderModel.setShipperLongitude(lastTransDetailInfo.getLongitude());
					// 发货方纬度
					subTmsShipbillHeaderModel.setShipperLatitude(lastTransDetailInfo.getLatitude());
					// 发货方备注
					subTmsShipbillHeaderModel.setShipperMemo(lastTransDetailInfo.getMemo());

				}
				// 收货方类型
				subTmsShipbillHeaderModel.setConsigneeType(vo.getType());
				// 收货方单位ID
				subTmsShipbillHeaderModel.setConsigneeUnitId(vo.getId());
				// 收货方单位编码
				subTmsShipbillHeaderModel.setConsigneeUnitCode(vo.getCode());
				// 收货方单位名称
				subTmsShipbillHeaderModel.setConsigneeUnitName(vo.getName());
				// 仓库ID
				subTmsShipbillHeaderModel.setBranchId(vo.getBranchId());
				subTmsShipbillHeaderModel.setBranchCode(vo.getBranchCode());
				subTmsShipbillHeaderModel.setBranchName(vo.getBranchName());
				// 收货方联系人
				subTmsShipbillHeaderModel.setConsigneeContact(vo.getContact());
				// 收货方手机号
				subTmsShipbillHeaderModel.setConsigneePhoneNumber(vo.getPhoneNumber());
				// 收货方座机号
				subTmsShipbillHeaderModel.setConsigneeLandlineNumber(vo.getLandlineNumber());
				// 收货方邮箱
				subTmsShipbillHeaderModel.setConsigneeEmail(vo.getEmail());
				// 收货方省编码
				subTmsShipbillHeaderModel.setConsigneeProvince(vo.getProvince());
				// 收货方省名称
				subTmsShipbillHeaderModel.setConsigneeProvinceName(vo.getProvinceName());
				// 收货方市编码
				subTmsShipbillHeaderModel.setConsigneeCity(vo.getCity());
				// 收货方市名称
				subTmsShipbillHeaderModel.setConsigneeCityName(vo.getCityName());
				// 收货方区/县编码
				subTmsShipbillHeaderModel.setConsigneeDistrict(vo.getDistrict());
				// 收货方区/县名称
				subTmsShipbillHeaderModel.setConsigneeDistrictName(vo.getDistrictName());
				// 收货方详细地址
				subTmsShipbillHeaderModel.setConsigneeAddress(vo.getAddress());
				// 收货方经度
				subTmsShipbillHeaderModel.setConsigneeLongitude(vo.getLongitude());
				// 收货方纬度
				subTmsShipbillHeaderModel.setConsigneeLatitude(vo.getLatitude());
				// 收货方备注
				subTmsShipbillHeaderModel.setConsigneeMemo(vo.getMemo());

				subTmsShipbillHeaderModel.setCreateperson(user.getNickname());
				subTmsShipbillHeaderModel.setCreatetime(date);
				subTmsShipbillHeaderModel.setUpdateperson(user.getNickname());
				subTmsShipbillHeaderModel.setUpdatetime(date);
				// 保存运单汇总
				subTmsShipbillHeaderModel.setShipbillType(ShipBillTypeEnum.NORMAL.getCode());
				subTmsShipbillHeaderModel.setSignInStatus(SignInStatusEnum.NOT_SIGN.getCode());
				subTmsShipbillHeaderModel.setDriverReceiveStatus(DriverReceiveStatusEnum.N.getCode());
				subTmsShipbillHeaderModel.setIntelligentLock(IntelligentLockEnum.UN_LOCK.getCode());
				tmsShipbillHeaderMapper.save(subTmsShipbillHeaderModel);

				// 运输记录
				saveTransportLog(subTmsShipbillHeaderModel.getShipbillId(), date, subTmsShipbillHeaderModel.getEstimatedPickupStartTime());

				// 运单明细保存
				for (TmsShipbillDetailModel detailModel : tmsShipbillDetailModels) {
					TmsShipbillDetailModel subTmsShipbillDetailModel = new TmsShipbillDetailModel();
					// 运单明细ID
					RestMessage<String> restMessage2 = maindataTmsResource.getCodeNumberByCode(SeriaNnumberConstant.TMS_SHIPBILL_DETAIL_ID, "L");
					if (!restMessage2.isSuccess()) {
						throw new RuntimeException("生成运单明细ID失败");
					}
					String subShipbillDetailId = restMessage2.getData();

					BeanUtils.copyProperties(detailModel, subTmsShipbillDetailModel);
					subTmsShipbillDetailModel.setId(subShipbillDetailId);
					// 运单ID
					subTmsShipbillDetailModel.setShipbillId(subTmsShipbillHeaderModel.getShipbillId());
					// 运单编号
					subTmsShipbillDetailModel.setShipbillNo(subTmsShipbillHeaderModel.getShipbillNo());
					// 仓库ID
					subTmsShipbillDetailModel.setBranchId(subTmsShipbillHeaderModel.getBranchId());
					// 仓库编码
					subTmsShipbillDetailModel.setBranchCode(subTmsShipbillHeaderModel.getBranchCode());
					// 仓库名称
					subTmsShipbillDetailModel.setBranchName(subTmsShipbillHeaderModel.getBranchName());

					subTmsShipbillDetailModel.setCreateperson(user.getNickname());
					subTmsShipbillDetailModel.setCreatetime(date);
					subTmsShipbillDetailModel.setUpdateperson(user.getNickname());
					subTmsShipbillDetailModel.setUpdatetime(date);
					subTmsShipbillDetailModel.setOrigPcs(subTmsShipbillDetailModel.getPcs());
					subTmsShipbillDetailModel.setClosingPcs(BigDecimal.valueOf(0));
					subTmsShipbillDetailModel.setDeliveryPcs(BigDecimal.valueOf(0));
					subTmsShipbillDetailModel.setFatherId(detailModel.getId());
					subTmsShipbillDetailModel.setScanStatus(DataDictionaryConstant.SCAN_STATUS_INIT);
					tmsShipbillDetailMapper.save(subTmsShipbillDetailModel);
				}

				// 子运单日志保存
				ShipbillOperateLogSaveVO subShipbillOperateLogSaveVO = new ShipbillOperateLogSaveVO();
				subShipbillOperateLogSaveVO.setShipbillId(subTmsShipbillHeaderModel.getShipbillId());
				subShipbillOperateLogSaveVO.setShipbillNo(subTmsShipbillHeaderModel.getShipbillNo());
				subShipbillOperateLogSaveVO.setOperateEvent(DataDictionaryConstant.SHIPBILL_EVENT_NAME_TRANSIT_SUB);
				subShipbillOperateLogSaveVO.setOldStatus(DataDictionaryConstant.SHIPBILL_STATUS_REVIEW);
				subShipbillOperateLogSaveVO.setNewStatus(DataDictionaryConstant.SHIPBILL_STATUS_REVIEW);
				shipbillOperateLogService.addShipbillOperateLogData(subShipbillOperateLogSaveVO);

				// 运单节点保存
				ShipbillNodeTrackingSaveVO shipbillNodeTrackingSaveVO = new ShipbillNodeTrackingSaveVO();
				shipbillNodeTrackingSaveVO.setShipbillId(subTmsShipbillHeaderModel.getShipbillId());
				shipbillNodeTrackingSaveVO.setShipbillNo(subTmsShipbillHeaderModel.getShipbillId());
				shipbillNodeTrackingSaveVO.setStatus(DataDictionaryConstant.SHIPBILL_STATUS_REVIEW);
				shipbillNodeTrackingSaveVO.setNodeEvent(DataDictionaryConstant.SHIPBILL_STATUSNAME_REW);
				shipbillNodeTrackingService.addShipbillNodeTrackingData(shipbillNodeTrackingSaveVO);

				index++;
			}
			// 最后一段的中转站
			// 运单汇总ID
			RestMessage<String> restMessage3 = maindataTmsResource.getCodeNumberByCode(SeriaNnumberConstant.TMS_SHIPBILL_HEADER_ID, "L");
			if (!restMessage3.isSuccess()) {
				throw new RuntimeException("生成运单汇总ID失败");
			}
			String lastSubShipbillId = "";
			// 运单ID生成规则
			if (DataDictionaryConstant.SHIPBILL_ID_CREATE_RULE_AUTO.equals(sysParamConfigModel.getValue())) {
				// 获取运单汇总ID
				RestMessage<String> restMessageAutoCreateShipbillId = maindataTmsResource.getCodeNumberByCode(SeriaNnumberConstant.TMS_SHIPBILL_HEADER_ID, "L");
				if (!restMessageAutoCreateShipbillId.isSuccess()) {
					throw new RuntimeException("生成运单汇总ID失败");
				}
				lastSubShipbillId = restMessageAutoCreateShipbillId.getData();
			} else {
				StringBuffer buffNo2 = new StringBuffer(shipbillId);
				buffNo2.append(DataDictionaryConstant.SUB_SHIPBILL_NO);
				buffNo2.append(index + 1);
				lastSubShipbillId = buffNo2.toString();
			}
			newShipbillIds.add(lastSubShipbillId);

			// 保存中转子单的运单汇总
			TmsShipbillHeaderModel lastSubTmsShipbillHeaderModel = new TmsShipbillHeaderModel();
			BeanUtils.copyProperties(tmsShipbillHeaderModel, lastSubTmsShipbillHeaderModel);

			lastSubTmsShipbillHeaderModel.setShipbillId(lastSubShipbillId);
			lastSubTmsShipbillHeaderModel.setShipbillNo(lastSubShipbillId);

			if (user.getUserType().equals(BussinessConstant.USER_TYPE_ZY)) {
				// 拆单状态 0未拆单
				lastSubTmsShipbillHeaderModel.setSplitOrderStatus(DataDictionaryConstant.SPLIT_ORDER_STATUS_UN);
				// 拆单类型 3拆段子单
				lastSubTmsShipbillHeaderModel.setSplitOrderType(DataDictionaryConstant.SPLIT_ORDER_TYPE_TRANSIT_SUB);
			} else {
				// 拆单状态 0未拆单
				lastSubTmsShipbillHeaderModel.setCarrierSplitOrderStatus(DataDictionaryConstant.CARRIER_SPLIT_ORDER_STATUS_UN);
				// 拆单类型 3拆段子单
				lastSubTmsShipbillHeaderModel.setCarrierSplitOrderType(DataDictionaryConstant.CARRIER_SPLIT_ORDER_TYPE_TRANSIT_SUB);
			}
			// 父级运单ID
			lastSubTmsShipbillHeaderModel.setFatherShipbillId(tmsShipbillHeaderModel.getShipbillId());
			// 父级运单编号
			lastSubTmsShipbillHeaderModel.setFatherShipbillNo(tmsShipbillHeaderModel.getShipbillNo());
			// 原始运单ID
			String originalShipbillId = tmsShipbillHeaderModel.getOriginalShipbillId() == null ? tmsShipbillHeaderModel.getShipbillId() : tmsShipbillHeaderModel.getOriginalShipbillId();
			lastSubTmsShipbillHeaderModel.setOriginalShipbillId(originalShipbillId);
			// 原始运单编号
			String originalShipbillNo = tmsShipbillHeaderModel.getOriginalShipbillNo() == null ? tmsShipbillHeaderModel.getShipbillNo() : tmsShipbillHeaderModel.getOriginalShipbillNo();
			lastSubTmsShipbillHeaderModel.setOriginalShipbillNo(originalShipbillNo);

			TransitDetailInfoVO lastTransDetailInfo = transitDetailInfoVOLists.get(transitDetailInfoVOLists.size() - 1);
			// 上一站的出发时间 -> 预计提货开始时间
			lastSubTmsShipbillHeaderModel.setEstimatedPickupStartTime(lastTransDetailInfo.getEstimatedSendStartTime());
			// 预计提货结束时间
			lastSubTmsShipbillHeaderModel.setEstimatedPickupEndTime(lastTransDetailInfo.getEstimatedSendEndTime());
			// 时效
			lastSubTmsShipbillHeaderModel.setTransportAging(getTransportAging(tmsShipbillHeaderModel.getEstimatedDeliveryEndTime(), lastTransDetailInfo.getEstimatedSendEndTime()));
			// 发货方单位ID
			lastSubTmsShipbillHeaderModel.setShipperUnitId(lastTransDetailInfo.getId());
			// 发货方单位编码
			lastSubTmsShipbillHeaderModel.setShipperUnitCode(lastTransDetailInfo.getCode());
			// 发货方单位名称
			lastSubTmsShipbillHeaderModel.setShipperUnitName(lastTransDetailInfo.getName());
			// 发货方联系人
			lastSubTmsShipbillHeaderModel.setShipperContact(lastTransDetailInfo.getContact());
			// 发货方手机号
			lastSubTmsShipbillHeaderModel.setShipperPhoneNumber(lastTransDetailInfo.getPhoneNumber());
			// 发货方座机号
			lastSubTmsShipbillHeaderModel.setShipperLandlineNumber(lastTransDetailInfo.getLandlineNumber());
			// 发货方邮箱
			lastSubTmsShipbillHeaderModel.setShipperEmail(lastTransDetailInfo.getEmail());
			// 发货方省编码
			lastSubTmsShipbillHeaderModel.setShipperProvince(lastTransDetailInfo.getProvince());
			// 发货方省名称
			lastSubTmsShipbillHeaderModel.setShipperProvinceName(lastTransDetailInfo.getProvinceName());
			// 发货方市编码
			lastSubTmsShipbillHeaderModel.setShipperCity(lastTransDetailInfo.getCity());
			// 发货方市名称
			lastSubTmsShipbillHeaderModel.setShipperCityName(lastTransDetailInfo.getCityName());
			// 发货方区/县编码
			lastSubTmsShipbillHeaderModel.setShipperDistrict(lastTransDetailInfo.getDistrict());
			// 发货方区/县名称
			lastSubTmsShipbillHeaderModel.setShipperDistrictName(lastTransDetailInfo.getDistrictName());
			// 发货方详细地址
			lastSubTmsShipbillHeaderModel.setShipperAddress(lastTransDetailInfo.getAddress());
			// 发货方经度
			lastSubTmsShipbillHeaderModel.setShipperLongitude(lastTransDetailInfo.getLongitude());
			// 发货方纬度
			lastSubTmsShipbillHeaderModel.setShipperLatitude(lastTransDetailInfo.getLatitude());
			// 发货方备注
			lastSubTmsShipbillHeaderModel.setShipperMemo(lastTransDetailInfo.getMemo());
			lastSubTmsShipbillHeaderModel.setUpdateperson(user.getNickname());
			lastSubTmsShipbillHeaderModel.setUpdatetime(date);
			lastSubTmsShipbillHeaderModel.setCreateperson(user.getNickname());
			lastSubTmsShipbillHeaderModel.setCreatetime(date);
			// 保存运单汇总
			lastSubTmsShipbillHeaderModel.setShipbillType(ShipBillTypeEnum.NORMAL.getCode());
			lastSubTmsShipbillHeaderModel.setSignInStatus(SignInStatusEnum.NOT_SIGN.getCode());
			lastSubTmsShipbillHeaderModel.setDriverReceiveStatus(DriverReceiveStatusEnum.N.getCode());
			lastSubTmsShipbillHeaderModel.setIntelligentLock(IntelligentLockEnum.UN_LOCK.getCode());
			tmsShipbillHeaderMapper.save(lastSubTmsShipbillHeaderModel);

			// 运输记录
			saveTransportLog(lastSubTmsShipbillHeaderModel.getShipbillId(), date, lastSubTmsShipbillHeaderModel.getEstimatedPickupStartTime());

			// 运单明细保存
			for (TmsShipbillDetailModel detailModel : tmsShipbillDetailModels) {
				TmsShipbillDetailModel subTmsShipbillDetailModel = new TmsShipbillDetailModel();
				// 运单明细ID
				RestMessage<String> restMessage4 = maindataTmsResource.getCodeNumberByCode(SeriaNnumberConstant.TMS_SHIPBILL_DETAIL_ID, "L");
				if (!restMessage4.isSuccess()) {
					throw new RuntimeException("生成运单明细ID失败");
				}
				String lastSubShipbillDetailId = restMessage4.getData();

				BeanUtils.copyProperties(detailModel, subTmsShipbillDetailModel);
				subTmsShipbillDetailModel.setId(lastSubShipbillDetailId);
				// 运单ID
				subTmsShipbillDetailModel.setShipbillId(lastSubTmsShipbillHeaderModel.getShipbillId());
				// 运单编号
				subTmsShipbillDetailModel.setShipbillNo(lastSubTmsShipbillHeaderModel.getShipbillNo());
				// 仓库ID
				subTmsShipbillDetailModel.setBranchId(lastSubTmsShipbillHeaderModel.getBranchId());
				// 仓库编码
				subTmsShipbillDetailModel.setBranchCode(lastSubTmsShipbillHeaderModel.getBranchCode());
				// 仓库名称
				subTmsShipbillDetailModel.setBranchName(lastSubTmsShipbillHeaderModel.getBranchName());

				subTmsShipbillDetailModel.setCreateperson(user.getNickname());
				subTmsShipbillDetailModel.setCreatetime(date);
				subTmsShipbillDetailModel.setUpdateperson(user.getNickname());
				subTmsShipbillDetailModel.setUpdatetime(date);
				subTmsShipbillDetailModel.setOrigPcs(subTmsShipbillDetailModel.getPcs());
				subTmsShipbillDetailModel.setClosingPcs(BigDecimal.valueOf(0));
				subTmsShipbillDetailModel.setDeliveryPcs(BigDecimal.valueOf(0));
				subTmsShipbillDetailModel.setFatherId(detailModel.getId());
				subTmsShipbillDetailModel.setScanStatus(DataDictionaryConstant.SCAN_STATUS_INIT);
				tmsShipbillDetailMapper.save(subTmsShipbillDetailModel);
			}
			// 子运单日志保存
			ShipbillOperateLogSaveVO subShipbillOperateLogSaveVO = new ShipbillOperateLogSaveVO();
			subShipbillOperateLogSaveVO.setShipbillId(lastSubTmsShipbillHeaderModel.getShipbillId());
			subShipbillOperateLogSaveVO.setShipbillNo(lastSubTmsShipbillHeaderModel.getShipbillNo());
			subShipbillOperateLogSaveVO.setOperateEvent(DataDictionaryConstant.SHIPBILL_EVENT_NAME_TRANSIT_SUB);
			subShipbillOperateLogSaveVO.setOldStatus(DataDictionaryConstant.SHIPBILL_STATUS_REVIEW);
			subShipbillOperateLogSaveVO.setNewStatus(DataDictionaryConstant.SHIPBILL_STATUS_REVIEW);
			shipbillOperateLogService.addShipbillOperateLogData(subShipbillOperateLogSaveVO);
			// 运单节点保存
			ShipbillNodeTrackingSaveVO shipbillNodeTrackingSaveVO = new ShipbillNodeTrackingSaveVO();
			shipbillNodeTrackingSaveVO.setShipbillId(lastSubTmsShipbillHeaderModel.getShipbillId());
			shipbillNodeTrackingSaveVO.setShipbillNo(lastSubTmsShipbillHeaderModel.getShipbillId());
			shipbillNodeTrackingSaveVO.setStatus(DataDictionaryConstant.SHIPBILL_STATUS_REVIEW);
			shipbillNodeTrackingSaveVO.setNodeEvent(DataDictionaryConstant.SHIPBILL_STATUSNAME_REW);
			shipbillNodeTrackingService.addShipbillNodeTrackingData(shipbillNodeTrackingSaveVO);

			// 子单的包裹信息维护
			// 原运单的包裹信息取得
			Criteria oldPakHeadCriteria = Criteria.forClass(TmsShipbillPackageModel.class);
			Restriction r3 = Restrictions.eq("shipbillId", shipbillId);
			Restriction r4 = Restrictions.eq("enterpriseId", user.getEnterpriseId());
			oldPakHeadCriteria.setRestriction(Restrictions.and(r3, r4));
			oldPakHeadCriteria.setOrder(Order.newInstance().desc(new String[] { "updatetime" }));
			List<TmsShipbillPackageModel> tmsShipbillPackageModels = tmsShipbillPackageMapper.findByCriteria(oldPakHeadCriteria);
			for (String newShipbillId : newShipbillIds) {
				for (TmsShipbillPackageModel oldPkg : tmsShipbillPackageModels) {
					// 运单包裹表ID
					RestMessage<String> restMessage4 = maindataTmsResource.getCodeNumberByCode(SeriaNnumberConstant.TMS_SHIPBILL_PACKAGE_ID, "L");
					if (!restMessage4.isSuccess()) {
						throw new RuntimeException("生成运单包裹表ID失败");
					}
					String newPkgId = restMessage4.getData();

					TmsShipbillPackageModel newPkg = new TmsShipbillPackageModel();
					BeanUtils.copyProperties(oldPkg, newPkg);
					newPkg.setId(newPkgId);
					newPkg.setShipbillId(newShipbillId);
					newPkg.setShipbillNo(newShipbillId);
					newPkg.setCreateperson(user.getNickname());
					newPkg.setCreatetime(date);
					newPkg.setUpdateperson(user.getNickname());
					newPkg.setUpdatetime(date);
					tmsShipbillPackageMapper.save(newPkg);
					// 原包裹明细取得
					Criteria oldPakDetailCriteria = Criteria.forClass(TmsShipbillPkgDetailModel.class);
					Restriction r5 = Restrictions.eq("shipbillId", shipbillId);
					Restriction r6 = Restrictions.eq("packageId", oldPkg.getPackageId());
					Restriction r7 = Restrictions.eq("enterpriseId", user.getEnterpriseId());
					oldPakDetailCriteria.setRestriction(Restrictions.and(r5, r6, r7));
					oldPakDetailCriteria.setOrder(Order.newInstance().desc(new String[] { "updatetime" }));
					List<TmsShipbillPkgDetailModel> tmsShipbillPkgDetailModels = tmsShipbillPackageDetailMapper.findByCriteria(oldPakDetailCriteria);
					for (TmsShipbillPkgDetailModel oldPkgDetail : tmsShipbillPkgDetailModels) {
						// 运单包裹明细表ID
						RestMessage<String> restMessage5 = maindataTmsResource.getCodeNumberByCode(SeriaNnumberConstant.TMS_SHIPBILL_PACKAGE_DETAIL_ID, "L");
						if (!restMessage5.isSuccess()) {
							throw new RuntimeException("生成运单包裹明细表ID失败");
						}
						String newPkgDetailId = restMessage5.getData();
						TmsShipbillPkgDetailModel newPkgDetail = new TmsShipbillPkgDetailModel();
						BeanUtils.copyProperties(oldPkgDetail, newPkgDetail);
						newPkgDetail.setId(newPkgDetailId);
						newPkgDetail.setShipbillId(newShipbillId);
						newPkgDetail.setShipbillNo(newShipbillId);
						newPkgDetail.setCreateperson(user.getNickname());
						newPkgDetail.setCreatetime(date);
						newPkgDetail.setUpdateperson(user.getNickname());
						newPkgDetail.setUpdatetime(date);
						tmsShipbillPackageDetailMapper.save(newPkgDetail);
					}
				}
			}
		}
		if (ToolKits.isNotEmpty(transitVO.getShipbillIdList())) {
			updatePlanBill(transitVO.getShipbillIdList(), user);
		}
	}

	/**
	 * 地址解析查询
	 */
	@SuppressWarnings("resource")
	@Override
	public Page<PendingDispatchAddressPageDTO> parseAddressQueryData(PendingDispatchAddressPageVO pendingDispatchAddressPageVO) {
		ToolKits.isParamNull(pendingDispatchAddressPageVO, "地址解析查询请求不为空");
		ToolKits.isParamNull(pendingDispatchAddressPageVO.getPageNum(), "当前页码不为空");
		ToolKits.isParamNull(pendingDispatchAddressPageVO.getPageSize(), "每页条数不为空");
		ToolKits.isParamNull(pendingDispatchAddressPageVO.getShipbillIds(), "运单ID集不为空");

		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.SHIPPER_TYPE, null, null, null);
		if (!restMessage1.isSuccess()) {
			throw new RuntimeException("发货方类型翻译失败!");
		} else {
			data1 = restMessage1.getData();
		}
		// 收货方类型
		RestMessage<List<Map<String, Object>>> restMessage2 = maindataTmsResource.getDropDownById(DataDictionaryConstant.CONSIGNEE_TYPE, null, null, null);
		if (!restMessage2.isSuccess()) {
			throw new RuntimeException("收货方类型翻译失败!");
		} else {
			data2 = restMessage2.getData();
		}

		// 添加查询条件
		Criteria criteria = Criteria.forClass(TmsShipbillHeaderModel.class);
		Restriction r1 = ToolKits.isEmpty(pendingDispatchAddressPageVO.getOrderNo()) ? null : Restrictions.like("orderNo", "%" + pendingDispatchAddressPageVO.getOrderNo() + "%");
		Restriction r2 = ToolKits.isEmpty(pendingDispatchAddressPageVO.getShipbillNo()) ? null : Restrictions.like("shipbillNo", "%" + pendingDispatchAddressPageVO.getShipbillNo() + "%");
		Restriction r3 = ToolKits.isEmpty(pendingDispatchAddressPageVO.getCargoOwnerName()) ? null : Restrictions.like("cargoOwnerName", "%" + pendingDispatchAddressPageVO.getCargoOwnerName() + "%");
		Restriction r4 = ToolKits.isEmpty(pendingDispatchAddressPageVO.getShipperUnitName()) ? null : Restrictions.like("shipperUnitName", "%" + pendingDispatchAddressPageVO.getShipperUnitName() + "%");
		Restriction r5 = ToolKits.isEmpty(pendingDispatchAddressPageVO.getConsigneeUnitName()) ? null : Restrictions.like("consigneeUnitName", "%" + pendingDispatchAddressPageVO.getConsigneeUnitName() + "%");
		Restriction r6 = Restrictions.in("shipbillId", pendingDispatchAddressPageVO.getShipbillIds().toArray());
		Restriction r8 = Restrictions.eq("enterpriseId", user.getEnterpriseId());

		// 权限控制
		Restriction r7 = null;
		Restriction r11 = null;
		Restriction r12 = null;
		Restriction r13 = null;
		Restriction r14 = null;
		Restriction r15 = null;
		Restriction r16 = null;
		// 判断账号类型
		if (user.getUserType().equals(BussinessConstant.USER_TYPE_ZY)) {
			// 自有账号
			// 判断是否为部门权限
			r7 = Restrictions.in("status", new Integer[] { DataDictionaryConstant.SHIPBILL_STATUS_REVIEW });
			if (user.getOwnedAllDataAuthFlag().equals(BussinessConstant.USER_DEPARTMENT_AUTH_Y)) {
				r11 = Restrictions.in("departmentId", user.getDepts().stream().toArray(String[]::new));
			} else {
				r11 = Restrictions.in("departmentId", user.getDepts().stream().toArray(String[]::new));
				// 其它权限
				// 货主
				r12 = Restrictions.in("cargoOwnerId", user.getConsignors().toArray());
				// 客户
				r13 = Restrictions.in("consigneeUnitId", user.getCustomers().toArray());
				// 供应商
				r14 = Restrictions.in("consigneeUnitId", user.getSuppliers().toArray());
				// 仓库
				r15 = Restrictions.in("consigneeUnitId", user.getWarehouses().toArray());

				r16 = Restrictions.or(r13, r14, r15);
			}
		} else if (user.getUserType().equals(BussinessConstant.USER_TYPE_CYS)) {
			// 运单状态
			r7 = Restrictions.in("status", new Integer[] { DataDictionaryConstant.SHIPBILL_STATUS_DISPATCH });
			// 承运商账号
			r11 = Restrictions.eq("carrierId", Long.valueOf(user.getLoginUserCompanyInfo().getId()));
			// 承运商运单状态
			r12 = Restrictions.in("carrierShipbillStatus", new Integer[] { DataDictionaryConstant.CARRIER_SHIPBILL_STATUS_AUDITED });
		} else {
			throw new BizException("当前人员没有操作权限！");
		}

		criteria.setRestriction(Restrictions.and(r1, r2, r3, r4, r5, r6, r7, r8, r11, r12, r16));
		criteria.setOrder(Order.newInstance().desc(new String[] { "updatetime" }));
		PageUtils.startPage(pendingDispatchAddressPageVO.getPageNum(), pendingDispatchAddressPageVO.getPageSize());
		List<TmsShipbillHeaderModel> tmsShipbillHeaderModels = tmsShipbillHeaderMapper.findByCriteria(criteria);

		List<PendingDispatchAddressPageDTO> pendingDispatchAddressPageDTOs = Lists.newArrayList();
		for (TmsShipbillHeaderModel tmsShipbillHeaderModel : tmsShipbillHeaderModels) {
			PendingDispatchAddressPageDTO pendingDispatchAddressPageDTO = new PendingDispatchAddressPageDTO();
			BeanUtils.copyProperties(tmsShipbillHeaderModel, pendingDispatchAddressPageDTO);
			pendingDispatchAddressPageDTO.setShipperTypeName(PublicMethods.change(data1, String.valueOf(pendingDispatchAddressPageDTO.getShipperType())));
			pendingDispatchAddressPageDTO.setConsigneeTypeName(PublicMethods.change(data2, String.valueOf(pendingDispatchAddressPageDTO.getConsigneeType())));

			pendingDispatchAddressPageDTOs.add(pendingDispatchAddressPageDTO);
		}

		// 分页重组
		Page<PendingDispatchAddressPageDTO> page = PageUtils.getPage(pendingDispatchAddressPageDTOs);
		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;
	}

	/**
	 * 待调度地址解析
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void parseAddressData(PendingDispatchParseAddressVO vo) {
		UserEntity user = PlgFxUsrUtils.getUserEntity();
		ToolKits.isParamNull(user, "当前人员没有操作权限");

		ToolKits.isParamNull(vo, "运单地址解析请求不为空！");
		ToolKits.isParamNull(vo.getShipperId(), "运单ID不为空");

		// 是否更新发货方
		Boolean updateShipperSign = false;
		// 是否更新收货方
		Boolean updateConsigneeSign = false;

		if (ToolKits.isNotEmpty(vo.getConsigneeAddress()) || ToolKits.isNotEmpty(vo.getConsigneeLatitude()) || ToolKits.isNotEmpty(vo.getConsigneeLongitude())) {
			ToolKits.isParamNull(vo.getConsigneeId(), "收货方ID不为空");
			updateConsigneeSign = true;
		}

		if (ToolKits.isNotEmpty(vo.getShipperAddress()) || ToolKits.isNotEmpty(vo.getShipperLatitude()) || ToolKits.isNotEmpty(vo.getShipperLongitude())) {
			ToolKits.isParamNull(vo.getShipperId(), "发货方ID不为空");
			updateShipperSign = true;
		}

		TmsShipbillHeaderModel model = tmsShipbillHeaderMapper.findById(vo.getShipbillId(), TmsShipbillHeaderModel.class);

		RestMessage<String> restMessage = new RestMessage<String>();
		// 更新发货方数据
		if (updateShipperSign) {
			if (DataDictionaryConstant.SHIPPER_TYPE_KH.equals(model.getShipperType())) {
				restMessage = maindataTmsResource.parseCustomerConsigneeAddress(vo.getShipperId(), vo.getShipperLongitude(), vo.getShipperLatitude(), vo.getShipperAddress());
			} else if (DataDictionaryConstant.SHIPPER_TYPE_CK.equals(model.getShipperType())) {
				restMessage = maindataTmsResource.parseBranchAddress(vo.getShipperId(), vo.getShipperLongitude(), vo.getShipperLatitude(), vo.getShipperAddress());
			} else if (DataDictionaryConstant.SHIPPER_TYPE_GYS.equals(model.getShipperType())) {
				restMessage = maindataTmsResource.parseProviderShipperAddress(vo.getShipperId(), vo.getShipperLongitude(), vo.getShipperLatitude(), vo.getShipperAddress());
			}

			if (!restMessage.isSuccess()) {
				throw new ParameterException("更新发货方失败");
			}
		}

		// 更新收货方数据
		if (updateConsigneeSign) {
			if (DataDictionaryConstant.CONSIGNEE_TYPE_KH.equals(model.getConsigneeType())) {
				restMessage = maindataTmsResource.parseCustomerConsigneeAddress(vo.getConsigneeId(), vo.getConsigneeLongitude(), vo.getConsigneeLatitude(), vo.getConsigneeAddress());
			} else if (DataDictionaryConstant.CONSIGNEE_TYPE_CK.equals(model.getConsigneeType())) {
				restMessage = maindataTmsResource.parseBranchAddress(vo.getConsigneeId(), vo.getConsigneeLongitude(), vo.getConsigneeLatitude(), vo.getConsigneeAddress());
			} else if (DataDictionaryConstant.CONSIGNEE_TYPE_GYS.equals(model.getConsigneeType())) {
				restMessage = maindataTmsResource.parseProviderShipperAddress(vo.getConsigneeId(), vo.getConsigneeLongitude(), vo.getConsigneeLatitude(), vo.getConsigneeAddress());
			}

			if (!restMessage.isSuccess()) {
				throw new ParameterException("更新收货方失败");
			}
		}

		model.setShipperLatitude(vo.getShipperLatitude());
		model.setShipperLongitude(vo.getShipperLongitude());
		model.setShipperAddress(ToolKits.isEmpty(vo.getShipperAddress()) ? null : vo.getShipperAddress());

		model.setConsigneeLatitude(vo.getConsigneeLatitude());
		model.setConsigneeLatitude(vo.getConsigneeLatitude());
		model.setConsigneeAddress(ToolKits.isEmpty(vo.getConsigneeAddress()) ? null : vo.getConsigneeAddress());

		model.setUpdateperson(user.getNickname());
		model.setUpdatetime(DateUtil.date());
		tmsShipbillHeaderMapper.update(model);

		// 运单操作日志保存
		ShipbillOperateLogSaveVO shipbillOperateLogSaveVO = new ShipbillOperateLogSaveVO();
		shipbillOperateLogSaveVO.setShipbillId(model.getShipbillId());
		shipbillOperateLogSaveVO.setShipbillNo(model.getShipbillNo());
		shipbillOperateLogSaveVO.setOperateEvent(DataDictionaryConstant.SHIPBILL_OPERATENAME_XG);
		shipbillOperateLogSaveVO.setOldStatus(model.getStatus());
		shipbillOperateLogSaveVO.setNewStatus(model.getStatus());
		shipbillOperateLogService.addShipbillOperateLogData(shipbillOperateLogSaveVO);
	}

	/**
	 * 待调度运单打印
	 *
	 * @param id
	 * @return
	 */
	@Override
	public Map<String, Object> shipbillPrint(String id) {
		ToolKits.isParamNull(id, "运单ID不为空");

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

		// 查询运单信息
		TmsShipbillHeaderModel tmsShipbillHeaderModel = tmsShipbillHeaderMapper.findById(id, TmsShipbillHeaderModel.class);

		ToolKits.isParamNull(tmsShipbillHeaderModel, "运单ID[" + id + "]信息不存在");

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

		// 订单类型
		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();
		}

		// 打印头部数据
		PendingDispatchPrintHeadDTO printHeadDTO = new PendingDispatchPrintHeadDTO();
		BeanUtils.copyProperties(tmsShipbillHeaderModel, printHeadDTO);

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

		StringBuffer consigneeProvinceCityDistrict = new StringBuffer();
		// 目的地
		consigneeProvinceCityDistrict.append(ToolKits.isEmpty(tmsShipbillHeaderModel.getConsigneeProvinceName()) ? "" : tmsShipbillHeaderModel.getConsigneeProvinceName());
		consigneeProvinceCityDistrict.append(ToolKits.isEmpty(tmsShipbillHeaderModel.getConsigneeCityName()) ? "" : tmsShipbillHeaderModel.getConsigneeCityName());
		consigneeProvinceCityDistrict.append(ToolKits.isEmpty(tmsShipbillHeaderModel.getConsigneeDistrictName()) ? "" : tmsShipbillHeaderModel.getConsigneeDistrictName());
		printHeadDTO.setConsigneeProvinceCityDistrict(consigneeProvinceCityDistrict.toString());
		// 始发地
		StringBuffer shipperProvinceCityDistrict = new StringBuffer();
		shipperProvinceCityDistrict.append(ToolKits.isEmpty(tmsShipbillHeaderModel.getShipperProvinceName()) ? "" : tmsShipbillHeaderModel.getShipperProvinceName());
		shipperProvinceCityDistrict.append(ToolKits.isEmpty(tmsShipbillHeaderModel.getShipperCityName()) ? "" : tmsShipbillHeaderModel.getShipperCityName());
		shipperProvinceCityDistrict.append(ToolKits.isEmpty(tmsShipbillHeaderModel.getShipperDistrictName()) ? "" : tmsShipbillHeaderModel.getShipperDistrictName());
		printHeadDTO.setShipperProvinceCityDistrict(shipperProvinceCityDistrict.toString());

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

		// 获取商品信息
		// 数据字典翻译数据集合
		List<Map<String, Object>> data8 = Lists.newArrayList();
		List<Map<String, Object>> data9 = Lists.newArrayList();

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

		Criteria criteria = Criteria.forClass(TmsShipbillDetailModel.class);
		Restriction r1 = Restrictions.eq("shipbillId", id);
		criteria.setRestriction(r1);
		List<TmsShipbillDetailModel> tmsShipbillDetailModels = tmsShipbillDetailMapper.findByCriteria(criteria);

		List<PendingDispatchPrintDetailDTO> shipbillPSPrintTableDTOs = new ArrayList<PendingDispatchPrintDetailDTO>();

		if (ToolKits.isNotEmpty(tmsShipbillDetailModels)) {
			for (TmsShipbillDetailModel item : tmsShipbillDetailModels) {
				PendingDispatchPrintDetailDTO dto = new PendingDispatchPrintDetailDTO();
				BeanUtils.copyProperties(item, dto);
				dto.setPackTypeName(PublicMethods.change(data8, String.valueOf(item.getPackType())));
				dto.setCargoThermosphereName(PublicMethods.change(data9, String.valueOf(item.getCargoThermosphere())));
				shipbillPSPrintTableDTOs.add(dto);
			}
		}

		// TODO print
		return null;
	}

	/**
	 * 待调度导出所有数据
	 *
	 * @param pendingDispatchExportAllDataVO
	 * @return
	 */
	@Override
	public List<PendingDispatchExportDetailDataDTO> exportAllDetailData(PendingDispatchExportAllDataVO pendingDispatchExportAllDataVO) {
		ToolKits.isParamNull(pendingDispatchExportAllDataVO, "导出所有数据查询条件不为空");

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

		if (ToolKits.isNotEmpty(pendingDispatchExportAllDataVO.getCargoOwnerIds())) {
			String[] ids = pendingDispatchExportAllDataVO.getCargoOwnerIds().split(",");
			pendingDispatchExportAllDataVO.setCargoOwnerIdList(Arrays.stream(ids).map(id -> Long.valueOf(id)).collect(Collectors.toList()));
		}
		if (ToolKits.isNotEmpty(pendingDispatchExportAllDataVO.getLineIds())) {
			String[] ids = pendingDispatchExportAllDataVO.getLineIds().split(",");
			pendingDispatchExportAllDataVO.setLineIdList(Arrays.stream(ids).map(id -> Long.valueOf(id)).collect(Collectors.toList()));
		}
		List<ZoneVO> shipperAdministrativeAreas = pendingDispatchExportAllDataVO.getShipperAdministrativeAreas();
		if (ToolKits.isNotEmpty(shipperAdministrativeAreas)) {
			List<String> provinceList = parseCode(shipperAdministrativeAreas, "province");
			if (ToolKits.isNotEmpty(provinceList)) {
				pendingDispatchExportAllDataVO.setShipperProvinceList(provinceList);
			}
			List<String> cityList = parseCode(shipperAdministrativeAreas, "city");
			if (ToolKits.isNotEmpty(cityList)) {
				pendingDispatchExportAllDataVO.setShipperCityList(cityList);
			}
			List<String> districtList = parseCode(shipperAdministrativeAreas, "district");
			if (ToolKits.isNotEmpty(districtList)) {
				pendingDispatchExportAllDataVO.setShipperDistrictList(districtList);
			}
		}
		List<ZoneVO> consigneeAdministrativeAreas = pendingDispatchExportAllDataVO.getAdministrativeAreas();
		if (ToolKits.isNotEmpty(consigneeAdministrativeAreas)) {
			List<String> provinceList = parseCode(consigneeAdministrativeAreas, "province");
			if (ToolKits.isNotEmpty(provinceList)) {
				pendingDispatchExportAllDataVO.setConsigneeProvinceList(provinceList);
			}
			List<String> cityList = parseCode(consigneeAdministrativeAreas, "city");
			if (ToolKits.isNotEmpty(cityList)) {
				pendingDispatchExportAllDataVO.setConsigneeCityList(cityList);
			}
			List<String> districtList = parseCode(consigneeAdministrativeAreas, "district");
			if (ToolKits.isNotEmpty(districtList)) {
				pendingDispatchExportAllDataVO.setConsigneeDistrictList(districtList);
			}
		}
		// 数据字典翻译数据集合
		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.ORDER_BUSINESS_TYPE // 订单业务类型
		});

		// 添加查询条件
		Criteria criteria = Criteria.forClass(TmsShipbillHeaderModel.class);
		Restriction r1 = ToolKits.isEmpty(pendingDispatchExportAllDataVO.getCargoOwnerIdList()) ? null : Restrictions.in("cargoOwnerId", pendingDispatchExportAllDataVO.getCargoOwnerIdList().stream().toArray(Long[]::new));
		Restriction r2 = ToolKits.isEmpty(pendingDispatchExportAllDataVO.getOrderNo()) ? null : Restrictions.like("orderNo", "%" + pendingDispatchExportAllDataVO.getOrderNo() + "%");
		Restriction r3 = ToolKits.isEmpty(pendingDispatchExportAllDataVO.getShipbillNo()) ? null : Restrictions.like("shipbillNo", "%" + pendingDispatchExportAllDataVO.getShipbillNo() + "%");
		Restriction r4 = ToolKits.isEmpty(pendingDispatchExportAllDataVO.getOrderBusinessType()) ? null : Restrictions.eq("orderBusinessType", pendingDispatchExportAllDataVO.getOrderBusinessType());
		Restriction r5 = ToolKits.isEmpty(pendingDispatchExportAllDataVO.getEstimatedPickupStartTime()) ? null : Restrictions.ge("estimatedPickupStartTime", pendingDispatchExportAllDataVO.getEstimatedPickupStartTime());
		Restriction r6 = ToolKits.isEmpty(pendingDispatchExportAllDataVO.getEstimatedPickupEndTime()) ? null : Restrictions.le("estimatedPickupEndTime", pendingDispatchExportAllDataVO.getEstimatedPickupEndTime());
		Restriction r7 = ToolKits.isEmpty(pendingDispatchExportAllDataVO.getEstimatedDeliveryStartTime()) ? null : Restrictions.ge("estimatedDeliveryStartTime", pendingDispatchExportAllDataVO.getEstimatedDeliveryStartTime());
		Restriction r8 = ToolKits.isEmpty(pendingDispatchExportAllDataVO.getEstimatedDeliveryEndTime()) ? null : Restrictions.le("estimatedDeliveryEndTime", pendingDispatchExportAllDataVO.getEstimatedDeliveryEndTime());
		Restriction r9 = ToolKits.isEmpty(pendingDispatchExportAllDataVO.getLineIdList()) ? null : Restrictions.in("lineId", pendingDispatchExportAllDataVO.getLineIdList().stream().toArray(Long[]::new));

		Restriction r10 = ToolKits.isEmpty(pendingDispatchExportAllDataVO.getShipperProvinceList()) ? null : Restrictions.in(TmsShipbillHeaderModel::getShipperProvince, pendingDispatchExportAllDataVO.getShipperProvinceList().stream().toArray(String[]::new));
		Restriction r44 = ToolKits.isEmpty(pendingDispatchExportAllDataVO.getShipperCityList()) ? null : Restrictions.in(TmsShipbillHeaderModel::getShipperCity, pendingDispatchExportAllDataVO.getShipperCityList().stream().toArray(String[]::new));
		Restriction r45 = ToolKits.isEmpty(pendingDispatchExportAllDataVO.getShipperDistrictList()) ? null : Restrictions.in(TmsShipbillHeaderModel::getShipperDistrict, pendingDispatchExportAllDataVO.getShipperDistrictList().stream().toArray(String[]::new));
		Restriction r55 = Restrictions.or(r10, r44, r45);

		Restriction r11 = ToolKits.isEmpty(pendingDispatchExportAllDataVO.getConsigneeProvinceList()) ? null : Restrictions.in(TmsShipbillHeaderModel::getConsigneeProvince, pendingDispatchExportAllDataVO.getConsigneeProvinceList().stream().toArray(String[]::new));
		Restriction r46 = ToolKits.isEmpty(pendingDispatchExportAllDataVO.getConsigneeCityList()) ? null : Restrictions.in(TmsShipbillHeaderModel::getConsigneeCity, pendingDispatchExportAllDataVO.getConsigneeCityList().stream().toArray(String[]::new));
		Restriction r47 = ToolKits.isEmpty(pendingDispatchExportAllDataVO.getConsigneeDistrictList()) ? null : Restrictions.in(TmsShipbillHeaderModel::getConsigneeDistrict, pendingDispatchExportAllDataVO.getConsigneeDistrictList().stream().toArray(String[]::new));
		Restriction r58 = Restrictions.or(r11, r46, r47);

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

		Restriction r15 = null;
		Restriction r23 = 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 r33 = Restrictions.in(TmsShipbillHeaderModel::getShipperUnitId, user.getWarehouses().stream().toArray(Long[]::new));
				Restriction r34 = Restrictions.in(TmsShipbillHeaderModel::getShipperUnitId, user.getSuppliers().stream().toArray(Long[]::new));
				Restriction r35 = Restrictions.in(TmsShipbillHeaderModel::getShipperUnitId, user.getCustomers().stream().toArray(Long[]::new));

				Restriction r21 = Restrictions.or(r18, r19, r20, r33, r34, r35);
				r15 = Restrictions.and(r16, r17, r21);
			}
		} else {
			// 非自有账号
			r13 = Restrictions.eq("carrierSplitOrderStatus", DataDictionaryConstant.CARRIER_SPLIT_ORDER_STATUS_UN);
			Restriction r16 = Restrictions.eq("carrierId", Long.valueOf(user.getLoginUserCompanyInfo().getId()));
			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);
		}

		Restriction r17 = null;
		if (ToolKits.isNotEmpty(pendingDispatchExportAllDataVO.getShipperLocation()) && pendingDispatchExportAllDataVO.getShipperLocation().intValue() == 0) {
			Restriction r18 = Restrictions.isnull("shipperLongitude");
			Restriction r19 = Restrictions.isnull("shipperLatitude");
			r17 = Restrictions.or(r18, r19);
		} else if (ToolKits.isNotEmpty(pendingDispatchExportAllDataVO.getShipperLocation()) && pendingDispatchExportAllDataVO.getShipperLocation().intValue() == 1) {
			Restriction r18 = Restrictions.isNotNull("shipperLongitude");
			Restriction r19 = Restrictions.isNotNull("shipperLatitude");
			r17 = Restrictions.and(r18, r19);
		}
		Restriction r20 = null;
		if (ToolKits.isNotEmpty(pendingDispatchExportAllDataVO.getConsigneeLocation()) && pendingDispatchExportAllDataVO.getConsigneeLocation().intValue() == 0) {
			Restriction r18 = Restrictions.isnull("consigneeLongitude");
			Restriction r19 = Restrictions.isnull("consigneeLatitude");
			r20 = Restrictions.or(r18, r19);
		} else if (ToolKits.isNotEmpty(pendingDispatchExportAllDataVO.getConsigneeLocation()) && pendingDispatchExportAllDataVO.getConsigneeLocation().intValue() == 1) {
			Restriction r18 = Restrictions.isNotNull("consigneeLongitude");
			Restriction r19 = Restrictions.isNotNull("consigneeLatitude");
			r20 = Restrictions.and(r18, r19);
		}
		Restriction r57 = ToolKits.isEmpty(pendingDispatchExportAllDataVO.getRecordTagWord()) ? null : Restrictions.like(TmsShipbillHeaderModel::getRecordTagWord, "%" + pendingDispatchExportAllDataVO.getRecordTagWord() + "%");
        Restriction r59 = ToolKits.isEmpty(pendingDispatchExportAllDataVO.getOrderDateStart()) ? null : Restrictions.ge(TmsShipbillHeaderModel::getOrderDate, pendingDispatchExportAllDataVO.getOrderDateStart());
        Restriction r60 = ToolKits.isEmpty(pendingDispatchExportAllDataVO.getOrderDateEnd()) ? null : Restrictions.le(TmsShipbillHeaderModel::getOrderDate, pendingDispatchExportAllDataVO.getOrderDateEnd());

		Restriction r61 = ToolKits.isEmpty(pendingDispatchExportAllDataVO.getCreateDateStart()) ? null : Restrictions.ge(TmsShipbillHeaderModel::getCreatetime, pendingDispatchExportAllDataVO.getCreateDateStart());
		Restriction r62 = ToolKits.isEmpty(pendingDispatchExportAllDataVO.getCreateDateEnd()) ? null : Restrictions.le(TmsShipbillHeaderModel::getCreatetime, pendingDispatchExportAllDataVO.getCreateDateEnd());
		Restriction r63 = Restrictions.gt(TmsShipbillHeaderModel::getTotalPcs, BigDecimal.valueOf(0));

		Restriction r64 = ToolKits.isEmpty(pendingDispatchExportAllDataVO.getCreateperson()) ? null : Restrictions.in(TmsShipbillHeaderModel::getCreateperson, pendingDispatchExportAllDataVO.getCreateperson().split(","));
		Restriction r65 = ToolKits.isEmpty(pendingDispatchExportAllDataVO.getConsigneeType()) ? null : Restrictions.eq(TmsShipbillHeaderModel::getConsigneeType, pendingDispatchExportAllDataVO.getConsigneeType());
		Restriction r66 = ToolKits.isEmpty(pendingDispatchExportAllDataVO.getConsigneeId()) ? null : Restrictions.in(TmsShipbillHeaderModel::getConsigneeId, pendingDispatchExportAllDataVO.getConsigneeId().split(","));
		Restriction r67 = ToolKits.isEmpty(pendingDispatchExportAllDataVO.getConsigneeStationId()) ? null : Restrictions.in(TmsShipbillHeaderModel::getConsigneeStationId, pendingDispatchExportAllDataVO.getConsigneeStationId().split(","));
		Restriction r68 = ToolKits.isEmpty(pendingDispatchExportAllDataVO.getConsigneeAddress()) ? null : Restrictions.likeAll(TmsShipbillHeaderModel::getConsigneeAddress, pendingDispatchExportAllDataVO.getConsigneeAddress());
		Restriction r69 = Restrictions.eq(TmsShipbillHeaderModel::getIntelligentLock, 0);
		Restriction r70 = ToolKits.isEmpty(pendingDispatchExportAllDataVO.getCarriersId()) ? null : Restrictions.eq(TmsShipbillHeaderModel::getCarriersId, pendingDispatchExportAllDataVO.getCarriersId());

		criteria.setRestriction(Restrictions.and(r1, r2, r3, r4, r5, r6, r7, r8, r9, r55, r57, r58, r12, r13, r14, r15, r22, r23, r17, r20, r59, r60, r61, r62, r63, r64, r65, r66, r67, r68,r69,r70));
		criteria.setOrder(Order.newInstance().desc(new String[] { "updatetime" }));

		List<TmsShipbillHeaderModel> tmsShipbillHeaderModels = tmsShipbillHeaderMapper.findByCriteria(criteria);

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

		for (TmsShipbillHeaderModel tmsShipbillHeaderModel : tmsShipbillHeaderModels) {
			PendingDispatchExportDetailDataDTO exportDetailDataDTO = new PendingDispatchExportDetailDataDTO();
			BeanUtils.copyProperties(tmsShipbillHeaderModel, exportDetailDataDTO);
			// 收货方位置(经纬度判断)
			if (ToolKits.isNotEmpty(tmsShipbillHeaderModel.getConsigneeLongitude()) && ToolKits.isNotEmpty(tmsShipbillHeaderModel.getConsigneeLatitude())) {
				exportDetailDataDTO.setConsigneePositioning(StatusConstant.POSITIONING_YDW);
			} else {
				exportDetailDataDTO.setConsigneePositioning(StatusConstant.POSITIONING_WDW);
			}
			// 发货方位置(经纬度判断)
			if (ToolKits.isNotEmpty(tmsShipbillHeaderModel.getShipperLongitude()) && ToolKits.isNotEmpty(tmsShipbillHeaderModel.getShipperLatitude())) {
				exportDetailDataDTO.setShipperPositioning(StatusConstant.POSITIONING_YDW);
			} else {
				exportDetailDataDTO.setShipperPositioning(StatusConstant.POSITIONING_WDW);
			}
			StringBuffer consigneeProvinceCityDistrict = new StringBuffer();
			// 目的地
			consigneeProvinceCityDistrict.append(ToolKits.isEmpty(tmsShipbillHeaderModel.getConsigneeProvinceName()) ? "" : tmsShipbillHeaderModel.getConsigneeProvinceName());
			consigneeProvinceCityDistrict.append(ToolKits.isEmpty(tmsShipbillHeaderModel.getConsigneeCityName()) ? "" : tmsShipbillHeaderModel.getConsigneeCityName());
			consigneeProvinceCityDistrict.append(ToolKits.isEmpty(tmsShipbillHeaderModel.getConsigneeDistrictName()) ? "" : tmsShipbillHeaderModel.getConsigneeDistrictName());
			exportDetailDataDTO.setConsigneeProvinceCityDistrict(consigneeProvinceCityDistrict.toString());
			// 始发地
			StringBuffer shipperProvinceCityDistrict = new StringBuffer();
			shipperProvinceCityDistrict.append(ToolKits.isEmpty(tmsShipbillHeaderModel.getShipperProvinceName()) ? "" : tmsShipbillHeaderModel.getShipperProvinceName());
			shipperProvinceCityDistrict.append(ToolKits.isEmpty(tmsShipbillHeaderModel.getShipperCityName()) ? "" : tmsShipbillHeaderModel.getShipperCityName());
			shipperProvinceCityDistrict.append(ToolKits.isEmpty(tmsShipbillHeaderModel.getShipperDistrictName()) ? "" : tmsShipbillHeaderModel.getShipperDistrictName());
			exportDetailDataDTO.setShipperProvinceCityDistrict(shipperProvinceCityDistrict.toString());

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

			pendingDispatchExportDetailDataDTOList.add(exportDetailDataDTO);
		}
		return pendingDispatchExportDetailDataDTOList;
	}

	/**
	 * 待调度导出当前页数据
	 *
	 * @param currenPageDataVO
	 * @return
	 */
	@Override
	public List<PendingDispatchExportDetailDataDTO> exportCurrentPageDetailData(PendingDispatchExportCurrenPageDataVO currenPageDataVO) {
		ToolKits.isParamNull(currenPageDataVO, "导出当前页数据查询条件不为空");

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

		if (ToolKits.isNotEmpty(currenPageDataVO.getCargoOwnerIds())) {
			String[] ids = currenPageDataVO.getCargoOwnerIds().split(",");
			currenPageDataVO.setCargoOwnerIdList(Arrays.stream(ids).map(id -> Long.valueOf(id)).collect(Collectors.toList()));
		}
		if (ToolKits.isNotEmpty(currenPageDataVO.getLineIds())) {
			String[] ids = currenPageDataVO.getLineIds().split(",");
			currenPageDataVO.setLineIdList(Arrays.stream(ids).map(id -> Long.valueOf(id)).collect(Collectors.toList()));
		}
		List<ZoneVO> shipperAdministrativeAreas = currenPageDataVO.getShipperAdministrativeAreas();
		if (ToolKits.isNotEmpty(shipperAdministrativeAreas)) {
			List<String> provinceList = parseCode(shipperAdministrativeAreas, "province");
			if (ToolKits.isNotEmpty(provinceList)) {
				currenPageDataVO.setShipperProvinceList(provinceList);
			}
			List<String> cityList = parseCode(shipperAdministrativeAreas, "city");
			if (ToolKits.isNotEmpty(cityList)) {
				currenPageDataVO.setShipperCityList(cityList);
			}
			List<String> districtList = parseCode(shipperAdministrativeAreas, "district");
			if (ToolKits.isNotEmpty(districtList)) {
				currenPageDataVO.setShipperDistrictList(districtList);
			}
		}
		List<ZoneVO> consigneeAdministrativeAreas = currenPageDataVO.getAdministrativeAreas();
		if (ToolKits.isNotEmpty(consigneeAdministrativeAreas)) {
			List<String> provinceList = parseCode(consigneeAdministrativeAreas, "province");
			if (ToolKits.isNotEmpty(provinceList)) {
				currenPageDataVO.setConsigneeProvinceList(provinceList);
			}
			List<String> cityList = parseCode(consigneeAdministrativeAreas, "city");
			if (ToolKits.isNotEmpty(cityList)) {
				currenPageDataVO.setConsigneeCityList(cityList);
			}
			List<String> districtList = parseCode(consigneeAdministrativeAreas, "district");
			if (ToolKits.isNotEmpty(districtList)) {
				currenPageDataVO.setConsigneeDistrictList(districtList);
			}
		}
		// 数据字典翻译数据集合
		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.ORDER_BUSINESS_TYPE // 订单业务类型
		});

		// 添加查询条件
		Criteria criteria = Criteria.forClass(TmsShipbillHeaderModel.class);
		Restriction r1 = ToolKits.isEmpty(currenPageDataVO.getCargoOwnerIdList()) ? null : Restrictions.in("cargoOwnerId", currenPageDataVO.getCargoOwnerIdList().stream().toArray(Long[]::new));
		Restriction r2 = ToolKits.isEmpty(currenPageDataVO.getOrderNo()) ? null : Restrictions.like("orderNo", "%" + currenPageDataVO.getOrderNo() + "%");
		Restriction r3 = ToolKits.isEmpty(currenPageDataVO.getShipbillNo()) ? null : Restrictions.like("shipbillNo", "%" + currenPageDataVO.getShipbillNo() + "%");
		Restriction r4 = ToolKits.isEmpty(currenPageDataVO.getOrderBusinessType()) ? null : Restrictions.eq("orderBusinessType", currenPageDataVO.getOrderBusinessType());
		Restriction r5 = ToolKits.isEmpty(currenPageDataVO.getEstimatedPickupStartTime()) ? null : Restrictions.ge("estimatedPickupStartTime", currenPageDataVO.getEstimatedPickupStartTime());
		Restriction r6 = ToolKits.isEmpty(currenPageDataVO.getEstimatedPickupEndTime()) ? null : Restrictions.le("estimatedPickupEndTime", currenPageDataVO.getEstimatedPickupEndTime());
		Restriction r7 = ToolKits.isEmpty(currenPageDataVO.getEstimatedDeliveryStartTime()) ? null : Restrictions.ge("estimatedDeliveryStartTime", currenPageDataVO.getEstimatedDeliveryStartTime());
		Restriction r8 = ToolKits.isEmpty(currenPageDataVO.getEstimatedDeliveryEndTime()) ? null : Restrictions.le("estimatedDeliveryEndTime", currenPageDataVO.getEstimatedDeliveryEndTime());
		Restriction r9 = ToolKits.isEmpty(currenPageDataVO.getLineIdList()) ? null : Restrictions.in("lineId", currenPageDataVO.getLineIdList().stream().toArray(Long[]::new));

		Restriction r10 = ToolKits.isEmpty(currenPageDataVO.getShipperProvinceList()) ? null : Restrictions.in(TmsShipbillHeaderModel::getShipperProvince, currenPageDataVO.getShipperProvinceList().stream().toArray(String[]::new));
		Restriction r44 = ToolKits.isEmpty(currenPageDataVO.getShipperCityList()) ? null : Restrictions.in(TmsShipbillHeaderModel::getShipperCity, currenPageDataVO.getShipperCityList().stream().toArray(String[]::new));
		Restriction r45 = ToolKits.isEmpty(currenPageDataVO.getShipperDistrictList()) ? null : Restrictions.in(TmsShipbillHeaderModel::getShipperDistrict, currenPageDataVO.getShipperDistrictList().stream().toArray(String[]::new));
		Restriction r55 = Restrictions.or(r10, r44, r45);

		Restriction r11 = ToolKits.isEmpty(currenPageDataVO.getConsigneeProvinceList()) ? null : Restrictions.in(TmsShipbillHeaderModel::getConsigneeProvince, currenPageDataVO.getConsigneeProvinceList().stream().toArray(String[]::new));
		Restriction r46 = ToolKits.isEmpty(currenPageDataVO.getConsigneeCityList()) ? null : Restrictions.in(TmsShipbillHeaderModel::getConsigneeCity, currenPageDataVO.getConsigneeCityList().stream().toArray(String[]::new));
		Restriction r47 = ToolKits.isEmpty(currenPageDataVO.getConsigneeDistrictList()) ? null : Restrictions.in(TmsShipbillHeaderModel::getConsigneeDistrict, currenPageDataVO.getConsigneeDistrictList().stream().toArray(String[]::new));
		Restriction r58 = Restrictions.or(r11, r46, r47);

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

		Restriction r15 = null;
		Restriction r23 = 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 r33 = Restrictions.in(TmsShipbillHeaderModel::getShipperUnitId, user.getWarehouses().stream().toArray(Long[]::new));
				Restriction r34 = Restrictions.in(TmsShipbillHeaderModel::getShipperUnitId, user.getSuppliers().stream().toArray(Long[]::new));
				Restriction r35 = Restrictions.in(TmsShipbillHeaderModel::getShipperUnitId, user.getCustomers().stream().toArray(Long[]::new));

				Restriction r21 = Restrictions.or(r18, r19, r20, r33, r34, r35);
				r15 = Restrictions.and(r16, r17, r21);
			}
		} else {
			// 非自有账号
			r13 = Restrictions.eq("carrierSplitOrderStatus", DataDictionaryConstant.CARRIER_SPLIT_ORDER_STATUS_UN);
			Restriction r16 = Restrictions.eq("carrierId", Long.valueOf(user.getLoginUserCompanyInfo().getId()));
			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);
		}
		Restriction r17 = null;
		if (ToolKits.isNotEmpty(currenPageDataVO.getShipperLocation()) && currenPageDataVO.getShipperLocation().intValue() == 0) {
			Restriction r18 = Restrictions.isnull("shipperLongitude");
			Restriction r19 = Restrictions.isnull("shipperLatitude");
			r17 = Restrictions.or(r18, r19);
		} else if (ToolKits.isNotEmpty(currenPageDataVO.getShipperLocation()) && currenPageDataVO.getShipperLocation().intValue() == 1) {
			Restriction r18 = Restrictions.isNotNull("shipperLongitude");
			Restriction r19 = Restrictions.isNotNull("shipperLatitude");
			r17 = Restrictions.and(r18, r19);
		}
		Restriction r20 = null;
		if (ToolKits.isNotEmpty(currenPageDataVO.getConsigneeLocation()) && currenPageDataVO.getConsigneeLocation().intValue() == 0) {
			Restriction r18 = Restrictions.isnull("consigneeLongitude");
			Restriction r19 = Restrictions.isnull("consigneeLatitude");
			r20 = Restrictions.or(r18, r19);
		} else if (ToolKits.isNotEmpty(currenPageDataVO.getConsigneeLocation()) && currenPageDataVO.getConsigneeLocation().intValue() == 1) {
			Restriction r18 = Restrictions.isNotNull("consigneeLongitude");
			Restriction r19 = Restrictions.isNotNull("consigneeLatitude");
			r20 = Restrictions.and(r18, r19);
		}
		Restriction r57 = ToolKits.isEmpty(currenPageDataVO.getRecordTagWord()) ? null : Restrictions.like(TmsShipbillHeaderModel::getRecordTagWord, "%" + currenPageDataVO.getRecordTagWord() + "%");
        Restriction r59 = ToolKits.isEmpty(currenPageDataVO.getOrderDateStart()) ? null : Restrictions.ge(TmsShipbillHeaderModel::getOrderDate, currenPageDataVO.getOrderDateStart());
        Restriction r60 = ToolKits.isEmpty(currenPageDataVO.getOrderDateEnd()) ? null : Restrictions.le(TmsShipbillHeaderModel::getOrderDate, currenPageDataVO.getOrderDateEnd());

		Restriction r61 = ToolKits.isEmpty(currenPageDataVO.getCreateDateStart()) ? null : Restrictions.ge(TmsShipbillHeaderModel::getCreatetime, currenPageDataVO.getCreateDateStart());
		Restriction r62 = ToolKits.isEmpty(currenPageDataVO.getCreateDateEnd()) ? null : Restrictions.le(TmsShipbillHeaderModel::getCreatetime, currenPageDataVO.getCreateDateEnd());
		Restriction r63 = Restrictions.gt(TmsShipbillHeaderModel::getTotalPcs, BigDecimal.valueOf(0));

		Restriction r64 = ToolKits.isEmpty(currenPageDataVO.getCreateperson()) ? null : Restrictions.in(TmsShipbillHeaderModel::getCreateperson, currenPageDataVO.getCreateperson().split(","));
		Restriction r65 = ToolKits.isEmpty(currenPageDataVO.getConsigneeType()) ? null : Restrictions.eq(TmsShipbillHeaderModel::getConsigneeType, currenPageDataVO.getConsigneeType());
		Restriction r66 = ToolKits.isEmpty(currenPageDataVO.getConsigneeId()) ? null : Restrictions.in(TmsShipbillHeaderModel::getConsigneeId, currenPageDataVO.getConsigneeId().split(","));
		Restriction r67 = ToolKits.isEmpty(currenPageDataVO.getConsigneeStationId()) ? null : Restrictions.in(TmsShipbillHeaderModel::getConsigneeStationId, currenPageDataVO.getConsigneeStationId().split(","));
		Restriction r68 = ToolKits.isEmpty(currenPageDataVO.getConsigneeAddress()) ? null : Restrictions.likeAll(TmsShipbillHeaderModel::getConsigneeAddress, currenPageDataVO.getConsigneeAddress());
		Restriction r69 = Restrictions.eq(TmsShipbillHeaderModel::getIntelligentLock, 0);
		Restriction r70 = ToolKits.isEmpty(currenPageDataVO.getCarriersId()) ? null : Restrictions.eq(TmsShipbillHeaderModel::getCarriersId, currenPageDataVO.getCarriersId());

		criteria.setRestriction(Restrictions.and(r1, r2, r3, r4, r5, r6, r7, r8, r9, r55, r57, r58, r12, r13, r14, r15, r22, r23, r17, r20, r59, r60, r61, r62, r63, r64, r65, r66, r67, r68,r69,r70));
		criteria.setOrder(Order.newInstance().desc(new String[] { "updatetime" }));

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

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

		for (TmsShipbillHeaderModel tmsShipbillHeaderModel : tmsShipbillHeaderModels) {
			PendingDispatchExportDetailDataDTO exportDetailDataDTO = new PendingDispatchExportDetailDataDTO();
			BeanUtils.copyProperties(tmsShipbillHeaderModel, exportDetailDataDTO);
			// 收货方位置(经纬度判断)
			if (ToolKits.isNotEmpty(tmsShipbillHeaderModel.getConsigneeLongitude()) && ToolKits.isNotEmpty(tmsShipbillHeaderModel.getConsigneeLatitude())) {
				exportDetailDataDTO.setConsigneePositioning(StatusConstant.POSITIONING_YDW);
			} else {
				exportDetailDataDTO.setConsigneePositioning(StatusConstant.POSITIONING_WDW);
			}
			// 发货方位置(经纬度判断)
			if (ToolKits.isNotEmpty(tmsShipbillHeaderModel.getShipperLongitude()) && ToolKits.isNotEmpty(tmsShipbillHeaderModel.getShipperLatitude())) {
				exportDetailDataDTO.setShipperPositioning(StatusConstant.POSITIONING_YDW);
			} else {
				exportDetailDataDTO.setShipperPositioning(StatusConstant.POSITIONING_WDW);
			}
			StringBuffer consigneeProvinceCityDistrict = new StringBuffer();
			// 目的地
			consigneeProvinceCityDistrict.append(ToolKits.isEmpty(tmsShipbillHeaderModel.getConsigneeProvinceName()) ? "" : tmsShipbillHeaderModel.getConsigneeProvinceName());
			consigneeProvinceCityDistrict.append(ToolKits.isEmpty(tmsShipbillHeaderModel.getConsigneeCityName()) ? "" : tmsShipbillHeaderModel.getConsigneeCityName());
			consigneeProvinceCityDistrict.append(ToolKits.isEmpty(tmsShipbillHeaderModel.getConsigneeDistrictName()) ? "" : tmsShipbillHeaderModel.getConsigneeDistrictName());
			exportDetailDataDTO.setConsigneeProvinceCityDistrict(consigneeProvinceCityDistrict.toString());
			// 始发地
			StringBuffer shipperProvinceCityDistrict = new StringBuffer();
			shipperProvinceCityDistrict.append(ToolKits.isEmpty(tmsShipbillHeaderModel.getShipperProvinceName()) ? "" : tmsShipbillHeaderModel.getShipperProvinceName());
			shipperProvinceCityDistrict.append(ToolKits.isEmpty(tmsShipbillHeaderModel.getShipperCityName()) ? "" : tmsShipbillHeaderModel.getShipperCityName());
			shipperProvinceCityDistrict.append(ToolKits.isEmpty(tmsShipbillHeaderModel.getShipperDistrictName()) ? "" : tmsShipbillHeaderModel.getShipperDistrictName());
			exportDetailDataDTO.setShipperProvinceCityDistrict(shipperProvinceCityDistrict.toString());

			// 类型翻译

			exportDetailDataDTO.setOrderTypeName(ConvertorUtil.getName(dicData, DataDictionaryConstant.ORDER_TYPE, String.valueOf(tmsShipbillHeaderModel.getOrderType())));
			exportDetailDataDTO.setOrderBusinessTypeName(ConvertorUtil.getName(dicData, DataDictionaryConstant.ORDER_BUSINESS_TYPE, String.valueOf(tmsShipbillHeaderModel.getOrderBusinessType())));
			exportDetailDataDTO.setDeliveryMethodTypeName(ConvertorUtil.getName(dicData, DataDictionaryConstant.DELIVERY_METHOD_TYPE, String.valueOf(tmsShipbillHeaderModel.getDeliveryMethodType())));
			exportDetailDataDTO.setTransportTypeName(ConvertorUtil.getName(dicData, DataDictionaryConstant.TRANSPORT_TYPE, String.valueOf(tmsShipbillHeaderModel.getTransportType())));
			exportDetailDataDTO.setTemperatureRequirementName(ConvertorUtil.getName(dicData, DataDictionaryConstant.TEMPERATURE_REQUIREMENT, String.valueOf(tmsShipbillHeaderModel.getTemperatureRequirement())));
			exportDetailDataDTO.setShipperTypeName(ConvertorUtil.getName(dicData, DataDictionaryConstant.SHIPPER_TYPE, String.valueOf(tmsShipbillHeaderModel.getShipperType())));
			exportDetailDataDTO.setConsigneeTypeName(ConvertorUtil.getName(dicData, DataDictionaryConstant.CONSIGNEE_TYPE, String.valueOf(tmsShipbillHeaderModel.getConsigneeType())));

			pendingDispatchExportDetailDataDTOList.add(exportDetailDataDTO);
		}
		return pendingDispatchExportDetailDataDTOList;
	}

	/**
	 * 待调度导出选择行数据
	 *
	 * @param shipbillIdList
	 * @return
	 */
	public List<PendingDispatchExportDetailDataDTO> exportSelectLineData(List<String> shipbillIdList) {
		ToolKits.isParamNull(shipbillIdList, "导出选择行数据查询条件不为空");

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

		// 数据字典翻译数据集合
		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.ORDER_BUSINESS_TYPE // 订单业务类型
		});

		// 添加查询条件
		Criteria criteria = Criteria.forClass(TmsShipbillHeaderModel.class);
		Restriction r2 = Restrictions.eq("enterpriseId", user.getEnterpriseId());
		String[] shipbillIdArray = shipbillIdList.stream().toArray(String[]::new);
		Restriction r3 = Restrictions.in("shipbillId", shipbillIdArray);

		criteria.setRestriction(Restrictions.and(r2, r3));
		criteria.setOrder(Order.newInstance().desc(new String[] { "updatetime" }));

		List<TmsShipbillHeaderModel> tmsShipbillHeaderModels = tmsShipbillHeaderMapper.findByCriteria(criteria);

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

		for (TmsShipbillHeaderModel tmsShipbillHeaderModel : tmsShipbillHeaderModels) {
			PendingDispatchExportDetailDataDTO pendingDispatchExportDetailDataDTO = new PendingDispatchExportDetailDataDTO();
			BeanUtils.copyProperties(tmsShipbillHeaderModel, pendingDispatchExportDetailDataDTO);
			// 收货方位置(经纬度判断)
			if (ToolKits.isNotEmpty(tmsShipbillHeaderModel.getConsigneeLongitude()) && ToolKits.isNotEmpty(tmsShipbillHeaderModel.getConsigneeLatitude())) {
				pendingDispatchExportDetailDataDTO.setConsigneePositioning(StatusConstant.POSITIONING_YDW);
			} else {
				pendingDispatchExportDetailDataDTO.setConsigneePositioning(StatusConstant.POSITIONING_WDW);
			}
			// 发货方位置(经纬度判断)
			if (ToolKits.isNotEmpty(tmsShipbillHeaderModel.getShipperLongitude()) && ToolKits.isNotEmpty(tmsShipbillHeaderModel.getShipperLatitude())) {
				pendingDispatchExportDetailDataDTO.setShipperPositioning(StatusConstant.POSITIONING_YDW);
			} else {
				pendingDispatchExportDetailDataDTO.setShipperPositioning(StatusConstant.POSITIONING_WDW);
			}
			StringBuffer consigneeProvinceCityDistrict = new StringBuffer();
			// 目的地
			consigneeProvinceCityDistrict.append(ToolKits.isEmpty(tmsShipbillHeaderModel.getConsigneeProvinceName()) ? "" : tmsShipbillHeaderModel.getConsigneeProvinceName());
			consigneeProvinceCityDistrict.append(ToolKits.isEmpty(tmsShipbillHeaderModel.getConsigneeCityName()) ? "" : tmsShipbillHeaderModel.getConsigneeCityName());
			consigneeProvinceCityDistrict.append(ToolKits.isEmpty(tmsShipbillHeaderModel.getConsigneeDistrictName()) ? "" : tmsShipbillHeaderModel.getConsigneeDistrictName());
			pendingDispatchExportDetailDataDTO.setConsigneeProvinceCityDistrict(consigneeProvinceCityDistrict.toString());
			// 始发地
			StringBuffer shipperProvinceCityDistrict = new StringBuffer();
			shipperProvinceCityDistrict.append(ToolKits.isEmpty(tmsShipbillHeaderModel.getShipperProvinceName()) ? "" : tmsShipbillHeaderModel.getShipperProvinceName());
			shipperProvinceCityDistrict.append(ToolKits.isEmpty(tmsShipbillHeaderModel.getShipperCityName()) ? "" : tmsShipbillHeaderModel.getShipperCityName());
			shipperProvinceCityDistrict.append(ToolKits.isEmpty(tmsShipbillHeaderModel.getShipperDistrictName()) ? "" : tmsShipbillHeaderModel.getShipperDistrictName());
			pendingDispatchExportDetailDataDTO.setShipperProvinceCityDistrict(shipperProvinceCityDistrict.toString());

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

			pendingDispatchExportDetailDataDTOList.add(pendingDispatchExportDetailDataDTO);
		}
		return pendingDispatchExportDetailDataDTOList;
	}

	/**
	 * 待调度查看
	 *
	 * @param shipbillId
	 * @return
	 */
	public PendingDispatchViewDTO pendingDispatchView(String shipbillId) {

		ToolKits.isParamNull(shipbillId, "运单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<Map<String, Object>> data9 = Lists.newArrayList();
		List<Map<String, Object>> data10 = Lists.newArrayList();
		List<Map<String, Object>> data11 = 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.PACK_TYPE, null, null, null);
		if (!restMessage8.isSuccess()) {
			throw new RuntimeException("包装类型翻译失败!");
		} else {
			data8 = restMessage8.getData();
		}
		// 货物温层
		RestMessage<List<Map<String, Object>>> restMessage9 = maindataTmsResource.getDropDownById(DataDictionaryConstant.CARGO_THERMOSPHERE, null, null, null);
		if (!restMessage9.isSuccess()) {
			throw new RuntimeException("货物温层翻译失败!");
		} else {
			data9 = restMessage9.getData();
		}

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

		// 设备类型
		RestMessage<List<Map<String, Object>>> restMessage11 = maindataTmsResource.getDropDownById(DataDictionaryConstant.DEVICE_COMPANY, null, null, null);
		if (!restMessage11.isSuccess()) {
			throw new RuntimeException("设备类型翻译失败!");
		} else {
			data11 = restMessage11.getData();
		}

		// 查询运单汇总信息
		TmsShipbillHeaderModel model = tmsShipbillHeaderMapper.findById(shipbillId, TmsShipbillHeaderModel.class);
		PendingDispatchViewDTO dto = new PendingDispatchViewDTO();
		BeanUtils.copyProperties(model, dto);

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

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

		// 运单明细数据集
		List<PendingDispatchViewDetailDTO> detailDTOs = Lists.newArrayList();

		// 查询运单明细
		Criteria criteria = Criteria.forClass(TmsShipbillDetailModel.class);
		Restriction r1 = Restrictions.eq("shipbillId", shipbillId);
		Restriction r2 = Restrictions.eq("enterpriseId", user.getEnterpriseId());
		criteria.setRestriction(Restrictions.and(r1, r2));
		criteria.setOrder(Order.newInstance().asc(new String[] { "seqno" }));
		List<TmsShipbillDetailModel> tmsShipbillDetailModels = tmsShipbillDetailMapper.findByCriteria(criteria);
		// 商品总件数
		BigDecimal goodsTotalPcs = new BigDecimal(0);
		// 商品总体积
		BigDecimal goodsTotalVolume = new BigDecimal(0);
		// 商品总重量
		BigDecimal goodsTotalWeight = new BigDecimal(0);
		if (ToolKits.isNotEmpty(tmsShipbillDetailModels)) {
			for (TmsShipbillDetailModel tmsShipbillDetailModel : tmsShipbillDetailModels) {
				PendingDispatchViewDetailDTO detailDTO = new PendingDispatchViewDetailDTO();
				BeanUtils.copyProperties(tmsShipbillDetailModel, detailDTO);
				// 数据字典翻译
				detailDTO.setPackTypeName(PublicMethods.change(data8, String.valueOf(detailDTO.getPackType())));
				detailDTO.setCargoThermosphereName(PublicMethods.change(data9, String.valueOf(detailDTO.getCargoThermosphere())));
				detailDTOs.add(detailDTO);

				goodsTotalPcs = goodsTotalPcs.add(detailDTO.getPcs());
				goodsTotalVolume = goodsTotalVolume.add(detailDTO.getVolume());
				goodsTotalWeight = goodsTotalWeight.add(detailDTO.getWeight());
			}
			dto.setPendingDispatchViewDetailDTOs(detailDTOs);
			dto.setGoodsTotalPcs(goodsTotalPcs);
			dto.setGoodsTotalVolume(goodsTotalVolume);
			dto.setGoodsTotalWeight(goodsTotalWeight);
		}

		// 运单包裹数据集
		List<PendingDispatchViewPackageDTO> pendingDispatchPackageDTOs = Lists.newArrayList();

		// 查询运单包裹明细
		Criteria criteriaPkg = Criteria.forClass(TmsShipbillPackageModel.class);
		Restriction r3 = Restrictions.eq("shipbillId", shipbillId);
		Restriction r4 = Restrictions.eq("enterpriseId", user.getEnterpriseId());
		criteriaPkg.setRestriction(Restrictions.and(r3, r4));
		criteriaPkg.setOrder(Order.newInstance().desc(new String[] { "updatetime" }));
		List<TmsShipbillPackageModel> tmsShipbillPackageModels = tmsShipbillPackageMapper.findByCriteria(criteriaPkg);

		// 包裹总件数
		BigDecimal pkgTotalPcs = new BigDecimal(0);
		// 包裹总拼箱数
		BigDecimal pkgTotalLclPiece = new BigDecimal(0);
		// 包裹总整件数
		BigDecimal pkgTotalWholePiece = new BigDecimal(0);
		// 包裹总体积
		BigDecimal pkgTotalVolume = new BigDecimal(0);
		// 包裹总重量
		BigDecimal pkgTotalWeight = new BigDecimal(0);
		if (ToolKits.isNotEmpty(tmsShipbillPackageModels)) {
			for (TmsShipbillPackageModel tmsShipbillPackageModel : tmsShipbillPackageModels) {
				PendingDispatchViewPackageDTO pkgDTO = new PendingDispatchViewPackageDTO();
				BeanUtils.copyProperties(tmsShipbillPackageModel, pkgDTO);
				// 数据字典翻译
				pkgDTO.setPackageTypeName(PublicMethods.change(data10, String.valueOf(pkgDTO.getPackageType())));
				pkgDTO.setDeviceCompanyName(PublicMethods.change(data11, String.valueOf(pkgDTO.getDeviceCompany())));
				pendingDispatchPackageDTOs.add(pkgDTO);

				pkgTotalPcs = pkgTotalPcs.add(pkgDTO.getLclPiece()).add(pkgDTO.getWholePiece());
				pkgTotalLclPiece = pkgTotalLclPiece.add(pkgDTO.getLclPiece());
				pkgTotalWholePiece = pkgTotalWholePiece.add(pkgDTO.getWholePiece());
				pkgTotalVolume = pkgTotalVolume.add(pkgDTO.getVolume());
				pkgTotalWeight = pkgTotalWeight.add(pkgDTO.getWeight());
			}
			dto.setPendingDispatchViewPackageDTOs(pendingDispatchPackageDTOs);
			dto.setPkgTotalPcs(pkgTotalPcs);
			dto.setPkgTotalLclPiece(pkgTotalLclPiece);
			dto.setPkgTotalWholePiece(pkgTotalWholePiece);
			dto.setPkgTotalVolume(pkgTotalVolume);
			dto.setPkgTotalWeight(pkgTotalWeight);
		}
		return dto;
	}

	/**
	 * 待调度按商品拆分
	 *
	 * @param splitVO
	 * @return
	 */
	@Transactional(rollbackFor = Exception.class)
	public void goodsSplit(SplitVO splitVO) {
		ToolKits.isParamNull(splitVO, "待调度拆分请求不为空");

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

		// 当前时间
		Date date = DateUtil.date();
		// STD-DEVELOP20220823 lhb bwc0823003 20220824 start
		autoGoodsSplit(splitVO, user, date);
		// STD-DEVELOP20220823 lhb bwc0823003 20220824 end
	}

	// STD-DEVELOP20220823 lhb bwc0823003 20220824 start

	/**
	 * 手动拆分（公共处理）
	 *
	 * @param splitVO
	 */
	public void autoGoodsSplit(SplitVO splitVO, UserEntity user, Date date,String...isPlanDisSplit) {
		log.info("拆分入参:{}",JSONObject.toJSONString(splitVO));
		// STD-DEVELOP20220823 lhb 承运商拆分完善 20220916 start
		// 原装车明细更新
		Map<String, Object> mapUpdate = Maps.newHashMap();
		mapUpdate.put("updateperson", user.getNickname());
		mapUpdate.put("updatetime", date);
		// STD-DEVELOP20220823 lhb 承运商拆分完善 20220916 end
		// 原运单更新
		TmsShipbillHeaderModel tmsShipbillHeaderModel = tmsShipbillHeaderMapper.findById(splitVO.getShipbillId(), TmsShipbillHeaderModel.class);
		if (user.getUserType().equals(BussinessConstant.USER_TYPE_ZY)) {
			if (!DataDictionaryConstant.SHIPBILL_STATUS_REVIEW.equals(tmsShipbillHeaderModel.getStatus())) {
				throw new PrologException("运单【" + tmsShipbillHeaderModel.getShipbillNo() + "】非待调度状态,拆单失败");
			}
			if (!DataDictionaryConstant.SPLIT_ORDER_STATUS_UN.equals(tmsShipbillHeaderModel.getSplitOrderStatus())) {
				throw new PrologException("运单【" + tmsShipbillHeaderModel.getShipbillNo() + "】非待调度状态,拆单失败");
			}
			tmsShipbillHeaderModel.setSplitOrderStatus(DataDictionaryConstant.SPLIT_ORDER_STATUS_ED);
			// 原始主单被拆分时，拆单类型更新为2拆分主单，子单被拆分时，不更新拆单类型
			if (ToolKits.isEmpty(tmsShipbillHeaderModel.getSplitOrderType()) || DataDictionaryConstant.SPLIT_ORDER_TYPE_UN.equals(tmsShipbillHeaderModel.getSplitOrderType())) {
				tmsShipbillHeaderModel.setSplitOrderType(DataDictionaryConstant.SPLIT_ORDER_TYPE_SPLIT_MASTER);
			}
		} else if (user.getUserType().equals(BussinessConstant.USER_TYPE_CYS)) {
			if (!DataDictionaryConstant.CARRIER_SHIPBILL_STATUS_AUDITED.equals(tmsShipbillHeaderModel.getCarrierShipbillStatus())) {
				throw new PrologException("运单【" + tmsShipbillHeaderModel.getShipbillNo() + "】非待调度状态,拆单失败");
			}
			if (!DataDictionaryConstant.CARRIER_SPLIT_ORDER_STATUS_UN.equals(tmsShipbillHeaderModel.getCarrierSplitOrderStatus())) {
				throw new PrologException("运单【" + tmsShipbillHeaderModel.getShipbillNo() + "】非待调度状态,拆单失败");
			}
			tmsShipbillHeaderModel.setCarrierSplitOrderStatus(DataDictionaryConstant.CARRIER_SPLIT_ORDER_STATUS_ED);
			// 原始主单被拆分时，拆单类型更新为2拆分主单，子单被拆分时，不更新拆单类型
			if (ToolKits.isEmpty(tmsShipbillHeaderModel.getCarrierSplitOrderType()) || DataDictionaryConstant.CARRIER_SPLIT_ORDER_TYPE_UN.equals(tmsShipbillHeaderModel.getCarrierSplitOrderType())) {
				tmsShipbillHeaderModel.setCarrierSplitOrderType(DataDictionaryConstant.CARRIER_SPLIT_ORDER_TYPE_SPLIT_MASTER);
			}

			// STD-DEVELOP20220823 lhb 承运商拆分完善 20220916 start
			// 更新装车单明细
			mapUpdate.put("carrierSplitOrderStatus", DataDictionaryConstant.CARRIER_SPLIT_ORDER_STATUS_ED);
			if (ToolKits.isEmpty(tmsShipbillHeaderModel.getCarrierSplitOrderType()) || DataDictionaryConstant.CARRIER_SPLIT_ORDER_TYPE_UN.equals(tmsShipbillHeaderModel.getCarrierSplitOrderType())) {
				mapUpdate.put("carrierSplitOrderType", DataDictionaryConstant.CARRIER_SPLIT_ORDER_TYPE_SPLIT_MASTER);
			}
			Criteria criteriaDetail = Criteria.forClass(TmsLoadingBillDetailModel.class);
			Restriction r1 = Restrictions.eq(TmsLoadingBillDetailModel::getCarrierShipbillStatus, DataDictionaryConstant.CARRIER_SHIPBILL_STATUS_AUDITED);
			Restriction r2 = Restrictions.eq(TmsLoadingBillDetailModel::getShipbillId, tmsShipbillHeaderModel.getShipbillId());
			criteriaDetail.setRestriction(Restrictions.and(r1, r2));
			tmsLoadingBillDetailMapper.updateMapByCriteria(mapUpdate, criteriaDetail);
			// STD-DEVELOP20220823 lhb 承运商拆分完善 20220916 end
		} else {
			throw new ParameterException("当前人员没有操作权限");
		}

		tmsShipbillHeaderModel.setUpdateperson(user.getNickname());
		tmsShipbillHeaderModel.setUpdatetime(date);
		tmsShipbillHeaderMapper.update(tmsShipbillHeaderModel);

		// 原运单日志保存
		ShipbillOperateLogSaveVO shipbillOperateLogSaveVO = new ShipbillOperateLogSaveVO();
		shipbillOperateLogSaveVO.setShipbillId(tmsShipbillHeaderModel.getShipbillId());
		shipbillOperateLogSaveVO.setShipbillNo(tmsShipbillHeaderModel.getShipbillNo());
		shipbillOperateLogSaveVO.setOperateEvent(DataDictionaryConstant.SHIPBILL_EVENT_NAME_SPLIT);
		shipbillOperateLogSaveVO.setOldStatus(DataDictionaryConstant.SHIPBILL_STATUS_DISPATCH);
		shipbillOperateLogSaveVO.setNewStatus(DataDictionaryConstant.SHIPBILL_STATUS_DISPATCH);
		shipbillOperateLogService.addShipbillOperateLogData(shipbillOperateLogSaveVO);

		// 拆分成多个子单
		int index = 1;
		RestMessage<SysParamConfigModel> restMessageShipbillId = maindataTmsResource.getValue(DataDictionaryConstant.SHIPBILL_ID_CREATE_RULE);
		if (!restMessageShipbillId.isSuccess()) {
			throw new RuntimeException("获取运单ID生成规则的系统参数失败!");
		}
		SysParamConfigModel sysParamConfigModel = restMessageShipbillId.getData();
		for (SplitGoodsListVO subSplitList : splitVO.getSplitGoodsList()) {
			// 运单汇总ID
			String subShipbillId = "";
			// 运单ID生成规则
			if (DataDictionaryConstant.SHIPBILL_ID_CREATE_RULE_AUTO.equals(sysParamConfigModel.getValue())) {
				// 获取运单汇总ID
				RestMessage<String> restMessageAutoCreateShipbillId = maindataTmsResource.getCodeNumberByCode(SeriaNnumberConstant.TMS_SHIPBILL_HEADER_ID, "L");
				if (!restMessageAutoCreateShipbillId.isSuccess()) {
					throw new RuntimeException("生成运单汇总ID失败");
				}
				subShipbillId = restMessageAutoCreateShipbillId.getData();
			} else {
				StringBuffer buffNo1 = new StringBuffer(splitVO.getShipbillId());
				buffNo1.append(DataDictionaryConstant.SUB_SHIPBILL_NO);
				buffNo1.append(DataDictionaryConstant.SPLIT_SHIPBILL_NO);
				buffNo1.append(index);
				subShipbillId = buffNo1.toString();
			}

			// 商品总件数
			BigDecimal goodsTotalPcs = new BigDecimal(0);
			// 商品总体积
			BigDecimal goodsTotalVolume = new BigDecimal(0);
			// 商品总重量
			BigDecimal goodsTotalWeight = new BigDecimal(0);

			BigDecimal zero = new BigDecimal(0);

			// 保存每个子单中的明细信息
			for (SplitGoodsDetailVO splitGoodsDetailVO : subSplitList.getSplitGoodsDetailVOList()) {
				TmsShipbillDetailModel subTmsShipbillDetailModel = new TmsShipbillDetailModel();
				TmsShipbillDetailModel origDetailModel = tmsShipbillDetailMapper.findById(splitGoodsDetailVO.getId(),TmsShipbillDetailModel.class);
				if (ToolKits.isEmpty(origDetailModel)) {
					throw new PluginException(StrUtil.format("运单{}的商品明细{}不存在",splitGoodsDetailVO.getShipbillNo(),splitGoodsDetailVO.getItemName()));
				}
				// 运单明细ID
				RestMessage<String> restMessage2 = maindataTmsResource.getCodeNumberByCode(SeriaNnumberConstant.TMS_SHIPBILL_DETAIL_ID, "L");
				if (!restMessage2.isSuccess()) {
					throw new RuntimeException("生成运单明细ID失败");
				}
				String subShipbillDetailId = restMessage2.getData();
				BeanUtils.copyProperties(origDetailModel, subTmsShipbillDetailModel);

				ItemCheckVO itemCheckVO = new ItemCheckVO();
				itemCheckVO.setItemId(splitGoodsDetailVO.getItemId());
				RestMessage<ItemCheckDTO> restMessage3 = maindataTmsResource.getItem(itemCheckVO);
				if (!restMessage3.isSuccess()) {
					throw new RuntimeException("取商品资料信息失败:" + restMessage3.getMessage());
				}
				ItemCheckDTO rsItemInfo = restMessage3.getData();

				// ID
				subTmsShipbillDetailModel.setId(subShipbillDetailId);
				// 运单ID
				subTmsShipbillDetailModel.setShipbillId(subShipbillId);
				// 运单编号
				subTmsShipbillDetailModel.setShipbillNo(subShipbillId);

				subTmsShipbillDetailModel.setEnterpriseId(user.getEnterpriseId());
				subTmsShipbillDetailModel.setEnterpriseName(user.getEnterpriseName());

				subTmsShipbillDetailModel.setPcs(splitGoodsDetailVO.getPcs());
				subTmsShipbillDetailModel.setWeight(splitGoodsDetailVO.getWeight());
				subTmsShipbillDetailModel.setVolume(splitGoodsDetailVO.getVolume());
				subTmsShipbillDetailModel.setPlanStatus(null);

				subTmsShipbillDetailModel.setUnitVolume(rsItemInfo.getVolume());
				subTmsShipbillDetailModel.setUnitWeight(rsItemInfo.getWeight());
				subTmsShipbillDetailModel.setCreateperson(user.getNickname());
				subTmsShipbillDetailModel.setCreatetime(date);
				subTmsShipbillDetailModel.setUpdateperson(user.getNickname());
				subTmsShipbillDetailModel.setUpdatetime(date);
				subTmsShipbillDetailModel.setOrigPcs(subTmsShipbillDetailModel.getPcs());
				subTmsShipbillDetailModel.setClosingPcs(BigDecimal.valueOf(0));
				subTmsShipbillDetailModel.setDeliveryPcs(BigDecimal.valueOf(0));
				subTmsShipbillDetailModel.setFatherId(splitGoodsDetailVO.getId());
				subTmsShipbillDetailModel.setScanStatus(DataDictionaryConstant.SCAN_STATUS_INIT);
				tmsShipbillDetailMapper.save(subTmsShipbillDetailModel);

				goodsTotalPcs = goodsTotalPcs.add(splitGoodsDetailVO.getPcs());
				goodsTotalVolume = goodsTotalVolume.add(splitGoodsDetailVO.getVolume());
				goodsTotalWeight = goodsTotalWeight.add(splitGoodsDetailVO.getWeight());
			}

			// 保存拆分子单的运单汇总
			TmsShipbillHeaderModel subTmsShipbillHeaderModel = new TmsShipbillHeaderModel();
			BeanUtils.copyProperties(tmsShipbillHeaderModel, subTmsShipbillHeaderModel);

			subTmsShipbillHeaderModel.setShipbillNo(subShipbillId);
			subTmsShipbillHeaderModel.setShipbillId(subShipbillId);
			if (user.getUserType().equals(BussinessConstant.USER_TYPE_ZY)) {
				// 拆单状态 0未拆单
				subTmsShipbillHeaderModel.setSplitOrderStatus(DataDictionaryConstant.SPLIT_ORDER_STATUS_UN);
				// 拆单类型 3拆分子单
				subTmsShipbillHeaderModel.setSplitOrderType(DataDictionaryConstant.SPLIT_ORDER_TYPE_SPLIT_SUB);

				// 拆单状态 0未拆单
				subTmsShipbillHeaderModel.setCarrierSplitOrderStatus(DataDictionaryConstant.CARRIER_SPLIT_ORDER_STATUS_UN);
				// 拆单类型 3拆分子单
				subTmsShipbillHeaderModel.setCarrierSplitOrderType(DataDictionaryConstant.CARRIER_SPLIT_ORDER_TYPE_UN);
			} else {
				// 拆单状态 0未拆单
				subTmsShipbillHeaderModel.setCarrierSplitOrderStatus(DataDictionaryConstant.CARRIER_SPLIT_ORDER_STATUS_UN);
				// 拆单类型 3拆分子单
				subTmsShipbillHeaderModel.setCarrierSplitOrderType(DataDictionaryConstant.CARRIER_SPLIT_ORDER_TYPE_SPLIT_SUB);

				// 拆单状态 0未拆单
				subTmsShipbillHeaderModel.setSplitOrderStatus(DataDictionaryConstant.SPLIT_ORDER_STATUS_UN);
				// 拆单类型 3拆分子单
				subTmsShipbillHeaderModel.setSplitOrderType(DataDictionaryConstant.SPLIT_ORDER_TYPE_UN);
			}
			// 父级运单ID
			subTmsShipbillHeaderModel.setFatherShipbillId(tmsShipbillHeaderModel.getShipbillId());
			// 父级运单编号
			subTmsShipbillHeaderModel.setFatherShipbillNo(tmsShipbillHeaderModel.getShipbillNo());
			// 原始运单ID
			String originalShipbillId = tmsShipbillHeaderModel.getOriginalShipbillId() == null ? tmsShipbillHeaderModel.getShipbillId() : tmsShipbillHeaderModel.getOriginalShipbillId();
			subTmsShipbillHeaderModel.setOriginalShipbillId(originalShipbillId);
			// 原始运单编号
			String originalShipbillNo = tmsShipbillHeaderModel.getOriginalShipbillNo() == null ? tmsShipbillHeaderModel.getShipbillNo() : tmsShipbillHeaderModel.getOriginalShipbillNo();
			subTmsShipbillHeaderModel.setOriginalShipbillNo(originalShipbillNo);
			// 总件数
			subTmsShipbillHeaderModel.setTotalPcs(goodsTotalPcs);
			// 总体积
			subTmsShipbillHeaderModel.setTotalVolume(goodsTotalVolume);
			// 总重量
			subTmsShipbillHeaderModel.setTotalWeight(goodsTotalWeight);
			// 实际总件数
			subTmsShipbillHeaderModel.setActualTotalPcs(goodsTotalPcs);
			// 实际总体积
			subTmsShipbillHeaderModel.setActualTotalVolume(goodsTotalVolume);
			// 实际总重量
			subTmsShipbillHeaderModel.setActualTotalWeight(goodsTotalWeight);
			// 包裹整件数
			subTmsShipbillHeaderModel.setPackageWholePiece(zero);
			// 包裹拼箱数
			subTmsShipbillHeaderModel.setPackageLclPiece(zero);
			// 包裹总体积
			subTmsShipbillHeaderModel.setPackageTotalVolume(zero);
			// 包裹总重量
			subTmsShipbillHeaderModel.setPackageTotalWeight(zero);

			subTmsShipbillHeaderModel.setCreateperson(user.getNickname());
			subTmsShipbillHeaderModel.setCreatetime(date);
			subTmsShipbillHeaderModel.setUpdateperson(user.getNickname());
			subTmsShipbillHeaderModel.setUpdatetime(date);
			subTmsShipbillHeaderModel.setShipbillType(ShipBillTypeEnum.NORMAL.getCode());
			subTmsShipbillHeaderModel.setSignInStatus(SignInStatusEnum.NOT_SIGN.getCode());
			subTmsShipbillHeaderModel.setDriverReceiveStatus(DriverReceiveStatusEnum.N.getCode());
			subTmsShipbillHeaderModel.setIntelligentLock(IntelligentLockEnum.UN_LOCK.getCode());
			tmsShipbillHeaderMapper.save(subTmsShipbillHeaderModel);

			// 运输记录
			saveTransportLog(subTmsShipbillHeaderModel.getShipbillId(), date, subTmsShipbillHeaderModel.getEstimatedPickupStartTime());

			// 子运单日志保存
			ShipbillOperateLogSaveVO subShipbillOperateLogSaveVO = new ShipbillOperateLogSaveVO();
			subShipbillOperateLogSaveVO.setShipbillId(subTmsShipbillHeaderModel.getShipbillId());
			subShipbillOperateLogSaveVO.setShipbillNo(subTmsShipbillHeaderModel.getShipbillNo());
			subShipbillOperateLogSaveVO.setOperateEvent(DataDictionaryConstant.SHIPBILL_EVENT_NAME_SPLIT_SUB);
			subShipbillOperateLogSaveVO.setOldStatus(DataDictionaryConstant.SHIPBILL_STATUS_REVIEW);
			subShipbillOperateLogSaveVO.setNewStatus(DataDictionaryConstant.SHIPBILL_STATUS_REVIEW);
			shipbillOperateLogService.addShipbillOperateLogData(subShipbillOperateLogSaveVO);

			// 运单节点保存
			ShipbillNodeTrackingSaveVO shipbillNodeTrackingSaveVO = new ShipbillNodeTrackingSaveVO();
			shipbillNodeTrackingSaveVO.setShipbillId(subShipbillId);
			shipbillNodeTrackingSaveVO.setShipbillNo(subShipbillId);
			shipbillNodeTrackingSaveVO.setStatus(DataDictionaryConstant.SHIPBILL_STATUS_REVIEW);
			shipbillNodeTrackingSaveVO.setNodeEvent(DataDictionaryConstant.SHIPBILL_STATUSNAME_REW);
			shipbillNodeTrackingService.addShipbillNodeTrackingData(shipbillNodeTrackingSaveVO);
			index++;
		}
		if (ToolKits.isEmpty(isPlanDisSplit)) {
			List<String> ids = Lists.newArrayList();
			ids.add(splitVO.getShipbillId());
			updatePlanBill(ids, user);
		}
	}

	// STD-DEVELOP20220823 lhb bwc0823003 20220824 end

	/**
	 * 待调度撤销
	 *
	 * @param revokeVO
	 * @return
	 */
	@Transactional(rollbackFor = Exception.class)
	public void revoke(RevokeVO revokeVO) {
		ToolKits.isParamNull(revokeVO, "待调度撤销请求不为空");
		ToolKits.isParamNull(revokeVO.getShipbillId(), "运单ID不为空");
		ToolKits.isParamNull(revokeVO.getFatherShipbillId(), "父运单ID不为空");

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

		Criteria criteriaFather = Criteria.forClass(TmsShipbillHeaderModel.class);
		Restriction r8 = Restrictions.eq(TmsShipbillHeaderModel::getFatherShipbillId, revokeVO.getFatherShipbillId());
		Restriction r9 = Restrictions.eq(TmsShipbillHeaderModel::getEnterpriseId, user.getEnterpriseId());
		criteriaFather.setRestriction(Restrictions.and(r8, r9));
		List<TmsShipbillHeaderModel> allTmsShipbillHeaderModels = tmsShipbillHeaderMapper.findByCriteria(criteriaFather);
		if (ToolKits.isEmpty(allTmsShipbillHeaderModels)) {
			throw new PrologException("父运单【" + revokeVO.getFatherShipbillId() + "】对应的子单不存在");
		}

		allTmsShipbillHeaderModels.forEach(o -> {
			if (o.getSplitOrderStatus().equals(DataDictionaryConstant.SPLIT_ORDER_STATUS_ED)) {
				throw new PrologException("运单【" + o.getShipbillId() + "】的同级子单已被拆分或者中转，不能撤销");
			}
			if (o.getCarrierSplitOrderStatus().equals(DataDictionaryConstant.CARRIER_SPLIT_ORDER_STATUS_ED)) {
				throw new PrologException("运单【" + o.getShipbillId() + "】的同级子单已被拆分或者中转，不能撤销");
			}
		});

		if (user.getUserType().equals(BussinessConstant.USER_TYPE_ZY)) {
			int cnt = allTmsShipbillHeaderModels.stream().filter(o -> DataDictionaryConstant.SHIPBILL_STATUS_REVIEW.equals(o.getStatus())).collect(Collectors.toList()).size();
			if (cnt != allTmsShipbillHeaderModels.size()) {
				throw new PrologException("父运单【" + revokeVO.getFatherShipbillId() + "】下有已调度的子单，子单【" + revokeVO.getShipbillId() + "】不能再撤销");
			}
		} else if (user.getUserType().equals(BussinessConstant.USER_TYPE_CYS)) {
			int cnt = allTmsShipbillHeaderModels.stream().filter(o -> DataDictionaryConstant.CARRIER_SHIPBILL_STATUS_AUDITED.equals(o.getCarrierShipbillStatus())).collect(Collectors.toList()).size();
			if (cnt != allTmsShipbillHeaderModels.size()) {
				throw new PrologException("父运单【" + revokeVO.getFatherShipbillId() + "】下有已调度的子单，子单【" + revokeVO.getShipbillId() + "】不能再撤销");
			}
		} else {
			throw new ParameterException("当前人员没有操作权限");
		}

		// 当前时间
		Date date = DateUtil.date();
		// 更新父级运单
		TmsShipbillHeaderModel fatherTmsShipbillHeaderModel = tmsShipbillHeaderMapper.findById(revokeVO.getFatherShipbillId(), TmsShipbillHeaderModel.class);

		// 父级运单的拆单类型为中转主单或者拆分主单时，回退为未拆单
		if (user.getUserType().equals(BussinessConstant.USER_TYPE_ZY)) {
			if (fatherTmsShipbillHeaderModel.getSplitOrderType().equals(DataDictionaryConstant.SPLIT_ORDER_TYPE_SPLIT_MASTER) || fatherTmsShipbillHeaderModel.getSplitOrderType().equals(DataDictionaryConstant.SPLIT_ORDER_TYPE_TRANSIT_MASTER)) {
				fatherTmsShipbillHeaderModel.setSplitOrderType(DataDictionaryConstant.SPLIT_ORDER_TYPE_UN);
				// 拆单状态 0未拆单
				fatherTmsShipbillHeaderModel.setSplitOrderStatus(DataDictionaryConstant.SPLIT_ORDER_STATUS_UN);
			}
		} else {
			if (fatherTmsShipbillHeaderModel.getCarrierSplitOrderType().equals(DataDictionaryConstant.CARRIER_SPLIT_ORDER_TYPE_SPLIT_MASTER) || fatherTmsShipbillHeaderModel.getCarrierSplitOrderType().equals(DataDictionaryConstant.CARRIER_SPLIT_ORDER_TYPE_TRANSIT_MASTER)) {
				fatherTmsShipbillHeaderModel.setCarrierSplitOrderType(DataDictionaryConstant.CARRIER_SPLIT_ORDER_TYPE_UN);
				fatherTmsShipbillHeaderModel.setCarrierShipbillStatus(DataDictionaryConstant.CARRIER_SPLIT_ORDER_STATUS_UN);
			}
		}
		fatherTmsShipbillHeaderModel.setUpdateperson(user.getNickname());
		fatherTmsShipbillHeaderModel.setUpdatetime(date);
		tmsShipbillHeaderMapper.update(fatherTmsShipbillHeaderModel);

		// 父级运单日志保存
		ShipbillOperateLogSaveVO shipbillOperateLogSaveVO = new ShipbillOperateLogSaveVO();
		shipbillOperateLogSaveVO.setShipbillId(fatherTmsShipbillHeaderModel.getShipbillId());
		shipbillOperateLogSaveVO.setShipbillNo(fatherTmsShipbillHeaderModel.getShipbillNo());
		shipbillOperateLogSaveVO.setOperateEvent(DataDictionaryConstant.SHIPBILL_EVENT_NAME_REVOKE);
		shipbillOperateLogSaveVO.setOldStatus(DataDictionaryConstant.SHIPBILL_STATUS_REVIEW);
		shipbillOperateLogSaveVO.setNewStatus(DataDictionaryConstant.SHIPBILL_STATUS_REVIEW);
		shipbillOperateLogService.addShipbillOperateLogData(shipbillOperateLogSaveVO);

		// 删除子单对应的明细
		for (TmsShipbillHeaderModel delHeaderModel : allTmsShipbillHeaderModels) {
			// 删除商品明细表的数据
			Criteria criteriaDelSubDetail = Criteria.forClass(TmsShipbillDetailModel.class);
			Restriction r3 = Restrictions.eq("shipbillId", delHeaderModel.getShipbillId());
			criteriaDelSubDetail.setRestriction(Restrictions.and(r3));
			tmsShipbillDetailMapper.deleteByCriteria(criteriaDelSubDetail);

			// 删除包裹表中相应的数据
			Criteria criteriaDelPkg = Criteria.forClass(TmsShipbillPackageModel.class);
			Restriction r4 = Restrictions.eq("shipbillId", delHeaderModel.getShipbillId());
			criteriaDelPkg.setRestriction(Restrictions.and(r4));
			tmsShipbillPackageMapper.deleteByCriteria(criteriaDelPkg);

			// 删除包裹明细表中相应的数据
			Criteria criteriaDelPkgDetail = Criteria.forClass(TmsShipbillPkgDetailModel.class);
			Restriction r5 = Restrictions.eq("shipbillId", delHeaderModel.getShipbillId());
			criteriaDelPkgDetail.setRestriction(Restrictions.and(r5));
			tmsShipbillPackageDetailMapper.deleteByCriteria(criteriaDelPkgDetail);

			// 删除节点表中对应的数据
			Criteria criteriaNodeTrackingModel = Criteria.forClass(ShipbillNodeTracking.class);
			Restriction r6 = Restrictions.eq("shipbillId", delHeaderModel.getShipbillId());
			criteriaNodeTrackingModel.setRestriction(Restrictions.and(r6));
			tmsShipbillNodeTrackingMapper.deleteByCriteria(criteriaNodeTrackingModel);

			// 删除日志表中对应的数据
			Criteria criteriaLogModel = Criteria.forClass(TmsShipbillOperateLogModel.class);
			Restriction r7 = Restrictions.eq("shipbillId", delHeaderModel.getShipbillId());
			criteriaLogModel.setRestriction(Restrictions.and(r7));
			tmsShipbillOperateLogMapper.deleteByCriteria(criteriaLogModel);

			Criteria criteriaTransLogModel = Criteria.forClass(TmsShipbillTransLogModel.class);
			Restriction r10 = Restrictions.eq(TmsShipbillTransLogModel::getShipbillId, delHeaderModel.getShipbillId());
			criteriaTransLogModel.setRestriction(Restrictions.and(r10));
			tmsShipbillTransportLogMapper.deleteByCriteria(criteriaTransLogModel);
		}

		// 删除拥有相同父级运单ID的运单总表中相应的数据
		tmsShipbillHeaderMapper.deleteByCriteria(criteriaFather);
	}

	/**
	 * 待调度商品包裹信息查询
	 *
	 * @param pendingDispatchPackageByDetailVO
	 * @return
	 */
	@SuppressWarnings("resource")
	public Page<PendingDispatchPackageDTO> viewDetailPackage(PendingDispatchPackageByDetailVO pendingDispatchPackageByDetailVO) {
		ToolKits.isParamNull(pendingDispatchPackageByDetailVO, "待调度商品包裹信息查询请求不为空");
		ToolKits.isParamNull(pendingDispatchPackageByDetailVO.getShipbillId(), "运单ID不为空");
		ToolKits.isParamNull(pendingDispatchPackageByDetailVO.getItemId(), "商品ID不为空");
		ToolKits.isParamNull(pendingDispatchPackageByDetailVO.getPageNum(), "当前页码不为空");
		ToolKits.isParamNull(pendingDispatchPackageByDetailVO.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.PACKAGE_TYPE, null, null, null);
		if (!restMessage1.isSuccess()) {
			throw new RuntimeException("包裹类型翻译失败!");
		} else {
			data1 = restMessage1.getData();
		}

		// 设备类型
		RestMessage<List<Map<String, Object>>> restMessage2 = maindataTmsResource.getDropDownById(DataDictionaryConstant.DEVICE_COMPANY, null, null, null);
		if (!restMessage2.isSuccess()) {
			throw new RuntimeException("设备类型翻译失败!");
		} else {
			data2 = restMessage2.getData();
		}
		List<PendingDispatchPackageDTO> pendingDispatchPackageDTOs = new ArrayList<PendingDispatchPackageDTO>();
		// 查询商品对应的包裹ID
		Criteria criteria = Criteria.forClass(TmsShipbillPkgDetailModel.class);
		Restriction r1 = Restrictions.eq("shipbillId", pendingDispatchPackageByDetailVO.getShipbillId());
		Restriction r2 = Restrictions.eq("itemId", pendingDispatchPackageByDetailVO.getItemId());
		Restriction r3 = Restrictions.eq("enterpriseId", user.getEnterpriseId());
		criteria.setRestriction(Restrictions.and(r1, r2, r3));

		List<TmsShipbillPkgDetailModel> tmsShipbillPkgDetailModels = tmsShipbillPackageDetailMapper.findByCriteria(criteria);

		if (ToolKits.isEmpty(tmsShipbillPkgDetailModels)) {
			Page<PendingDispatchPackageDTO> page = PageUtils.getPage(pendingDispatchPackageDTOs);
			return page;
		}

		List<String> packageIds = tmsShipbillPkgDetailModels.stream().filter(o -> ToolKits.isNotEmpty(o.getPackageId())).map(TmsShipbillPkgDetailModel::getPackageId).distinct().collect(Collectors.toList());

		PageUtils.startPage(pendingDispatchPackageByDetailVO.getPageNum(), pendingDispatchPackageByDetailVO.getPageSize());
		List<TmsShipbillPackageModel> tmsShipbillPackageModels = tmsShipbillPackageMapper.findByIds(TmsShipbillPackageModel.class, packageIds.toArray(), null);

		// 响应对象集合
		for (TmsShipbillPackageModel tmsShipbillPackageModel : tmsShipbillPackageModels) {
			// 响应对象
			PendingDispatchPackageDTO pendingDispatchPackageDTO = new PendingDispatchPackageDTO();
			BeanUtils.copyProperties(tmsShipbillPackageModel, pendingDispatchPackageDTO);
			pendingDispatchPackageDTO.setPackageTypeName(PublicMethods.change(data1, String.valueOf(tmsShipbillPackageModel.getPackageType())));
			pendingDispatchPackageDTO.setDeviceCompanyName(PublicMethods.change(data2, String.valueOf(tmsShipbillPackageModel.getDeviceCompany())));
			pendingDispatchPackageDTOs.add(pendingDispatchPackageDTO);
		}

		// 分页重组
		Page<PendingDispatchPackageDTO> page = PageUtils.getPage(pendingDispatchPackageDTOs);
		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 pendingDispatchDetailByPackageVO
	 * @return
	 */
	@SuppressWarnings("resource")
	public Page<PendingDispatchPackageDetailDTO> viewPackageDetail(PendingDispatchDetailByPackageVO pendingDispatchDetailByPackageVO) {
		ToolKits.isParamNull(pendingDispatchDetailByPackageVO, "待调度包裹商品信息查询请求不为空");
		ToolKits.isParamNull(pendingDispatchDetailByPackageVO.getShipbillId(), "运单ID不为空");
		ToolKits.isParamNull(pendingDispatchDetailByPackageVO.getPackageId(), "包裹ID不为空");
		ToolKits.isParamNull(pendingDispatchDetailByPackageVO.getPageNum(), "当前页码不为空");
		ToolKits.isParamNull(pendingDispatchDetailByPackageVO.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();
		}

		// 查询商品对应的包裹ID
		Criteria criteria = Criteria.forClass(TmsShipbillPkgDetailModel.class);
		Restriction r1 = Restrictions.eq("shipbillId", pendingDispatchDetailByPackageVO.getShipbillId());
		Restriction r2 = Restrictions.eq("packageId", pendingDispatchDetailByPackageVO.getPackageId());
		Restriction r3 = Restrictions.eq("enterpriseId", user.getEnterpriseId());
		criteria.setRestriction(Restrictions.and(r1, r2, r3));

		PageUtils.startPage(pendingDispatchDetailByPackageVO.getPageNum(), pendingDispatchDetailByPackageVO.getPageSize());
		List<TmsShipbillPkgDetailModel> tmsShipbillPkgDetailModels = tmsShipbillPackageDetailMapper.findByCriteria(criteria);

		// 响应对象集合
		List<PendingDispatchPackageDetailDTO> pendingReviewPackageDetailDTOs = new ArrayList<>();

		if (ToolKits.isNotEmpty(tmsShipbillPkgDetailModels)) {
			for (TmsShipbillPkgDetailModel tmsShipbillPkgDetailModel : tmsShipbillPkgDetailModels) {
				PendingDispatchPackageDetailDTO pkgDetailDTO = new PendingDispatchPackageDetailDTO();
				BeanUtils.copyProperties(tmsShipbillPkgDetailModel, pkgDetailDTO);

				pkgDetailDTO.setPackTypeName(PublicMethods.change(data1, String.valueOf(pkgDetailDTO.getPackType())));
				pkgDetailDTO.setCargoThermosphereName(PublicMethods.change(data2, String.valueOf(pkgDetailDTO.getCargoThermosphere())));
				pendingReviewPackageDetailDTOs.add(pkgDetailDTO);
			}
		}
		// 分页重组
		Page<PendingDispatchPackageDetailDTO> page = PageUtils.getPage(pendingReviewPackageDetailDTOs);
		if (tmsShipbillPkgDetailModels instanceof com.github.pagehelper.Page) {
			com.github.pagehelper.Page<TmsShipbillPkgDetailModel> p0 = (com.github.pagehelper.Page<TmsShipbillPkgDetailModel>) tmsShipbillPkgDetailModels;
			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 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;
	}

	// 运输时效
	public BigDecimal getTransportAging(Date startDt, Date endDt) {
		if (ToolKits.isEmpty(startDt) || ToolKits.isEmpty(endDt)) {
			return null;
		}
		long betweenDay = DateUtil.between(endDt, startDt, DateUnit.MINUTE);
		return BigDecimal.valueOf(betweenDay / 60);
	}

	/**
	 * 待待调度点击运单查看运单相关信息
	 *
	 * @param shipbillId
	 * @return
	 */
	public PendingDispatchViewDTO viewShipbillData(String shipbillId) {
		ToolKits.isParamNull(shipbillId, "运单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<Map<String, Object>> data9 = Lists.newArrayList();
		List<Map<String, Object>> data10 = Lists.newArrayList();
		List<Map<String, Object>> data11 = 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.PACK_TYPE, null, null, null);
		if (!restMessage8.isSuccess()) {
			throw new RuntimeException("包装类型翻译失败!");
		} else {
			data8 = restMessage8.getData();
		}
		// 货物温层
		RestMessage<List<Map<String, Object>>> restMessage9 = maindataTmsResource.getDropDownById(DataDictionaryConstant.CARGO_THERMOSPHERE, null, null, null);
		if (!restMessage9.isSuccess()) {
			throw new RuntimeException("货物温层翻译失败!");
		} else {
			data9 = restMessage9.getData();
		}

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

		// 设备类型
		RestMessage<List<Map<String, Object>>> restMessage11 = maindataTmsResource.getDropDownById(DataDictionaryConstant.DEVICE_COMPANY, null, null, null);
		if (!restMessage11.isSuccess()) {
			throw new RuntimeException("设备类型翻译失败!");
		} else {
			data11 = restMessage11.getData();
		}

		// 查询运单汇总信息
		TmsShipbillHeaderModel model = tmsShipbillHeaderMapper.findById(shipbillId, TmsShipbillHeaderModel.class);
		PendingDispatchViewDTO dto = new PendingDispatchViewDTO();
		BeanUtils.copyProperties(model, dto);

		// 类型翻译
		dto.setOrderTypeName(PublicMethods.change(data1, String.valueOf(dto.getOrderType())));
		dto.setOrderBusinessTypeName(PublicMethods.change(data2, String.valueOf(dto.getOrderBusinessType())));
		dto.setDeliveryMethodTypeName(PublicMethods.change(data3, String.valueOf(dto.getDeliveryMethodType())));
		dto.setTransportTypeName(PublicMethods.change(data4, String.valueOf(dto.getTransportType())));
		dto.setTemperatureRequirementName(PublicMethods.change(data5, String.valueOf(dto.getTemperatureRequirement())));
		dto.setShipperTypeName(PublicMethods.change(data6, String.valueOf(dto.getShipperType())));
		dto.setConsigneeTypeName(PublicMethods.change(data7, String.valueOf(dto.getConsigneeType())));
		// 运单明细数据集
		List<PendingDispatchViewDetailDTO> detailDTOs = Lists.newArrayList();

		// 查询运单明细
		Criteria criteria = Criteria.forClass(TmsShipbillDetailModel.class);
		Restriction r1 = Restrictions.eq("shipbillId", shipbillId);
		Restriction r2 = Restrictions.eq("enterpriseId", user.getEnterpriseId());
		criteria.setRestriction(Restrictions.and(r1, r2));
		criteria.setOrder(Order.newInstance().asc(new String[] { "seqno" }));
		List<TmsShipbillDetailModel> tmsShipbillDetailModels = tmsShipbillDetailMapper.findByCriteria(criteria);
		// 商品总件数
		BigDecimal goodsTotalPcs = new BigDecimal(0);
		// 商品总体积
		BigDecimal goodsTotalVolume = new BigDecimal(0);
		// 商品总重量
		BigDecimal goodsTotalWeight = new BigDecimal(0);
		if (ToolKits.isNotEmpty(tmsShipbillDetailModels)) {
			for (TmsShipbillDetailModel tmsShipbillDetailModel : tmsShipbillDetailModels) {
				PendingDispatchViewDetailDTO detailDTO = new PendingDispatchViewDetailDTO();
				BeanUtils.copyProperties(tmsShipbillDetailModel, detailDTO);
				// 数据字典翻译
				detailDTO.setPackTypeName(PublicMethods.change(data8, String.valueOf(detailDTO.getPackType())));
				detailDTO.setCargoThermosphereName(PublicMethods.change(data9, String.valueOf(detailDTO.getCargoThermosphere())));
				detailDTOs.add(detailDTO);

				goodsTotalPcs = goodsTotalPcs.add(detailDTO.getPcs());
				goodsTotalVolume = goodsTotalVolume.add(detailDTO.getVolume());
				goodsTotalWeight = goodsTotalWeight.add(detailDTO.getWeight());
			}
			dto.setPendingDispatchViewDetailDTOs(detailDTOs);
			dto.setGoodsTotalPcs(goodsTotalPcs);
			dto.setGoodsTotalVolume(goodsTotalVolume);
			dto.setGoodsTotalWeight(goodsTotalWeight);
		}

		// 运单包裹数据集
		List<PendingDispatchViewPackageDTO> pendingDispatchPackageDTOs = Lists.newArrayList();

		// 查询运单包裹明细
		Criteria criteriaPkg = Criteria.forClass(TmsShipbillPackageModel.class);
		Restriction r3 = Restrictions.eq("shipbillId", shipbillId);
		Restriction r4 = Restrictions.eq("enterpriseId", user.getEnterpriseId());
		criteriaPkg.setRestriction(Restrictions.and(r3, r4));
		criteriaPkg.setOrder(Order.newInstance().desc(new String[] { "updatetime" }));
		List<TmsShipbillPackageModel> tmsShipbillPackageModels = tmsShipbillPackageMapper.findByCriteria(criteriaPkg);

		// 包裹总件数
		BigDecimal pkgTotalPcs = new BigDecimal(0);
		// 包裹总拼箱数
		BigDecimal pkgTotalLclPiece = new BigDecimal(0);
		// 包裹总整件数
		BigDecimal pkgTotalWholePiece = new BigDecimal(0);
		// 包裹总体积
		BigDecimal pkgTotalVolume = new BigDecimal(0);
		// 包裹总重量
		BigDecimal pkgTotalWeight = new BigDecimal(0);
		if (ToolKits.isNotEmpty(tmsShipbillPackageModels)) {
			for (TmsShipbillPackageModel tmsShipbillPackageModel : tmsShipbillPackageModels) {
				PendingDispatchViewPackageDTO pkgDTO = new PendingDispatchViewPackageDTO();
				BeanUtils.copyProperties(tmsShipbillPackageModel, pkgDTO);
				// 数据字典翻译
				pkgDTO.setPackageTypeName(PublicMethods.change(data10, String.valueOf(pkgDTO.getPackageType())));
				pkgDTO.setDeviceCompanyName(PublicMethods.change(data11, String.valueOf(pkgDTO.getDeviceCompany())));
				pendingDispatchPackageDTOs.add(pkgDTO);

				pkgTotalPcs = pkgTotalPcs.add(pkgDTO.getLclPiece()).add(pkgDTO.getWholePiece());
				pkgTotalLclPiece = pkgTotalLclPiece.add(pkgDTO.getLclPiece());
				pkgTotalWholePiece = pkgTotalWholePiece.add(pkgDTO.getWholePiece());
				pkgTotalVolume = pkgTotalVolume.add(pkgDTO.getVolume());
				pkgTotalWeight = pkgTotalWeight.add(pkgDTO.getWeight());
			}
			dto.setPendingDispatchViewPackageDTOs(pendingDispatchPackageDTOs);
			dto.setPkgTotalPcs(pkgTotalPcs);
			dto.setPkgTotalLclPiece(pkgTotalLclPiece);
			dto.setPkgTotalWholePiece(pkgTotalWholePiece);
			dto.setPkgTotalVolume(pkgTotalVolume);
			dto.setPkgTotalWeight(pkgTotalWeight);
		}
		return dto;
	}

	/**
	 * 智能拆分
	 *
	 * @param smartSplitVO
	 * @return
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public List<SmartSplitDTO> smartSplitData(SmartSplitVO smartSplitVO) {
		ToolKits.isParamNull(smartSplitVO.getShipbillIds(), "运单id不能为空");

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

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

		// 返回数据
		List<SmartSplitDTO> smartSplitDTOS = Lists.newArrayList();

		// 查询对应运单
		List<TmsShipbillHeaderModel> tmsShipbillHeaderModels = tmsShipbillHeaderMapper.findByIds(TmsShipbillHeaderModel.class, smartSplitVO.getShipbillIds().toArray(), null);
		if (ToolKits.isEmpty(tmsShipbillHeaderModels)) {
			throw new PrologException("运单不存在");
		}

		for (TmsShipbillHeaderModel tmsShipbillHeaderModel : tmsShipbillHeaderModels) {
			// 获取商品集合
			Criteria criteriaDetail = Criteria.forClass(TmsShipbillDetailModel.class);
			Restriction r1 = Restrictions.eq(TmsShipbillDetailModel::getShipbillId, tmsShipbillHeaderModel.getShipbillId());
			criteriaDetail.setRestriction(r1);
			List<TmsShipbillDetailModel> tmsShipbillDetailModels = tmsShipbillDetailMapper.findByCriteria(criteriaDetail);

			if (ToolKits.isEmpty(tmsShipbillDetailModels)) {
				// 运单没商品
				continue;
			}
			// 获取拆分策略
			StrategySplitMatchingVO strategySplitMatchingVO = new StrategySplitMatchingVO();
			BeanUtils.copyProperties(tmsShipbillHeaderModel, strategySplitMatchingVO);
			RestMessage<List<StrategySplitMatchingDTO>> restMessage = maindataTmsResource.matchingExecute(strategySplitMatchingVO);
			if (!restMessage.isSuccess()) {
				throw new PrologException("获取拆分策略失败:" + restMessage.getMessage());
			}
			// 策略集合
			List<StrategySplitMatchingDTO> strategySplitMatchingDTOS = restMessage.getData();
			// 如果为空跳过
			if (ToolKits.isEmpty(strategySplitMatchingDTOS)) {
				continue;
			} else if (strategySplitMatchingDTOS.size() > 1) {// 如果为多条
				// 封装返回数据
				SmartSplitDTO smartSplitDTO = new SmartSplitDTO();
				smartSplitDTO.setShipbillId(tmsShipbillHeaderModel.getShipbillId());
				smartSplitDTO.setStrategySplitMatchingDTOS(strategySplitMatchingDTOS);
				smartSplitDTOS.add(smartSplitDTO);
				continue;
			}
			StrategySplitMatchingDTO strategyDTO = strategySplitMatchingDTOS.get(0);

			if (user.getUserType().equals(BussinessConstant.USER_TYPE_ZY)) {
				if (!DataDictionaryConstant.SHIPBILL_STATUS_REVIEW.equals(tmsShipbillHeaderModel.getStatus())) {
					throw new PrologException("运单【" + tmsShipbillHeaderModel.getShipbillNo() + "】非待调度状态,拆单失败");
				}
				if (!DataDictionaryConstant.SPLIT_ORDER_STATUS_UN.equals(tmsShipbillHeaderModel.getSplitOrderStatus())) {
					throw new PrologException("运单【" + tmsShipbillHeaderModel.getShipbillNo() + "】非待调度状态,拆单失败");
				}
				tmsShipbillHeaderModel.setSplitOrderStatus(DataDictionaryConstant.SPLIT_ORDER_STATUS_ED);
				// 原始主单被拆分时，拆单类型更新为2拆分主单，子单被拆分时，不更新拆单类型
				if (ToolKits.isEmpty(tmsShipbillHeaderModel.getSplitOrderType()) || DataDictionaryConstant.SPLIT_ORDER_TYPE_UN.equals(tmsShipbillHeaderModel.getSplitOrderType())) {
					tmsShipbillHeaderModel.setSplitOrderType(DataDictionaryConstant.SPLIT_ORDER_TYPE_SPLIT_MASTER);
				}

			} else if (user.getUserType().equals(BussinessConstant.USER_TYPE_CYS)) {
				if (!DataDictionaryConstant.CARRIER_SHIPBILL_STATUS_AUDITED.equals(tmsShipbillHeaderModel.getCarrierShipbillStatus())) {
					throw new PrologException("运单【" + tmsShipbillHeaderModel.getShipbillNo() + "】非待调度状态,拆单失败");
				}
				if (!DataDictionaryConstant.CARRIER_SPLIT_ORDER_STATUS_UN.equals(tmsShipbillHeaderModel.getCarrierSplitOrderStatus())) {
					throw new PrologException("运单【" + tmsShipbillHeaderModel.getShipbillNo() + "】非待调度状态,拆单失败");
				}
				tmsShipbillHeaderModel.setCarrierSplitOrderStatus(DataDictionaryConstant.CARRIER_SPLIT_ORDER_STATUS_ED);
				// 原始主单被拆分时，拆单类型更新为2拆分主单，子单被拆分时，不更新拆单类型
				if (ToolKits.isEmpty(tmsShipbillHeaderModel.getCarrierSplitOrderType()) || DataDictionaryConstant.CARRIER_SPLIT_ORDER_TYPE_UN.equals(tmsShipbillHeaderModel.getCarrierSplitOrderType())) {
					tmsShipbillHeaderModel.setCarrierSplitOrderType(DataDictionaryConstant.CARRIER_SPLIT_ORDER_TYPE_SPLIT_MASTER);
				}
			}
			autoSplit(strategyDTO, tmsShipbillHeaderModel, user, date);
		}
		return smartSplitDTOS;
	}

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

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

		for (SmartSplitStrategyVO smartSplitStrategyVO : smartSplitStrategyVOS) {
			ToolKits.isParamNull(smartSplitStrategyVO.getShipbillId(), "运单id不能为空");
			ToolKits.isParamNull(smartSplitStrategyVO.getStrategyId(), "策略id不能为空");

			TmsShipbillHeaderModel tmsShipbillHeaderModel = tmsShipbillHeaderMapper.findById(smartSplitStrategyVO.getShipbillId(), TmsShipbillHeaderModel.class);
			if (ToolKits.isEmpty(tmsShipbillHeaderModel)) {
				continue;
			}

			// 获取商品集合
			Criteria criteriaDetail = Criteria.forClass(TmsShipbillDetailModel.class);
			Restriction r1 = Restrictions.eq(TmsShipbillDetailModel::getShipbillId, tmsShipbillHeaderModel.getShipbillId());
			criteriaDetail.setRestriction(r1);
			List<TmsShipbillDetailModel> tmsShipbillDetailModels = tmsShipbillDetailMapper.findByCriteria(criteriaDetail);
			if (ToolKits.isEmpty(tmsShipbillDetailModels)) {
				continue;
			}

			// 用选择的拆分策略拆分
			StrategySplitMatchingDTO strategyDTO = new StrategySplitMatchingDTO();
			BeanUtils.copyProperties(smartSplitStrategyVO, strategyDTO);

			if (user.getUserType().equals(BussinessConstant.USER_TYPE_ZY)) {
				if (!DataDictionaryConstant.SHIPBILL_STATUS_REVIEW.equals(tmsShipbillHeaderModel.getStatus())) {
					throw new PrologException("运单【" + tmsShipbillHeaderModel.getShipbillNo() + "】非待调度状态,拆单失败");
				}
				if (!DataDictionaryConstant.SPLIT_ORDER_STATUS_UN.equals(tmsShipbillHeaderModel.getSplitOrderStatus())) {
					throw new PrologException("运单【" + tmsShipbillHeaderModel.getShipbillNo() + "】非待调度状态,拆单失败");
				}
				tmsShipbillHeaderModel.setSplitOrderStatus(DataDictionaryConstant.SPLIT_ORDER_STATUS_ED);
				// 原始主单被拆分时，拆单类型更新为2拆分主单，子单被拆分时，不更新拆单类型
				if (ToolKits.isEmpty(tmsShipbillHeaderModel.getSplitOrderType()) || DataDictionaryConstant.SPLIT_ORDER_TYPE_UN.equals(tmsShipbillHeaderModel.getSplitOrderType())) {
					tmsShipbillHeaderModel.setSplitOrderType(DataDictionaryConstant.SPLIT_ORDER_TYPE_SPLIT_MASTER);
				}

			} else if (user.getUserType().equals(BussinessConstant.USER_TYPE_CYS)) {
				if (!DataDictionaryConstant.CARRIER_SHIPBILL_STATUS_AUDITED.equals(tmsShipbillHeaderModel.getCarrierShipbillStatus())) {
					throw new PrologException("运单【" + tmsShipbillHeaderModel.getShipbillNo() + "】非待调度状态,拆单失败");
				}
				if (!DataDictionaryConstant.CARRIER_SPLIT_ORDER_STATUS_UN.equals(tmsShipbillHeaderModel.getCarrierSplitOrderStatus())) {
					throw new PrologException("运单【" + tmsShipbillHeaderModel.getShipbillNo() + "】非待调度状态,拆单失败");
				}
				tmsShipbillHeaderModel.setCarrierSplitOrderStatus(DataDictionaryConstant.CARRIER_SPLIT_ORDER_STATUS_ED);
				// 原始主单被拆分时，拆单类型更新为2拆分主单，子单被拆分时，不更新拆单类型
				if (ToolKits.isEmpty(tmsShipbillHeaderModel.getCarrierSplitOrderType()) || DataDictionaryConstant.CARRIER_SPLIT_ORDER_TYPE_UN.equals(tmsShipbillHeaderModel.getCarrierSplitOrderType())) {
					tmsShipbillHeaderModel.setCarrierSplitOrderType(DataDictionaryConstant.CARRIER_SPLIT_ORDER_TYPE_SPLIT_MASTER);
				}
			}
			autoSplit(strategyDTO, tmsShipbillHeaderModel, user, date);
		}
	}

	/**
	 * 智能拆分（公共处理）
	 *
	 * @param strategyDTO
	 */
	@Override
	public void autoSplit(StrategySplitMatchingDTO strategyDTO, TmsShipbillHeaderModel shipbillHeaderModel, UserEntity user, Date date) {

		// 获取商品集合
		Criteria criteriaDetail = Criteria.forClass(TmsShipbillDetailModel.class);
		Restriction r1 = Restrictions.eq(TmsShipbillDetailModel::getShipbillId, shipbillHeaderModel.getShipbillId());
		criteriaDetail.setRestriction(r1);
		List<TmsShipbillDetailModel> tmsShipbillDetailModels = tmsShipbillDetailMapper.findByCriteria(criteriaDetail);

		// 拆分完的明细集合
		Map<Object, List<TmsShipbillDetailModel>> map = Maps.newHashMap();
		// 拆分的不足单子
		List<TmsShipbillDetailModel> modelSplitIns = Lists.newArrayList();
		// 库存足的单子
		List<TmsShipbillDetailModel> modelNotIns = Lists.newArrayList();
		// 获取库存不足单子
		List<TmsShipbillDetailModel> modelIns = Lists.newArrayList();

		switch (strategyDTO.getRuleCode().intValue()) {
		case 1: // 按商品品类拆分
			try {
				map = tmsShipbillDetailModels.stream().collect(Collectors.groupingBy(TmsShipbillDetailModel::getItemCategoryId));
				if (map.size() == 1) {
					map.clear();
				}
			} catch (Exception e) {
			}
			break;
		case 2:// 按包装类型拆分
			try {
				map = tmsShipbillDetailModels.stream().collect(Collectors.groupingBy(TmsShipbillDetailModel::getPackType));
				if (map.size() == 1) {
					map.clear();
				}
			} catch (Exception e) {
			}
			break;
		case 3:// 按货物温层拆分
			try {
				map = tmsShipbillDetailModels.stream().collect(Collectors.groupingBy(TmsShipbillDetailModel::getCargoThermosphere));
				if (map.size() == 1) {
					map.clear();
				}
			} catch (Exception e) {
			}
			break;
		case 4:// 按数量、库存数量拆分
				// 获取库存不足单子
			try {
				modelIns = tmsShipbillDetailModels.stream().filter(o -> (o.getPcs().intValue() > o.getInventoryPcs().intValue() && ToolKits.isNotEmpty(o.getInventoryPcs()) && o.getInventoryPcs().intValue() > 0)).collect(Collectors.toList());
			} catch (Exception e) {
			}
			// 没有库存不足的就不拆分
			if (ToolKits.isEmpty(modelIns)) {
				break;
			}
			// 获取库存足的单子
			modelNotIns = tmsShipbillDetailModels.stream().filter(o -> o.getPcs().intValue() < o.getInventoryPcs().intValue()).collect(Collectors.toList());

			for (TmsShipbillDetailModel model : modelIns) {
				TmsShipbillDetailModel model1 = new TmsShipbillDetailModel();
				TmsShipbillDetailModel model2 = new TmsShipbillDetailModel();
				BeanUtils.copyProperties(model, model1);
				BeanUtils.copyProperties(model, model2);
				model1.setPcs(new BigDecimal(model.getInventoryPcs()));
				model2.setPcs(model.getPcs().subtract(new BigDecimal(model.getInventoryPcs())));
				model2.setInventoryPcs(0);

				// 计算商品的体积，重量
				ItemCheckVO itemCheckVO = new ItemCheckVO();
				itemCheckVO.setItemId(model.getItemId());
				RestMessage<ItemCheckDTO> itemRestMessage = maindataTmsResource.getItem(itemCheckVO);

				if (!itemRestMessage.isSuccess()) {
					throw new PrologException("获取商品服务失败:" + itemRestMessage.getMessage());
				}
				if (ToolKits.isEmpty(itemRestMessage.getData())) {
					throw new PrologException("未找到对应商品【" + model.getItemName() + "】");
				}
				ItemCheckDTO itemCheckDTO = itemRestMessage.getData();

				if (ToolKits.isNotEmpty(itemCheckDTO.getWeight())) {
					model1.setWeight(itemCheckDTO.getWeight().multiply(model1.getPcs()));
					model2.setWeight(itemCheckDTO.getWeight().multiply(model2.getPcs()));
				}
				if (ToolKits.isNotEmpty(itemCheckDTO.getVolume())) {
					model1.setVolume(itemCheckDTO.getVolume().multiply(model1.getPcs()));
					model2.setVolume(itemCheckDTO.getVolume().multiply(model2.getPcs()));
				}
				modelNotIns.add(model1);
				modelSplitIns.add(model2);
			}
			// 封装到map集合
			// 库存足
			map.put("modelSplitIns", modelNotIns);
			// 库存不足
			map.put("modelSplitInsNo", modelSplitIns);
			break;
		case 5:// 按默认存放仓库、数量、库存数量拆分
			Map<Long, List<TmsShipbillDetailModel>> collect = Maps.newHashMap();
			try {
				collect = tmsShipbillDetailModels.stream().collect(Collectors.groupingBy(TmsShipbillDetailModel::getBranchId));
			} catch (Exception e) {
				break;
			}
			for (Long l : collect.keySet()) {
				List<TmsShipbillDetailModel> list = collect.get(l);
				// 获取库存不足单子
				List<TmsShipbillDetailModel> modelInsList = list.stream().filter(o -> (o.getPcs().intValue() > o.getInventoryPcs().intValue() && ToolKits.isNotEmpty(o.getInventoryPcs()) && o.getInventoryPcs().intValue() > 0)).collect(Collectors.toList());
				// 库存足,有分组的也拆分
				if (ToolKits.isEmpty(modelInsList)) {
					if (collect.size() > 1) {
						map.put(l + "-Ins-U-Flow", list);
					}
					continue;
				}
				// 获取库存足的单子
				List<TmsShipbillDetailModel> modelNotInsList = list.stream().filter(o -> o.getPcs().intValue() < o.getInventoryPcs().intValue()).collect(Collectors.toList());

				// 拆分的不足单子
				List<TmsShipbillDetailModel> modelSplitInsList = Lists.newArrayList();
				for (TmsShipbillDetailModel model : modelInsList) {

					TmsShipbillDetailModel model1 = new TmsShipbillDetailModel();
					TmsShipbillDetailModel model2 = new TmsShipbillDetailModel();
					BeanUtils.copyProperties(model, model1);
					BeanUtils.copyProperties(model, model2);
					model1.setPcs(new BigDecimal(model.getInventoryPcs()));
					model2.setPcs(model.getPcs().subtract(new BigDecimal(model.getInventoryPcs())));
					model2.setInventoryPcs(0);

					// 计算商品的体积，重量
					ItemCheckVO itemCheckVO = new ItemCheckVO();
					itemCheckVO.setItemId(model.getItemId());
					RestMessage<ItemCheckDTO> itemRestMessage = maindataTmsResource.getItem(itemCheckVO);

					if (!itemRestMessage.isSuccess()) {
						throw new PrologException("获取商品服务失败");
					}
					if (ToolKits.isEmpty(itemRestMessage.getData())) {
						throw new PrologException("未找到对应商品[商品:" + model.getItemName() + "]");
					}
					ItemCheckDTO itemCheckDTO = itemRestMessage.getData();

					if (ToolKits.isNotEmpty(itemCheckDTO.getWeight())) {
						model1.setWeight(itemCheckDTO.getWeight().multiply(model1.getPcs()));
						model2.setWeight(itemCheckDTO.getWeight().multiply(model2.getPcs()));
					}
					if (ToolKits.isNotEmpty(itemCheckDTO.getVolume())) {
						model1.setVolume(itemCheckDTO.getVolume().multiply(model1.getPcs()));
						model2.setVolume(itemCheckDTO.getVolume().multiply(model2.getPcs()));
					}
					modelNotInsList.add(model1);
					modelSplitInsList.add(model2);
				}
				// 封装到map集合
				// 库存足的运单
				map.put(l + "-SplitIns-U-Flow", modelNotInsList);
				// 库存不足的运单
				map.put(l + "-SplitInsNo-U-Flow", modelSplitInsList);
			}
			break;
		case 6:// 按默认存放仓库拆分
			Map<Long, List<TmsShipbillDetailModel>> collect6 = Maps.newHashMap();
			try {
				collect6 = tmsShipbillDetailModels.stream().collect(Collectors.groupingBy(TmsShipbillDetailModel::getBranchId));
			} catch (Exception e) {
				break;
			}
			if (collect6.size() > 1) {
				for (Long l : collect6.keySet()) {
					List<TmsShipbillDetailModel> list6 = collect6.get(l);
					map.put(l + "-Ins-U-Flow", list6);
				}
			}
			break;
		case 7:// 按运单明细关键字拆分
			String splitKey = strategyDTO.getShipbillDetailSplitKey();
			if (ToolKits.isNotEmpty(splitKey)) {
				List<String> keyList = Arrays.stream(splitKey.split(",")).distinct().collect(Collectors.toList());
				List<TmsShipbillDetailModel> noMatchShipbillDetails = tmsShipbillDetailModels.stream().filter(t -> ToolKits.isEmpty(t.getMemo())).collect(Collectors.toList());

				List<TmsShipbillDetailModel> matchShipbillDetails = Lists.newArrayList();

				tmsShipbillDetailModels = tmsShipbillDetailModels.stream().filter(t -> ToolKits.isNotEmpty(t.getMemo())).collect(Collectors.toList());

				Map<String, List<TmsShipbillDetailModel>> collect7 = Maps.newHashMap();
				if (ToolKits.isNotEmpty(tmsShipbillDetailModels)) {
					for (TmsShipbillDetailModel detailModel : tmsShipbillDetailModels) {
						boolean match = false;
						for (String key : keyList) {
							if (detailModel.getMemo().contains(key)) {
								detailModel.setUpdateperson(key);
								matchShipbillDetails.add(detailModel);
								match = true;
								break;
							}
						}
						if (!match) {
							noMatchShipbillDetails.add(detailModel);
						}
					}
					collect7 = matchShipbillDetails.stream().collect(Collectors.groupingBy(TmsShipbillDetailModel::getUpdateperson));
				}
				if (ToolKits.isNotEmpty(noMatchShipbillDetails)) {
					if (collect7.size() > 0) {
						for (String l : collect7.keySet()) {
							List<TmsShipbillDetailModel> list7 = collect7.get(l);
							map.put(l + "-key-split", list7);
						}
						map.put("no" + "-key-split", noMatchShipbillDetails);
					}
				} else {
					if (collect7.size() > 1) {
						for (String l : collect7.keySet()) {
							List<TmsShipbillDetailModel> list7 = collect7.get(l);
							map.put(l + "-key-split", list7);
						}
					}
				}
			}
			break;
		}
		if (ToolKits.isEmpty(map)) {
			return;
		}
		// 保存拆单明细
		int index = 1;
		RestMessage<SysParamConfigModel> restMessageShipbillId = maindataTmsResource.getValue(DataDictionaryConstant.SHIPBILL_ID_CREATE_RULE);
		if (!restMessageShipbillId.isSuccess()) {
			throw new RuntimeException("获取运单ID生成规则的系统参数失败!");
		}
		SysParamConfigModel sysParamConfigModel = restMessageShipbillId.getData();
		for (Object obj : map.keySet()) {
			List<TmsShipbillDetailModel> list = map.get(obj);
			if (ToolKits.isEmpty(list)) {
				continue;
			}
			String subShipbillId = "";
			if (DataDictionaryConstant.SHIPBILL_ID_CREATE_RULE_AUTO.equals(sysParamConfigModel.getValue())) {
				// 获取运单汇总ID
				RestMessage<String> restMessageAutoCreateShipbillId = maindataTmsResource.getCodeNumberByCode(SeriaNnumberConstant.TMS_SHIPBILL_HEADER_ID, "L");
				if (!restMessageAutoCreateShipbillId.isSuccess()) {
					throw new RuntimeException("生成运单汇总ID失败");
				}
				subShipbillId = restMessageAutoCreateShipbillId.getData();
			} else {
				StringBuffer buffNo1 = new StringBuffer(shipbillHeaderModel.getShipbillId());
				buffNo1.append(DataDictionaryConstant.SUB_SHIPBILL_NO);
				buffNo1.append(DataDictionaryConstant.SPLIT_SHIPBILL_NO);
				buffNo1.append(index);
				subShipbillId = buffNo1.toString();
				index++;
			}

			// 商品总件数
			BigDecimal goodsTotalPcs = new BigDecimal(0);
			// 商品总体积
			BigDecimal goodsTotalVolume = new BigDecimal(0);
			// 商品总重量
			BigDecimal goodsTotalWeight = new BigDecimal(0);

			BigDecimal zero = new BigDecimal(0);

			// 保存拆分子单的运单汇总
			TmsShipbillHeaderModel subTmsShipbillHeaderModel = new TmsShipbillHeaderModel();
			BeanUtils.copyProperties(shipbillHeaderModel, subTmsShipbillHeaderModel);
			Long branchId = list.get(0).getBranchId();
			if (obj.toString().contains("U-Flow")) {
				// 取新仓库信息
				RestMessage<TmsBaseBranchDTO> restMessageBranch = maindataTmsResource.viewBranch(branchId);
				if (restMessageBranch.isSuccess()) {
					TmsBaseBranchDTO tmsBaseBranchDTO = restMessageBranch.getData();
					// 重新设定发货方数据
					// 发货方类型
					subTmsShipbillHeaderModel.setShipperType(DataDictionaryConstant.SHIPPER_TYPE_CK);
					// 发货方单位ID
					subTmsShipbillHeaderModel.setShipperUnitId(tmsBaseBranchDTO.getId());
					subTmsShipbillHeaderModel.setShipperUnitCode(tmsBaseBranchDTO.getCode());
					subTmsShipbillHeaderModel.setShipperUnitName(tmsBaseBranchDTO.getName());
					// 发货方ID
					subTmsShipbillHeaderModel.setShipperId(tmsBaseBranchDTO.getId());
					subTmsShipbillHeaderModel.setShipperCode(tmsBaseBranchDTO.getCode());
					subTmsShipbillHeaderModel.setShipperName(tmsBaseBranchDTO.getName());

					// 发货方联系人
					subTmsShipbillHeaderModel.setShipperContact(tmsBaseBranchDTO.getContact());
					// 发货方手机号
					subTmsShipbillHeaderModel.setShipperPhoneNumber(tmsBaseBranchDTO.getPhoneNumber());
					// 发货方座机号
					subTmsShipbillHeaderModel.setShipperLandlineNumber(tmsBaseBranchDTO.getLandlineNumber());

					subTmsShipbillHeaderModel.setShipperEmail(tmsBaseBranchDTO.getEmail());

					subTmsShipbillHeaderModel.setShipperRelatedPhoneNumber(tmsBaseBranchDTO.getPhoneNumber());
					// 发货方省编码
					subTmsShipbillHeaderModel.setShipperProvince(tmsBaseBranchDTO.getProvince());
					// 发货方省名称
					subTmsShipbillHeaderModel.setShipperProvinceName(tmsBaseBranchDTO.getProvinceName());
					// 发货方市编码
					subTmsShipbillHeaderModel.setShipperCity(tmsBaseBranchDTO.getCity());
					subTmsShipbillHeaderModel.setShipperCityName(tmsBaseBranchDTO.getCityName());
					// 发货方区/县编码
					subTmsShipbillHeaderModel.setShipperDistrict(tmsBaseBranchDTO.getDistrict());
					subTmsShipbillHeaderModel.setShipperDistrictName(tmsBaseBranchDTO.getDistrictName());

					// 发货方详细地址
					subTmsShipbillHeaderModel.setShipperAddress(tmsBaseBranchDTO.getAddress());

					// 发货方经度
					subTmsShipbillHeaderModel.setShipperLongitude(tmsBaseBranchDTO.getLongitude());
					// 发货方纬度
					subTmsShipbillHeaderModel.setShipperLatitude(tmsBaseBranchDTO.getLatitude());
					subTmsShipbillHeaderModel.setShipperMemo(tmsBaseBranchDTO.getMemo());

					// 重新适配新业务流程,取流程失败时，此运单不做拆分
					ShipbillFitBusinessFlowDTO flowData = shipbillMatchBusinessFlow(subTmsShipbillHeaderModel, 2);
					if (ToolKits.isEmpty(flowData) || ToolKits.isEmpty(flowData.getFlowConfig())) {
						throw new RuntimeException("运单匹配业务流程失败");
					}
					subTmsShipbillHeaderModel.setFlowConfig(flowData.getFlowConfig());
				} else {
					throw new RuntimeException("取得拆分运单的仓库信息失败");
				}
				if (strategyDTO.getRematchLine().equals(DataDictionaryConstant.REMATCH_LINE_YES)) {
					// 子单重新匹配线路
					ShipbillMatchLineDTO lineData = shipbillMatchLine(subTmsShipbillHeaderModel);
					if (ToolKits.isNotEmpty(lineData) && ToolKits.isNotEmpty(lineData.getLineId())) {
						// 订单绑定线路
						subTmsShipbillHeaderModel.setLineId(lineData.getLineId());
						subTmsShipbillHeaderModel.setLineCode(lineData.getLineCode());
						subTmsShipbillHeaderModel.setLineName(lineData.getLineName());
						subTmsShipbillHeaderModel.setLineDirection(lineData.getLineDirection());
						subTmsShipbillHeaderModel.setShippingOrder(lineData.getShippingOrder());
						subTmsShipbillHeaderModel.setPickUpOrder(lineData.getPickUpOrder());
					}
				}
			}

			// 保存每个子单中的明细信息
			int idx = 1;
			for (TmsShipbillDetailModel detailModel : list) {
				TmsShipbillDetailModel subTmsShipbillDetailModel = new TmsShipbillDetailModel();
				// 运单明细ID
				RestMessage<String> restMessage2 = maindataTmsResource.getCodeNumberByCode(SeriaNnumberConstant.TMS_SHIPBILL_DETAIL_ID, "L");
				if (!restMessage2.isSuccess()) {
					throw new RuntimeException("生成运单明细ID失败");
				}
				String subShipbillDetailId = restMessage2.getData();

				// 取商品资料
				// STD-DEVELOP20220823 lhb 计算件重体 20220913 start
				ItemCheckVO itemCheckVO = new ItemCheckVO();
				itemCheckVO.setItemId(detailModel.getItemId());
				RestMessage<ItemCheckDTO> restMessage3 = maindataTmsResource.getItem(itemCheckVO);
				if (!restMessage3.isSuccess()) {
					throw new RuntimeException("取商品资料信息失败:" + restMessage3.getMessage());
				}
				ItemCheckDTO rsItemInfo = restMessage3.getData();
				// STD-DEVELOP20220823 lhb 计算件重体 20220913 end

				BeanUtils.copyProperties(detailModel, subTmsShipbillDetailModel);

				// ID
				subTmsShipbillDetailModel.setId(subShipbillDetailId);
				subTmsShipbillDetailModel.setSeqno(idx);
				idx++;
				subTmsShipbillDetailModel.setOriginalSeqno(subTmsShipbillDetailModel.getSeqno());
				// 运单ID
				subTmsShipbillDetailModel.setShipbillId(subShipbillId);
				// 运单编号
				subTmsShipbillDetailModel.setShipbillNo(subShipbillId);

				subTmsShipbillDetailModel.setEnterpriseId(user.getEnterpriseId());
				subTmsShipbillDetailModel.setEnterpriseName(user.getEnterpriseName());

				subTmsShipbillDetailModel.setCreateperson(user.getNickname());
				subTmsShipbillDetailModel.setCreatetime(date);
				subTmsShipbillDetailModel.setUpdateperson(user.getNickname());
				subTmsShipbillDetailModel.setUpdatetime(date);
				// STD-DEVELOP20220823 lhb 计算件重体 20220913 start
				subTmsShipbillDetailModel.setWeight(detailModel.getPcs().multiply(rsItemInfo.getWeight()));
				subTmsShipbillDetailModel.setVolume(detailModel.getPcs().multiply(rsItemInfo.getVolume()));
				// STD-DEVELOP20220823 lhb 计算件重体 20220913 end

				subTmsShipbillDetailModel.setUnitVolume(rsItemInfo.getVolume());
				subTmsShipbillDetailModel.setUnitWeight(rsItemInfo.getWeight());
				subTmsShipbillDetailModel.setOrigPcs(subTmsShipbillDetailModel.getPcs());
				subTmsShipbillDetailModel.setClosingPcs(BigDecimal.valueOf(0));
				subTmsShipbillDetailModel.setDeliveryPcs(BigDecimal.valueOf(0));
				subTmsShipbillDetailModel.setFatherId(detailModel.getId());
				subTmsShipbillDetailModel.setScanStatus(DataDictionaryConstant.SCAN_STATUS_INIT);
				tmsShipbillDetailMapper.save(subTmsShipbillDetailModel);
				// STD-DEVELOP20220823 lhb 计算件重体 20220913 start
				if (ToolKits.isNotEmpty(subTmsShipbillDetailModel.getPcs())) {
					goodsTotalPcs = goodsTotalPcs.add(subTmsShipbillDetailModel.getPcs());
				}
				if (ToolKits.isNotEmpty(subTmsShipbillDetailModel.getVolume())) {
					goodsTotalVolume = goodsTotalVolume.add(subTmsShipbillDetailModel.getVolume());
				}
				if (ToolKits.isNotEmpty(subTmsShipbillDetailModel.getWeight())) {
					goodsTotalWeight = goodsTotalWeight.add(subTmsShipbillDetailModel.getWeight());
				}
				// STD-DEVELOP20220823 lhb 计算件重体 20220913 end
			}

			subTmsShipbillHeaderModel.setShipbillId(subShipbillId);
			subTmsShipbillHeaderModel.setShipbillNo(subShipbillId);
			// 运单状态
			subTmsShipbillHeaderModel.setStatus(DataDictionaryConstant.SHIPBILL_STATUS_REVIEW);
			if (user.getUserType().equals(BussinessConstant.USER_TYPE_ZY)) {
				// 拆单状态 0未拆单
				subTmsShipbillHeaderModel.setSplitOrderStatus(DataDictionaryConstant.SPLIT_ORDER_STATUS_UN);
				// 拆单类型 3拆分子单
				subTmsShipbillHeaderModel.setSplitOrderType(DataDictionaryConstant.SPLIT_ORDER_TYPE_SPLIT_SUB);

				// 拆单状态 0未拆单
				subTmsShipbillHeaderModel.setCarrierSplitOrderStatus(DataDictionaryConstant.CARRIER_SPLIT_ORDER_STATUS_UN);
				// 拆单类型 3拆分子单
				subTmsShipbillHeaderModel.setCarrierSplitOrderType(DataDictionaryConstant.CARRIER_SPLIT_ORDER_TYPE_UN);
			} else {
				// 拆单状态 0未拆单
				subTmsShipbillHeaderModel.setCarrierSplitOrderStatus(DataDictionaryConstant.CARRIER_SPLIT_ORDER_STATUS_UN);
				// 拆单类型 3拆分子单
				subTmsShipbillHeaderModel.setCarrierSplitOrderType(DataDictionaryConstant.CARRIER_SPLIT_ORDER_TYPE_SPLIT_SUB);

				subTmsShipbillHeaderModel.setSplitOrderStatus(DataDictionaryConstant.SPLIT_ORDER_STATUS_UN);
				// 拆单类型 3拆分子单
				subTmsShipbillHeaderModel.setSplitOrderType(DataDictionaryConstant.SPLIT_ORDER_TYPE_UN);
			}

			// 父级运单ID
			subTmsShipbillHeaderModel.setFatherShipbillId(shipbillHeaderModel.getShipbillId());
			// 父级运单编号
			subTmsShipbillHeaderModel.setFatherShipbillNo(shipbillHeaderModel.getShipbillNo());
			// 原始运单ID
			String originalShipbillId = shipbillHeaderModel.getOriginalShipbillId() == null ? shipbillHeaderModel.getShipbillId() : shipbillHeaderModel.getOriginalShipbillId();
			subTmsShipbillHeaderModel.setOriginalShipbillId(originalShipbillId);
			// 原始运单编号
			String originalShipbillNo = shipbillHeaderModel.getOriginalShipbillNo() == null ? shipbillHeaderModel.getShipbillNo() : shipbillHeaderModel.getOriginalShipbillNo();
			subTmsShipbillHeaderModel.setOriginalShipbillNo(originalShipbillNo);
			// 总件数
			subTmsShipbillHeaderModel.setTotalPcs(goodsTotalPcs);
			// 总体积
			subTmsShipbillHeaderModel.setTotalVolume(goodsTotalVolume);
			// 总重量
			subTmsShipbillHeaderModel.setTotalWeight(goodsTotalWeight);
			// 实际总件数
			subTmsShipbillHeaderModel.setActualTotalPcs(goodsTotalPcs);
			// 实际总体积
			subTmsShipbillHeaderModel.setActualTotalVolume(goodsTotalVolume);
			// 实际总重量
			subTmsShipbillHeaderModel.setActualTotalWeight(goodsTotalWeight);
			// 包裹整件数
			subTmsShipbillHeaderModel.setPackageWholePiece(zero);
			// 包裹拼箱数
			subTmsShipbillHeaderModel.setPackageLclPiece(zero);
			// 包裹总体积
			subTmsShipbillHeaderModel.setPackageTotalVolume(zero);
			// 包裹总重量
			subTmsShipbillHeaderModel.setPackageTotalWeight(zero);

			subTmsShipbillHeaderModel.setCreateperson(user.getNickname());
			subTmsShipbillHeaderModel.setCreatetime(date);
			subTmsShipbillHeaderModel.setUpdateperson(user.getNickname());
			subTmsShipbillHeaderModel.setUpdatetime(date);
			subTmsShipbillHeaderModel.setShipbillType(ShipBillTypeEnum.NORMAL.getCode());
			subTmsShipbillHeaderModel.setSignInStatus(SignInStatusEnum.NOT_SIGN.getCode());
			subTmsShipbillHeaderModel.setDriverReceiveStatus(DriverReceiveStatusEnum.N.getCode());
			subTmsShipbillHeaderModel.setIntelligentLock(IntelligentLockEnum.UN_LOCK.getCode());
			tmsShipbillHeaderMapper.save(subTmsShipbillHeaderModel);

			// 初期化订单运输记录表
			saveTransportLog(subTmsShipbillHeaderModel.getShipbillId(), date, subTmsShipbillHeaderModel.getEstimatedPickupStartTime());

			// 子运单日志保存
			ShipbillOperateLogSaveNewVO subShipbillOperateLogSaveVO = new ShipbillOperateLogSaveNewVO();
			subShipbillOperateLogSaveVO.setShipbillId(subTmsShipbillHeaderModel.getShipbillId());
			subShipbillOperateLogSaveVO.setShipbillNo(subTmsShipbillHeaderModel.getShipbillNo());
			subShipbillOperateLogSaveVO.setOperateDate(date);
			subShipbillOperateLogSaveVO.setOperateEvent(DataDictionaryConstant.SHIPBILL_EVENT_NAME_SPLIT_SUB);
			subShipbillOperateLogSaveVO.setOldStatus(DataDictionaryConstant.SHIPBILL_STATUS_YTJ);
			subShipbillOperateLogSaveVO.setNewStatus(DataDictionaryConstant.SHIPBILL_STATUS_REVIEW);

			subShipbillOperateLogSaveVO.setUserId(user.getUserid());
			subShipbillOperateLogSaveVO.setUserName(user.getNickname());
			subShipbillOperateLogSaveVO.setEnterpriseId(user.getEnterpriseId());
			subShipbillOperateLogSaveVO.setEnterpriseName(user.getEnterpriseName());
			shipbillOperateLogService.addShipbillOperateLogNewData(subShipbillOperateLogSaveVO);

			// 运单节点保存
			ShipbillNodeTrackingSaveNewVO shipbillNodeTrackingSaveVO = new ShipbillNodeTrackingSaveNewVO();
			shipbillNodeTrackingSaveVO.setShipbillId(subShipbillId);
			shipbillNodeTrackingSaveVO.setNodeDate(date);
			shipbillNodeTrackingSaveVO.setShipbillNo(subShipbillId);
			shipbillNodeTrackingSaveVO.setStatus(DataDictionaryConstant.SHIPBILL_STATUS_REVIEW);
			shipbillNodeTrackingSaveVO.setNodeEvent(DataDictionaryConstant.SHIPBILL_STATUSNAME_REW);

			shipbillNodeTrackingSaveVO.setUserId(user.getUserid());
			shipbillNodeTrackingSaveVO.setUserName(user.getNickname());
			shipbillNodeTrackingSaveVO.setEnterpriseId(user.getEnterpriseId());
			shipbillNodeTrackingSaveVO.setEnterpriseName(user.getEnterpriseName());
			shipbillNodeTrackingService.addShipbillNodeTrackingNewData(shipbillNodeTrackingSaveVO);
		}

		// 拆分主单更新
		shipbillHeaderModel.setUpdateperson(user.getNickname());
		shipbillHeaderModel.setUpdatetime(date);
		tmsShipbillHeaderMapper.update(shipbillHeaderModel);

		// STD-DEVELOP20220823 lhb 承运商拆分完善 20220916 start
		if (user.getUserType().equals(BussinessConstant.USER_TYPE_CYS)) {
			// 更新装车单明细
			Map<String, Object> mapLoadingDetailUpdate = Maps.newHashMap();
			mapLoadingDetailUpdate.put("updateperson", user.getNickname());
			mapLoadingDetailUpdate.put("updatetime", date);
			mapLoadingDetailUpdate.put("carrierSplitOrderStatus", DataDictionaryConstant.CARRIER_SPLIT_ORDER_STATUS_ED);
			if (ToolKits.isEmpty(shipbillHeaderModel.getCarrierSplitOrderType()) || DataDictionaryConstant.CARRIER_SPLIT_ORDER_TYPE_UN.equals(shipbillHeaderModel.getCarrierSplitOrderType())) {
				mapLoadingDetailUpdate.put("carrierSplitOrderType", DataDictionaryConstant.CARRIER_SPLIT_ORDER_TYPE_SPLIT_MASTER);
			}
			Criteria criteriaLoadingDetail = Criteria.forClass(TmsLoadingBillDetailModel.class);
			Restriction r21 = Restrictions.eq(TmsLoadingBillDetailModel::getCarrierShipbillStatus, DataDictionaryConstant.CARRIER_SHIPBILL_STATUS_AUDITED);
			Restriction r22 = Restrictions.eq(TmsLoadingBillDetailModel::getShipbillId, shipbillHeaderModel.getShipbillId());
			criteriaLoadingDetail.setRestriction(Restrictions.and(r21, r22));
			tmsLoadingBillDetailMapper.updateMapByCriteria(mapLoadingDetailUpdate, criteriaLoadingDetail);
		}
		// STD-DEVELOP20220823 lhb 承运商拆分完善 20220916 end

		// 原运单日志保存
		ShipbillOperateLogSaveVO shipbillOperateLogSaveVO = new ShipbillOperateLogSaveVO();
		shipbillOperateLogSaveVO.setShipbillId(shipbillHeaderModel.getShipbillId());
		shipbillOperateLogSaveVO.setShipbillNo(shipbillHeaderModel.getShipbillNo());
		shipbillOperateLogSaveVO.setOperateEvent(DataDictionaryConstant.SHIPBILL_EVENT_NAME_SPLIT);
		shipbillOperateLogSaveVO.setOldStatus(DataDictionaryConstant.SHIPBILL_STATUS_REVIEW);
		shipbillOperateLogSaveVO.setNewStatus(DataDictionaryConstant.SHIPBILL_STATUS_REVIEW);
		shipbillOperateLogService.addShipbillOperateLogData(shipbillOperateLogSaveVO);
	}

	/**
	 * 策略调度
	 *
	 * @param shipbillIds
	 * @param shipbillIds
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public String smartDispatchStrategy(@RequestBody List<String> shipbillIds) {
		ToolKits.isParamNull(shipbillIds, "策略调度请求不为空");

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

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

		List<TmsShipbillHeaderModel> shipbillHeaderModels = tmsShipbillHeaderMapper.findByIds(TmsShipbillHeaderModel.class, shipbillIds.stream().toArray(String[]::new), null);

		if (ToolKits.isEmpty(shipbillHeaderModels)) {
			throw new PrologException("选择的运单信息不存在");
		}
		List<ShipbillMatchCarrierVO> matchCarrierVOS = Lists.newArrayList();
		for (TmsShipbillHeaderModel headerModel : shipbillHeaderModels) {
			ShipbillMatchCarrierVO carrierVO = new ShipbillMatchCarrierVO();
			BeanUtils.copyProperties(headerModel, carrierVO);
			carrierVO.setShipperAgingTime(headerModel.getEstimatedPickupStartTime());
			carrierVO.setPickupStartTime(headerModel.getEstimatedPickupStartTime());
			matchCarrierVOS.add(carrierVO);
		}

		RestMessage<Map<String, ShipbillMatchCarrierDTO>> shipbillMatchRs = maindataTmsResource.shipbillMatchCarrierExecute(matchCarrierVOS);
		if (!shipbillMatchRs.isSuccess()) {
			throw new RuntimeException("承运方匹配策略适配失败!");
		}
		Map<String, ShipbillMatchCarrierDTO> rsCarriers = shipbillMatchRs.getData();
		StringBuffer msg = new StringBuffer();
		if (ToolKits.isEmpty(rsCarriers)) {
			return msg.append("运单【" + shipbillIds.stream().collect(Collectors.joining(",")) + "】没有自动匹配到承运方,不能策略调度").toString();
		}
		log.info("自动调度策略:" + JSON.toJSONString(rsCarriers));
		List<String> ngDispatchShipbills = Lists.newArrayList();
		List<String> okDispatchShipbills = Lists.newArrayList();

		for (String shipbillId : shipbillIds) {
			List<TmsShipbillHeaderModel> oneShipbillHeaderModels = shipbillHeaderModels.stream().filter(s -> s.getShipbillId().equals(shipbillId)).collect(Collectors.toList());
			if (ToolKits.isEmpty(oneShipbillHeaderModels)) {
				throw new PrologException("运单【" + shipbillId + "】不存在");
			}
			TmsShipbillHeaderModel disHeaderModel = oneShipbillHeaderModels.get(0);
			ShipbillMatchCarrierDTO carrierDTO = rsCarriers.get(shipbillId);
			log.info("运单【" + shipbillId + "】自动调度:" + JSON.toJSONString(carrierDTO));
			if (ToolKits.isNotEmpty(carrierDTO) && ToolKits.isNotEmpty(carrierDTO.getCarrierId())) {
				PendingDispatchVO pendingDispatchVO = new PendingDispatchVO();
				LoadingBillHeaderVO loadingBillHeaderVO = new LoadingBillHeaderVO();
				List<LoadingBillDetailVO> loadingBillDetailVOS = Lists.newArrayList();
				LoadingBillDetailVO loadingBillDetailVO = new LoadingBillDetailVO();
				if (ToolKits.isNotEmpty(carrierDTO) && ToolKits.isNotEmpty(carrierDTO.getCarrierId())) {
					// 承运方类型
					loadingBillHeaderVO.setCarrierType(carrierDTO.getCarrierType());

					if (DataDictionaryConstant.LINE_CARRIER_TYPE_SJ.equals(carrierDTO.getCarrierType())) {
						// 司机ID
						loadingBillHeaderVO.setDriverId(carrierDTO.getCarrierId());
						loadingBillHeaderVO.setDriverCode(carrierDTO.getCarrierCode());
						loadingBillHeaderVO.setDriverName(carrierDTO.getCarrierName());
						// 送货员
						loadingBillHeaderVO.setDeliverymanId(carrierDTO.getDeliverymanId());
						loadingBillHeaderVO.setDeliverymanCode(carrierDTO.getDeliverymanCode());
						loadingBillHeaderVO.setDeliverymanName(carrierDTO.getDeliverymanName());
						loadingBillHeaderVO.setDeliverymanPhoneNumber(carrierDTO.getDeliverymanPhoneNumber());
						// 车辆
						loadingBillHeaderVO.setVehicleId(carrierDTO.getVehicleId());
						loadingBillHeaderVO.setVehicleCode(carrierDTO.getVehicleCode());
						loadingBillHeaderVO.setVehicleName(carrierDTO.getVehicleName());
						loadingBillHeaderVO.setVehiclePlateNumber(carrierDTO.getVehiclePlateNumber());
						// 车型
						loadingBillHeaderVO.setVehicleTypeId(carrierDTO.getVehicleTypeId());
						loadingBillHeaderVO.setVehicleTypeCode(carrierDTO.getVehicleTypeCode());
						loadingBillHeaderVO.setVehicleTypeName(carrierDTO.getVehicleTypeName());

						if (ToolKits.isNotEmpty(carrierDTO.getVehicleDeviceId())) {
							loadingBillHeaderVO.setVehicleDeviceId(String.valueOf(carrierDTO.getVehicleDeviceId()));
							loadingBillHeaderVO.setVehicleDeviceCode(carrierDTO.getVehicleDeviceCode());
							loadingBillHeaderVO.setVehicleDeviceName(carrierDTO.getVehicleDeviceName());
						}
						if (ToolKits.isNotEmpty(carrierDTO.getContainerId())) {
							loadingBillHeaderVO.setContainerId(carrierDTO.getContainerId());
							loadingBillHeaderVO.setContainerCode(carrierDTO.getContainerCode());
							loadingBillHeaderVO.setContainerName(carrierDTO.getContainerName());
						}
						if (ToolKits.isNotEmpty(carrierDTO.getVehicleTypeCategoryName())) {
							loadingBillHeaderVO.setVehicleTypeCategory(carrierDTO.getVehicleTypeCategoryName());
						}
						if (ToolKits.isNotEmpty(carrierDTO.getVehicleAffiliationId())) {
							loadingBillHeaderVO.setVehicleAffiliationId(String.valueOf(carrierDTO.getVehicleAffiliationId()));
							loadingBillHeaderVO.setVehicleAffiliationCode(String.valueOf(carrierDTO.getVehicleAffiliationCode()));
							loadingBillHeaderVO.setVehicleAffiliationName(String.valueOf(carrierDTO.getVehicleAffiliationName()));
						}
					} else {
						// 承运商ID
						loadingBillHeaderVO.setCarrierId(Long.valueOf(carrierDTO.getCarrierId()));
						loadingBillHeaderVO.setCarrierCode(carrierDTO.getCarrierCode());
						loadingBillHeaderVO.setCarrierName(carrierDTO.getCarrierName());
					}
					// 司机手机号
					loadingBillHeaderVO.setDriverPhoneNumber(carrierDTO.getDriverPhoneNumber());
					// 车牌号
					loadingBillHeaderVO.setVehiclePlateNumber(carrierDTO.getVehiclePlateNumber());
					// 运单数
					loadingBillHeaderVO.setShipbillNumber(1);
					// 站点数
					loadingBillHeaderVO.setSiteNumber(1);
					// 客户数
					loadingBillHeaderVO.setCustomerNumber(1);
					// 总件数
					loadingBillHeaderVO.setTotalPcs(disHeaderModel.getTotalPcs());
					// 总体积
					loadingBillHeaderVO.setTotalVolume(disHeaderModel.getTotalVolume());
					// 总重量
					loadingBillHeaderVO.setTotalWeight(disHeaderModel.getTotalWeight());
					// 实际总件数
					loadingBillHeaderVO.setActualTotalPcs(disHeaderModel.getTotalPcs());
					// 实际总体积
					loadingBillHeaderVO.setActualTotalVolume(disHeaderModel.getTotalVolume());
					// 实际总重量
					loadingBillHeaderVO.setActualTotalWeight(disHeaderModel.getTotalWeight());
					// 总整件数
					loadingBillHeaderVO.setTotalWholePiece(disHeaderModel.getPackageWholePiece());
					// 总拼箱数
					loadingBillHeaderVO.setTotalLclPiece(disHeaderModel.getPackageLclPiece());
					// 备注
					loadingBillHeaderVO.setMemo("待审核后自动调度");

					loadingBillHeaderVO.setVehicleId(carrierDTO.getVehicleId());
					loadingBillHeaderVO.setVehicleCode(carrierDTO.getVehicleCode());
					loadingBillHeaderVO.setVehicleName(carrierDTO.getVehicleName());

					// 设置调度单数据
					pendingDispatchVO.setLoadingBillHeaderVO(loadingBillHeaderVO);
					// 设置调度单明细
					BeanUtils.copyProperties(disHeaderModel, loadingBillDetailVO);
					loadingBillDetailVO.setShippingOrder(1);
					loadingBillDetailVO.setPickUpOrder(1);
					loadingBillDetailVOS.add(loadingBillDetailVO);
					pendingDispatchVO.setLoadingBillDetailVO(loadingBillDetailVOS);
					// 自动调度
					autoDispatch(pendingDispatchVO, user, date,"");
				}
				okDispatchShipbills.add(shipbillId);
			} else {
				ngDispatchShipbills.add(shipbillId);
			}
		}
		if (ToolKits.isNotEmpty(ngDispatchShipbills)) {
			msg.append("运单【" + ngDispatchShipbills.stream().collect(Collectors.joining(",")) + "】没有自动匹配到承运方,不能策略调度,");
		}

		if (ToolKits.isNotEmpty(okDispatchShipbills)) {
			msg.append("运单【" + okDispatchShipbills.stream().collect(Collectors.joining(",")) + "】调度成功");
		}

		return msg.toString();
	}

	/**
	 * 运单匹配业务流程
	 *
	 * @param model
	 * @return
	 */
	public ShipbillFitBusinessFlowDTO shipbillMatchBusinessFlow(TmsShipbillHeaderModel model, Integer flowType) {
		// 新增后自动提交判定
		BusinessFlowShipbillVO matchFlowVO = new BusinessFlowShipbillVO();
		// 流程类型 承运商
		matchFlowVO.setFlowType(flowType);
		// 配送方式
		matchFlowVO.setDeliveryMethodType(model.getDeliveryMethodType());
		// 发货方类型
		matchFlowVO.setShipperType(model.getShipperType());
		// 发货方单位ID
		matchFlowVO.setShipperUnitId(model.getShipperUnitId());
		// 收货方类型
		matchFlowVO.setConsigneeType(model.getConsigneeType());
		// 收货方单位ID
		matchFlowVO.setConsigneeUnitId(model.getConsigneeUnitId());
		// 订单类型
		matchFlowVO.setOrderType(model.getOrderType());
		// 订单业务类型
		matchFlowVO.setOrderBusinessType(model.getOrderBusinessType());
		// 运输模式
		matchFlowVO.setTransportType(model.getTransportType());
		// 温度要求
		matchFlowVO.setTemperatureRequirement(model.getTemperatureRequirement());
		// 货主ID
		matchFlowVO.setCargoOwnerId(model.getCargoOwnerId());
		matchFlowVO.setCarriersType(model.getCarriersType());
		RestMessage<ShipbillFitBusinessFlowDTO> matchRs = maindataTmsResource.shipbillMatchFlowQuery(matchFlowVO);
		if (!matchRs.isSuccess()) {
			throw new PrologException("运单【" + model.getShipbillNo() + "】调用maindata服务运单匹配业务流程失败");
		}
		return matchRs.getData();
	}

	/**
	 * 生成运输记录表
	 */
	public void saveTransportLog(String shipbillId, Date date, Date pickUpStartDt) {
		TmsShipbillTransLogModel logModel = new TmsShipbillTransLogModel();
		RestMessage<String> restMessage = maindataTmsResource.getCodeNumberByCode(SeriaNnumberConstant.TMS_SHIPBILL_TRANSPORT_LOG_ID, "L");
		if (!restMessage.isSuccess()) {
			throw new RuntimeException("生成运输记录ID失败");
		}
		String id = restMessage.getData();
		UserEntity user = PlgFxUsrUtils.getUserEntity();
		logModel.setId(id);
		logModel.setShipbillId(shipbillId);
		logModel.setShipbillNo(shipbillId);

		logModel.setOrderDt(date);
		logModel.setCommitDt(date);
		logModel.setReviewDt(date);
		logModel.setEstimatedPickupStartTime(pickUpStartDt);
		logModel.setEnterpriseId(user.getEnterpriseId());
		logModel.setEnterpriseName(user.getEnterpriseName());
		logModel.setCreateperson(user.getNickname());
		logModel.setCreatetime(date);
		logModel.setUpdateperson(user.getNickname());
		logModel.setUpdatetime(date);

		tmsShipbillTransportLogMapper.save(logModel);
	}

	// 调度审核匹配审批流程
	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 model
	 * @return
	 */
	public ShipbillMatchLineDTO shipbillMatchLine(TmsShipbillHeaderModel model) {
		// 新增后自动提交判定
		ShipbillMatchLineVO matchLineVO = new ShipbillMatchLineVO();
		// 配送方式
		matchLineVO.setDeliveryMethodType(model.getDeliveryMethodType());
		// 发货方类型
		matchLineVO.setShipperType(model.getShipperType());
		// 发货方单位ID
		matchLineVO.setShipperUnitId(model.getShipperUnitId());
		matchLineVO.setShipperProvince(model.getShipperProvince());
		matchLineVO.setShipperCity(model.getShipperCity());
		matchLineVO.setShipperDistrict(model.getShipperDistrict());
		// 收货方类型
		matchLineVO.setConsigneeType(model.getConsigneeType());
		// 收货方单位ID
		matchLineVO.setConsigneeUnitId(model.getConsigneeUnitId());
		matchLineVO.setConsigneeId(model.getConsigneeId());
		matchLineVO.setConsigneeProvince(model.getConsigneeProvince());
		matchLineVO.setConsigneeCity(model.getConsigneeCity());
		matchLineVO.setConsigneeDistrict(model.getConsigneeDistrict());
		// 订单类型
		matchLineVO.setOrderType(model.getOrderType());
		// 订单业务类型
		matchLineVO.setOrderBusinessType(model.getOrderBusinessType());
		// 运输模式
		matchLineVO.setTransportType(model.getTransportType());
		// 温度要求
		matchLineVO.setTemperatureRequirement(model.getTemperatureRequirement());
		// 货主ID
		matchLineVO.setCargoOwnerId(model.getCargoOwnerId());
		matchLineVO.setDepartmentId(model.getDepartmentId());
		matchLineVO.setEnterpriseId(model.getEnterpriseId());
		log.info("运单匹配线路={}", JSON.toJSON(matchLineVO));
		RestMessage<ShipbillMatchLineDTO> matchRs = maindataTmsResource.shipbillMatchLineExecute(matchLineVO);
		if (!matchRs.isSuccess()) {
			throw new PrologException("运单【" + model.getShipbillNo() + "】调用maindata服务运单匹配线路策略失败");
		}
		return matchRs.getData();
	}

	/**
	 * 策略中转
	 *
	 * @param shipbillIds
	 */
	public void smartTransferData(List<String> shipbillIds) {
		ToolKits.isParamNull(shipbillIds, "策略中转请求不为空");

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

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

		for (String shipbillId : shipbillIds) {
			TmsShipbillHeaderModel tmsShipbillHeaderModel = tmsShipbillHeaderMapper.findById(shipbillId, TmsShipbillHeaderModel.class);

			if (!tmsShipbillHeaderModel.getConsigneeType().equals(DataDictionaryConstant.CONSIGNEE_TYPE_KH)) {
				throw new PrologException("运单【" + tmsShipbillHeaderModel.getShipbillId() + "收货方不是客户,不支持中转】");
			}
			// 原装车明细更新
			Map<String, Object> mapUpdate = Maps.newHashMap();
			mapUpdate.put("updateperson", user.getNickname());
			mapUpdate.put("updatetime", date);
			if (user.getUserType().equals(BussinessConstant.USER_TYPE_ZY)) {
				if (!DataDictionaryConstant.SHIPBILL_STATUS_REVIEW.equals(tmsShipbillHeaderModel.getStatus())) {
					throw new PrologException("运单【" + tmsShipbillHeaderModel.getShipbillNo() + "】非待调度状态,中转失败");
				}
				if (!DataDictionaryConstant.SPLIT_ORDER_STATUS_UN.equals(tmsShipbillHeaderModel.getSplitOrderStatus())) {
					throw new PrologException("运单【" + tmsShipbillHeaderModel.getShipbillNo() + "】非待调度状态,中转失败");
				}
				// 中转拆分状态
				tmsShipbillHeaderModel.setSplitOrderStatus(DataDictionaryConstant.SPLIT_ORDER_STATUS_ED);
				// 原始主单被中转时，拆单类型更新为4中转主单，子单被中转时，不更新拆单类型
				if (ToolKits.isEmpty(tmsShipbillHeaderModel.getSplitOrderType()) || DataDictionaryConstant.SPLIT_ORDER_TYPE_UN.equals(tmsShipbillHeaderModel.getSplitOrderType())) {
					tmsShipbillHeaderModel.setSplitOrderType(DataDictionaryConstant.SPLIT_ORDER_TYPE_TRANSIT_MASTER);
				}
			} else if (user.getUserType().equals(BussinessConstant.USER_TYPE_CYS)) {
				if (!DataDictionaryConstant.CARRIER_SHIPBILL_STATUS_AUDITED.equals(tmsShipbillHeaderModel.getCarrierShipbillStatus())) {
					throw new PrologException("运单【" + tmsShipbillHeaderModel.getShipbillNo() + "】非待调度状态,不能中转");
				}
				if (!DataDictionaryConstant.CARRIER_SPLIT_ORDER_STATUS_UN.equals(tmsShipbillHeaderModel.getCarrierSplitOrderStatus())) {
					throw new PrologException("运单【" + tmsShipbillHeaderModel.getShipbillNo() + "】非待调度状态,不能中转");
				}
				// 中转拆分状态
				tmsShipbillHeaderModel.setCarrierSplitOrderStatus(DataDictionaryConstant.CARRIER_SPLIT_ORDER_STATUS_ED);

				// 原始主单被中转时，拆单类型更新为4中转主单，子单被中转时，不更新拆单类型
				if (ToolKits.isEmpty(tmsShipbillHeaderModel.getCarrierSplitOrderType()) || DataDictionaryConstant.CARRIER_SPLIT_ORDER_TYPE_UN.equals(tmsShipbillHeaderModel.getCarrierSplitOrderType())) {
					tmsShipbillHeaderModel.setCarrierSplitOrderType(DataDictionaryConstant.CARRIER_SPLIT_ORDER_TYPE_TRANSIT_MASTER);
				}
				// 更新装车单明细
				mapUpdate.put("carrierSplitOrderStatus", DataDictionaryConstant.CARRIER_SPLIT_ORDER_STATUS_ED);
				if (ToolKits.isEmpty(tmsShipbillHeaderModel.getCarrierSplitOrderType()) || DataDictionaryConstant.CARRIER_SPLIT_ORDER_TYPE_UN.equals(tmsShipbillHeaderModel.getCarrierSplitOrderType())) {
					mapUpdate.put("carrierSplitOrderType", DataDictionaryConstant.CARRIER_SPLIT_ORDER_TYPE_TRANSIT_MASTER);
				}
			} else {
				throw new ParameterException("当前人员没有操作权限");
			}

			StrategyTransferMatchingDTO transferMatchingDTO = shipbillMatchTransfer(tmsShipbillHeaderModel);
			if (ToolKits.isNotEmpty(transferMatchingDTO)) {
				Criteria criteriaDetail = Criteria.forClass(TmsLoadingBillDetailModel.class);
				Restriction r21 = Restrictions.eq(TmsLoadingBillDetailModel::getCarrierShipbillStatus, DataDictionaryConstant.CARRIER_SHIPBILL_STATUS_AUDITED);
				Restriction r22 = Restrictions.eq(TmsLoadingBillDetailModel::getShipbillId, shipbillId);
				criteriaDetail.setRestriction(Restrictions.and(r21, r22));
				tmsLoadingBillDetailMapper.updateMapByCriteria(mapUpdate, criteriaDetail);

				tmsShipbillHeaderModel.setUpdateperson(user.getNickname());
				tmsShipbillHeaderModel.setUpdatetime(date);
				tmsShipbillHeaderMapper.update(tmsShipbillHeaderModel);

				// 原运单日志保存
				ShipbillOperateLogSaveVO shipbillOperateLogSaveVO = new ShipbillOperateLogSaveVO();
				shipbillOperateLogSaveVO.setShipbillId(tmsShipbillHeaderModel.getShipbillId());
				shipbillOperateLogSaveVO.setShipbillNo(tmsShipbillHeaderModel.getShipbillNo());
				shipbillOperateLogSaveVO.setOperateEvent(DataDictionaryConstant.SHIPBILL_EVENT_NAME_TRANSIT);
				shipbillOperateLogSaveVO.setOldStatus(DataDictionaryConstant.SHIPBILL_STATUS_REVIEW);
				shipbillOperateLogSaveVO.setNewStatus(DataDictionaryConstant.SHIPBILL_STATUS_REVIEW);
				shipbillOperateLogService.addShipbillOperateLogData(shipbillOperateLogSaveVO);

				// 原运单明细
				// 添加查询条件
				Criteria criteria = Criteria.forClass(TmsShipbillDetailModel.class);
				Restriction r1 = Restrictions.eq(TmsShipbillDetailModel::getShipbillId, shipbillId);
				Restriction r2 = Restrictions.eq(TmsShipbillDetailModel::getEnterpriseId, user.getEnterpriseId());
				criteria.setRestriction(Restrictions.and(r1, r2));
				List<TmsShipbillDetailModel> tmsShipbillDetailModels = tmsShipbillDetailMapper.findByCriteria(criteria);

				// 中转信息
				int index = 0;
				// 中转成多个子单
				List<String> newShipbillIds = new ArrayList<>();
				RestMessage<SysParamConfigModel> restMessageShipbillId = maindataTmsResource.getValue(DataDictionaryConstant.SHIPBILL_ID_CREATE_RULE);
				if (!restMessageShipbillId.isSuccess()) {
					throw new RuntimeException("获取运单ID生成规则的系统参数失败!");
				}
				SysParamConfigModel sysParamConfigModel = restMessageShipbillId.getData();
				List<StrategyTransferStationDTO> transferStationDTOS = transferMatchingDTO.getTransferStationDTOS();
				transferStationDTOS = transferStationDTOS.stream().sorted(Comparator.comparing(StrategyTransferStationDTO::getTransferOrder)).collect(Collectors.toList());

				Map<Integer, TransferDtDTO> transferDtDTOMap = getTransDate(tmsShipbillHeaderModel, transferStationDTOS, user);
				TransferDtDTO lastStationDt = null;
				TmsTransferStationByViewDTO lastTransferStationByViewDTO = null;
				for (StrategyTransferStationDTO transferStationDTO : transferStationDTOS) {
					TransferDtDTO transferDtDTO = transferDtDTOMap.get(transferStationDTO.getTransferOrder());
					if (ObjectUtil.isEmpty(transferDtDTO)) {
						throw new PrologException("中转站策略没有送达日期和提货日期");
					}
					TmsTransferStationVO stationVO = new TmsTransferStationVO();
					stationVO.setId(transferStationDTO.getTransferStationId());
					RestMessage<TmsTransferStationByViewDTO> RestTransferStation = maindataTmsResource.view(stationVO);
					if (!RestTransferStation.isSuccess()) {
						throw new RuntimeException("调用获取中转站信息服务失败");
					}
					TmsTransferStationByViewDTO stationByViewDTO = RestTransferStation.getData();
					if (ObjectUtil.isEmpty(stationByViewDTO)) {
						throw new RuntimeException("中转站【" + transferStationDTO.getTransferStationName() + "】信息不存在");
					}

					String subShipbillId = "";
					// 运单ID生成规则
					if (DataDictionaryConstant.SHIPBILL_ID_CREATE_RULE_AUTO.equals(sysParamConfigModel.getValue())) {
						// 获取运单汇总ID
						RestMessage<String> restMessageAutoCreateShipbillId = maindataTmsResource.getCodeNumberByCode(SeriaNnumberConstant.TMS_SHIPBILL_HEADER_ID, "L");
						if (!restMessageAutoCreateShipbillId.isSuccess()) {
							throw new RuntimeException("生成运单汇总ID失败");
						}
						subShipbillId = restMessageAutoCreateShipbillId.getData();
					} else {
						StringBuffer buffNo1 = new StringBuffer(shipbillId);
						buffNo1.append(DataDictionaryConstant.SUB_SHIPBILL_NO);
						buffNo1.append(index + 1);
						subShipbillId = buffNo1.toString();
					}
					newShipbillIds.add(subShipbillId);
					// 保存中转子单的运单汇总
					TmsShipbillHeaderModel subTmsShipbillHeaderModel = new TmsShipbillHeaderModel();
					BeanUtils.copyProperties(tmsShipbillHeaderModel, subTmsShipbillHeaderModel);

					subTmsShipbillHeaderModel.setShipbillId(subShipbillId);
					subTmsShipbillHeaderModel.setShipbillNo(subShipbillId);
					if (user.getUserType().equals(BussinessConstant.USER_TYPE_ZY)) {
						// 拆单状态 0未拆单
						subTmsShipbillHeaderModel.setSplitOrderStatus(DataDictionaryConstant.SPLIT_ORDER_STATUS_UN);
						// 拆单类型 3拆段子单
						subTmsShipbillHeaderModel.setSplitOrderType(DataDictionaryConstant.SPLIT_ORDER_TYPE_TRANSIT_SUB);
					} else {
						// 拆单状态 0未拆单
						subTmsShipbillHeaderModel.setCarrierSplitOrderStatus(DataDictionaryConstant.CARRIER_SPLIT_ORDER_STATUS_UN);
						// 拆单类型 3拆段子单
						subTmsShipbillHeaderModel.setCarrierSplitOrderType(DataDictionaryConstant.CARRIER_SPLIT_ORDER_TYPE_TRANSIT_SUB);
					}
					// 父级运单ID
					subTmsShipbillHeaderModel.setFatherShipbillId(tmsShipbillHeaderModel.getShipbillId());
					// 父级运单编号
					subTmsShipbillHeaderModel.setFatherShipbillNo(tmsShipbillHeaderModel.getShipbillNo());
					// 原始运单ID
					String originalShipbillId = StrUtil.isBlank(tmsShipbillHeaderModel.getOriginalShipbillId()) ? tmsShipbillHeaderModel.getShipbillId() : tmsShipbillHeaderModel.getOriginalShipbillId();
					subTmsShipbillHeaderModel.setOriginalShipbillId(originalShipbillId);
					// 原始运单编号
					String originalShipbillNo = StrUtil.isBlank(tmsShipbillHeaderModel.getOriginalShipbillNo()) ? tmsShipbillHeaderModel.getShipbillNo() : tmsShipbillHeaderModel.getOriginalShipbillNo();
					subTmsShipbillHeaderModel.setOriginalShipbillNo(originalShipbillNo);

					if (transferStationDTO.getTransferOrder().intValue() == 1) {
						// 第一段的中转站
						// 预计提货开始时间
						subTmsShipbillHeaderModel.setEstimatedPickupStartTime(tmsShipbillHeaderModel.getEstimatedPickupStartTime());
						// 预计提货结束时间
						subTmsShipbillHeaderModel.setEstimatedPickupEndTime(tmsShipbillHeaderModel.getEstimatedPickupEndTime());
						// 预计送达开始时间
						subTmsShipbillHeaderModel.setEstimatedDeliveryStartTime(transferDtDTO.getEstimatedDeliveryStartTime());
						// 预计送达结束时间
						subTmsShipbillHeaderModel.setEstimatedDeliveryEndTime(transferDtDTO.getEstimatedDeliveryEndTime());
						// 时效 送达时间 - 提货时间
						subTmsShipbillHeaderModel.setTransportAging(ObjectUtil.isEmpty(tmsShipbillHeaderModel.getEstimatedPickupEndTime()) ? null : getTransportAging(tmsShipbillHeaderModel.getEstimatedPickupEndTime(), transferDtDTO.getEstimatedDeliveryEndTime()));
					} else {
						// 中间段的中转站
						// 上一站的出发时间 -> 预计提货开始时间
						subTmsShipbillHeaderModel.setEstimatedPickupStartTime(lastStationDt.getEstimatedSendStartTime());
						// 预计提货结束时间
						subTmsShipbillHeaderModel.setEstimatedPickupEndTime(lastStationDt.getEstimatedSendEndTime());
						// 预计送达开始时间
						subTmsShipbillHeaderModel.setEstimatedDeliveryStartTime(transferDtDTO.getEstimatedDeliveryStartTime());
						// 预计送达结束时间
						subTmsShipbillHeaderModel.setEstimatedDeliveryEndTime(transferDtDTO.getEstimatedDeliveryEndTime());
						// 时效 送达时间 - 提货时间
						subTmsShipbillHeaderModel.setTransportAging(ObjectUtil.isEmpty(lastStationDt.getEstimatedSendEndTime()) ? null : getTransportAging(lastStationDt.getEstimatedSendEndTime(), transferDtDTO.getEstimatedDeliveryEndTime()));

						// 发货方单位ID
						subTmsShipbillHeaderModel.setShipperUnitId(lastTransferStationByViewDTO.getId());
						// 发货方单位编码
						subTmsShipbillHeaderModel.setShipperUnitCode(lastTransferStationByViewDTO.getCode());
						// 发货方单位名称
						subTmsShipbillHeaderModel.setShipperUnitName(lastTransferStationByViewDTO.getName());
						// 发货方联系人
						subTmsShipbillHeaderModel.setShipperContact(lastTransferStationByViewDTO.getContact());
						// 发货方手机号
						subTmsShipbillHeaderModel.setShipperPhoneNumber(lastTransferStationByViewDTO.getPhoneNumber());
						// 发货方座机号
						subTmsShipbillHeaderModel.setShipperLandlineNumber(lastTransferStationByViewDTO.getLandlineNumber());
						// 发货方邮箱
						subTmsShipbillHeaderModel.setShipperEmail(lastTransferStationByViewDTO.getEmail());
						// 发货方省编码
						subTmsShipbillHeaderModel.setShipperProvince(lastTransferStationByViewDTO.getProvince());
						// 发货方省名称
						subTmsShipbillHeaderModel.setShipperProvinceName(lastTransferStationByViewDTO.getProvinceName());
						// 发货方市编码
						subTmsShipbillHeaderModel.setShipperCity(lastTransferStationByViewDTO.getCity());
						// 发货方市名称
						subTmsShipbillHeaderModel.setShipperCityName(lastTransferStationByViewDTO.getCityName());
						// 发货方区/县编码
						subTmsShipbillHeaderModel.setShipperDistrict(lastTransferStationByViewDTO.getDistrict());
						// 发货方区/县名称
						subTmsShipbillHeaderModel.setShipperDistrictName(lastTransferStationByViewDTO.getDistrictName());
						// 发货方详细地址
						subTmsShipbillHeaderModel.setShipperAddress(lastTransferStationByViewDTO.getAddress());
						// 发货方经度
						subTmsShipbillHeaderModel.setShipperLongitude(lastTransferStationByViewDTO.getLongitude());
						// 发货方纬度
						subTmsShipbillHeaderModel.setShipperLatitude(lastTransferStationByViewDTO.getLatitude());
						// 发货方备注
						subTmsShipbillHeaderModel.setShipperMemo(lastTransferStationByViewDTO.getMemo());
					}
					// 收货方类型
					subTmsShipbillHeaderModel.setConsigneeType(DataDictionaryConstant.CONSIGNEE_TYPE_KH);
					// 收货方单位ID
					subTmsShipbillHeaderModel.setConsigneeUnitId(stationByViewDTO.getId());
					// 收货方单位编码
					subTmsShipbillHeaderModel.setConsigneeUnitCode(stationByViewDTO.getCode());
					// 收货方单位名称
					subTmsShipbillHeaderModel.setConsigneeUnitName(stationByViewDTO.getName());
					// 仓库ID
					subTmsShipbillHeaderModel.setBranchId(stationByViewDTO.getBranchId());
					subTmsShipbillHeaderModel.setBranchCode(stationByViewDTO.getBranchCode());
					subTmsShipbillHeaderModel.setBranchName(stationByViewDTO.getBranchName());
					// 收货方联系人
					subTmsShipbillHeaderModel.setConsigneeContact(stationByViewDTO.getContact());
					// 收货方手机号
					subTmsShipbillHeaderModel.setConsigneePhoneNumber(stationByViewDTO.getPhoneNumber());
					// 收货方座机号
					subTmsShipbillHeaderModel.setConsigneeLandlineNumber(stationByViewDTO.getLandlineNumber());
					// 收货方邮箱
					subTmsShipbillHeaderModel.setConsigneeEmail(stationByViewDTO.getEmail());
					// 收货方省编码
					subTmsShipbillHeaderModel.setConsigneeProvince(stationByViewDTO.getProvince());
					// 收货方省名称
					subTmsShipbillHeaderModel.setConsigneeProvinceName(stationByViewDTO.getProvinceName());
					// 收货方市编码
					subTmsShipbillHeaderModel.setConsigneeCity(stationByViewDTO.getCity());
					// 收货方市名称
					subTmsShipbillHeaderModel.setConsigneeCityName(stationByViewDTO.getCityName());
					// 收货方区/县编码
					subTmsShipbillHeaderModel.setConsigneeDistrict(stationByViewDTO.getDistrict());
					// 收货方区/县名称
					subTmsShipbillHeaderModel.setConsigneeDistrictName(stationByViewDTO.getDistrictName());
					// 收货方详细地址
					subTmsShipbillHeaderModel.setConsigneeAddress(stationByViewDTO.getAddress());
					// 收货方经度
					subTmsShipbillHeaderModel.setConsigneeLongitude(stationByViewDTO.getLongitude());
					// 收货方纬度
					subTmsShipbillHeaderModel.setConsigneeLatitude(stationByViewDTO.getLatitude());
					// 收货方备注
					subTmsShipbillHeaderModel.setConsigneeMemo(stationByViewDTO.getMemo());

					subTmsShipbillHeaderModel.setCreateperson(user.getNickname());
					subTmsShipbillHeaderModel.setCreatetime(date);
					subTmsShipbillHeaderModel.setUpdateperson(user.getNickname());
					subTmsShipbillHeaderModel.setUpdatetime(date);
					// 保存运单汇总
					subTmsShipbillHeaderModel.setShipbillType(ShipBillTypeEnum.NORMAL.getCode());
					subTmsShipbillHeaderModel.setSignInStatus(SignInStatusEnum.NOT_SIGN.getCode());
					subTmsShipbillHeaderModel.setDriverReceiveStatus(DriverReceiveStatusEnum.N.getCode());

					if (ToolKits.isNotEmpty(transferMatchingDTO.getRematchLine()) && transferMatchingDTO.getRematchLine().equals(DataDictionaryConstant.REMATCH_LINE_YES)) {
						// 子单重新匹配线路
						ShipbillMatchLineDTO lineData = shipbillMatchLine(subTmsShipbillHeaderModel);
						if (ToolKits.isNotEmpty(lineData) && ToolKits.isNotEmpty(lineData.getLineId())) {
							// 订单绑定线路
							subTmsShipbillHeaderModel.setLineId(lineData.getLineId());
							subTmsShipbillHeaderModel.setLineCode(lineData.getLineCode());
							subTmsShipbillHeaderModel.setLineName(lineData.getLineName());
							subTmsShipbillHeaderModel.setLineDirection(lineData.getLineDirection());
							subTmsShipbillHeaderModel.setShippingOrder(lineData.getShippingOrder());
							subTmsShipbillHeaderModel.setPickUpOrder(lineData.getPickUpOrder());
						}
					}
					subTmsShipbillHeaderModel.setIntelligentLock(IntelligentLockEnum.UN_LOCK.getCode());
					tmsShipbillHeaderMapper.save(subTmsShipbillHeaderModel);

					// 运输记录
					saveTransportLog(subTmsShipbillHeaderModel.getShipbillId(), date, subTmsShipbillHeaderModel.getEstimatedPickupStartTime());

					// 运单明细保存
					for (TmsShipbillDetailModel detailModel : tmsShipbillDetailModels) {
						TmsShipbillDetailModel subTmsShipbillDetailModel = new TmsShipbillDetailModel();
						// 运单明细ID
						RestMessage<String> restMessage2 = maindataTmsResource.getCodeNumberByCode(SeriaNnumberConstant.TMS_SHIPBILL_DETAIL_ID, "L");
						if (!restMessage2.isSuccess()) {
							throw new RuntimeException("生成运单明细ID失败");
						}
						String subShipbillDetailId = restMessage2.getData();

						BeanUtils.copyProperties(detailModel, subTmsShipbillDetailModel);
						subTmsShipbillDetailModel.setId(subShipbillDetailId);
						// 运单ID
						subTmsShipbillDetailModel.setShipbillId(subTmsShipbillHeaderModel.getShipbillId());
						// 运单编号
						subTmsShipbillDetailModel.setShipbillNo(subTmsShipbillHeaderModel.getShipbillNo());
						// 仓库ID
						subTmsShipbillDetailModel.setBranchId(subTmsShipbillHeaderModel.getBranchId());
						// 仓库编码
						subTmsShipbillDetailModel.setBranchCode(subTmsShipbillHeaderModel.getBranchCode());
						// 仓库名称
						subTmsShipbillDetailModel.setBranchName(subTmsShipbillHeaderModel.getBranchName());

						subTmsShipbillDetailModel.setCreateperson(user.getNickname());
						subTmsShipbillDetailModel.setCreatetime(date);
						subTmsShipbillDetailModel.setUpdateperson(user.getNickname());
						subTmsShipbillDetailModel.setUpdatetime(date);
						subTmsShipbillDetailModel.setOrigPcs(subTmsShipbillDetailModel.getPcs());
						subTmsShipbillDetailModel.setClosingPcs(BigDecimal.valueOf(0));
						subTmsShipbillDetailModel.setDeliveryPcs(BigDecimal.valueOf(0));
						subTmsShipbillDetailModel.setFatherId(detailModel.getId());
						subTmsShipbillDetailModel.setScanStatus(DataDictionaryConstant.SCAN_STATUS_INIT);
						tmsShipbillDetailMapper.save(subTmsShipbillDetailModel);
					}

					// 子运单日志保存
					ShipbillOperateLogSaveVO subShipbillOperateLogSaveVO = new ShipbillOperateLogSaveVO();
					subShipbillOperateLogSaveVO.setShipbillId(subTmsShipbillHeaderModel.getShipbillId());
					subShipbillOperateLogSaveVO.setShipbillNo(subTmsShipbillHeaderModel.getShipbillNo());
					subShipbillOperateLogSaveVO.setOperateEvent(DataDictionaryConstant.SHIPBILL_EVENT_NAME_TRANSIT_SUB);
					subShipbillOperateLogSaveVO.setOldStatus(DataDictionaryConstant.SHIPBILL_STATUS_REVIEW);
					subShipbillOperateLogSaveVO.setNewStatus(DataDictionaryConstant.SHIPBILL_STATUS_REVIEW);
					shipbillOperateLogService.addShipbillOperateLogData(subShipbillOperateLogSaveVO);

					// 运单节点保存
					ShipbillNodeTrackingSaveVO shipbillNodeTrackingSaveVO = new ShipbillNodeTrackingSaveVO();
					shipbillNodeTrackingSaveVO.setShipbillId(subTmsShipbillHeaderModel.getShipbillId());
					shipbillNodeTrackingSaveVO.setShipbillNo(subTmsShipbillHeaderModel.getShipbillId());
					shipbillNodeTrackingSaveVO.setStatus(DataDictionaryConstant.SHIPBILL_STATUS_REVIEW);
					shipbillNodeTrackingSaveVO.setNodeEvent(DataDictionaryConstant.SHIPBILL_STATUSNAME_REW);
					shipbillNodeTrackingService.addShipbillNodeTrackingData(shipbillNodeTrackingSaveVO);
					index++;
					lastStationDt = transferDtDTO;
					lastTransferStationByViewDTO = stationByViewDTO;
				}
				// 最后一段的中转站
				// 运单汇总ID
				RestMessage<String> restMessage3 = maindataTmsResource.getCodeNumberByCode(SeriaNnumberConstant.TMS_SHIPBILL_HEADER_ID, "L");
				if (!restMessage3.isSuccess()) {
					throw new RuntimeException("生成运单汇总ID失败");
				}
				String lastSubShipbillId = "";
				// 运单ID生成规则
				if (DataDictionaryConstant.SHIPBILL_ID_CREATE_RULE_AUTO.equals(sysParamConfigModel.getValue())) {
					// 获取运单汇总ID
					RestMessage<String> restMessageAutoCreateShipbillId = maindataTmsResource.getCodeNumberByCode(SeriaNnumberConstant.TMS_SHIPBILL_HEADER_ID, "L");
					if (!restMessageAutoCreateShipbillId.isSuccess()) {
						throw new RuntimeException("生成运单汇总ID失败");
					}
					lastSubShipbillId = restMessageAutoCreateShipbillId.getData();
				} else {
					StringBuffer buffNo2 = new StringBuffer(shipbillId);
					buffNo2.append(DataDictionaryConstant.SUB_SHIPBILL_NO);
					buffNo2.append(index + 1);
					lastSubShipbillId = buffNo2.toString();
				}
				newShipbillIds.add(lastSubShipbillId);

				// 保存中转子单的运单汇总
				TmsShipbillHeaderModel lastSubTmsShipbillHeaderModel = new TmsShipbillHeaderModel();
				BeanUtils.copyProperties(tmsShipbillHeaderModel, lastSubTmsShipbillHeaderModel);

				lastSubTmsShipbillHeaderModel.setShipbillId(lastSubShipbillId);
				lastSubTmsShipbillHeaderModel.setShipbillNo(lastSubShipbillId);

				if (user.getUserType().equals(BussinessConstant.USER_TYPE_ZY)) {
					// 拆单状态 0未拆单
					lastSubTmsShipbillHeaderModel.setSplitOrderStatus(DataDictionaryConstant.SPLIT_ORDER_STATUS_UN);
					// 拆单类型 3拆段子单
					lastSubTmsShipbillHeaderModel.setSplitOrderType(DataDictionaryConstant.SPLIT_ORDER_TYPE_TRANSIT_SUB);
				} else {
					// 拆单状态 0未拆单
					lastSubTmsShipbillHeaderModel.setCarrierSplitOrderStatus(DataDictionaryConstant.CARRIER_SPLIT_ORDER_STATUS_UN);
					// 拆单类型 3拆段子单
					lastSubTmsShipbillHeaderModel.setCarrierSplitOrderType(DataDictionaryConstant.CARRIER_SPLIT_ORDER_TYPE_TRANSIT_SUB);
				}
				// 父级运单ID
				lastSubTmsShipbillHeaderModel.setFatherShipbillId(tmsShipbillHeaderModel.getShipbillId());
				// 父级运单编号
				lastSubTmsShipbillHeaderModel.setFatherShipbillNo(tmsShipbillHeaderModel.getShipbillNo());
				// 原始运单ID
				String originalShipbillId = ObjectUtil.isEmpty(tmsShipbillHeaderModel.getOriginalShipbillId()) ? tmsShipbillHeaderModel.getShipbillId() : tmsShipbillHeaderModel.getOriginalShipbillId();
				lastSubTmsShipbillHeaderModel.setOriginalShipbillId(originalShipbillId);
				// 原始运单编号
				String originalShipbillNo = ObjectUtil.isEmpty(tmsShipbillHeaderModel.getOriginalShipbillNo()) ? tmsShipbillHeaderModel.getShipbillNo() : tmsShipbillHeaderModel.getOriginalShipbillNo();
				lastSubTmsShipbillHeaderModel.setOriginalShipbillNo(originalShipbillNo);

				// 上一站的出发时间 -> 预计提货开始时间
				lastSubTmsShipbillHeaderModel.setEstimatedPickupStartTime(lastStationDt.getEstimatedSendStartTime());
				// 预计提货结束时间
				lastSubTmsShipbillHeaderModel.setEstimatedPickupEndTime(lastStationDt.getEstimatedSendEndTime());
				// 时效
				lastSubTmsShipbillHeaderModel.setTransportAging(getTransportAging(tmsShipbillHeaderModel.getEstimatedDeliveryEndTime(), lastStationDt.getEstimatedSendEndTime()));
				// 发货方单位ID
				lastSubTmsShipbillHeaderModel.setShipperUnitId(lastTransferStationByViewDTO.getId());
				// 发货方单位编码
				lastSubTmsShipbillHeaderModel.setShipperUnitCode(lastTransferStationByViewDTO.getCode());
				// 发货方单位名称
				lastSubTmsShipbillHeaderModel.setShipperUnitName(lastTransferStationByViewDTO.getName());
				// 发货方联系人
				lastSubTmsShipbillHeaderModel.setShipperContact(lastTransferStationByViewDTO.getContact());
				// 发货方手机号
				lastSubTmsShipbillHeaderModel.setShipperPhoneNumber(lastTransferStationByViewDTO.getPhoneNumber());
				// 发货方座机号
				lastSubTmsShipbillHeaderModel.setShipperLandlineNumber(lastTransferStationByViewDTO.getLandlineNumber());
				// 发货方邮箱
				lastSubTmsShipbillHeaderModel.setShipperEmail(lastTransferStationByViewDTO.getEmail());
				// 发货方省编码
				lastSubTmsShipbillHeaderModel.setShipperProvince(lastTransferStationByViewDTO.getProvince());
				// 发货方省名称
				lastSubTmsShipbillHeaderModel.setShipperProvinceName(lastTransferStationByViewDTO.getProvinceName());
				// 发货方市编码
				lastSubTmsShipbillHeaderModel.setShipperCity(lastTransferStationByViewDTO.getCity());
				// 发货方市名称
				lastSubTmsShipbillHeaderModel.setShipperCityName(lastTransferStationByViewDTO.getCityName());
				// 发货方区/县编码
				lastSubTmsShipbillHeaderModel.setShipperDistrict(lastTransferStationByViewDTO.getDistrict());
				// 发货方区/县名称
				lastSubTmsShipbillHeaderModel.setShipperDistrictName(lastTransferStationByViewDTO.getDistrictName());
				// 发货方详细地址
				lastSubTmsShipbillHeaderModel.setShipperAddress(lastTransferStationByViewDTO.getAddress());
				// 发货方经度
				lastSubTmsShipbillHeaderModel.setShipperLongitude(lastTransferStationByViewDTO.getLongitude());
				// 发货方纬度
				lastSubTmsShipbillHeaderModel.setShipperLatitude(lastTransferStationByViewDTO.getLatitude());
				// 发货方备注
				lastSubTmsShipbillHeaderModel.setShipperMemo(lastTransferStationByViewDTO.getMemo());
				lastSubTmsShipbillHeaderModel.setUpdateperson(user.getNickname());
				lastSubTmsShipbillHeaderModel.setUpdatetime(date);
				lastSubTmsShipbillHeaderModel.setCreateperson(user.getNickname());
				lastSubTmsShipbillHeaderModel.setCreatetime(date);
				// 保存运单汇总
				lastSubTmsShipbillHeaderModel.setShipbillType(ShipBillTypeEnum.NORMAL.getCode());
				lastSubTmsShipbillHeaderModel.setSignInStatus(SignInStatusEnum.NOT_SIGN.getCode());
				lastSubTmsShipbillHeaderModel.setDriverReceiveStatus(DriverReceiveStatusEnum.N.getCode());

				if (ToolKits.isNotEmpty(transferMatchingDTO.getRematchLine()) && transferMatchingDTO.getRematchLine().equals(DataDictionaryConstant.REMATCH_LINE_YES)) {
					// 子单重新匹配线路
					ShipbillMatchLineDTO lineData = shipbillMatchLine(lastSubTmsShipbillHeaderModel);
					if (ToolKits.isNotEmpty(lineData) && ToolKits.isNotEmpty(lineData.getLineId())) {
						// 订单绑定线路
						lastSubTmsShipbillHeaderModel.setLineId(lineData.getLineId());
						lastSubTmsShipbillHeaderModel.setLineCode(lineData.getLineCode());
						lastSubTmsShipbillHeaderModel.setLineName(lineData.getLineName());
						lastSubTmsShipbillHeaderModel.setLineDirection(lineData.getLineDirection());
						lastSubTmsShipbillHeaderModel.setShippingOrder(lineData.getShippingOrder());
						lastSubTmsShipbillHeaderModel.setPickUpOrder(lineData.getPickUpOrder());
					}
				}
				lastSubTmsShipbillHeaderModel.setIntelligentLock(IntelligentLockEnum.UN_LOCK.getCode());
				tmsShipbillHeaderMapper.save(lastSubTmsShipbillHeaderModel);

				// 运输记录
				saveTransportLog(lastSubTmsShipbillHeaderModel.getShipbillId(), date, lastSubTmsShipbillHeaderModel.getEstimatedPickupStartTime());

				// 运单明细保存
				for (TmsShipbillDetailModel detailModel : tmsShipbillDetailModels) {
					TmsShipbillDetailModel subTmsShipbillDetailModel = new TmsShipbillDetailModel();
					// 运单明细ID
					RestMessage<String> restMessage4 = maindataTmsResource.getCodeNumberByCode(SeriaNnumberConstant.TMS_SHIPBILL_DETAIL_ID, "L");
					if (!restMessage4.isSuccess()) {
						throw new RuntimeException("生成运单明细ID失败");
					}
					String lastSubShipbillDetailId = restMessage4.getData();

					BeanUtils.copyProperties(detailModel, subTmsShipbillDetailModel);
					subTmsShipbillDetailModel.setId(lastSubShipbillDetailId);
					// 运单ID
					subTmsShipbillDetailModel.setShipbillId(lastSubTmsShipbillHeaderModel.getShipbillId());
					// 运单编号
					subTmsShipbillDetailModel.setShipbillNo(lastSubTmsShipbillHeaderModel.getShipbillNo());
					// 仓库ID
					subTmsShipbillDetailModel.setBranchId(lastSubTmsShipbillHeaderModel.getBranchId());
					// 仓库编码
					subTmsShipbillDetailModel.setBranchCode(lastSubTmsShipbillHeaderModel.getBranchCode());
					// 仓库名称
					subTmsShipbillDetailModel.setBranchName(lastSubTmsShipbillHeaderModel.getBranchName());

					subTmsShipbillDetailModel.setCreateperson(user.getNickname());
					subTmsShipbillDetailModel.setCreatetime(date);
					subTmsShipbillDetailModel.setUpdateperson(user.getNickname());
					subTmsShipbillDetailModel.setUpdatetime(date);
					subTmsShipbillDetailModel.setOrigPcs(subTmsShipbillDetailModel.getPcs());
					subTmsShipbillDetailModel.setClosingPcs(BigDecimal.valueOf(0));
					subTmsShipbillDetailModel.setDeliveryPcs(BigDecimal.valueOf(0));
					subTmsShipbillDetailModel.setFatherId(detailModel.getId());
					subTmsShipbillDetailModel.setScanStatus(DataDictionaryConstant.SCAN_STATUS_INIT);
					tmsShipbillDetailMapper.save(subTmsShipbillDetailModel);
				}
				// 子运单日志保存
				ShipbillOperateLogSaveVO subShipbillOperateLogSaveVO = new ShipbillOperateLogSaveVO();
				subShipbillOperateLogSaveVO.setShipbillId(lastSubTmsShipbillHeaderModel.getShipbillId());
				subShipbillOperateLogSaveVO.setShipbillNo(lastSubTmsShipbillHeaderModel.getShipbillNo());
				subShipbillOperateLogSaveVO.setOperateEvent(DataDictionaryConstant.SHIPBILL_EVENT_NAME_TRANSIT_SUB);
				subShipbillOperateLogSaveVO.setOldStatus(DataDictionaryConstant.SHIPBILL_STATUS_REVIEW);
				subShipbillOperateLogSaveVO.setNewStatus(DataDictionaryConstant.SHIPBILL_STATUS_REVIEW);
				shipbillOperateLogService.addShipbillOperateLogData(subShipbillOperateLogSaveVO);
				// 运单节点保存
				ShipbillNodeTrackingSaveVO shipbillNodeTrackingSaveVO = new ShipbillNodeTrackingSaveVO();
				shipbillNodeTrackingSaveVO.setShipbillId(lastSubTmsShipbillHeaderModel.getShipbillId());
				shipbillNodeTrackingSaveVO.setShipbillNo(lastSubTmsShipbillHeaderModel.getShipbillId());
				shipbillNodeTrackingSaveVO.setStatus(DataDictionaryConstant.SHIPBILL_STATUS_REVIEW);
				shipbillNodeTrackingSaveVO.setNodeEvent(DataDictionaryConstant.SHIPBILL_STATUSNAME_REW);
				shipbillNodeTrackingService.addShipbillNodeTrackingData(shipbillNodeTrackingSaveVO);

				// 子单的包裹信息维护
				// 原运单的包裹信息取得
				Criteria oldPakHeadCriteria = Criteria.forClass(TmsShipbillPackageModel.class);
				Restriction r3 = Restrictions.eq("shipbillId", shipbillId);
				Restriction r4 = Restrictions.eq("enterpriseId", user.getEnterpriseId());
				oldPakHeadCriteria.setRestriction(Restrictions.and(r3, r4));
				oldPakHeadCriteria.setOrder(Order.newInstance().desc(new String[] { "updatetime" }));
				List<TmsShipbillPackageModel> tmsShipbillPackageModels = tmsShipbillPackageMapper.findByCriteria(oldPakHeadCriteria);
				for (String newShipbillId : newShipbillIds) {
					for (TmsShipbillPackageModel oldPkg : tmsShipbillPackageModels) {
						// 运单包裹表ID
						RestMessage<String> restMessage4 = maindataTmsResource.getCodeNumberByCode(SeriaNnumberConstant.TMS_SHIPBILL_PACKAGE_ID, "L");
						if (!restMessage4.isSuccess()) {
							throw new RuntimeException("生成运单包裹表ID失败");
						}
						String newPkgId = restMessage4.getData();

						TmsShipbillPackageModel newPkg = new TmsShipbillPackageModel();
						BeanUtils.copyProperties(oldPkg, newPkg);
						newPkg.setId(newPkgId);
						newPkg.setShipbillId(newShipbillId);
						newPkg.setShipbillNo(newShipbillId);
						newPkg.setCreateperson(user.getNickname());
						newPkg.setCreatetime(date);
						newPkg.setUpdateperson(user.getNickname());
						newPkg.setUpdatetime(date);
						tmsShipbillPackageMapper.save(newPkg);
						// 原包裹明细取得
						Criteria oldPakDetailCriteria = Criteria.forClass(TmsShipbillPkgDetailModel.class);
						Restriction r5 = Restrictions.eq("shipbillId", shipbillId);
						Restriction r6 = Restrictions.eq("packageId", oldPkg.getPackageId());
						Restriction r7 = Restrictions.eq("enterpriseId", user.getEnterpriseId());
						oldPakDetailCriteria.setRestriction(Restrictions.and(r5, r6, r7));
						oldPakDetailCriteria.setOrder(Order.newInstance().desc(new String[] { "updatetime" }));
						List<TmsShipbillPkgDetailModel> tmsShipbillPkgDetailModels = tmsShipbillPackageDetailMapper.findByCriteria(oldPakDetailCriteria);
						for (TmsShipbillPkgDetailModel oldPkgDetail : tmsShipbillPkgDetailModels) {
							// 运单包裹明细表ID
							RestMessage<String> restMessage5 = maindataTmsResource.getCodeNumberByCode(SeriaNnumberConstant.TMS_SHIPBILL_PACKAGE_DETAIL_ID, "L");
							if (!restMessage5.isSuccess()) {
								throw new RuntimeException("生成运单包裹明细表ID失败");
							}
							String newPkgDetailId = restMessage5.getData();
							TmsShipbillPkgDetailModel newPkgDetail = new TmsShipbillPkgDetailModel();
							BeanUtils.copyProperties(oldPkgDetail, newPkgDetail);
							newPkgDetail.setId(newPkgDetailId);
							newPkgDetail.setShipbillId(newShipbillId);
							newPkgDetail.setShipbillNo(newShipbillId);
							newPkgDetail.setCreateperson(user.getNickname());
							newPkgDetail.setCreatetime(date);
							newPkgDetail.setUpdateperson(user.getNickname());
							newPkgDetail.setUpdatetime(date);
							tmsShipbillPackageDetailMapper.save(newPkgDetail);
						}
					}
				}
			}
		}
		updatePlanBill(shipbillIds, user);
	}

	/**
	 * 运单匹配中转策略
	 *
	 * @param model
	 * @return
	 */
	public StrategyTransferMatchingDTO shipbillMatchTransfer(TmsShipbillHeaderModel model) {
		// 新增后自动提交判定
		StrategyTransferMatchingVO transferMatchingVO = new StrategyTransferMatchingVO();
		// 收货方单位ID
		transferMatchingVO.setConsigneeUnitId(model.getConsigneeUnitId());
		transferMatchingVO.setConsigneeId(model.getConsigneeId());

		RestMessage<List<StrategyTransferMatchingDTO>> matchRs = maindataTmsResource.matchingTransferExecute(transferMatchingVO);
		if (!matchRs.isSuccess()) {
			throw new PrologException("运单【" + model.getShipbillNo() + "】调用maindata服务运单匹配中转策略失败");
		}
		List<StrategyTransferMatchingDTO> matchRsData = matchRs.getData();
		if (CollectionUtil.isEmpty(matchRsData)) {
			throw new PrologException("运单【" + model.getShipbillNo() + "】没有匹配到中转策略");
		}
		return matchRsData.get(0);
	}

	public Map<Integer, TransferDtDTO> getTransDate(TmsShipbillHeaderModel headerModel, List<StrategyTransferStationDTO> transferStationDTOS, UserEntity user) {
		Map<Integer, TransferDtDTO> transferDtDTOMap = Maps.newHashMap();

		Criteria criteriaTransLog = Criteria.forClass(TmsShipbillTransLogModel.class);
		Restriction r1 = Restrictions.eq(TmsShipbillTransLogModel::getShipbillId, headerModel.getShipbillId());
		Restriction r2 = Restrictions.eq(TmsShipbillTransLogModel::getEnterpriseId, user.getEnterpriseId());
		criteriaTransLog.setRestriction(Restrictions.and(r1, r2));
		List<TmsShipbillTransLogModel> transLogModels = tmsShipbillTransportLogMapper.findByCriteria(criteriaTransLog);
		if (ToolKits.isEmpty(transLogModels)) {
			throw new PrologException("运单【" + headerModel.getShipbillId() + "】没有提交日期和审核日期");
		}
		TmsShipbillTransLogModel transLogModel = transLogModels.get(0);
		Date reviewDt = transLogModel.getReviewDt();
		Date commitDt = transLogModel.getCommitDt();
		if (ToolKits.isEmpty(reviewDt) || ToolKits.isEmpty(commitDt)) {
			throw new PrologException("运单【" + headerModel.getShipbillId() + "】没有提交日期和审核日期");
		}
		for (StrategyTransferStationDTO transferStationDTO : transferStationDTOS) {
			TransferDtDTO transferDtDTO = new TransferDtDTO();
			Date estimatedDeliveryStartTime = null;
			Date estimatedDeliveryEndTime = null;

			Date estimatedSendStartTime = null;
			Date estimatedSendEndTime = null;

			// 到达时间
			if (transferStationDTO.getDeliveryStartTimeType().equals(DataDictionaryConstant.TRANSFER_TIME_TYPE_ORDER_DT)) {
				if (ToolKits.isEmpty(headerModel.getOrderDate())) {
					throw new PrologException("运单【" + headerModel.getShipbillId() + "】没有下单日期");
				}
				estimatedDeliveryStartTime = headerModel.getOrderDate();
			} else if (transferStationDTO.getDeliveryStartTimeType().equals(DataDictionaryConstant.TRANSFER_TIME_TYPE_COMMIT_DT)) {
				estimatedDeliveryStartTime = commitDt;
			} else if (transferStationDTO.getDeliveryStartTimeType().equals(DataDictionaryConstant.TRANSFER_TIME_TYPE_REVIEW_DT)) {
				estimatedDeliveryStartTime = reviewDt;
			}
			if (ToolKits.isNotEmpty(transferStationDTO.getDeliveryStartTimeHour())) {
				estimatedDeliveryStartTime = DateUtil.offsetHour(estimatedDeliveryStartTime, transferStationDTO.getDeliveryStartTimeHour());
			}
			if (ToolKits.isNotEmpty(transferStationDTO.getDeliveryStartTimeMinute())) {
				estimatedDeliveryStartTime = DateUtil.offsetMinute(estimatedDeliveryStartTime, transferStationDTO.getDeliveryStartTimeMinute());
			}
			if (transferStationDTO.getDeliveryEndTimeType().equals(DataDictionaryConstant.TRANSFER_TIME_TYPE_ORDER_DT)) {
				if (ToolKits.isEmpty(headerModel.getOrderDate())) {
					throw new PrologException("运单【" + headerModel.getShipbillId() + "】没有下单日期");
				}
				estimatedDeliveryEndTime = headerModel.getOrderDate();
			} else if (transferStationDTO.getDeliveryEndTimeType().equals(DataDictionaryConstant.TRANSFER_TIME_TYPE_COMMIT_DT)) {
				estimatedDeliveryEndTime = commitDt;
			} else if (transferStationDTO.getDeliveryEndTimeType().equals(DataDictionaryConstant.TRANSFER_TIME_TYPE_REVIEW_DT)) {
				estimatedDeliveryEndTime = reviewDt;
			}
			if (ToolKits.isNotEmpty(transferStationDTO.getDeliveryEndTimeDay())) {
				estimatedDeliveryEndTime = DateUtil.offsetDay(estimatedDeliveryEndTime, transferStationDTO.getDeliveryEndTimeDay());
			}
			if (ToolKits.isNotEmpty(transferStationDTO.getDeliveryEndTimeHour())) {
				estimatedDeliveryEndTime = DateUtil.offsetHour(estimatedDeliveryEndTime, transferStationDTO.getDeliveryEndTimeHour());
			}
			if (ToolKits.isNotEmpty(transferStationDTO.getDeliveryEndTimeMinute())) {
				estimatedDeliveryEndTime = DateUtil.offsetMinute(estimatedDeliveryEndTime, transferStationDTO.getDeliveryEndTimeMinute());
			}
			// 提货时间
			if (transferStationDTO.getSendStartTimeType().equals(DataDictionaryConstant.TRANSFER_TIME_TYPE_ORDER_DT)) {
				if (ToolKits.isEmpty(headerModel.getOrderDate())) {
					throw new PrologException("运单【" + headerModel.getShipbillId() + "】没有下单日期");
				}
				estimatedSendStartTime = headerModel.getOrderDate();
			} else if (transferStationDTO.getSendStartTimeType().equals(DataDictionaryConstant.TRANSFER_TIME_TYPE_COMMIT_DT)) {
				estimatedSendStartTime = commitDt;
			} else if (transferStationDTO.getSendStartTimeType().equals(DataDictionaryConstant.TRANSFER_TIME_TYPE_REVIEW_DT)) {
				estimatedSendStartTime = reviewDt;
			}
			if (ToolKits.isNotEmpty(transferStationDTO.getSendStartTimeHour())) {
				estimatedSendStartTime = DateUtil.offsetHour(estimatedSendStartTime, transferStationDTO.getSendStartTimeHour());
			}
			if (ToolKits.isNotEmpty(transferStationDTO.getSendStartTimeMinute())) {
				estimatedSendStartTime = DateUtil.offsetMinute(estimatedSendStartTime, transferStationDTO.getSendStartTimeMinute());
			}
			if (transferStationDTO.getSendEndTimeType().equals(DataDictionaryConstant.TRANSFER_TIME_TYPE_ORDER_DT)) {
				if (ToolKits.isEmpty(headerModel.getOrderDate())) {
					throw new PrologException("运单【" + headerModel.getShipbillId() + "】没有下单日期");
				}
				estimatedSendEndTime = headerModel.getOrderDate();
			} else if (transferStationDTO.getSendEndTimeType().equals(DataDictionaryConstant.TRANSFER_TIME_TYPE_COMMIT_DT)) {
				estimatedSendEndTime = commitDt;
			} else if (transferStationDTO.getSendEndTimeType().equals(DataDictionaryConstant.TRANSFER_TIME_TYPE_REVIEW_DT)) {
				estimatedSendEndTime = reviewDt;
			}
			if (ToolKits.isNotEmpty(transferStationDTO.getSendEndTimeDay())) {
				estimatedSendEndTime = DateUtil.offsetDay(estimatedSendEndTime, transferStationDTO.getSendEndTimeDay());
			}
			if (ToolKits.isNotEmpty(transferStationDTO.getSendEndTimeDayHour())) {
				estimatedSendEndTime = DateUtil.offsetHour(estimatedSendEndTime, transferStationDTO.getSendEndTimeDayHour());
			}
			if (ToolKits.isNotEmpty(transferStationDTO.getSendEndTimeDayMinute())) {
				estimatedSendEndTime = DateUtil.offsetMinute(estimatedSendEndTime, transferStationDTO.getSendEndTimeDayMinute());
			}
			transferDtDTO.setEstimatedDeliveryStartTime(estimatedDeliveryStartTime);
			transferDtDTO.setEstimatedDeliveryEndTime(estimatedDeliveryEndTime);
			transferDtDTO.setEstimatedSendStartTime(estimatedSendStartTime);
			transferDtDTO.setEstimatedSendEndTime(estimatedSendEndTime);

			transferDtDTOMap.put(transferStationDTO.getTransferOrder(), transferDtDTO);
		}
		return transferDtDTOMap;
	}

	/**
	 * 查询调度策略
	 *
	 * @param shipbillIds
	 */
	@Override
	public ShipbillMatchCarrierDTO queryDispatchStrategyData(List<String> shipbillIds) {
		TimeInterval timer = DateUtil.timer();
		if (ToolKits.isEmpty(shipbillIds)) {
			return null;
		}
		List<TmsShipbillHeaderModel> shipbillHeaderModels = tmsShipbillHeaderMapper.shipbillsQuery(shipbillIds);
		if (ToolKits.isEmpty(shipbillHeaderModels)) {
			throw new PrologException("选择的运单信息不存在");
		}
		ShipbillMatchCarrierDTO timesDTO = new ShipbillMatchCarrierDTO();
		BigDecimal totalWeight = shipbillHeaderModels.stream().map(TmsShipbillHeaderModel::getTotalWeight).reduce(BigDecimal.ZERO, NumberUtil::add);
		BigDecimal totalVolume = shipbillHeaderModels.stream().map(TmsShipbillHeaderModel::getTotalVolume).reduce(BigDecimal.ZERO, NumberUtil::add);
		// 最早提货时间
		List<TmsShipbillHeaderModel> pickupStartTimes = shipbillHeaderModels.stream().filter(s -> ToolKits.isNotEmpty(s.getEstimatedPickupStartTime())).collect(Collectors.toList());
		if (ToolKits.isNotEmpty(pickupStartTimes)) {
			Optional<TmsShipbillHeaderModel> pickupStartTime = pickupStartTimes.stream().min(Comparator.comparing(TmsShipbillHeaderModel::getEstimatedPickupStartTime));
			if (ToolKits.isNotEmpty(pickupStartTime.get().getEstimatedPickupStartTime())) {
				timesDTO.setMinEstimatedPickupTime(pickupStartTime.get().getEstimatedPickupStartTime());
			}
		}
		// 最晚送达时间
		List<TmsShipbillHeaderModel> deliveryEndTimes = shipbillHeaderModels.stream().filter(s -> ToolKits.isNotEmpty(s.getEstimatedDeliveryEndTime())).collect(Collectors.toList());
		if (ToolKits.isNotEmpty(deliveryEndTimes)) {
			Optional<TmsShipbillHeaderModel> deliveryEndTime = deliveryEndTimes.stream().max(Comparator.comparing(TmsShipbillHeaderModel::getEstimatedDeliveryEndTime));
			if (ToolKits.isNotEmpty(deliveryEndTime.get().getEstimatedDeliveryEndTime())) {
				timesDTO.setMaxEstimatedDeliveryTime(deliveryEndTime.get().getEstimatedDeliveryEndTime());
			}
		}

		List<ShipbillMatchCarrierVO> matchCarrierVOS = Lists.newArrayList();
		List<String> carrierItems = Lists.newArrayList();

		log.warn("系统分组 运单件数=======" + shipbillHeaderModels.size());
		// 运单按匹配条件去重
		for (TmsShipbillHeaderModel headerModel : shipbillHeaderModels) {
			if (ToolKits.isNotEmpty(headerModel.getDeliveryMethodType())) {
				carrierItems.add(headerModel.getDeliveryMethodType().toString());
			} else {
				carrierItems.add("1");
			}
			if (ToolKits.isNotEmpty(headerModel.getOrderType())) {
				carrierItems.add(headerModel.getOrderType().toString());
			} else {
				carrierItems.add("1");
			}
			if (ToolKits.isNotEmpty(headerModel.getOrderBusinessType())) {
				carrierItems.add(headerModel.getOrderBusinessType().toString());
			} else {
				carrierItems.add("1");
			}
			if (ToolKits.isNotEmpty(headerModel.getTransportType())) {
				carrierItems.add(headerModel.getTransportType().toString());
			} else {
				carrierItems.add("1");
			}
			if (ToolKits.isNotEmpty(headerModel.getTemperatureRequirement())) {
				carrierItems.add(headerModel.getTemperatureRequirement().toString());
			} else {
				carrierItems.add("1");
			}
			if (ToolKits.isNotEmpty(headerModel.getCargoOwnerId())) {
				carrierItems.add(headerModel.getCargoOwnerId().toString());
			} else {
				carrierItems.add("1");
			}
			if (ToolKits.isNotEmpty(headerModel.getDepartmentId())) {
				carrierItems.add(headerModel.getDepartmentId().toString());
			} else {
				carrierItems.add("1");
			}
			if (ToolKits.isNotEmpty(headerModel.getConsigneeType())) {
				carrierItems.add(headerModel.getConsigneeType().toString());
			} else {
				carrierItems.add("1");
			}
			if (ToolKits.isNotEmpty(headerModel.getConsigneeUnitId())) {
				carrierItems.add(headerModel.getConsigneeUnitId().toString());
			} else {
				carrierItems.add("1");
			}
			if (ToolKits.isNotEmpty(headerModel.getConsigneeId())) {
				carrierItems.add(headerModel.getConsigneeId().toString());
			} else {
				carrierItems.add("1");
			}
			if (ToolKits.isNotEmpty(headerModel.getShipperType())) {
				carrierItems.add(headerModel.getShipperType().toString());
			} else {
				carrierItems.add("1");
			}
			if (ToolKits.isNotEmpty(headerModel.getShipperUnitId())) {
				carrierItems.add(headerModel.getShipperUnitId().toString());
			} else {
				carrierItems.add("1");
			}
			if (ToolKits.isNotEmpty(headerModel.getLineId())) {
				carrierItems.add(headerModel.getLineId().toString());
			} else {
				carrierItems.add("1");
			}
			headerModel.setExtStr1(carrierItems.stream().collect(Collectors.joining()));
			carrierItems.clear();
		}
		shipbillHeaderModels = shipbillHeaderModels.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(TmsShipbillHeaderModel::getExtStr1))), ArrayList::new));
		log.warn("系统分组 运单去重后件数=======" + shipbillHeaderModels.size());
		for (TmsShipbillHeaderModel headerModel : shipbillHeaderModels) {
			ShipbillMatchCarrierVO carrierVO = new ShipbillMatchCarrierVO();
			BeanUtils.copyProperties(headerModel, carrierVO);
			carrierVO.setTotalWeight(totalWeight);
			carrierVO.setTotalVolume(totalVolume);
			carrierVO.setShipperAgingTime(headerModel.getEstimatedPickupStartTime());
			carrierVO.setPickupStartTime(headerModel.getEstimatedPickupStartTime());
			matchCarrierVOS.add(carrierVO);
		}
		log.warn("系统分组 默认承运商的运单查询时间=======" + timer.interval());
		log.info("承运方策略查询入参:" + JSON.toJSONString(matchCarrierVOS));
		RestMessage<Map<String, ShipbillMatchCarrierDTO>> shipbillMatchRs = maindataTmsResource.shipbillMatchCarrierExecute(matchCarrierVOS);
		if (!shipbillMatchRs.isSuccess()) {
			return timesDTO;
		}
		log.info("承运方策略查询返回:" + JSON.toJSONString(shipbillMatchRs));
		Map<String, ShipbillMatchCarrierDTO> rsCarriers = shipbillMatchRs.getData();
		if (ToolKits.isEmpty(rsCarriers)) {
			return null;
		}
		List<ShipbillMatchCarrierDTO> carrierDTOS = rsCarriers.values().stream().collect(Collectors.toList());
		if (carrierDTOS.stream().allMatch(dto -> ToolKits.isEmpty(dto.getCarrierId()))) {
			List<ShipbillMatchCarrierDTO> vehicleTypes = carrierDTOS.stream().filter(dto->ToolKits.isNotEmpty(dto.getVehicleTypeId())).collect(Collectors.toList());
			if (ToolKits.isNotEmpty(vehicleTypes)) {
				timesDTO.setVehicleTypeId(vehicleTypes.get(0).getVehicleTypeId());
				timesDTO.setVehicleTypeCode(vehicleTypes.get(0).getVehicleTypeCode());
				timesDTO.setVehicleTypeName(vehicleTypes.get(0).getVehicleTypeName());
				timesDTO.setCarrierType(vehicleTypes.get(0).getCarrierType());
				timesDTO.setWeight(vehicleTypes.get(0).getWeight());
				timesDTO.setVolume(vehicleTypes.get(0).getVolume());
			}
			return timesDTO;
		} else if (carrierDTOS.stream().anyMatch(dto -> ToolKits.isEmpty(dto.getCarrierId()))) {
			return timesDTO;
		}
        List<String> carrierIds = carrierDTOS.stream().map(ShipbillMatchCarrierDTO::getCarrierId).distinct().collect(Collectors.toList());
        if (carrierIds.size() == 1) {
            List<SysRefdatadModel> dicData = convertorUtil.getDictionary(new String[] { DataDictionaryConstant.LINE_CARRIER_TYPE // 承运方类型
			});
            ShipbillMatchCarrierDTO carrierDTO = carrierDTOS.get(0);
            carrierDTO.setCarrierTypeName(ConvertorUtil.getName(dicData, DataDictionaryConstant.LINE_CARRIER_TYPE, String.valueOf(carrierDTO.getCarrierType())));
			if (carrierDTO.getCarrierType().equals(DataDictionaryConstant.LINE_CARRIER_TYPE_CYF)) {
				// 同一承运商
				carrierDTO.setMaxEstimatedDeliveryTime(timesDTO.getMaxEstimatedDeliveryTime());
				carrierDTO.setMinEstimatedPickupTime(timesDTO.getMinEstimatedPickupTime());
				return carrierDTO;
			} else {
				// 同一司机，车辆
				List<String> vehiclePlateNumbers = carrierDTOS.stream().map(ShipbillMatchCarrierDTO::getVehiclePlateNumber).distinct().collect(Collectors.toList());
				if (vehiclePlateNumbers.size() == 1) {
					carrierDTO.setDriverId(carrierDTO.getCarrierId());
					carrierDTO.setDriverCode(carrierDTO.getCarrierCode());
					carrierDTO.setDriverName(carrierDTO.getCarrierName());

					carrierDTO.setCarrierId(null);
					carrierDTO.setCarrierCode(null);
					carrierDTO.setCarrierName(null);

					carrierDTO.setMaxEstimatedDeliveryTime(timesDTO.getMaxEstimatedDeliveryTime());
					carrierDTO.setMinEstimatedPickupTime(timesDTO.getMinEstimatedPickupTime());
					log.warn("系统分组 默认承运商查询时间=======" + timer.interval());
					return carrierDTO;
				}
			}
		}
		log.warn("系统分组 默认承运商查询时间=======" + timer.interval());
		return timesDTO;
	}

	/**
	 * 运单匹配线路
	 *
	 * @param vo
	 */
	public void matchLineStrategy(SysGroupQueryVO vo) {
		ToolKits.isParamNull(vo, "运单匹配线路请求不为空");

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

		if (ToolKits.isNotEmpty(vo.getCargoOwnerIds())) {
			String[] ids = vo.getCargoOwnerIds().split(",");
			vo.setCargoOwnerIdList(Arrays.stream(ids).map(id -> Long.valueOf(id)).collect(Collectors.toList()));
		}
		if (ToolKits.isNotEmpty(vo.getLineIds())) {
			String[] ids = vo.getLineIds().split(",");
			vo.setLineIdList(Arrays.stream(ids).map(id -> Long.valueOf(id)).collect(Collectors.toList()));
		}
		List<ZoneVO> shipperAdministrativeAreas = vo.getShipperAdministrativeAreas();
		if (ToolKits.isNotEmpty(shipperAdministrativeAreas)) {
			List<String> provinceList = parseCode(shipperAdministrativeAreas, "province");
			if (ToolKits.isNotEmpty(provinceList)) {
				vo.setShipperProvinceList(provinceList);
			}
			List<String> cityList = parseCode(shipperAdministrativeAreas, "city");
			if (ToolKits.isNotEmpty(cityList)) {
				vo.setShipperCityList(cityList);
			}
			List<String> districtList = parseCode(shipperAdministrativeAreas, "district");
			if (ToolKits.isNotEmpty(districtList)) {
				vo.setShipperDistrictList(districtList);
			}
		}
		List<ZoneVO> consigneeAdministrativeAreas = vo.getAdministrativeAreas();
		if (ToolKits.isNotEmpty(consigneeAdministrativeAreas)) {
			List<String> provinceList = parseCode(consigneeAdministrativeAreas, "province");
			if (ToolKits.isNotEmpty(provinceList)) {
				vo.setConsigneeProvinceList(provinceList);
			}
			List<String> cityList = parseCode(consigneeAdministrativeAreas, "city");
			if (ToolKits.isNotEmpty(cityList)) {
				vo.setConsigneeCityList(cityList);
			}
			List<String> districtList = parseCode(consigneeAdministrativeAreas, "district");
			if (ToolKits.isNotEmpty(districtList)) {
				vo.setConsigneeDistrictList(districtList);
			}
		}
		vo.setUserType(user.getUserType());
		vo.setEnterpriseId(user.getEnterpriseId());
		if (ObjectUtil.equal(user.getUserType(), BussinessConstant.USER_TYPE_ZY)) {// 自有账号
			vo.setDepts(ToolKits.isEmpty(user.getDepts()) ? null : user.getDepts().stream().toArray(String[]::new));
			if (BussinessConstant.USER_DEPARTMENT_AUTH_Y.equals(user.getOwnedAllDataAuthFlag())) {// 部门权限
				vo.setIsDept("YES");
			} else {// 业务员权限
				vo.setIsDept("NO");
				// 货主
				vo.setConsignors(ToolKits.isEmpty(user.getConsignors()) ? null : user.getConsignors().stream().toArray(Long[]::new));
				// 客户
				vo.setCustomers(ToolKits.isEmpty(user.getCustomers()) ? null : user.getCustomers().stream().toArray(Long[]::new));
				// 供应商
				vo.setSuppliers(ToolKits.isEmpty(user.getSuppliers()) ? null : user.getSuppliers().stream().toArray(Long[]::new));
				// 仓库
				vo.setWsarehouses(ToolKits.isEmpty(user.getWarehouses()) ? null : user.getWarehouses().stream().toArray(Long[]::new));
			}
		} else if (ObjectUtil.equal(user.getUserType(), BussinessConstant.USER_TYPE_CYS)) {// 承运商账号
			vo.setCarrierId(Long.valueOf(user.getLoginUserCompanyInfo().getId()));
		}
		List<TmsShipbillHeaderModel> shipbillQueryDTOS = tmsShipbillHeaderMapper.shipbillMatchLineQuery(vo);

		if (ToolKits.isNotEmpty(shipbillQueryDTOS)) {
			List<ShipbillMatchLineVO> matchLineVOS = Lists.newArrayList();
			for (TmsShipbillHeaderModel model : shipbillQueryDTOS) {
				ShipbillMatchLineVO matchLineVO = new ShipbillMatchLineVO();
				matchLineVO.setShipbillId(model.getShipbillId());
				// 配送方式
				matchLineVO.setDeliveryMethodType(model.getDeliveryMethodType());
				// 发货方类型
				matchLineVO.setShipperType(model.getShipperType());
				// 发货方单位ID
				matchLineVO.setShipperUnitId(model.getShipperUnitId());
				matchLineVO.setShipperProvince(model.getShipperProvince());
				matchLineVO.setShipperCity(model.getShipperCity());
				matchLineVO.setShipperDistrict(model.getShipperDistrict());
				// 收货方类型
				matchLineVO.setConsigneeType(model.getConsigneeType());
				// 收货方单位ID
				matchLineVO.setConsigneeUnitId(model.getConsigneeUnitId());
				matchLineVO.setConsigneeId(model.getConsigneeId());
				matchLineVO.setConsigneeProvince(model.getConsigneeProvince());
				matchLineVO.setConsigneeCity(model.getConsigneeCity());
				matchLineVO.setConsigneeDistrict(model.getConsigneeDistrict());
				// 订单类型
				matchLineVO.setOrderType(model.getOrderType());
				// 订单业务类型
				matchLineVO.setOrderBusinessType(model.getOrderBusinessType());
				// 运输模式
				matchLineVO.setTransportType(model.getTransportType());
				// 温度要求
				matchLineVO.setTemperatureRequirement(model.getTemperatureRequirement());
				// 货主ID
				matchLineVO.setCargoOwnerId(model.getCargoOwnerId());
				matchLineVO.setDepartmentId(model.getDepartmentId());
				matchLineVO.setEnterpriseId(model.getEnterpriseId());
				matchLineVOS.add(matchLineVO);
			}
			if (ToolKits.isEmpty(matchLineVOS)) {
				throw new PrologException("运单不存在");
			}
			RestMessage<Map<String, ShipbillMatchLineDTO>> matchRs = maindataTmsResource.shipbillMatchLineBatchExecute(matchLineVOS);
			if (!matchRs.isSuccess()) {
				throw new PrologException("运单调用maindata服务运单匹配线路失败");
			}
			Map<String, ShipbillMatchLineDTO> shipbillLineInfos = matchRs.getData();
			if (ToolKits.isEmpty(shipbillLineInfos)) {
				throw new PrologException("运单没有匹配到线路");
			}
			for (String shipbillId : shipbillLineInfos.keySet()) {
				ShipbillMatchLineDTO lineData = shipbillLineInfos.get(shipbillId);
				if (ToolKits.isNotEmpty(lineData) && ToolKits.isNotEmpty(lineData.getLineId())) {
					// 订单绑定线路
					Map<String, Object> mapUpdate = Maps.newHashMap();
					mapUpdate.put("updateperson", user.getNickname());
					mapUpdate.put("updatetime", DateUtils.nowDate());
					mapUpdate.put("lineId", lineData.getLineId());
					mapUpdate.put("lineCode", lineData.getLineCode());
					mapUpdate.put("lineName", lineData.getLineName());
					mapUpdate.put("lineDirection", lineData.getLineDirection());
					mapUpdate.put("shippingOrder", lineData.getShippingOrder());
					mapUpdate.put("pickUpOrder", lineData.getPickUpOrder());
					mapUpdate.put("shipperDeliveryOrder", lineData.getPickUpOrder());
					mapUpdate.put("consigneeDeliveryOrder", lineData.getShippingOrder());

					tmsShipbillHeaderMapper.updateMapById(shipbillId, mapUpdate, TmsShipbillHeaderModel.class);
				}
			}
		}
	}

	public List<String> parseCode(List<ZoneVO> codeList, String codeLevel) {
		List<String> rsCodes = Lists.newArrayList();
		if (ToolKits.isEmpty(codeList)) {
			return rsCodes;
		}
		try {
			switch (codeLevel) {
			case "province":
				List<ZoneVO> provinceList = codeList.stream().filter(d -> ToolKits.isNotEmpty(d.getZlevel()) && d.getZlevel().intValue() == 2).collect(Collectors.toList());
				if (ToolKits.isNotEmpty(provinceList)) {
					rsCodes.addAll(provinceList.stream().map(ZoneVO::getZoneid).collect(Collectors.toList()));
				}
				break;
			case "city":
				List<ZoneVO> cityList = codeList.stream().filter(d -> ToolKits.isNotEmpty(d.getZlevel()) && d.getZlevel().intValue() == 3).collect(Collectors.toList());
				if (ToolKits.isNotEmpty(cityList)) {
					rsCodes.addAll(cityList.stream().map(ZoneVO::getZoneid).collect(Collectors.toList()));
				}
				break;
			case "district":
				List<ZoneVO> districtList = codeList.stream().filter(d -> ToolKits.isNotEmpty(d.getZlevel()) && d.getZlevel().intValue() == 4).collect(Collectors.toList());
				if (ToolKits.isNotEmpty(districtList)) {
					rsCodes.addAll(districtList.stream().map(ZoneVO::getZoneid).collect(Collectors.toList()));
				}
				break;
			}
		} catch (Exception e) {
			log.info("行政区编码{}解析出错", JSON.toJSONString(codeList));
			return rsCodes;
		}
		return rsCodes;
	}

	/**
	 * 根据站点计算总里程
	 *
	 * @param vos
	 */
	@Override
	public CalculateMileageDTO calculateTotalMileage(List<CalculateMileageVO> vos) {
		log.info("根据站点{}计算总里程开始",vos);
		ToolKits.isParamNull(vos, "计算总里程请求不为空");
		CalculateMileageDTO mileageDTO = new CalculateMileageDTO();
		mileageDTO.setTotalMileage(BigDecimal.ZERO);
		vos = vos.stream().sorted(Comparator.comparing(CalculateMileageVO::getSiteOrder)).collect(Collectors.toList());
		// 按站点排序
		if (vos.stream().allMatch(vo->ToolKits.isNotEmpty(vo.getGroupItem())
				&& ToolKits.isNotEmpty(vo.getStationName())
				&& vo.getGroupItem().contains("consignee_station_name"))) {
			mileageDTO.setDeliveryLines(vos.stream().map(CalculateMileageVO::getStationName).distinct().collect(Collectors.joining("-")));
		} else {
			List<CalculateMileageVO> names = vos.stream().filter(vo -> ToolKits.isNotEmpty(vo.getScName())).collect(Collectors.toList());
			mileageDTO.setDeliveryLines(names.stream().map(CalculateMileageVO::getScName).distinct().collect(Collectors.joining("-")));
		}
		if (vos.stream().anyMatch(vo->ToolKits.isEmpty(vo.getSiteOrder())
						|| ToolKits.isEmpty(vo.getStationName())) || 2 > vos.size()) {
			log.info("站点信息不全{}不能获取到总里程",vos);
			return mileageDTO;
		}
		List<StationDistanceVO> names = Lists.newArrayList();
		TreeMap<String,Integer> shipbillMaps = new TreeMap<>();
		vos.stream().forEach(shipbill -> {
			shipbillMaps.put(shipbill.getStationName(), shipbill.getSiteOrder());
		});
		List<String> stationNames = shipbillMaps.keySet().stream().collect(Collectors.toList());
		if (2 > stationNames.size()) {
			return mileageDTO;
		}
		for (int idx = 0; idx < stationNames.size() - 1; idx++) {
			StationDistanceVO distanceVO = new StationDistanceVO();
			distanceVO.setStartingStationName(stationNames.get(idx));
			distanceVO.setStationName(stationNames.get(idx + 1));
			names.add(distanceVO);
		}
		log.info("运单货量统计时,计算总里程的站点路线:{}", JSON.toJSONString(names));

		BigDecimal totalMileage = calculateMileage(names);
		if (ToolKits.isEmpty(totalMileage)) {
			return mileageDTO;
		}
		mileageDTO.setTotalMileage(totalMileage);
		log.info("根据站点计算总里程完成,总里程={}",mileageDTO);
		return mileageDTO;
	}

	public BigDecimal calculateMileage(List<StationDistanceVO> names) {

		RestMessage<List<StationDistanceDTO>> restMessage = maindataTmsResource.queryStationDistanceExecute(names);
		if (!restMessage.isSuccess() || ToolKits.isEmpty(restMessage.getData())) {
			log.info("获取站点距离失败:{}", JSON.toJSONString(restMessage));
			return BigDecimal.ZERO;
		}
		// 武汉-孝感-恩施
		List<StationDistanceDTO> stationDistanceDTOS = restMessage.getData();
		if (names.size() != stationDistanceDTOS.size()) {
			log.info("部分站点没有获取到距离:{}", JSON.toJSONString(stationDistanceDTOS));
			return BigDecimal.ZERO;
		}
		BigDecimal totalMileage = stationDistanceDTOS.stream().map(StationDistanceDTO::getDistance)
											   .reduce(BigDecimal.ZERO, BigDecimal::add);
		return totalMileage;
	}

	public PlanBillLoadingDTO planDispatchLoadingStatistics(PlanBillLoadingVO vo) {
		ToolKits.isParamNull(vo, "计划调度配载单信息统计请求不为空");
		ToolKits.isParamNull(vo.getPlanDetailIds(), "计划单明细ID不为空");

		UserEntity user = PlgFxUsrUtils.getUserEntity();
		ToolKits.isParamNull(user, "当前人员没有操作权限");
		String[] planDetailIds = vo.getPlanDetailIds().split(",");
		List<TmsTransPlanBillDetailModel> planBillDetailModels = tmsTransPlanBillDetailMapper.findByIds(TmsTransPlanBillDetailModel.class,planDetailIds,null);
		if (ToolKits.isEmpty(planBillDetailModels)) {
			throw new PluginException("计划单明细不存在");
		}
		if (planBillDetailModels.stream().anyMatch(d->Integer.valueOf(20).equals(d.getStatus()))) {
			throw new PluginException("计划单明细已调度");
		}
		List<String> allPlanBillIds = planBillDetailModels.stream().map(TmsTransPlanBillDetailModel::getPlanBillId).distinct().collect(Collectors.toList());
		List<TmsTransPlanBillHeaderModel> planBillHeaderModels = tmsTransPlanBillHeaderMapper.findByIds(TmsTransPlanBillHeaderModel.class,allPlanBillIds.stream().toArray(),null);
		if (ToolKits.isEmpty(planBillHeaderModels)) {
			throw new PluginException("计划单不存在");
		}
		if (planBillHeaderModels.stream().anyMatch(header -> Integer.valueOf("20").equals(header.getStatus()))) {
			throw new PluginException(StrUtil.format("计划单{}已调度",
					planBillHeaderModels.stream().filter(header -> Integer.valueOf("20").equals(header.getStatus())).map(TmsTransPlanBillHeaderModel::getPlanBillId).collect(Collectors.joining(","))));
		}
		List<String> shipbillIds = planBillDetailModels.stream().map(TmsTransPlanBillDetailModel::getShipbillId).distinct().collect(Collectors.toList());

		shipbillIds.stream().forEach(id->{
			TmsShipbillHeaderModel headerModel = tmsShipbillHeaderMapper.findById(id,TmsShipbillHeaderModel.class);
			if (ToolKits.isEmpty(headerModel)) {
				throw new PluginException(StrUtil.format("运单{}不存在",id));
			}
			if (!DataDictionaryConstant.SHIPBILL_STATUS_REVIEW.equals(headerModel.getStatus())) {
				throw new PluginException(StrUtil.format("运单{}非待调度状态,不能调度",id));
			}
			if (!DataDictionaryConstant.SPLIT_ORDER_STATUS_UN.equals(headerModel.getSplitOrderStatus())) {
				throw new PluginException(StrUtil.format("运单{}已被拆单,不能调度", headerModel.getShipbillNo()));
			}
		});

		SysGroupQueryVO goodsQtyStatisticsVO = new SysGroupQueryVO();
		goodsQtyStatisticsVO.setShipbillIdList(shipbillIds);
		PendingDispatchShipbillQtyDTO shipbillQtyDTO = goodsQtyStatistics(goodsQtyStatisticsVO);

		PlanBillLoadingDTO planBillLoadingDTO = new PlanBillLoadingDTO();
		BeanUtil.copyProperties(shipbillQtyDTO,planBillLoadingDTO);

		planBillLoadingDTO.setPlanDetailIds(vo.getPlanDetailIds());

		List<TmsTransPlanBillDetailModel> transfinitePlanDetails = planBillDetailModels.stream().filter(detail->Integer.valueOf("1").equals(detail.getIsTransfinite())).collect(Collectors.toList());
		if (ToolKits.isNotEmpty(transfinitePlanDetails)) {
			long size = transfinitePlanDetails.stream().collect(Collectors.groupingBy(o -> o.getShipbillId())).size();
			planBillLoadingDTO.setTransfiniteBillNumber(Long.valueOf(size).intValue());
		} else {
			planBillLoadingDTO.setTransfiniteBillNumber(0);
		}
		if (planBillHeaderModels.stream().anyMatch(p->Integer.valueOf(1).equals(p.getIsWeigh()))) {
			planBillLoadingDTO.setIsWeigh(1);
			planBillLoadingDTO.setIsWeighName("是");
		} else {
			planBillLoadingDTO.setIsWeigh(0);
			planBillLoadingDTO.setIsWeighName("否");
		}
		List<Integer> carrierTypes = planBillHeaderModels.stream().map(TmsTransPlanBillHeaderModel::getCarrierType).distinct().collect(Collectors.toList());
		TmsTransPlanBillHeaderModel planBillHeaderModel = planBillHeaderModels.get(0);
		if (carrierTypes.size() == 1 && DataDictionaryConstant.LINE_CARRIER_TYPE_CYF.equals(carrierTypes.get(0))) {
			planBillLoadingDTO.setCarrierType(planBillHeaderModel.getCarrierType());
			planBillLoadingDTO.setCarrierId(planBillHeaderModel.getCarrierId());
			planBillLoadingDTO.setCarrierCode(planBillHeaderModel.getCarrierCode());
			planBillLoadingDTO.setCarrierName(planBillHeaderModel.getCarrierName());
		} else if (carrierTypes.size() == 1 && DataDictionaryConstant.LINE_CARRIER_TYPE_SJ.equals(carrierTypes.get(0))) {
			Map<Object, List<TmsTransPlanBillHeaderModel>> planBillHeaderMap = Maps.newHashMap();
			planBillHeaderMap = planBillHeaderModels.stream().collect(Collectors.groupingBy(o -> o.getDriverCode() + "_" + o.getVehicleCode()));

			if (1 == planBillHeaderMap.size()) {
				planBillLoadingDTO.setCarrierType(planBillHeaderModel.getCarrierType());
				planBillLoadingDTO.setDriverId(planBillHeaderModel.getDriverId());
				planBillLoadingDTO.setDriverCode(planBillHeaderModel.getDriverCode());
				planBillLoadingDTO.setDriverName(planBillHeaderModel.getDriverName());
				planBillLoadingDTO.setDriverPhoneNumber(planBillHeaderModel.getDriverPhoneNumber());
				planBillLoadingDTO.setVehicleId(planBillHeaderModel.getVehicleId());
				planBillLoadingDTO.setVehicleCode(planBillHeaderModel.getVehicleCode());
				planBillLoadingDTO.setVehicleName(planBillHeaderModel.getVehicleName());
				planBillLoadingDTO.setVehiclePlateNumber(planBillHeaderModel.getVehiclePlateNumber());
			}
		}
		planBillLoadingDTO.setOrderNos(planBillDetailModels.stream().map(TmsTransPlanBillDetailModel::getOrderNo).distinct().collect(Collectors.joining(",")));

		if (ObjectUtil.isNotEmpty(planBillLoadingDTO.getDriverId())) {
			VehiclePopupVO vehiclePopupVO = new VehiclePopupVO();
			List<Long> ids = Lists.newArrayList();
			ids.add(planBillLoadingDTO.getDriverId());
			vehiclePopupVO.setDriverIds(ids);
			vehiclePopupVO.setPageNum(1);
			vehiclePopupVO.setPageSize(999);
			RestMessage<Page<VehiclePopupDTO>> vehicleRestMessage = maindataTmsResource.popupVehicleExecute(vehiclePopupVO);
			if (vehicleRestMessage.isSuccess()) {
				Page<VehiclePopupDTO> vehiclePopupDTOPage = vehicleRestMessage.getData();
				List<VehiclePopupDTO> vehiclePopupDTOS = vehiclePopupDTOPage.getList();
				if (ObjectUtil.isNotEmpty(vehiclePopupDTOS)) {
					VehiclePopupDTO vehicleDTO = vehiclePopupDTOS.get(0);
					planBillLoadingDTO.setWeight(vehicleDTO.getWeight());
					planBillLoadingDTO.setVolume(vehicleDTO.getVolume());

					planBillLoadingDTO.setVehicleTypeId(vehicleDTO.getVehicleTypeId());
					planBillLoadingDTO.setVehicleTypeCode(vehicleDTO.getVehicleTypeCode());
					planBillLoadingDTO.setVehicleTypeName(vehicleDTO.getVehicleTypeName());

					planBillLoadingDTO.setVehicleAscription(vehicleDTO.getVehicleAscription());
					planBillLoadingDTO.setVehicleAscriptionName(vehicleDTO.getVehicleAscriptionName());
					planBillLoadingDTO.setAffiliationId(vehicleDTO.getAffiliationId());
					planBillLoadingDTO.setAffiliationCode(vehicleDTO.getAffiliationCode());
					planBillLoadingDTO.setAffiliationName(vehicleDTO.getAffiliationName());

					planBillLoadingDTO.setVehicleAffiliationId(vehicleDTO.getAffiliationId());
					planBillLoadingDTO.setVehicleAffiliationCode(vehicleDTO.getAffiliationCode());
					planBillLoadingDTO.setVehicleAffiliationName(vehicleDTO.getAffiliationName());

					planBillLoadingDTO.setVehicleTypeCategory(vehicleDTO.getTypeCategory());
					planBillLoadingDTO.setVehicleTypeCategoryName(vehicleDTO.getTypeCategoryName());
				}
			}
		}
		PlanBillLoadingDTO calc = calcItemWeightVolume(planBillDetailModels);
		planBillLoadingDTO.setTotalPieceQty(calc.getTotalPieceQty());
		planBillLoadingDTO.setTotalWeightQty(calc.getTotalWeightQty());
		planBillLoadingDTO.setTotalVolumeQty(calc.getTotalVolumeQty());
		return planBillLoadingDTO;
	}

	public PlanBillLoadingDTO calcItemWeightVolume(List<TmsTransPlanBillDetailModel> transfinitePlanDetails) {
		PlanBillLoadingDTO dto = new PlanBillLoadingDTO();
		BigDecimal totalPieceQty = BigDecimal.ZERO;
		BigDecimal totalWeightQty = BigDecimal.ZERO;
		BigDecimal totalVolumeQty = BigDecimal.ZERO;
		Map<Long,ItemCheckDTO> itemMap = Maps.newHashMap();
		for (TmsTransPlanBillDetailModel detailModel:transfinitePlanDetails) {
			totalPieceQty = NumberUtil.add(totalPieceQty,detailModel.getPlanPcs());
			ItemCheckDTO rsItemInfo = itemMap.get(detailModel.getItemId());
			if (ToolKits.isEmpty(rsItemInfo)) {
				ItemCheckVO itemCheckVO = new ItemCheckVO();
				itemCheckVO.setItemId(detailModel.getItemId());
				RestMessage<ItemCheckDTO> restMessage3 = maindataTmsResource.getItem(itemCheckVO);
				if (!restMessage3.isSuccess()) {
					throw new RuntimeException("取商品资料信息失败:" + restMessage3.getMessage());
				}
				rsItemInfo = restMessage3.getData();
				itemMap.put(detailModel.getItemId(), rsItemInfo);
			}
			if (ToolKits.isEmpty(rsItemInfo)) {
				continue;
			}
			totalWeightQty = NumberUtil.add(totalWeightQty,detailModel.getPlanPcs().multiply(rsItemInfo.getWeight()));
			totalVolumeQty = NumberUtil.add(totalVolumeQty,detailModel.getPlanPcs().multiply(rsItemInfo.getVolume()));
		}
		dto.setTotalWeightQty(totalWeightQty);
		dto.setTotalVolumeQty(totalVolumeQty);
		return dto;
	}

	@Transactional(rollbackFor = Exception.class)
	public void planDispatch(List<PlanDispatchVO> vos, String...isAudit) {
		ToolKits.isParamNull(vos, "计划调度请求不为空");

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

		if (vos.stream().anyMatch(vo->ToolKits.isEmpty(vo.getLoadingBillHeaderVO()))) {
			throw new PluginException("派车单信息不为空");
		}
		if (vos.stream().anyMatch(vo->ToolKits.isEmpty(vo.getPlanDetailIds()))) {
			throw new PluginException("计划单明细信息不为空");
		}

		for (PlanDispatchVO vo:vos) {
			LoadingBillHeaderVO loadingBillHeader = vo.getLoadingBillHeaderVO();
			List<LoadingBillDetailVO> loadingBillDetails = Lists.newArrayList();
			String[] planDetailIds = vo.getPlanDetailIds().split(",");
			List<TmsTransPlanBillDetailModel> allPlanBillDetailModels = tmsTransPlanBillDetailMapper.findByIds(TmsTransPlanBillDetailModel.class,planDetailIds,null);
			if (ToolKits.isEmpty(allPlanBillDetailModels)) {
				throw new PluginException("计划单明细不存在");
			}
			if (allPlanBillDetailModels.stream().anyMatch(d->!Integer.valueOf(10).equals(d.getStatus()))) {
				throw new PluginException("计划单明细已调度");
			}
			List<String> allPlanBillIds = allPlanBillDetailModels.stream().map(TmsTransPlanBillDetailModel::getPlanBillId).distinct().collect(Collectors.toList());

            log.info("调度的计划单:{}", JSONObject.toJSONString(allPlanBillIds));
			for (String planBillId:allPlanBillIds) {
				TmsTransPlanBillHeaderModel planBillHeaderModel = tmsTransPlanBillHeaderMapper.findById(planBillId,TmsTransPlanBillHeaderModel.class);
				if (ToolKits.isEmpty(planBillHeaderModel)) {
					throw new PluginException(StrUtil.format("计划单{}不存在",planBillId));
				}
				if (Integer.valueOf("20").equals(planBillHeaderModel.getStatus())) {
					throw new PluginException(StrUtil.format("计划单{}已调度",planBillHeaderModel.getPlanBillId()));
				}

				PlanBillDetailQueryVO detailQueryVO = new PlanBillDetailQueryVO();
				detailQueryVO.setPlanBillId(planBillId);
				detailQueryVO.setIds(Arrays.stream(planDetailIds).collect(Collectors.toList()));
				detailQueryVO.setIsDispatch("1");
				List<PlanBillDetailDTO> planBillDetailDTOList = tmsTransPlanBillDetailMapper.queryPlanBillDetail(detailQueryVO);
				if (ToolKits.isEmpty(planBillDetailDTOList)) {
					throw new PluginException("计划单明细已调度");
				}
				Map<Object, List<PlanBillDetailDTO>> shipbillMap = Maps.newHashMap();
				shipbillMap = planBillDetailDTOList.stream().collect(Collectors.groupingBy(o ->o.getShipbillId()));
				for (Object key:shipbillMap.keySet()) {
					List<PlanBillDetailDTO> oneShipBillPlanBillDetailDTOS = shipbillMap.get(key);
					List<String> dispatchShipbillDetailIds = oneShipBillPlanBillDetailDTOS.stream().map(PlanBillDetailDTO::getShipbillDetailId).collect(Collectors.toList());

					TmsShipbillHeaderModel headerModel = tmsShipbillHeaderMapper.findById(oneShipBillPlanBillDetailDTOS.get(0).getShipbillId(),TmsShipbillHeaderModel.class);
					if (ToolKits.isEmpty(headerModel)) {
						throw new PluginException(StrUtil.format("运单{}不存在",oneShipBillPlanBillDetailDTOS.get(0).getShipbillId()));
					}
					if (!DataDictionaryConstant.SHIPBILL_STATUS_REVIEW.equals(headerModel.getStatus())) {
						throw new PluginException(StrUtil.format("运单{}非待调度状态,不能调度",headerModel.getShipbillNo()));
					}
					if (!DataDictionaryConstant.SPLIT_ORDER_STATUS_UN.equals(headerModel.getSplitOrderStatus())) {
						throw new PluginException(StrUtil.format("运单{}已被拆单,不能调度", headerModel.getShipbillNo()));
					}

					Criteria criteriaShipbillDetail = Criteria.forClass(TmsShipbillDetailModel.class);
					Restriction r1 = Restrictions.eq(TmsShipbillDetailModel::getShipbillId, headerModel.getShipbillId());
					Restriction r2 = Restrictions.notIn(TmsShipbillDetailModel::getId, dispatchShipbillDetailIds.stream().toArray());
					Restriction r3 = Restrictions.eq(TmsShipbillDetailModel::getEnterpriseId, user.getEnterpriseId());
					criteriaShipbillDetail.setRestriction(Restrictions.and(r1, r2,r3));
					List<TmsShipbillDetailModel> noDispatchShipbillDetailModels = tmsShipbillDetailMapper.findByCriteria(criteriaShipbillDetail);

					if (ToolKits.isEmpty(noDispatchShipbillDetailModels)) {
						LoadingBillDetailVO detailVO = new LoadingBillDetailVO();
						detailVO.setShipbillId(headerModel.getShipbillId());
						loadingBillDetails.add(detailVO);
					} else {
						SplitVO splitVO = new SplitVO();
						splitVO.setShipbillId(headerModel.getShipbillId());
						List<SplitGoodsListVO> splitGoodsList = Lists.newArrayList();

						SplitGoodsListVO noDispatchGoods = new SplitGoodsListVO();
						List<SplitGoodsDetailVO> noDispatchShipbillDetails = Lists.newArrayList();
						noDispatchShipbillDetailModels.stream().forEach(shipbillDetail-> {
							SplitGoodsDetailVO detailVO = BeanUtil.copyProperties(shipbillDetail,SplitGoodsDetailVO.class);
							noDispatchShipbillDetails.add(detailVO);
						});
						noDispatchGoods.setSplitGoodsDetailVOList(noDispatchShipbillDetails);
						splitGoodsList.add(noDispatchGoods);

						SplitGoodsListVO dispatchGoods = new SplitGoodsListVO();
						List<SplitGoodsDetailVO> dispatchShipbillDetails = Lists.newArrayList();
						dispatchShipbillDetailIds.stream().forEach(id-> {
							TmsShipbillDetailModel detailModel = tmsShipbillDetailMapper.findById(id,TmsShipbillDetailModel.class);
							SplitGoodsDetailVO detailVO = BeanUtil.copyProperties(detailModel,SplitGoodsDetailVO.class);
							dispatchShipbillDetails.add(detailVO);
						});
						dispatchGoods.setSplitGoodsDetailVOList(dispatchShipbillDetails);
						splitGoodsList.add(dispatchGoods);

						splitVO.setSplitGoodsList(splitGoodsList);
						autoGoodsSplit(splitVO,user,DateUtil.date(),"planDisSplit");

						LoadingBillDetailVO detailVO = new LoadingBillDetailVO();
						oneShipBillPlanBillDetailDTOS.stream().forEach(detail->{
							String shipbillId = updatePlanDetail(detail.getShipbillNo(),detail.getShipbillDetailId(),detail.getId(),user);
							detailVO.setShipbillId(shipbillId);
						});
						loadingBillDetails.add(detailVO);

						Criteria planDetailCriteria = Criteria.forClass(TmsTransPlanBillDetailModel.class);
						noDispatchShipbillDetailModels.stream().forEach(detail->{
							Restriction r13 = Restrictions.eq(TmsTransPlanBillDetailModel::getShipbillId, detail.getShipbillId());
							Restriction r14 = Restrictions.eq(TmsTransPlanBillDetailModel::getShipbillDetailId, detail.getId());
							planDetailCriteria.setRestriction(Restrictions.and(r13,r14));
							List<TmsTransPlanBillDetailModel> planBillDetailModels = tmsTransPlanBillDetailMapper.findByCriteria(planDetailCriteria);

							List<TmsTransPlanBillDetailModel> otherPlanBillDetailModels = planBillDetailModels.stream().filter(planDetail->!planBillId.equals(planDetail.getPlanBillId())).collect(Collectors.toList());
							if (ToolKits.isNotEmpty(otherPlanBillDetailModels)) {
								updatePlanDetail(detail.getShipbillNo(),detail.getId(),otherPlanBillDetailModels.get(0).getId(),user);
							}
							List<TmsTransPlanBillDetailModel> selfPlanBillDetailModels = planBillDetailModels.stream().filter(planDetail->planBillId.equals(planDetail.getPlanBillId())).collect(Collectors.toList());
							if (ToolKits.isNotEmpty(selfPlanBillDetailModels)) {
								tmsTransPlanBillDetailMapper.deleteById(selfPlanBillDetailModels.get(0).getId(),TmsTransPlanBillDetailModel.class);
							}
						});
					}
				}
				Criteria criteriaPlanDetail = Criteria.forClass(TmsTransPlanBillDetailModel.class);
				Restriction r11 = Restrictions.in(TmsTransPlanBillDetailModel::getId, planDetailIds);
				Restriction r12 = Restrictions.eq(TmsTransPlanBillDetailModel::getEnterpriseId, user.getEnterpriseId());
				Restriction r13 = Restrictions.eq(TmsTransPlanBillDetailModel::getPlanBillId, planBillId);
				criteriaPlanDetail.setRestriction(Restrictions.and(r11, r12,r13));
				Map<String, Object> mapPlanDetail = Maps.newHashMap();
				mapPlanDetail.put("updateperson", user.getNickname());
				mapPlanDetail.put("updatetime", DateUtil.date());
				mapPlanDetail.put("status", 20);
				tmsTransPlanBillDetailMapper.updateMapByCriteria(mapPlanDetail,criteriaPlanDetail);

				detailQueryVO.setPlanBillId(planBillId);
				detailQueryVO.setIsDispatch("1");
				detailQueryVO.setIds(null);
				List<PlanBillDetailDTO> shipbillList = tmsTransPlanBillDetailMapper.queryPlanBillDetail(detailQueryVO);
				if (ToolKits.isNotEmpty(shipbillList) ) {
					planBillHeaderModel.setStatus(15);
				} else {
					planBillHeaderModel.setStatus(20);
				}
				BigDecimal actualTotalPcs = planBillDetailDTOList.stream().map(PlanBillDetailDTO::getPcs).reduce(BigDecimal.ZERO, NumberUtil::add);
				planBillHeaderModel.setActualTotalPcs(actualTotalPcs.longValue());
				planBillHeaderModel.setActualTotalVehicleNumber(planBillHeaderModel.getPlanTotalVehicleNumber());

				planBillHeaderModel.setUpdatetime(DateUtil.date());
				planBillHeaderModel.setUpdateperson(user.getNickname());
				tmsTransPlanBillHeaderMapper.update(planBillHeaderModel);
			}

			PendingDispatchVO dispatchVO = new PendingDispatchVO();
			dispatchVO.setLoadingBillHeaderVO(loadingBillHeader);
			dispatchVO.setLoadingBillDetailVO(loadingBillDetails);

            if (ToolKits.isNotEmpty(isAudit) && "Y".equals(isAudit[0])) {
                autoDispatch(dispatchVO,user,DateUtil.date(),"planDis",isAudit);
            } else {
                autoDispatch(dispatchVO,user,DateUtil.date(),"planDis");
            }
		}
	}

	public String updatePlanDetail(String shipBillNo,String shipBillDetailId,String planDetailId,UserEntity user) {
		Criteria criteriaShipbillDetail = Criteria.forClass(TmsShipbillDetailModel.class);
		Restriction r1 = Restrictions.eq(TmsShipbillDetailModel::getFatherId, shipBillDetailId);
		Restriction r2 = Restrictions.eq(TmsShipbillDetailModel::getEnterpriseId, user.getEnterpriseId());
		criteriaShipbillDetail.setRestriction(Restrictions.and(r1, r2));
		List<TmsShipbillDetailModel> newShipbillDetailModels = tmsShipbillDetailMapper.findByCriteria(criteriaShipbillDetail);
		if (ToolKits.isEmpty(newShipbillDetailModels)) {
			throw new PluginException(StrUtil.format("运单{}计划调度时,拆单后,新运单明细不存在",shipBillNo));
		}
		TmsShipbillDetailModel newShipBillDetail = newShipbillDetailModels.get(0);
		Map<String, Object> mapPlanDetail = Maps.newHashMap();
		mapPlanDetail.put("updateperson", user.getNickname());
		mapPlanDetail.put("updatetime", DateUtil.date());
		mapPlanDetail.put("shipbillId", newShipBillDetail.getShipbillId());
		mapPlanDetail.put("shipbillNo", newShipBillDetail.getShipbillNo());
		mapPlanDetail.put("shipbillDetailId", newShipBillDetail.getId());

		tmsTransPlanBillDetailMapper.updateMapById(planDetailId,mapPlanDetail,TmsTransPlanBillDetailModel.class);

		newShipBillDetail.setPlanStatus(10);
		tmsShipbillDetailMapper.update(newShipBillDetail);
		return newShipbillDetailModels.get(0).getShipbillId();
	}

    public void planDispatchReview(List<PlanDispatchVO> vos) {
        planDispatch(vos, "Y");
    }

	public PlanGroupQueryRsDTO planDispatchGroupQuery(PlanGroupQueryVO vo) {
		ToolKits.isParamNull(vo, "分组查询请求不为空");
		UserEntity user = PlgFxUsrUtils.getUserEntity();
		ToolKits.isParamNull(user, "当前人员没有操作权限");

		PlanGroupQueryRsDTO sysGroupQueryRsDTO = new PlanGroupQueryRsDTO();

		vo.setUserType(user.getUserType());
		vo.setEnterpriseId(user.getEnterpriseId());
		if (ObjectUtil.equal(user.getUserType(), BussinessConstant.USER_TYPE_ZY)) {
			// 自有账号
			vo.setDepts(user.getDepts().stream().toArray(String[]::new));
			if (BussinessConstant.USER_DEPARTMENT_AUTH_Y.equals(user.getOwnedAllDataAuthFlag())) {
				vo.setIsDept(StatusConstant.IS_DEPT_YES);
			} else {
				vo.setIsDept(StatusConstant.IS_DEPT_NO);
				// 其它权限
				// 货主
				vo.setConsignors(user.getConsignors().stream().toArray(Long[]::new));
			}
		} else {
			ToolKits.isParamNull(user, "当前人员没有操作权限");
		}

		List<String> groupDimensions = vo.getGroupDimensionList();
		if (ToolKits.isNotEmpty(vo.getPlanDetailIds())) {
			vo.setPlanDetailIdList(Arrays.stream(vo.getPlanDetailIds().split(",")).collect(Collectors.toList()));
		}
		List<PlanGroupQueryDTO> sysGroupQueryList = Lists.newArrayList();
		// 数据字典翻译数据集合
		List<SysRefdatadModel> dicData = convertorUtil.getDictionary(new String[] {
				DataDictionaryConstant.WHETHER,
				DataDictionaryConstant.GROUP_DISPATCH_PLAN
		});
		String groupItems = null;
		List<SysRefdatadModel> groupByItems = dicData.stream().filter(data -> DataDictionaryConstant.GROUP_DISPATCH_PLAN.equals(data.getObjectcode())).collect(Collectors.toList());
		if (ToolKits.isNotEmpty(groupDimensions)) {
			// 页面勾选的分组项目
			groupByItems = groupByItems.stream().filter(item -> groupDimensions.contains(item.getCode())).collect(Collectors.toList());
			groupByItems = groupByItems.stream().sorted(Comparator.comparing(SysRefdatadModel::getSortnum)).collect(Collectors.toList());
			String groupItem = groupByItems.stream().map(SysRefdatadModel::getCode).collect(Collectors.joining(","));
			groupItems = "t1." + groupByItems.stream().map(SysRefdatadModel::getCode).collect(Collectors.joining(",t1."));
			String groupItemName = groupByItems.stream().map(SysRefdatadModel::getName).collect(Collectors.joining(" "));
			vo.setQueryGroupItems(groupItems + ",");
			vo.setGroupByItems(groupItems);
			sysGroupQueryList = tmsTransPlanBillDetailMapper.planGroupQuery(vo);
			sysGroupQueryList.stream().forEach(oneDTO -> {
				setPlanGroupInfo(oneDTO, dicData,groupItemName);
				oneDTO.setGroupDimensionList(groupDimensions);
				oneDTO.setGroupItem(groupItem);
			});
			String[] groupItemNames = groupItemName.split(" ");
			sysGroupQueryRsDTO.setGroupItemNames(Arrays.stream(groupItemNames).collect(Collectors.toList()));

		} else {
			throw new PrologException("分组类型条件,请选择一个");
		}
		sysGroupQueryRsDTO.setGroupQueryDTOS(sysGroupQueryList);
		return sysGroupQueryRsDTO;
	}

	public void setPlanGroupInfo(PlanGroupQueryDTO groupQueryDTO, List<SysRefdatadModel> dicData,String groupItemName) {
		// 分组名称
		List<String> groupNames = Lists.newArrayList();
		Field[] fields = groupQueryDTO.getClass().getFields();

		for (Field field : fields) {
			try {
			Object val = field.get(groupQueryDTO);
			if (ToolKits.isNotEmpty(val) && "isTransfinite".equals(field.getName())) {
				groupNames.add("超限" +ConvertorUtil.getName(dicData, DataDictionaryConstant.WHETHER, String.valueOf(val)));
			} else if (ToolKits.isNotEmpty(val)) {
				groupNames.add((String) val);
			}
			} catch (Exception e) {}
		}

		if (ToolKits.isNotEmpty(groupNames)) {
			groupQueryDTO.setGroupName(groupNames.stream().collect(Collectors.joining(",")));
		} else {
			groupQueryDTO.setGroupName(groupItemName);
		}
		groupQueryDTO.setId(ToolKits.getUUID());

		String ids = groupQueryDTO.getPlanDetailIds();
		if (ToolKits.isEmpty(ids)) {
			return;
		}
		List<TmsTransPlanBillDetailModel> sysGroupShipQueryList = tmsTransPlanBillDetailMapper.findByIds(TmsTransPlanBillDetailModel.class,ids.split(","),null);
		if (ToolKits.isEmpty(sysGroupShipQueryList)) {
			return;
		}
		// 收货方数
		groupQueryDTO.setConsigneeQty(sysGroupShipQueryList.stream().filter(p->ToolKits.isNotEmpty(p.getConsigneeName())).map(TmsTransPlanBillDetailModel::getConsigneeName).distinct().collect(Collectors.toList()).size());
		// 承运单位数
		groupQueryDTO.setCarrierUnitQty(sysGroupShipQueryList.stream().filter(p->ToolKits.isNotEmpty(p.getCarrierName())).map(TmsTransPlanBillDetailModel::getCarrierName).distinct().collect(Collectors.toList()).size());
		// 计划总车数
		List<String> planBillIds = sysGroupShipQueryList.stream().map(TmsTransPlanBillDetailModel::getPlanBillId).distinct().collect(Collectors.toList());
		List<TmsTransPlanBillHeaderModel> planBillHeaderModels = tmsTransPlanBillHeaderMapper.findByIds(TmsTransPlanBillHeaderModel.class,planBillIds.stream().toArray(), null);
		if (ToolKits.isEmpty(planBillHeaderModels)) {
			return;
		}
		groupQueryDTO.setPlanTotalVehicleQty(planBillHeaderModels.stream().filter(p->ToolKits.isNotEmpty(p.getPlanTotalVehicleNumber())).map(h->BigDecimal.valueOf(h.getPlanTotalVehicleNumber().longValue())).reduce(BigDecimal.ZERO,BigDecimal::add).intValue());
		// 超限单数
		groupQueryDTO.setTransfiniteQty(sysGroupShipQueryList.stream().filter(p->DataDictionaryConstant.WHETHER_YES.equals(p.getIsTransfinite())).collect(Collectors.toList()).size());
		// 总计划单数
		groupQueryDTO.setTotalPlanBillQty(planBillIds.size());
		// 总运单数
		groupQueryDTO.setTotalShipbillQty(sysGroupShipQueryList.stream().map(TmsTransPlanBillDetailModel::getShipbillNo).distinct().collect(Collectors.toList()).size());
		if (ToolKits.isNotEmpty(groupQueryDTO.getPlanDetailIds())) {
			groupQueryDTO.setLoadingPlanDetailQty(groupQueryDTO.getPlanDetailIds().split(",").length);
		}

		PlanBillLoadingDTO calc = calcItemWeightVolume(sysGroupShipQueryList);
		groupQueryDTO.setTotalWeight(calc.getTotalWeightQty());
		groupQueryDTO.setTotalVolume(calc.getTotalVolumeQty());
	}
}
