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

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.prolog.common.util.DateUtils;
import com.prolog.common.util.ToolKits;
import com.prolog.framework.common.message.RestMessage;
import com.prolog.framework.core.exception.BizException;
import com.prolog.framework.core.exception.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.app.constant.BussinessConstant;
import com.prolog.rdc.tms.app.constant.DataDictionaryConstant;
import com.prolog.rdc.tms.app.constant.SeriaNnumberConstant;
import com.prolog.rdc.tms.app.constant.StatusConstant;
import com.prolog.rdc.tms.app.constant.enums.*;
import com.prolog.rdc.tms.app.dao.mapper.*;
import com.prolog.rdc.tms.app.model.dto.business.MatchCarrierStrategyDTO;
import com.prolog.rdc.tms.app.model.dto.business.PendingDisPackageDTO;
import com.prolog.rdc.tms.app.model.dto.business.PendingDisShipBillDtlDTO;
import com.prolog.rdc.tms.app.model.dto.business.PendingDispatchQueryDTO;
import com.prolog.rdc.tms.app.model.entity.*;
import com.prolog.rdc.tms.app.model.vo.business.*;
import com.prolog.rdc.tms.app.proxy.MainDataProxy;
import com.prolog.rdc.tms.app.service.business.*;
import com.prolog.rdc.tms.app.util.MessageUtil;
import com.prolog.rdc.tms.app.util.PublicMethods;
import com.prolog.rdc.tms.app.util.StrategyUtil;
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.StrategyBusinessMatchingDTO;
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.fleetManagement.VehicleAndDriverDTO;
import com.prolog.rdc.tms.model.dto.message.SendMessageDTO;
import com.prolog.rdc.tms.model.entity.SysParamConfigModel;
import com.prolog.rdc.tms.model.enums.MessageOrderTypeEnum;
import com.prolog.rdc.tms.model.enums.MessageTypeEnum;
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.basicData.ItemCheckVO;
import com.prolog.rdc.tms.model.vo.fleetManagement.VehicleAndVehicleVO;
import com.prolog.rdc.tms.rmi.feign.MaindataFeign;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.ArrayUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * 调度管理-待调度实现层
 *
 * @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 MaindataFeign maindataTmsResource;

	@Autowired
	private ShipbillNodeTrackingService shipbillNodeTrackingService;

	@Autowired
	private ShipbillOperateLogService shipbillOperateLogService;

	@Autowired
	private SendCarService sendCarService;

	@Autowired
	private TrailerService trailerService;

	@Autowired
	private TmsLoadingBillHeaderMapper tmsLoadingBillHeaderMapper;

	@Autowired
	private TmsLoadingBillDetailMapper tmsLoadingBillDetailMapper;

	@Autowired
	private TmsShipbillTransportLogMapper tmsShipbillTransportLogMapper;

	@Autowired
	private LoadingBillService loadingBillService;

	@Autowired
	private MainDataProxy mainDataProxy;

	@Autowired
	private StrategyUtil strategyUtil;

	@Autowired
	private TmsTransPlanBillDetailMapper tmsTransPlanBillDetailMapper;

	@Autowired
	private TmsTransPlanBillHeaderMapper tmsTransPlanBillHeaderMapper;

	/**
	 * 待调度查询
	 *
	 * @param pendingDispatchVO
	 * @return
	 */
	@SuppressWarnings("resource")
	@Override
	public Page<PendingDispatchQueryDTO> dispatchShipbillQuery(PendingDispatchQueryVO pendingDispatchVO) {
		ToolKits.isParamNull(pendingDispatchVO, "待调度查询请求不为空");
		ToolKits.isParamNull(pendingDispatchVO.getPageNum(), "当前页码不为空");
		ToolKits.isParamNull(pendingDispatchVO.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, "当前人员没有操作权限");
		}
		pendingDispatchVO.setDeliveryMethodType(DataDictionaryConstant.DELIVERY_METHOD_TYPE_SEND);
		pendingDispatchVO.setEnterpriseId(user.getEnterpriseId());

		pendingDispatchVO.setUserType(user.getUserType());
		// 权限控制
		if (ObjectUtil.equal(user.getUserType(), BussinessConstant.USER_TYPE_ZY)) {
			if (user.getOwnedAllDataAuthFlag().equals(BussinessConstant.USER_DEPARTMENT_AUTH_Y)) {
				pendingDispatchVO.setDepts(user.getDepts().stream().toArray(String[]::new));
				pendingDispatchVO.setIsDept(StatusConstant.IS_DEPT_YES);
			} else {
				pendingDispatchVO.setDepts(user.getDepts().stream().toArray(String[]::new));
				pendingDispatchVO.setIsDept(StatusConstant.IS_DEPT_NO);
				// 货主
				pendingDispatchVO.setConsignors(user.getConsignors().stream().toArray(Long[]::new));
				// 客户
				pendingDispatchVO.setCustomers(user.getCustomers().stream().toArray(Long[]::new));
				// 供应商
				pendingDispatchVO.setSuppliers(user.getSuppliers().stream().toArray(Long[]::new));
				// 仓库
				pendingDispatchVO.setWsarehouses(user.getWarehouses().stream().toArray(Long[]::new));
			}
		} else if (ObjectUtil.equal(user.getUserType(), BussinessConstant.USER_TYPE_CYS)) {

			pendingDispatchVO.setUnitId(Long.valueOf(user.getLoginUserCompanyInfo().getId()));
		} else {
			throw new PrologException("当前人员没有操作权限！");
		}

		PageUtils.startPage(pendingDispatchVO.getPageNum(), pendingDispatchVO.getPageSize());
		List<PendingDispatchQueryDTO> tmsShipbillHeaderModels = tmsShipbillHeaderMapper.dispatchShipbillQuery(pendingDispatchVO);

		// 订单业务类型
		List<Map<String, Object>> data2 = Lists.newArrayList();
		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();
		}

		// 响应对象集合
		for (PendingDispatchQueryDTO pendingDispatchDTO : tmsShipbillHeaderModels) {

			pendingDispatchDTO.setOrderBusinessTypeName(PublicMethods.change(data2, String.valueOf(pendingDispatchDTO.getOrderBusinessType())));
			pendingDispatchDTO.setOrderDate(pendingDispatchDTO.getOrderDate());

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

			// 发货方类型
			if (DataDictionaryConstant.SHIPPER_TYPE_KH.equals(pendingDispatchDTO.getShipperType())) {
				// 发货方名称
				pendingDispatchDTO.setShipperName(pendingDispatchDTO.getShipperUnitName() + DataDictionaryConstant.Line_SYMBOL + pendingDispatchDTO.getShipperName());
			}

			// 收货方电话
			StringBuffer tel = new StringBuffer();
			if (ToolKits.isNotEmpty(pendingDispatchDTO.getConsigneePhoneNumber())) {
				tel.append(pendingDispatchDTO.getConsigneePhoneNumber());
			} else if (ToolKits.isNotEmpty(pendingDispatchDTO.getConsigneeLandlineNumber())) {
				tel.append(pendingDispatchDTO.getConsigneeLandlineNumber());
			}
			if (ToolKits.isNotEmpty(tel.toString())) {
				pendingDispatchDTO.setConsigneeTel(tel.toString());
			}
			// 收货方类型
			if (DataDictionaryConstant.CONSIGNEE_TYPE_KH.equals(pendingDispatchDTO.getConsigneeType())) {
				// 收货方名称
				pendingDispatchDTO.setConsigneeName(pendingDispatchDTO.getConsigneeUnitName() + DataDictionaryConstant.Line_SYMBOL + pendingDispatchDTO.getConsigneeName());
			} else if (DataDictionaryConstant.CONSIGNEE_TYPE_GYS.equals(pendingDispatchDTO.getConsigneeType())) {
				// 收货方名称
				pendingDispatchDTO.setConsigneeName(pendingDispatchDTO.getConsigneeName() + DataDictionaryConstant.Line_SYMBOL + pendingDispatchDTO.getShipperName());
			}

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

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

			List<PendingDisPackageDTO> loadingPackageDTOList = Lists.newArrayList();
			for (TmsShipbillPackageModel packageModel : tmsShipbillPackageModels) {
				PendingDisPackageDTO packageDTO = new PendingDisPackageDTO();
				BeanUtils.copyProperties(packageModel, packageDTO);
				loadingPackageDTOList.add(packageDTO);
			}
			pendingDispatchDTO.setPendingDisPackageDTOS(loadingPackageDTOList);

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

				List<PendingDisShipBillDtlDTO> detailDTOList = Lists.newArrayList();
				// 匹配业务规则
				TmsShipbillHeaderModel model = new TmsShipbillHeaderModel();
				BeanUtils.copyProperties(pendingDispatchDTO, model);
				StrategyBusinessMatchingDTO businessData = strategyUtil.shipbillMatchBusinessRule(model, tmsShipbillDetailModels);
				if (ToolKits.isNotEmpty(businessData) && businessData.getApplyPcsSelect().intValue() == 1) {
					pendingDispatchDTO.setShowApplyPcs(businessData.getApplyPcsEnable());
				}
				if (ToolKits.isNotEmpty(businessData) && businessData.getInventoryCheckSelect().intValue() == 1) {
					pendingDispatchDTO.setInventoryCheck(businessData.getInventoryCheckEnable());
				}
				for (TmsShipbillDetailModel detailModel : tmsShipbillDetailModels) {
					PendingDisShipBillDtlDTO detailDTO = new PendingDisShipBillDtlDTO();
					BeanUtils.copyProperties(detailModel, detailDTO);
					detailDTOList.add(detailDTO);
				}
				// 商品信息
				pendingDispatchDTO.setShipBillDetailDTOS(detailDTOList);
			}
			if (ToolKits.isEmpty(pendingDispatchDTO.getShowApplyPcs())) {
				pendingDispatchDTO.setShowApplyPcs(Integer.valueOf(10));
			}
			if (ToolKits.isEmpty(pendingDispatchDTO.getInventoryCheck())) {
				pendingDispatchDTO.setInventoryCheck(Integer.valueOf(10));
			}
		}
		// 分页重组
		return PageUtils.getPage(tmsShipbillHeaderModels);
	}

	/**
	 * 调度
	 *
	 * @param dispatchVO
	 * @return
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void dispatch(PendingDispatchVO dispatchVO) {
		ToolKits.isParamNull(dispatchVO, "运单调度请求不为空");
		ToolKits.isParamNull(dispatchVO.getCarrierType(), "承运方类型不为空");
		ToolKits.isParamNull(dispatchVO.getDisShipbillVOS(), "运单不为空");

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

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

		// 调到给司机时，若司机未事先录入系统，自动将司机、车辆信息录入系统
		if (DataDictionaryConstant.LINE_CARRIER_TYPE_SJ.equals(dispatchVO.getCarrierType()) && ToolKits.isEmpty(dispatchVO.getDriverId())) {
			ToolKits.isParamNull(dispatchVO.getDriverName(), "司机名称不为空");
			ToolKits.isParamNull(dispatchVO.getDriverPhoneNumber(), "司机手机号不为空");
			ToolKits.isParamNull(dispatchVO.getVehiclePlateNumber(), "车牌号不为空");
			if (dispatchVO.getDriverName().split(",").length == 1) {
				// 校验司机车辆信息
				VehicleAndVehicleVO vehicleAndVehicleVO = new VehicleAndVehicleVO();
				vehicleAndVehicleVO.setDriverName(dispatchVO.getDriverName());
				vehicleAndVehicleVO.setPhoneNumber(dispatchVO.getDriverPhoneNumber());
				vehicleAndVehicleVO.setVehiclePlateNumber(dispatchVO.getVehiclePlateNumber());
				vehicleAndVehicleVO.setVehicleAscription(dispatchVO.getVehicleAscription());
				RestMessage<VehicleAndDriverDTO> restMessage = maindataTmsResource.vehicleAutomaticExecute(vehicleAndVehicleVO);
				if (!restMessage.isSuccess()) {
					throw new ParameterException("司机车辆信息校验失败:" + restMessage.getMessage());
				}
				// 车辆司机信息
				VehicleAndDriverDTO vehicleAndDriverDTO = restMessage.getData();
				// 司机信息
				dispatchVO.setDriverId(String.valueOf(vehicleAndDriverDTO.getDriver().getDriverId()));
				dispatchVO.setDriverCode(vehicleAndDriverDTO.getDriver().getDriverCode());
				dispatchVO.setDriverName(vehicleAndDriverDTO.getDriver().getDriverName());
				dispatchVO.setDriverPhoneNumber(vehicleAndDriverDTO.getDriver().getDriverPhoneNumber());
				dispatchVO.setCarrierId(vehicleAndDriverDTO.getDriver().getAffiliationId());
				dispatchVO.setCarrierCode(vehicleAndDriverDTO.getDriver().getAffiliationCode());
				dispatchVO.setCarrierName(vehicleAndDriverDTO.getDriver().getAffiliationName());

				// 车辆信息
				dispatchVO.setVehicleId(vehicleAndDriverDTO.getVehicle().getVehicleId());
				dispatchVO.setVehicleCode(vehicleAndDriverDTO.getVehicle().getVehicleCode());
				dispatchVO.setVehicleName(vehicleAndDriverDTO.getVehicle().getVehicleName());
				dispatchVO.setVehiclePlateNumber(vehicleAndDriverDTO.getVehicle().getVehiclePlateNumber());
			}
		}

		String dispatchSelfpickHandleType = mainDataProxy.getSystemParamByCode(DispatchSelfPickHandleTypeEnum.ENUM_NAME);
		// 拆分后需要调度的运单
		List<PendingDisShipbillVO> pendingDisShipbillVOS = dispatchVO.getDisShipbillVOS();
		List<String> disShipbills = Lists.newArrayList();
		for (PendingDisShipbillVO disShipbillVO : pendingDisShipbillVOS) {
			// 首先，按商品申请数量拆分
			// 调度的商品明细
			List<PendingSplitDetailVO> dispatchDetails = Lists.newArrayList();
			// 不调度的商品明细
			List<PendingSplitDetailVO> noDispatchDetails = Lists.newArrayList();
			List<String> splitShipbills = Lists.newArrayList();
			if (ToolKits.isNotEmpty(disShipbillVO.getShipBillDetailDTOS())) {
				for (PendingSplitDetailVO itemVO : disShipbillVO.getShipBillDetailDTOS()) {
					if (ToolKits.isEmpty(itemVO.getPcs()) || ToolKits.isEmpty(itemVO.getInventoryPcs()) || ToolKits.isEmpty(itemVO.getApplyPcs())) {
						itemVO.setApplyPcs(0);
						noDispatchDetails.add(itemVO);
						continue;
					}
					if (itemVO.getApplyPcs().intValue() == 0) {
						noDispatchDetails.add(itemVO);
						continue;
					}
					if (itemVO.getApplyPcs().intValue() > itemVO.getPcs().intValue()) {
						throw new PrologException("商品申请数量不能大于商品数量");
					}
					if (DispatchSelfPickHandleTypeEnum.VALID.getCode().equals(dispatchSelfpickHandleType) || DispatchSelfPickHandleTypeEnum.VALID_AND_QTY.getCode().equals(dispatchSelfpickHandleType)) {
						if (disShipbillVO.getInventoryCheck().intValue() == 10) {
							if (itemVO.getApplyPcs().intValue() > itemVO.getInventoryPcs().intValue()) {
								throw new PrologException("商品申请数量不能大于库存数量");
							}
						}
					}
					if (itemVO.getApplyPcs().intValue() == itemVO.getPcs().intValue()) {
						dispatchDetails.add(itemVO);
						continue;
					}
					// 调度的商品明细
					PendingSplitDetailVO disItem = new PendingSplitDetailVO();
					BeanUtils.copyProperties(itemVO, disItem);
					disItem.setPcs(BigDecimal.valueOf(itemVO.getApplyPcs()));
					dispatchDetails.add(disItem);

					// 不调度的商品明细
					PendingSplitDetailVO noDisItem = new PendingSplitDetailVO();
					BeanUtils.copyProperties(itemVO, noDisItem);
					noDisItem.setPcs(BigDecimal.valueOf(itemVO.getPcs().intValue() - itemVO.getApplyPcs().intValue()));
//                    noDisItem.setInventoryPcs(itemVO.getInventoryPcs().intValue() - itemVO.getApplyPcs().intValue());
					BigDecimal inventoryPcs = NumberUtil.sub(itemVO.getInventoryPcs(), itemVO.getApplyPcs());
					inventoryPcs = NumberUtil.isGreater(inventoryPcs, BigDecimal.ZERO) ? inventoryPcs : BigDecimal.ZERO;
					noDisItem.setInventoryPcs(inventoryPcs.intValue());
					noDispatchDetails.add(noDisItem);
				}

				// 按商品拆分运单
				if (ToolKits.isNotEmpty(dispatchDetails) && ToolKits.isNotEmpty(noDispatchDetails)) {
					DispatchSplitVO splitVO = new DispatchSplitVO();
					splitVO.setShipbillId(disShipbillVO.getShipbillId());
					Map<String, List<PendingSplitDetailVO>> goodsMap = Maps.newHashMap();

					goodsMap.put("disReg", dispatchDetails);
					goodsMap.put("disRegNo", noDispatchDetails);

					splitVO.setSplitGoodsMap(goodsMap);
					// 拆分处理
					splitShipbills.addAll(goodsSplit(splitVO, date, user));
				}
			}

			if (ToolKits.isEmpty(splitShipbills)) {
				disShipbills.add(disShipbillVO.getShipbillId());
			} else {
				disShipbills.addAll(splitShipbills);
			}
		}
		// 拆分后的运单参加调度
		dispatchVO.setShipbillIds(disShipbills);
		autoDispatch(dispatchVO, user, date);

	}

	/**
	 * 调度
	 *
	 * @param dispatchVO
	 * @return
	 */
	@Override
	public void autoDispatch(PendingDispatchVO dispatchVO, UserEntity user, Date date) {
		log.info("实际调度处理运单:" + JSON.toJSONString(dispatchVO));
		// 装车单明细
		List<String> shipbillIds = dispatchVO.getShipbillIds();
		ToolKits.isParamNull(ToolKits.isEmpty(shipbillIds) || shipbillIds.size() == 0, "运单ID不为空");
		List<TmsShipbillHeaderModel> shipbillHeaderModels = tmsShipbillHeaderMapper.findByIds(TmsShipbillHeaderModel.class, shipbillIds.stream().toArray(String[]::new), null);
		if (ToolKits.isEmpty(shipbillHeaderModels)) {
			throw new PrologException("运单【" + shipbillIds.stream().collect(Collectors.joining(",")) + "】不存在");
		}

		Map<String, List<TmsShipbillHeaderModel>> shipbillHeaderMap = Maps.newHashMap();

		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));
				if (ToolKits.isEmpty(shipbillHeaderMap)) {
					throw new PrologException("运单【" + shipbillIds.stream().collect(Collectors.joining(",")) + "】不存在");
				}
			} else {
				shipbillHeaderMap.put("one_loadingBillHeader", shipbillHeaderModels);
			}
		} else {
			shipbillHeaderMap.put("one_loadingBillHeader", shipbillHeaderModels);
		}
		if (ToolKits.isEmpty(shipbillHeaderMap)) {
			throw new PrologException("运单【" + shipbillIds.stream().collect(Collectors.joining(",")) + "】不存在");
		}
		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(dispatchVO, loadingBillHeaderModel);

			if (user.getUserType().equals(BussinessConstant.USER_TYPE_ZY)) {
				loadingBillHeaderModel.setScheduleType(DataDictionaryConstant.SCHEDULE_TYPE_ZY);
			} else {
				loadingBillHeaderModel.setScheduleType(DataDictionaryConstant.SCHEDULE_TYPE_CYS);
			}
			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(dispatchVO.getDriverName());
			// 解析送货员
			String deliverymanName = this.getFirstStr(dispatchVO.getDeliverymanName());
			if (DataDictionaryConstant.LINE_CARRIER_TYPE_SJ.equals(dispatchVO.getCarrierType())) {
				// 解析司机ID
				String driverId = this.getFirstStr(dispatchVO.getDriverId());
				// 解析司机编号
				String driverCode = this.getFirstStr(dispatchVO.getDriverCode());
				// 解析司机手机号
				String phoneNumber = this.getFirstStr(dispatchVO.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(dispatchVO.getDriverId()));
				loadingBillHeaderModel.setViceDriverId(StrUtil.isBlank(viceDriverId) ? null : viceDriverId);
				String viceDriverCode = this.subArrToString(dispatchVO.getDriverCode());
				loadingBillHeaderModel.setViceDriverCode(StrUtil.isBlank(viceDriverCode) ? null : viceDriverCode);
				String viceDriverName = this.subArrToString(dispatchVO.getDriverName());
				loadingBillHeaderModel.setViceDriverName(StrUtil.isBlank(viceDriverName) ? null : viceDriverName);
				String vicephoneNumber = this.subArrToString(dispatchVO.getDriverPhoneNumber());
				loadingBillHeaderModel.setViceDriverPhoneNumber(StrUtil.isBlank(vicephoneNumber) ? null : vicephoneNumber);
				// 送货员信息
				// 解析送货员ID
				String deliverymanId = this.getFirstStr(dispatchVO.getDeliverymanId());
				// 解析送货员编号
				String deliverymanCode = this.getFirstStr(dispatchVO.getDeliverymanCode());
				// 解析送货员手机号
				String deliverymanPhoneNumber = this.getFirstStr(dispatchVO.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(dispatchVO.getDeliverymanId());
				loadingBillHeaderModel.setViceDriverId(StrUtil.isBlank(viceDeliverymanId) ? null : viceDeliverymanId);
				String viceDeliverymanCode = this.subArrToString(dispatchVO.getDeliverymanCode());
				loadingBillHeaderModel.setViceDriverCode(StrUtil.isBlank(viceDeliverymanCode) ? null : viceDeliverymanCode);
				String viceDeliverymanName = this.subArrToString(dispatchVO.getDeliverymanName());
				loadingBillHeaderModel.setViceDeliverymanName(StrUtil.isBlank(viceDeliverymanName) ? null : viceDeliverymanName);
				String viceDeliverymanphoneNumber = this.subArrToString(dispatchVO.getDeliverymanPhoneNumber());
				loadingBillHeaderModel.setViceDeliverymanPhoneNumber(StrUtil.isBlank(viceDeliverymanphoneNumber) ? null : viceDeliverymanphoneNumber);
			}

			BigDecimal totalWholePiece = BigDecimal.valueOf(0);
			BigDecimal totalLclPiece = BigDecimal.valueOf(0);
			BigDecimal totalPcs = BigDecimal.valueOf(0);
			BigDecimal totalVolume = BigDecimal.valueOf(0);
			BigDecimal totalWeight = BigDecimal.valueOf(0);
			boolean autoDispatchCheck = false;

			int order = 1;
			log.info("待调度用户类型:" + JSON.toJSONString(user.getUserType()));
			for (TmsShipbillHeaderModel shipbillHeaderModel : shipbillHeaderModelList) {
				log.info("待调度运单:" + JSON.toJSONString(shipbillHeaderModel));
				Map<String, Object> mapShipbillHeadUpdate = Maps.newHashMap();
				// 装车单明细保存
				// 获取装车单明细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(shipbillHeaderModel, loadingBillDetailModel);

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

					mapShipbillHeadUpdate.put("status", DataDictionaryConstant.SHIPBILL_STATUS_DISPATCH);
					r23 = Restrictions.eq(TmsShipbillHeaderModel::getStatus, DataDictionaryConstant.SHIPBILL_STATUS_REVIEW);

					shipbillHeaderModel.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 (!autoDispatchCheck && shipbillHeaderModel.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(shipbillHeaderModel.getCarrierShipbillStatus())) {
						throw new PrologException("运单【" + shipbillHeaderModel.getShipbillNo() + "】非待调度状态,调度失败");
					}
					if (DataDictionaryConstant.SHIPBILL_STATUS_DISPATCH_CHECK.intValue() > shipbillHeaderModel.getStatus().intValue()) {
						throw new PrologException("运单【" + shipbillHeaderModel.getShipbillNo() + "】非待调度状态,调度失败");
					}
					loadingBillDetailModel.setCarrierShipbillStatus(DataDictionaryConstant.CARRIER_SHIPBILL_STATUS_DISPATCHED);
					shipbillHeaderModel.setCarrierShipbillStatus(DataDictionaryConstant.CARRIER_SHIPBILL_STATUS_DISPATCHED);

					mapShipbillHeadUpdate.put("carrierShipbillStatus", DataDictionaryConstant.CARRIER_SHIPBILL_STATUS_DISPATCHED);
					r23 = Restrictions.eq(TmsShipbillHeaderModel::getCarrierShipbillStatus, DataDictionaryConstant.CARRIER_SHIPBILL_STATUS_AUDITED);

					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 (!autoDispatchCheck && shipbillHeaderModel.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(dispatchVO.getCarrierType());

				loadingBillDetailModel.setSource(shipbillHeaderModel.getSource());
				nodeEvent.append(" ");
				if (DataDictionaryConstant.LINE_CARRIER_TYPE_CYF.equals(dispatchVO.getCarrierType())) {
					// 承运商
					nodeEvent.append(dispatchVO.getCarrierName());
					ShipbillFitBusinessFlowDTO flowData = shipbillMatchBusinessFlow(shipbillHeaderModel);
					shipbillHeaderModel.setCarrierFlowConfig(flowData.getFlowConfig());
					mapShipbillHeadUpdate.put("carrierFlowConfig", flowData.getFlowConfig());

					loadingBillDetailModel.setCarrierId(dispatchVO.getCarrierId());
					loadingBillDetailModel.setCarrierCode(dispatchVO.getCarrierCode());
					loadingBillDetailModel.setCarrierName(dispatchVO.getCarrierName());

					shipbillHeaderModel.setCarrierId(dispatchVO.getCarrierId());
					shipbillHeaderModel.setCarrierCode(dispatchVO.getCarrierCode());
					shipbillHeaderModel.setCarrierName(dispatchVO.getCarrierName());

					mapShipbillHeadUpdate.put("carrierId", dispatchVO.getCarrierId());
					mapShipbillHeadUpdate.put("carrierCode", dispatchVO.getCarrierCode());
					mapShipbillHeadUpdate.put("carrierName", dispatchVO.getCarrierName());

                } else if (DataDictionaryConstant.LINE_CARRIER_TYPE_SJ.equals(dispatchVO.getCarrierType())) {
                    // 司机
                    nodeEvent.append(ToolKits.isEmpty(driverName) ? "" : driverName);
                    nodeEvent.append(" ");
                    // 送货员名称
                    nodeEvent.append(ToolKits.isEmpty(deliverymanName) ? "" : deliverymanName);
                    nodeEvent.append(" ");
                    // 车牌号
                    nodeEvent.append(ToolKits.isEmpty(dispatchVO.getVehiclePlateNumber()) ? "" : dispatchVO.getVehiclePlateNumber());
                }
                // 保存调度单明细
                loadingBillDetailModel.setFlowConfig(shipbillHeaderModel.getFlowConfig());
                loadingBillDetailModel.setCarrierFlowConfig(shipbillHeaderModel.getCarrierFlowConfig());
                loadingBillDetailModel.setShippingOrder(order);
                order++;
                // 调度司机
                if (DataDictionaryConstant.LINE_CARRIER_TYPE_SJ.equals(dispatchVO.getCarrierType())) {
                    mapShipbillHeadUpdate.put("vehicleTypeCategory",dispatchVO.getVehicleTypeCategory());
                    mapShipbillHeadUpdate.put("vehicleDeviceId",dispatchVO.getVehicleDeviceId());
                    mapShipbillHeadUpdate.put("vehicleDeviceCode",dispatchVO.getVehicleDeviceCode());
                    mapShipbillHeadUpdate.put("vehicleDeviceName",dispatchVO.getVehicleDeviceName());

                    loadingBillDetailModel.setVehicleTypeCategory(dispatchVO.getVehicleTypeCategory());
                    loadingBillDetailModel.setVehicleDeviceId(dispatchVO.getVehicleDeviceId());
                    loadingBillDetailModel.setVehicleDeviceCode(dispatchVO.getVehicleDeviceCode());
                    loadingBillDetailModel.setVehicleDeviceName(dispatchVO.getVehicleDeviceName());
                    // 冷藏冷冻恒温的运单
                    if (!DataDictionaryConstant.TEMPERATURE_REQUIREMENT_CW.equals(shipbillHeaderModel.getTemperatureRequirement())) {
                        mapShipbillHeadUpdate.put("containerId",dispatchVO.getContainerId());
                        mapShipbillHeadUpdate.put("containerCode",dispatchVO.getContainerCode());
                        mapShipbillHeadUpdate.put("containerName",dispatchVO.getContainerName());

                        loadingBillDetailModel.setContainerId(dispatchVO.getContainerId());
                        loadingBillDetailModel.setContainerCode(dispatchVO.getContainerCode());
                        loadingBillDetailModel.setContainerName(dispatchVO.getContainerName());
                    }
                }
                tmsLoadingBillDetailMapper.save(loadingBillDetailModel);
                // 运单调度
                mapShipbillHeadUpdate.put("carrierType",dispatchVO.getCarrierType());
                mapShipbillHeadUpdate.put("updateperson", user.getNickname());
                mapShipbillHeadUpdate.put("updatetime", date);

				Criteria criteriaHead = Criteria.forClass(TmsShipbillHeaderModel.class);
				Restriction r24 = Restrictions.eq(TmsShipbillHeaderModel::getShipbillId, shipbillHeaderModel.getShipbillId());
				criteriaHead.setRestriction(Restrictions.and(r23, r24));
				long upCnt = tmsShipbillHeaderMapper.updateMapByCriteria(mapShipbillHeadUpdate, criteriaHead);
				if (upCnt == 0) {
					throw new PrologException("运单【" + shipbillHeaderModel.getShipbillNo() + "】非待调度状态,调度失败");
				}

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

				// 运单日志保存
				shipbillOperateLogSaveVO.setShipbillId(shipbillHeaderModel.getShipbillId());
				shipbillOperateLogSaveVO.setShipbillNo(shipbillHeaderModel.getShipbillNo());
				shipbillOperateLogSaveVO.setOperateEvent(nodeEvent.toString());
				shipbillOperateLogService.addShipbillOperateLogData(shipbillOperateLogSaveVO);

				// 更新运输记录表的调度时间
				Criteria criteriaTransLog = Criteria.forClass(TmsShipbillTransLogModel.class);
				Restriction r1 = Restrictions.eq(TmsShipbillTransLogModel::getShipbillId, shipbillHeaderModel.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 = NumberUtil.add(totalWholePiece,shipbillHeaderModel.getPackageWholePiece());
                totalLclPiece = NumberUtil.add(totalLclPiece, shipbillHeaderModel.getPackageLclPiece());
                totalPcs = NumberUtil.add(totalPcs,shipbillHeaderModel.getTotalPcs());
                totalWeight = NumberUtil.add(totalWeight,shipbillHeaderModel.getTotalWeight());
                totalVolume = NumberUtil.add(totalVolume,shipbillHeaderModel.getTotalVolume());
            }
            // 运单数
            loadingBillHeaderModel.setShipbillNumber(shipbillHeaderModels.size());
            // 客户数
            int customerCnt = shipbillHeaderModels.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(TmsShipbillHeaderModel::getConsigneeUnitId))), ArrayList::new)).size();
            loadingBillHeaderModel.setCustomerNumber(customerCnt);
            // 总站点数
            int siteCnt = shipbillHeaderModels.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(TmsShipbillHeaderModel::getConsigneeId))), ArrayList::new)).size();
            loadingBillHeaderModel.setSiteNumber(siteCnt);
            // 总件数
            loadingBillHeaderModel.setTotalPcs(totalPcs);
            loadingBillHeaderModel.setActualTotalPcs(totalPcs);
            // 总重量
            loadingBillHeaderModel.setTotalWeight(totalWeight);
            loadingBillHeaderModel.setActualTotalWeight(totalWeight);
            // 总体积
            loadingBillHeaderModel.setTotalVolume(totalVolume);
            loadingBillHeaderModel.setActualTotalVolume(totalVolume);
            // 总整件数
            loadingBillHeaderModel.setTotalWholePiece(totalWholePiece);
            // 总拼箱数
            loadingBillHeaderModel.setTotalLclPiece(totalLclPiece);
            loadingBillHeaderModel.setVehicleTypeCategory(dispatchVO.getVehicleTypeCategory());
            loadingBillHeaderModel.setVehicleDeviceId(dispatchVO.getVehicleDeviceId());
            loadingBillHeaderModel.setVehicleDeviceCode(dispatchVO.getVehicleDeviceCode());
            loadingBillHeaderModel.setVehicleDeviceName(dispatchVO.getVehicleDeviceName());
            loadingBillHeaderModel.setVehicleAffiliationId(dispatchVO.getVehicleAffiliationId());
            loadingBillHeaderModel.setVehicleAffiliationCode(dispatchVO.getVehicleAffiliationCode());
            loadingBillHeaderModel.setVehicleAffiliationName(dispatchVO.getVehicleAffiliationName());
            loadingBillHeaderModel.setContainerId(dispatchVO.getContainerId());
            loadingBillHeaderModel.setContainerCode(dispatchVO.getContainerCode());
            loadingBillHeaderModel.setContainerName(dispatchVO.getContainerName());
            loadingBillHeaderModel.setScanStatus(DataDictionaryConstant.SCAN_STATUS_INIT);

			if (DataDictionaryConstant.LINE_CARRIER_TYPE_SJ.equals(loadingBillHeaderModel.getCarrierType())) {
				loadingBillHeaderModel.setCarrierSysFlag(DataDictionaryConstant.CARRIER_SYS_FLAG_INNER);
			} else {
				if (ToolKits.isNotEmpty(dispatchVO.getCarrierSysFlag())) {
					loadingBillHeaderModel.setCarrierSysFlag(dispatchVO.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(dispatchVO.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 (ToolKits.isNotEmpty(ids)) {
            if (DataDictionaryConstant.LINE_CARRIER_TYPE_SJ.equals(dispatchVO.getCarrierType())) {
                // 调用派车单审核
                sendCarService.autoSendcarAuditData(ids, user, date);
            } else {
                // 调用托运单审核
                trailerService.autoTrailerAuditData(ids, user, date);
            }
        }
		updatePlanBill(shipbillIds,user);
    }

	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);
			}
		});
	}

	/**
	 * 承运商策略匹配
	 *
	 * @param vo
	 */
	@Override
	public MatchCarrierStrategyDTO matchCarrierStrategy(MatchCarrierStrategyVO vo) {
		List<TmsShipbillHeaderModel> tmsShipbillHeaderModelList = tmsShipbillHeaderMapper.findByIds(TmsShipbillHeaderModel.class, vo.getShipBillIdList().toArray(), null);
		if (CollectionUtil.isEmpty(tmsShipbillHeaderModelList)) {
			throw new BizException("运单不存在");
		}
		List<ShipbillMatchCarrierVO> matchCarrierVOs = tmsShipbillHeaderModelList.stream().map(tmsShipbillHeaderModel -> {
			ShipbillMatchCarrierVO shipbillMatchCarrierVO = new ShipbillMatchCarrierVO();
			shipbillMatchCarrierVO.setShipbillId(tmsShipbillHeaderModel.getShipbillId());
			shipbillMatchCarrierVO.setShipperType(tmsShipbillHeaderModel.getShipperType());
			shipbillMatchCarrierVO.setShipperUnitId(tmsShipbillHeaderModel.getShipperUnitId());
			shipbillMatchCarrierVO.setConsigneeType(tmsShipbillHeaderModel.getConsigneeType());
			shipbillMatchCarrierVO.setConsigneeUnitId(tmsShipbillHeaderModel.getConsigneeUnitId());
			shipbillMatchCarrierVO.setConsigneeId(tmsShipbillHeaderModel.getConsigneeId());
			shipbillMatchCarrierVO.setConsigneeProvince(tmsShipbillHeaderModel.getConsigneeProvince());
			shipbillMatchCarrierVO.setConsigneeCity(tmsShipbillHeaderModel.getConsigneeCity());
			shipbillMatchCarrierVO.setConsigneeDistrict(tmsShipbillHeaderModel.getConsigneeDistrict());
			shipbillMatchCarrierVO.setOrderType(tmsShipbillHeaderModel.getOrderType());
			shipbillMatchCarrierVO.setOrderBusinessType(tmsShipbillHeaderModel.getOrderBusinessType());
			shipbillMatchCarrierVO.setTransportType(tmsShipbillHeaderModel.getTransportType());
			shipbillMatchCarrierVO.setDeliveryMethodType(tmsShipbillHeaderModel.getDeliveryMethodType());
			shipbillMatchCarrierVO.setTemperatureRequirement(tmsShipbillHeaderModel.getTemperatureRequirement());
			shipbillMatchCarrierVO.setDepartmentId(tmsShipbillHeaderModel.getDepartmentId());
			shipbillMatchCarrierVO.setCargoOwnerId(tmsShipbillHeaderModel.getCargoOwnerId());
			shipbillMatchCarrierVO.setEnterpriseId(tmsShipbillHeaderModel.getEnterpriseId());
			shipbillMatchCarrierVO.setLineId(tmsShipbillHeaderModel.getLineId());
			shipbillMatchCarrierVO.setShipperAgingTime(tmsShipbillHeaderModel.getEstimatedPickupStartTime());
			shipbillMatchCarrierVO.setPickupStartTime(tmsShipbillHeaderModel.getEstimatedPickupStartTime());
			return shipbillMatchCarrierVO;
		}).collect(Collectors.toList());
		MatchCarrierStrategyDTO matchCarrierStrategyDTO = new MatchCarrierStrategyDTO();
		matchCarrierStrategyDTO.setMatchType(DispatchMatchCarrierTypeEnum.NON.getCode());
		// 匹配承运商策略
		Map<String, ShipbillMatchCarrierDTO> shipbillMatchCarrierDTOMap = mainDataProxy.shipbillMatchCarrierExecute(matchCarrierVOs);
		List<ShipbillMatchCarrierDTO> shipbillMatchCarrierDTOList = Lists.newArrayList(shipbillMatchCarrierDTOMap.values());
		if (shipbillMatchCarrierDTOList.stream().anyMatch(dto -> ToolKits.isEmpty(dto.getCarrierId()))) {
			return matchCarrierStrategyDTO;
		}
		Map<Integer, List<ShipbillMatchCarrierDTO>> carrierDTOMap = shipbillMatchCarrierDTOList.stream().filter(shipbillMatchCarrierDTO -> ObjectUtil.isNotNull(shipbillMatchCarrierDTO.getCarrierType())).collect(Collectors.groupingBy(ShipbillMatchCarrierDTO::getCarrierType));
		if (carrierDTOMap.size() == 1) {
			Integer carrierType = Lists.newArrayList(carrierDTOMap.keySet()).get(0);
			List<ShipbillMatchCarrierDTO> carrierDTOList = carrierDTOMap.get(carrierType);
			// 承运商
			if (DataDictionaryConstant.LINE_CARRIER_TYPE_CYF.equals(carrierType)) {
				Map<String, List<ShipbillMatchCarrierDTO>> carrierMap = carrierDTOList.stream().collect(Collectors.groupingBy(ShipbillMatchCarrierDTO::getCarrierId));
				if (carrierMap.size() == 1) {
					String carrierId = Lists.newArrayList(carrierMap.keySet()).get(0);
					ShipbillMatchCarrierDTO shipbillMatchCarrierDTO = carrierMap.get(carrierId).get(0);
					matchCarrierStrategyDTO.setMatchType(DispatchMatchCarrierTypeEnum.CARRIER.getCode());
					matchCarrierStrategyDTO.setShipbillMatchCarrierDTO(shipbillMatchCarrierDTO);
				}
			}
			// 司机
			else if (DataDictionaryConstant.LINE_CARRIER_TYPE_SJ.equals(carrierType)) {
				Map<String, Map<Long, List<ShipbillMatchCarrierDTO>>> driverMap = carrierDTOList.stream().collect(Collectors.groupingBy(ShipbillMatchCarrierDTO::getCarrierId, Collectors.groupingBy(ShipbillMatchCarrierDTO::getVehicleId)));
				if (driverMap.size() == 1) {
					String driverId = Lists.newArrayList(driverMap.keySet()).get(0);
					Map<Long, List<ShipbillMatchCarrierDTO>> vehicleMap = driverMap.get(driverId);
					if (vehicleMap.size() == 1) {
						Long vehicleId = Lists.newArrayList(vehicleMap.keySet()).get(0);
						matchCarrierStrategyDTO.setMatchType(DispatchMatchCarrierTypeEnum.DRIVER_VEHICLE.getCode());
						ShipbillMatchCarrierDTO shipbillMatchCarrierDTO = vehicleMap.get(vehicleId).get(0);
						matchCarrierStrategyDTO.setShipbillMatchCarrierDTO(shipbillMatchCarrierDTO);
					}
				}
			}
		}
		return matchCarrierStrategyDTO;
	}

	// 商品拆分
	public List<String> goodsSplit(DispatchSplitVO splitVO, Date date, UserEntity user) {
		ToolKits.isParamNull(splitVO, "调度拆分请求不为空");
		List<String> dispatchShipbills = Lists.newArrayList();
		// 原运单更新
		TmsShipbillHeaderModel tmsShipbillHeaderModel = tmsShipbillHeaderMapper.findById(splitVO.getShipbillId(), TmsShipbillHeaderModel.class);
		Map<String, Object> mapShipbillHeadUpdate = Maps.newHashMap();
		Restriction r23 = null;
		if (user.getUserType().equals(BussinessConstant.USER_TYPE_ZY)) {
			if (tmsShipbillHeaderModel.getSplitOrderStatus().equals(DataDictionaryConstant.SPLIT_ORDER_STATUS_ED)) {
				throw new PrologException("运单【" + tmsShipbillHeaderModel.getShipbillId() + "】已拆分,或者已调度");
			}
			r23 = Restrictions.eq(TmsShipbillHeaderModel::getSplitOrderStatus, DataDictionaryConstant.SPLIT_ORDER_STATUS_UN);
			mapShipbillHeadUpdate.put("splitOrderStatus", DataDictionaryConstant.SPLIT_ORDER_STATUS_ED);
			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);
				mapShipbillHeadUpdate.put("splitOrderType", DataDictionaryConstant.SPLIT_ORDER_TYPE_SPLIT_MASTER);
			}
		} else if (user.getUserType().equals(BussinessConstant.USER_TYPE_CYS)) {
			if (tmsShipbillHeaderModel.getCarrierSplitOrderStatus().equals(DataDictionaryConstant.CARRIER_SPLIT_ORDER_STATUS_ED)) {
				throw new PrologException("运单【" + tmsShipbillHeaderModel.getShipbillId() + "】已拆分,或者已调度");
			}
			r23 = Restrictions.eq(TmsShipbillHeaderModel::getCarrierSplitOrderStatus, DataDictionaryConstant.CARRIER_SPLIT_ORDER_STATUS_UN);
			mapShipbillHeadUpdate.put("carrierSplitOrderStatus", DataDictionaryConstant.CARRIER_SPLIT_ORDER_STATUS_ED);
			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);
				mapShipbillHeadUpdate.put("carrierSplitOrderType", DataDictionaryConstant.CARRIER_SPLIT_ORDER_TYPE_SPLIT_MASTER);
			}

			// STD-DEVELOP20220823 lhb 承运商拆分完善 20220916 start
			// 更新装车单明细
			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(tmsShipbillHeaderModel.getCarrierSplitOrderType()) || DataDictionaryConstant.CARRIER_SPLIT_ORDER_TYPE_UN.equals(tmsShipbillHeaderModel.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, tmsShipbillHeaderModel.getShipbillId());
			criteriaLoadingDetail.setRestriction(Restrictions.and(r21, r22));
			tmsLoadingBillDetailMapper.updateMapByCriteria(mapLoadingDetailUpdate, criteriaLoadingDetail);
			// STD-DEVELOP20220823 lhb 承运商拆分完善 20220916 end
		}
		Criteria criteriaHead = Criteria.forClass(TmsShipbillHeaderModel.class);
		Restriction r24 = Restrictions.eq(TmsShipbillHeaderModel::getShipbillId, tmsShipbillHeaderModel.getShipbillId());
		criteriaHead.setRestriction(Restrictions.and(r23, r24));
		mapShipbillHeadUpdate.put("updateperson", user.getNickname());
		mapShipbillHeadUpdate.put("updatetime", date);
		long upCnt = tmsShipbillHeaderMapper.updateMapByCriteria(mapShipbillHeadUpdate, criteriaHead);
		if (upCnt == 0) {
			throw new PrologException("运单【" + tmsShipbillHeaderModel.getShipbillId() + "】已拆分,或者已调度");
		}

		// 原运单日志保存
		ShipbillOperateLogSaveNewVO shipbillOperateLogSaveVO = new ShipbillOperateLogSaveNewVO();
		shipbillOperateLogSaveVO.setShipbillId(tmsShipbillHeaderModel.getShipbillId());
		shipbillOperateLogSaveVO.setShipbillNo(tmsShipbillHeaderModel.getShipbillNo());
		shipbillOperateLogSaveVO.setOperateEvent(DataDictionaryConstant.SHIPBILL_EVENT_NAME_SPLIT);
		shipbillOperateLogSaveVO.setOldStatus(DataDictionaryConstant.SHIPBILL_STATUS_REVIEW);
		shipbillOperateLogSaveVO.setNewStatus(DataDictionaryConstant.SHIPBILL_STATUS_REVIEW);
		shipbillOperateLogSaveVO.setOperateDate(date);
		shipbillOperateLogService.addShipbillOperateLogNewData(shipbillOperateLogSaveVO);

		// 拆分成多个子单
		RestMessage<SysParamConfigModel> restMessageShipbillId = maindataTmsResource.getValue(DataDictionaryConstant.SHIPBILL_ID_CREATE_RULE);
		if (!restMessageShipbillId.isSuccess()) {
			throw new RuntimeException("获取运单ID生成规则的系统参数失败!");
		}
		SysParamConfigModel sysParamConfigModel = restMessageShipbillId.getData();

		int index = 1;
		Map<String, List<PendingSplitDetailVO>> maps = splitVO.getSplitGoodsMap();
		for (String splitType : maps.keySet()) {
			// 运单汇总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 (PendingSplitDetailVO splitGoodsDetailVO : maps.get(splitType)) {
				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 计算件重体 20220909 start
				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();
				// STD-DEVELOP20220823 lhb 计算件重体 20220909 end

				TmsShipbillDetailModel detailModel = tmsShipbillDetailMapper.findById(splitGoodsDetailVO.getId(), TmsShipbillDetailModel.class);
				if (ToolKits.isEmpty(detailModel)) {
					throw new PrologException("运单【" + splitVO.getShipbillId() + "】的商品【" + splitGoodsDetailVO.getItemName() + "】信息不存在");
				}

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

				subTmsShipbillDetailModel.setPcs(splitGoodsDetailVO.getPcs());
				// STD-DEVELOP20220823 lhb 计算件重体 20220909 start
				subTmsShipbillDetailModel.setWeight(splitGoodsDetailVO.getPcs().multiply(ToolKits.isEmpty(rsItemInfo.getWeight()) ? BigDecimal.ZERO : rsItemInfo.getWeight()));
				subTmsShipbillDetailModel.setVolume(splitGoodsDetailVO.getPcs().multiply(ToolKits.isEmpty(rsItemInfo.getVolume()) ? BigDecimal.ZERO : rsItemInfo.getVolume()));
				// STD-DEVELOP20220823 lhb 计算件重体 20220909 end
				subTmsShipbillDetailModel.setEnterpriseId(user.getEnterpriseId());
				subTmsShipbillDetailModel.setEnterpriseName(user.getEnterpriseName());

				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.setScanStatus(DataDictionaryConstant.SCAN_STATUS_INIT);
				tmsShipbillDetailMapper.save(subTmsShipbillDetailModel);

				// STD-DEVELOP20220823 lhb 计算件重体 20220909 start
				goodsTotalPcs = goodsTotalPcs.add(subTmsShipbillDetailModel.getPcs());
				goodsTotalVolume = goodsTotalVolume.add(ToolKits.isEmpty(subTmsShipbillDetailModel.getVolume()) ? BigDecimal.ZERO : subTmsShipbillDetailModel.getVolume());
				goodsTotalWeight = goodsTotalWeight.add(ToolKits.isEmpty(subTmsShipbillDetailModel.getWeight()) ? BigDecimal.ZERO : subTmsShipbillDetailModel.getWeight());
				// STD-DEVELOP20220823 lhb 计算件重体 20220909 end
			}

			// 保存拆分子单的运单汇总
			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);

				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 = ToolKits.isEmpty(tmsShipbillHeaderModel.getOriginalShipbillId()) ? tmsShipbillHeaderModel.getShipbillId() : tmsShipbillHeaderModel.getOriginalShipbillId();
			subTmsShipbillHeaderModel.setOriginalShipbillId(originalShipbillId);
			// 原始运单编号
			String originalShipbillNo = ToolKits.isEmpty(tmsShipbillHeaderModel.getOriginalShipbillNo()) ? 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());

			// 子运单日志保存
			ShipbillOperateLogSaveNewVO subShipbillOperateLogSaveVO = new ShipbillOperateLogSaveNewVO();
			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);
			subShipbillOperateLogSaveVO.setOperateDate(date);
			shipbillOperateLogService.addShipbillOperateLogNewData(subShipbillOperateLogSaveVO);

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

			if (splitType.equals("disReg")) {
				dispatchShipbills.add(subTmsShipbillHeaderModel.getShipbillId());
			}
		}
		List<String> shipbillIds = Lists.newArrayList();
		shipbillIds.add(splitVO.getShipbillId());
		updatePlanBill(shipbillIds,user);

		return dispatchShipbills;
	}

	/**
	 * 获得第一个字符
	 *
	 * @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 model
	 * @return
	 */
	public ShipbillFitBusinessFlowDTO shipbillMatchBusinessFlow(TmsShipbillHeaderModel model) {
		// 新增后自动提交判定
		BusinessFlowShipbillVO matchFlowVO = new BusinessFlowShipbillVO();
		// 流程类型 承运商
		matchFlowVO.setFlowType(1);
		// 配送方式
		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());
		RestMessage<ShipbillFitBusinessFlowDTO> matchRs = maindataTmsResource.shipbillMatchFlowQuery(matchFlowVO);
		if (!matchRs.isSuccess()) {
			throw new PrologException("运单【" + model.getShipbillNo() + "】调用maindata服务运单匹配业务流程失败");
		}
		// Assert.isTrue(ToolKits.isNotEmpty(matchRs.getData().getFlowConfig()), "运单【" +
		// model.getShipbillNo() + "】没有匹配到承运商业务流程，请配置承运商业务流程");
		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);
	}
}
