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

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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.pojo.Page;
import com.prolog.framework.core.restriction.Criteria;
import com.prolog.framework.core.restriction.Order;
import com.prolog.framework.core.restriction.Restriction;
import com.prolog.framework.core.restriction.Restrictions;
import com.prolog.framework.dao.util.PageUtils;
import com.prolog.product.core.framework.entity.UserEntity;
import com.prolog.product.core.framework.util.PlgFxUsrUtils;
import com.prolog.rdc.tms.constant.BussinessConstant;
import com.prolog.rdc.tms.constant.DataDictionaryConstant;
import com.prolog.rdc.tms.constant.StatusConstant;
import com.prolog.rdc.tms.dao.mapper.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.TmsShipbillPackageMapper;
import com.prolog.rdc.tms.dao.mapper.TmsShipbillTransportLogMapper;
import com.prolog.rdc.tms.model.dto.DeviceByOneDTO;
import com.prolog.rdc.tms.model.dto.StorageHalfwayExportDTO;
import com.prolog.rdc.tms.model.dto.StorageHalfwayGetShipbillDTO;
import com.prolog.rdc.tms.model.dto.StorageHalfwayItemDetailDTO;
import com.prolog.rdc.tms.model.dto.StorageHalfwayPackageDetailDTO;
import com.prolog.rdc.tms.model.dto.StorageHalfwayPrintHeadDTO;
import com.prolog.rdc.tms.model.dto.StorageHalfwayPrintTableDTO;
import com.prolog.rdc.tms.model.dto.StorageHalfwayQueryByLoadbillDTO;
import com.prolog.rdc.tms.model.dto.basicConfigure.SignconfigPopDTO;
import com.prolog.rdc.tms.model.dto.message.SendMessageDTO;
import com.prolog.rdc.tms.model.entity.TmsLoadingBillDetailModel;
import com.prolog.rdc.tms.model.entity.TmsLoadingBillHeaderModel;
import com.prolog.rdc.tms.model.entity.TmsShipbillDetailModel;
import com.prolog.rdc.tms.model.entity.TmsShipbillHeaderModel;
import com.prolog.rdc.tms.model.entity.TmsShipbillPackageModel;
import com.prolog.rdc.tms.model.entity.TmsShipbillTransLogModel;
import com.prolog.rdc.tms.model.enums.MessageOrderTypeEnum;
import com.prolog.rdc.tms.model.enums.MessageTypeEnum;
import com.prolog.rdc.tms.model.vo.ShipbillNodeTrackingSaveNewVO;
import com.prolog.rdc.tms.model.vo.ShipbillOperateLogSaveNewVO;
import com.prolog.rdc.tms.model.vo.StorageHalfwayAbnormalRegisterByShipbillVO;
import com.prolog.rdc.tms.model.vo.StorageHalfwayAbnormalRegisterVO;
import com.prolog.rdc.tms.model.vo.StorageHalfwayAdvancedQueryVO;
import com.prolog.rdc.tms.model.vo.StorageHalfwayDeliveredConfirmByShipbillVO;
import com.prolog.rdc.tms.model.vo.StorageHalfwayDeliveredConfirmVO;
import com.prolog.rdc.tms.model.vo.StorageHalfwayExportAllVO;
import com.prolog.rdc.tms.model.vo.StorageHalfwayExportPageVO;
import com.prolog.rdc.tms.model.vo.StorageHalfwayFeedBackByShipbillVO;
import com.prolog.rdc.tms.model.vo.StorageHalfwayFeedBackVO;
import com.prolog.rdc.tms.model.vo.StorageHalfwayGetShipbillVO;
import com.prolog.rdc.tms.model.vo.StorageHalfwayItemDetailVO;
import com.prolog.rdc.tms.model.vo.StorageHalfwayPackageDetailVO;
import com.prolog.rdc.tms.model.vo.StorageHalfwayQueryByLoadbillVO;
import com.prolog.rdc.tms.model.vo.basicConfigure.SignconfigPopVO;
import com.prolog.rdc.tms.rmi.feign.MaindataFeign;
import com.prolog.rdc.tms.service.ShipbillNodeTrackingService;
import com.prolog.rdc.tms.service.ShipbillOperateLogService;
import com.prolog.rdc.tms.service.StorageHalfwayService;
import com.prolog.rdc.tms.util.MessageUtil;
import com.prolog.rdc.tms.util.PublicMethods;

/**
 * 运输管理-入库在途 实现层
 *
 * Company: 湖北普罗格科技股份有限公司
 *
 * @author zhangsj
 * @since 2022/6/17 11:12
 */
@Service
public class StorageHalfwayServiceImpl implements StorageHalfwayService {

	@Autowired
	private TmsLoadingBillHeaderMapper tmsLoadingBillHeaderMapper;

	@Autowired
	private TmsLoadingBillDetailMapper tmsLoadingBillDetailMapper;

	@Autowired
	private TmsShipbillHeaderMapper tmsShipbillHeaderMapper;

	@Autowired
	private TmsShipbillDetailMapper tmsShipbillDetailMapper;

	@Autowired
	private TmsShipbillPackageMapper tmsShipbillPackageMapper;

	@Autowired
	private MaindataFeign maindataTmsResource;

	@Autowired
	private ShipbillOperateLogService shipbillOperateLogService;

	@Autowired
	private ShipbillNodeTrackingService shipbillNodeTrackingService;

	@Autowired
	private TmsShipbillTransportLogMapper tmsShipbillTransportLogMapper;

	/**
	 * 派车单查询
	 *
	 * @param storageHalfwayQueryByLoadbillVO
	 * @return
	 */
	@SuppressWarnings("resource")
	@Override
	public Page<StorageHalfwayQueryByLoadbillDTO> queryLoadbillPageData(StorageHalfwayQueryByLoadbillVO storageHalfwayQueryByLoadbillVO) {
		ToolKits.isParamNull(storageHalfwayQueryByLoadbillVO, "汇总查询请求不为空");
		ToolKits.isParamNull(storageHalfwayQueryByLoadbillVO.getPageNum(), "当前页码不为空");
		ToolKits.isParamNull(storageHalfwayQueryByLoadbillVO.getPageSize(), "每页条数不为空");

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

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

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

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

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

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

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

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

			// 状态翻译
			dto.setStatusName(PublicMethods.change(data1, String.valueOf(dto.getStatus())));

			storageHalfwayQueryByLoadbillDTOS.add(dto);
		}

		// 分页重组
		Page<StorageHalfwayQueryByLoadbillDTO> page = PageUtils.getPage(storageHalfwayQueryByLoadbillDTOS);
		if (tmsLoadingBillHeaderModels instanceof com.github.pagehelper.Page) {
			com.github.pagehelper.Page<TmsLoadingBillHeaderModel> p0 = (com.github.pagehelper.Page<TmsLoadingBillHeaderModel>) tmsLoadingBillHeaderModels;
			page.setPageCount(p0.getPages());
			page.setPageNum(p0.getPageNum());
			page.setPageSize(p0.getPageSize());
			page.setTotalCount(p0.getTotal());
			page.setStartRow(p0.getStartRow());
			page.setEndRow(p0.getEndRow());
		}
		return page;
	}

	/**
	 * 派车单高级查询
	 *
	 * @param storageHalfwayAdvancedQueryVO
	 * @return
	 */
	@Override
	public Page<StorageHalfwayQueryByLoadbillDTO> advancedQueryLoadbillPageData(StorageHalfwayAdvancedQueryVO storageHalfwayAdvancedQueryVO) {
		ToolKits.isParamNull(storageHalfwayAdvancedQueryVO, "汇总查询请求不为空");
		ToolKits.isParamNull(storageHalfwayAdvancedQueryVO.getPageNum(), "当前页码不为空");
		ToolKits.isParamNull(storageHalfwayAdvancedQueryVO.getPageSize(), "每页条数不为空");

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

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

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

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

		// 权限控制
		storageHalfwayAdvancedQueryVO.setEnterpriseId(user.getEnterpriseId());
		storageHalfwayAdvancedQueryVO.setDepts(user.getDepts().stream().toArray(String[]::new));
		storageHalfwayAdvancedQueryVO.setCarrierType(DataDictionaryConstant.LINE_CARRIER_TYPE_SJ);
		storageHalfwayAdvancedQueryVO.setLoadingBillType(DataDictionaryConstant.LOADING_BILL_TYPE_RK);

		// 判断调度类型
		if (user.getUserType().equals(BussinessConstant.USER_TYPE_ZY)) {
			storageHalfwayAdvancedQueryVO.setScheduleType(DataDictionaryConstant.SCHEDULE_TYPE_ZY);
		} else {
			storageHalfwayAdvancedQueryVO.setScheduleType(DataDictionaryConstant.SCHEDULE_TYPE_CYS);
		}

		// 获取高级查询配置
		String conditions = null;
		RestMessage<String> restMessageAdvancedCfg = maindataTmsResource.getQueryConfiguration(DataDictionaryConstant.BIZ_TYPE_STORAGEHALFWAY);
		if (!restMessageAdvancedCfg.isSuccess()) {
			throw new RuntimeException("获取高级查询配置失败!");
		} else {
			conditions = restMessageAdvancedCfg.getData();
		}
		storageHalfwayAdvancedQueryVO.setSql(conditions);

		PageUtils.startPage(storageHalfwayAdvancedQueryVO.getPageNum(), storageHalfwayAdvancedQueryVO.getPageSize());
		List<StorageHalfwayQueryByLoadbillDTO> storageHalfwayQueryByLoadbillDTOS = tmsLoadingBillHeaderMapper.storageHalfwayAdvancedQuery(storageHalfwayAdvancedQueryVO);

		for (StorageHalfwayQueryByLoadbillDTO dto : storageHalfwayQueryByLoadbillDTOS) {
			// 状态翻译
			dto.setStatusName(PublicMethods.change(data1, String.valueOf(dto.getStatus())));

		}
		return PageUtils.getPage(storageHalfwayQueryByLoadbillDTOS);
	}

	/**
	 * 配载运单查询
	 *
	 * @param storageHalfwayGetShipbillVO
	 * @return
	 */
	@SuppressWarnings("resource")
	@Override
	public Page<StorageHalfwayGetShipbillDTO> getShipbillData(StorageHalfwayGetShipbillVO storageHalfwayGetShipbillVO) {
		ToolKits.isParamNull(storageHalfwayGetShipbillVO.getPageNum(), "当前页码不为空");
		ToolKits.isParamNull(storageHalfwayGetShipbillVO.getPageSize(), "每页条数不为空");
		ToolKits.isParamNull(storageHalfwayGetShipbillVO.getLoadingBillId(), "派车单ID不为空");

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

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

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

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

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

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

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

		for (TmsLoadingBillDetailModel model : tmsLoadingBillDetailModels) {

			StorageHalfwayGetShipbillDTO storageHalfwayGetShipbillDTO = new StorageHalfwayGetShipbillDTO();
			BeanUtils.copyProperties(model, storageHalfwayGetShipbillDTO);

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

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

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

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

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

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

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

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

							storageHalfwayGetShipbillDTO.setSignConfigId(signconfigPopDTO.getId());

							break Signconfig;
						}
					}
					break;
				}
			}

			list.add(storageHalfwayGetShipbillDTO);
		}

		// 分页重组
		Page<StorageHalfwayGetShipbillDTO> page = PageUtils.getPage(list);
		if (tmsLoadingBillDetailModels instanceof com.github.pagehelper.Page) {
			com.github.pagehelper.Page<TmsLoadingBillDetailModel> p0 = (com.github.pagehelper.Page<TmsLoadingBillDetailModel>) tmsLoadingBillDetailModels;
			page.setPageCount(p0.getPages());
			page.setPageNum(p0.getPageNum());
			page.setPageSize(p0.getPageSize());
			page.setTotalCount(p0.getTotal());
			page.setStartRow(p0.getStartRow());
			page.setEndRow(p0.getEndRow());
		}
		return page;
	}

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

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

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

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

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

		// 查询派车单明细
		Criteria criteria = Criteria.forClass(TmsLoadingBillDetailModel.class);
		Restriction r1 = Restrictions.eq("loadingBillId", storageHalfwayItemDetailVO.getLoadingBillId());
		criteria.setRestriction(r1);

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

		// 根据运单ID查询明细数据
		criteria = Criteria.forClass(TmsShipbillDetailModel.class);
		r1 = Restrictions.in("shipbillId", tmsLoadingBillDetailModels.stream().map(TmsLoadingBillDetailModel::getShipbillId).collect(Collectors.toList()).toArray());

		criteria.setRestriction(r1);

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

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

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

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

			list.add(dto);
		}

		// 分页重组
		Page<StorageHalfwayItemDetailDTO> page = PageUtils.getPage(list);
		if (tmsShipbillDetailModels instanceof com.github.pagehelper.Page) {
			com.github.pagehelper.Page<TmsShipbillDetailModel> p0 = (com.github.pagehelper.Page<TmsShipbillDetailModel>) tmsShipbillDetailModels;
			page.setPageCount(p0.getPages());
			page.setPageNum(p0.getPageNum());
			page.setPageSize(p0.getPageSize());
			page.setTotalCount(p0.getTotal());
			page.setStartRow(p0.getStartRow());
			page.setEndRow(p0.getEndRow());
		}

		return page;
	}

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

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

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

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

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

		// 查询派车单明细
		Criteria criteria = Criteria.forClass(TmsLoadingBillDetailModel.class);
		Restriction r1 = Restrictions.eq("loadingBillId", storageHalfwayPackageDetailVO.getLoadingBillId());
		criteria.setRestriction(r1);

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

		// 根据运单ID查询明细数据
		criteria = Criteria.forClass(TmsShipbillPackageModel.class);
		r1 = Restrictions.in("shipbillId", tmsLoadingBillDetailModels.stream().map(TmsLoadingBillDetailModel::getShipbillId).collect(Collectors.toList()).toArray());
		criteria.setRestriction(r1);

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

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

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

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

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

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

			list.add(dto);
		}

		// 分页重组
		Page<StorageHalfwayPackageDetailDTO> page = PageUtils.getPage(list);
		if (tmsShipbillPackageModels instanceof com.github.pagehelper.Page) {
			com.github.pagehelper.Page<TmsShipbillPackageModel> p0 = (com.github.pagehelper.Page<TmsShipbillPackageModel>) tmsShipbillPackageModels;
			page.setPageCount(p0.getPages());
			page.setPageNum(p0.getPageNum());
			page.setPageSize(p0.getPageSize());
			page.setTotalCount(p0.getTotal());
			page.setStartRow(p0.getStartRow());
			page.setEndRow(p0.getEndRow());
		}

		return page;
	}

	/**
	 * 运单-送达确认
	 *
	 * @param storageHalfwayDeliveredConfirmByShipbillVO
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void shipbillDeliveredConfirmData(StorageHalfwayDeliveredConfirmByShipbillVO storageHalfwayDeliveredConfirmByShipbillVO) {
		ToolKits.isParamNull(storageHalfwayDeliveredConfirmByShipbillVO.getShipbillIds(), "运单ID不能为空");
		ToolKits.isParamNull(storageHalfwayDeliveredConfirmByShipbillVO.getDeliveryTime(), "送达时间不能为空");
		ToolKits.isParamNull(storageHalfwayDeliveredConfirmByShipbillVO.getDeliveryStatus(), "配送状态不能为空");

		// 判断配送状态是滞留还是失败
		if (storageHalfwayDeliveredConfirmByShipbillVO.getDeliveryStatus() == DataDictionaryConstant.DELIVERY_STATUS_STAY) {
			ToolKits.isParamNull(storageHalfwayDeliveredConfirmByShipbillVO.getDeliveryStrandedReason(), "送达滞留原因不能为空");
		} else if (storageHalfwayDeliveredConfirmByShipbillVO.getDeliveryStatus() == DataDictionaryConstant.DELIVERY_STATUS_FAILED) {
			ToolKits.isParamNull(storageHalfwayDeliveredConfirmByShipbillVO.getDeliveryFailureReason(), "送达失败原因不能为空");
		}

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

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

		// 当前时间
		Date date = DateUtils.nowDate();
		// 签到时间是否为空
		boolean deliverySignTime = false;
		// 货物图片
		String GoodsPhoto = "";
		// 回单图片
		String ReceiptPhoto = "";

		// 节点内容
		StringBuffer nodeEvent = new StringBuffer();
		nodeEvent.append("送达确认 送达签收人:");
		nodeEvent.append(ToolKits.isEmpty(storageHalfwayDeliveredConfirmByShipbillVO.getDeliverySignPerson()) ? "" : storageHalfwayDeliveredConfirmByShipbillVO.getDeliverySignPerson());
		nodeEvent.append(" 送达备注:");
		nodeEvent.append(ToolKits.isEmpty(storageHalfwayDeliveredConfirmByShipbillVO.getDeliveryMemo()) ? "" : storageHalfwayDeliveredConfirmByShipbillVO.getDeliveryMemo());

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

		// 判断签到时间是否需要必填
		List<TmsShipbillHeaderModel> tmsShipbillHeaderModels = tmsShipbillHeaderMapperByIds.stream().filter(o -> StatusConstant.WHETHER_YES == o.getConsigneeDeliverySign()).collect(Collectors.toList());
		if (ToolKits.isNotEmpty(tmsShipbillHeaderModels)) {
			ToolKits.isParamNull(storageHalfwayDeliveredConfirmByShipbillVO.getDeliverySignTime(), "签到时间不能为空");
		}

		// 判断货物图片是否需要必填
		List<TmsShipbillHeaderModel> tmsShipbillHeaderModels2 = tmsShipbillHeaderMapperByIds.stream().filter(o -> StatusConstant.WHETHER_YES == o.getConsigneeDeliveryPicture()).collect(Collectors.toList());
		if (ToolKits.isNotEmpty(tmsShipbillHeaderModels2)) {
			ToolKits.isParamNull(storageHalfwayDeliveredConfirmByShipbillVO.getGoodsPhoto(), "货物图片不能为空");
			GoodsPhoto = storageHalfwayDeliveredConfirmByShipbillVO.getGoodsPhoto();

		}

		Criteria criteriaTransport = Criteria.forClass(TmsShipbillTransLogModel.class);
		Map<String, Object> mapTransportLogUpdate = Maps.newHashMap();
		mapTransportLogUpdate.put("updateperson", user.getNickname());
		mapTransportLogUpdate.put("updatetime", date);
		// 送达时间
		mapTransportLogUpdate.put("deliveryTime", storageHalfwayDeliveredConfirmByShipbillVO.getDeliveryTime());
		// 配送状态
		mapTransportLogUpdate.put("deliveryStatus", storageHalfwayDeliveredConfirmByShipbillVO.getDeliveryStatus());
		// 签到时间
		if (ToolKits.isNotEmpty(storageHalfwayDeliveredConfirmByShipbillVO.getDeliverySignTime())) {
			mapTransportLogUpdate.put("deliverySignTime", storageHalfwayDeliveredConfirmByShipbillVO.getDeliverySignTime());
		}
		// 备注
		if (ToolKits.isNotEmpty(storageHalfwayDeliveredConfirmByShipbillVO.getDeliveryMemo())) {
			mapTransportLogUpdate.put("deliveryMemo", storageHalfwayDeliveredConfirmByShipbillVO.getDeliveryMemo());
		}
		// 签到时间
		if (ToolKits.isNotEmpty(storageHalfwayDeliveredConfirmByShipbillVO.getDeliveryFailureReason())) {
			mapTransportLogUpdate.put("deliveryFailureReason", storageHalfwayDeliveredConfirmByShipbillVO.getDeliveryFailureReason());
		}
		// 备注
		if (ToolKits.isNotEmpty(storageHalfwayDeliveredConfirmByShipbillVO.getDeliveryStrandedReason())) {
			mapTransportLogUpdate.put("deliveryStrandedReason", storageHalfwayDeliveredConfirmByShipbillVO.getDeliveryStrandedReason());
		}

		for (TmsShipbillHeaderModel tmsShipbillHeaderModel : tmsShipbillHeaderMapperByIds) {
			Map<String, Object> mapDetailUpdate = Maps.newHashMap();

			// 修改运单
			tmsShipbillHeaderModel.setStatus(DataDictionaryConstant.SHIPBILL_STATUS_SD);
			tmsShipbillHeaderModel.setTransportStatus(DataDictionaryConstant.TRANSPORT_STATUS_ARRIVED);
			tmsShipbillHeaderModel.setUpdateperson(user.getNickname());
			tmsShipbillHeaderModel.setUpdatetime(date);

			Restriction r1 = Restrictions.eq("shipbillId", tmsShipbillHeaderModel.getShipbillId());
			criteriaTransport.setRestriction(r1);
			// 更新订单运输记录表
			tmsShipbillTransportLogMapper.updateMapByCriteria(mapTransportLogUpdate, criteriaTransport);

			// 运单节点信息
			ShipbillNodeTrackingSaveNewVO shipbillNodeTrackingSaveNewVO = new ShipbillNodeTrackingSaveNewVO();
			shipbillNodeTrackingSaveNewVO.setNodeDate(date);
			shipbillNodeTrackingSaveNewVO.setShipbillId(tmsShipbillHeaderModel.getShipbillId());
			shipbillNodeTrackingSaveNewVO.setShipbillNo(tmsShipbillHeaderModel.getShipbillId());
			shipbillNodeTrackingSaveNewVO.setUserId(user.getUserid());
			shipbillNodeTrackingSaveNewVO.setUserName(user.getNickname());
			shipbillNodeTrackingSaveNewVO.setEnterpriseId(user.getEnterpriseId());
			shipbillNodeTrackingSaveNewVO.setEnterpriseName(user.getEnterpriseName());

			// 运单日志信息
			ShipbillOperateLogSaveNewVO shipbillOperateLogSaveNewVO = new ShipbillOperateLogSaveNewVO();
			shipbillOperateLogSaveNewVO.setShipbillId(tmsShipbillHeaderModel.getShipbillId());
			shipbillOperateLogSaveNewVO.setShipbillNo(tmsShipbillHeaderModel.getShipbillId());
			shipbillOperateLogSaveNewVO.setOperateDate(date);
			shipbillOperateLogSaveNewVO.setEnterpriseId(user.getEnterpriseId());
			shipbillOperateLogSaveNewVO.setEnterpriseName(user.getEnterpriseName());
			shipbillOperateLogSaveNewVO.setUserId(user.getUserid());
			shipbillOperateLogSaveNewVO.setUserName(user.getNickname());

			if (ToolKits.isNotEmpty(storageHalfwayDeliveredConfirmByShipbillVO.getDeliverySignTime())) {
				// 运单节点保存
				shipbillNodeTrackingSaveNewVO.setStatus(DataDictionaryConstant.SHIPBILL_STATUS_SD);
				shipbillNodeTrackingSaveNewVO.setNodeEvent(DataDictionaryConstant.SHIPBILL_STATUSNAME_SDQD);
				shipbillNodeTrackingService.addShipbillNodeTrackingNewData(shipbillNodeTrackingSaveNewVO);

				// 运单日志保存
				shipbillOperateLogSaveNewVO.setOperateEvent(DataDictionaryConstant.SHIPBILL_STATUSNAME_SDQD);
				shipbillOperateLogSaveNewVO.setOldStatus(DataDictionaryConstant.SHIPBILL_STATUS_QY);
				shipbillOperateLogSaveNewVO.setNewStatus(DataDictionaryConstant.SHIPBILL_STATUS_SD);
				shipbillOperateLogService.addShipbillOperateLogNewData(shipbillOperateLogSaveNewVO);

				deliverySignTime = true;
			}

			// 运单节点保存
			shipbillNodeTrackingSaveNewVO.setStatus(DataDictionaryConstant.SHIPBILL_STATUS_SD);
			shipbillNodeTrackingSaveNewVO.setNodeEvent(nodeEvent.toString());
			shipbillNodeTrackingSaveNewVO.setPicUrl(storageHalfwayDeliveredConfirmByShipbillVO.getGoodsPhoto());
			shipbillNodeTrackingService.addShipbillNodeTrackingNewData(shipbillNodeTrackingSaveNewVO);

			// 运单日志保存
			shipbillOperateLogSaveNewVO.setOperateEvent(DataDictionaryConstant.SHIPBILL_STATUSNAME_SD);
			shipbillOperateLogSaveNewVO.setOldStatus(DataDictionaryConstant.SHIPBILL_STATUS_QY);
			shipbillOperateLogSaveNewVO.setNewStatus(DataDictionaryConstant.SHIPBILL_STATUS_SD);
			shipbillOperateLogService.addShipbillOperateLogNewData(shipbillOperateLogSaveNewVO);

			if (ToolKits.isNotEmpty(storageHalfwayDeliveredConfirmByShipbillVO.getReceiptPhoto())) {
				// 运单节点保存
				shipbillNodeTrackingSaveNewVO.setStatus(DataDictionaryConstant.SHIPBILL_STATUS_HD_PIC);
				shipbillNodeTrackingSaveNewVO.setNodeEvent(DataDictionaryConstant.SHIPBILL_STATUSNAME_HD_PIC);
				shipbillNodeTrackingSaveNewVO.setPicUrl(storageHalfwayDeliveredConfirmByShipbillVO.getReceiptPhoto());
				shipbillNodeTrackingService.addShipbillNodeTrackingNewData(shipbillNodeTrackingSaveNewVO);

				// 运单日志保存
				shipbillOperateLogSaveNewVO.setOperateEvent(DataDictionaryConstant.SHIPBILL_STATUSNAME_HD_PIC);
				shipbillOperateLogSaveNewVO.setOldStatus(DataDictionaryConstant.SHIPBILL_STATUS_QY);
				shipbillOperateLogSaveNewVO.setNewStatus(DataDictionaryConstant.SHIPBILL_STATUS_HD_PIC);
				shipbillOperateLogService.addShipbillOperateLogNewData(shipbillOperateLogSaveNewVO);

				ReceiptPhoto = storageHalfwayDeliveredConfirmByShipbillVO.getReceiptPhoto();

				tmsShipbillHeaderModel.setStatus(DataDictionaryConstant.SHIPBILL_STATUS_HD_PIC);

				mapDetailUpdate.put("status", DataDictionaryConstant.SHIPBILL_STATUS_HD_PIC);
			} else {
				mapDetailUpdate.put("status", DataDictionaryConstant.SHIPBILL_STATUS_SD);
			}

			// 运单修改操作
			tmsShipbillHeaderMapper.update(tmsShipbillHeaderModel);

			// 修改派车单明细
			Criteria criteriaDetail = Criteria.forClass(TmsLoadingBillDetailModel.class);
			r1 = Restrictions.eq("shipbillId", tmsShipbillHeaderModel.getShipbillId());
			criteriaDetail.setRestriction(r1);

			mapDetailUpdate.put("transportStatus", DataDictionaryConstant.TRANSPORT_STATUS_ARRIVED);
			mapDetailUpdate.put("updateperson", user.getNickname());
			mapDetailUpdate.put("updatetime", date);
			tmsLoadingBillDetailMapper.updateMapByCriteria(mapDetailUpdate, criteriaDetail);

			tmsLoadingBillDetailMapper.updateMapByCriteria(mapDetailUpdate, criteriaDetail);

			// 父运单的同步送达
			String fatherShipbillId = tmsShipbillHeaderModel.getShipbillId();
			while (ToolKits.isNotEmpty(fatherShipbillId)) {
				fatherShipbillId = fatherDeliveredConfirm(fatherShipbillId, date, user, deliverySignTime, GoodsPhoto, ReceiptPhoto, mapTransportLogUpdate);
				deliverySignTime = false;
			}
			MessageUtil.addMessage(new SendMessageDTO(MessageOrderTypeEnum.SHIP_NO.getCode(), MessageTypeEnum.DELIVERY.getCode(), Lists.newArrayList(tmsShipbillHeaderModel.getShipbillId())));
		}

	}

	/**
	 * 父运单同步送达
	 *
	 * @param shipbillId
	 * @param date
	 * @param user
	 * @param deliverySignTime
	 * @param GoodsPhoto
	 * @param ReceiptPhoto
	 * @param mapTransportLogUpdate
	 * @return
	 */
	private String fatherDeliveredConfirm(String shipbillId, Date date, UserEntity user, boolean deliverySignTime, String GoodsPhoto, String ReceiptPhoto, Map<String, Object> mapTransportLogUpdate) {
		// 查询运单
		TmsShipbillHeaderModel tmsShipbillHeaderModel = tmsShipbillHeaderMapper.findById(shipbillId, TmsShipbillHeaderModel.class);

		// 查询派车单明细
		Criteria criteriaDetail = Criteria.forClass(TmsLoadingBillDetailModel.class);
		Restriction rDetail = Restrictions.eq("shipbillId", shipbillId);
		criteriaDetail.setRestriction(rDetail);
		List<TmsLoadingBillDetailModel> tmsLoadingBillDetailModels = tmsLoadingBillDetailMapper.findByCriteria(criteriaDetail);
		ToolKits.isParamNull(tmsLoadingBillDetailModels, "查询派车单明细[运单:" + shipbillId + "]为空");

		TmsLoadingBillDetailModel tmsLoadingBillDetailModel = tmsLoadingBillDetailModels.get(0);

		// 获取同一个派车单下的明细
		rDetail = Restrictions.eq("loadingBillId", tmsLoadingBillDetailModel.getLoadingBillId());
		criteriaDetail.setRestriction(rDetail);
		List<TmsLoadingBillDetailModel> tmsLoadingBillDetailModelList = tmsLoadingBillDetailMapper.findByCriteria(criteriaDetail);

		List<TmsLoadingBillDetailModel> DetailModelList = tmsLoadingBillDetailModelList.stream().filter(o -> o.getStatus() == DataDictionaryConstant.SHIPBILL_STATUS_QY).collect(Collectors.toList());

		// 判断是否还有未完成的派车单明细
		if (ToolKits.isEmpty(DetailModelList)) {
			Map<String, Object> mapHeadUpdate = Maps.newHashMap();
			mapHeadUpdate.put("status", DataDictionaryConstant.LOADING_BILL_STATUS_SD);
			mapHeadUpdate.put("updateperson", user.getNickname());
			mapHeadUpdate.put("updatetime", date);
			// 修改派车单
			tmsLoadingBillHeaderMapper.updateMapById(tmsLoadingBillDetailModel.getLoadingBillId(), mapHeadUpdate, TmsLoadingBillHeaderModel.class);
		}

		// 判断是否为原始单号
		if (ToolKits.isNotEmpty(tmsShipbillHeaderModel.getFatherShipbillId()) && !tmsShipbillHeaderModel.getFatherShipbillId().equals(shipbillId)) {
			// 查找父级单号
			TmsShipbillHeaderModel fatherShipbillHeaderModel = tmsShipbillHeaderMapper.findById(tmsShipbillHeaderModel.getFatherShipbillId(), TmsShipbillHeaderModel.class);

			// 查找同级的所有子单
			Criteria criteria = Criteria.forClass(TmsShipbillHeaderModel.class);
			Restriction r1 = Restrictions.eq("fatherShipbillId", tmsShipbillHeaderModel.getFatherShipbillId());
			criteria.setRestriction(r1);
			List<TmsShipbillHeaderModel> tmsShipbillHeaderModelList = tmsShipbillHeaderMapper.findByCriteria(criteria);

			// 查找是否还有未完成的运单
			List<TmsShipbillHeaderModel> tmsShipbillHeaderModels = tmsShipbillHeaderModelList.stream().filter(o -> o.getStatus() == DataDictionaryConstant.SHIPBILL_STATUS_QY).collect(Collectors.toList());

			// 判断子单是否全部完成
			if (ToolKits.isEmpty(tmsShipbillHeaderModels)) {
				// 修改父级运单状态
				fatherShipbillHeaderModel.setStatus(DataDictionaryConstant.SHIPBILL_STATUS_SD);
				fatherShipbillHeaderModel.setTransportStatus(DataDictionaryConstant.TRANSPORT_STATUS_ARRIVED);
				fatherShipbillHeaderModel.setUpdatetime(date);
				fatherShipbillHeaderModel.setUpdateperson(user.getNickname());
				tmsShipbillHeaderMapper.update(fatherShipbillHeaderModel);

				// 修改父级运单运输记录表
				Criteria criteriaTransport = Criteria.forClass(TmsShipbillTransLogModel.class);
				r1 = Restrictions.eq("shipbillId", fatherShipbillHeaderModel.getShipbillId());
				criteriaTransport.setRestriction(r1);
				// 更新订单运输记录表
				tmsShipbillTransportLogMapper.updateMapByCriteria(mapTransportLogUpdate, criteriaTransport);

				// 运单节点信息
				ShipbillNodeTrackingSaveNewVO shipbillNodeTrackingSaveNewVO = new ShipbillNodeTrackingSaveNewVO();
				shipbillNodeTrackingSaveNewVO.setNodeDate(date);
				shipbillNodeTrackingSaveNewVO.setShipbillId(fatherShipbillHeaderModel.getShipbillId());
				shipbillNodeTrackingSaveNewVO.setShipbillNo(fatherShipbillHeaderModel.getShipbillId());
				shipbillNodeTrackingSaveNewVO.setUserId(user.getUserid());
				shipbillNodeTrackingSaveNewVO.setUserName(user.getNickname());
				shipbillNodeTrackingSaveNewVO.setEnterpriseId(user.getEnterpriseId());
				shipbillNodeTrackingSaveNewVO.setEnterpriseName(user.getEnterpriseName());

				// 运单日志信息
				ShipbillOperateLogSaveNewVO shipbillOperateLogSaveNewVO = new ShipbillOperateLogSaveNewVO();
				shipbillOperateLogSaveNewVO.setShipbillId(fatherShipbillHeaderModel.getShipbillId());
				shipbillOperateLogSaveNewVO.setShipbillNo(fatherShipbillHeaderModel.getShipbillId());
				shipbillOperateLogSaveNewVO.setOperateDate(date);
				shipbillOperateLogSaveNewVO.setEnterpriseId(user.getEnterpriseId());
				shipbillOperateLogSaveNewVO.setEnterpriseName(user.getEnterpriseName());
				shipbillOperateLogSaveNewVO.setUserId(user.getUserid());
				shipbillOperateLogSaveNewVO.setUserName(user.getNickname());

				// 判断第一个子单是否有签到时间
				if (deliverySignTime) {
					// 运单节点保存
					shipbillNodeTrackingSaveNewVO.setStatus(DataDictionaryConstant.SHIPBILL_STATUS_SD);
					shipbillNodeTrackingSaveNewVO.setNodeEvent(DataDictionaryConstant.SHIPBILL_STATUSNAME_SDQD);
					shipbillNodeTrackingService.addShipbillNodeTrackingNewData(shipbillNodeTrackingSaveNewVO);

					// 运单日志保存
					shipbillOperateLogSaveNewVO.setOperateEvent(DataDictionaryConstant.SHIPBILL_STATUSNAME_SDQD);
					shipbillOperateLogSaveNewVO.setOldStatus(DataDictionaryConstant.SHIPBILL_STATUS_QY);
					shipbillOperateLogSaveNewVO.setNewStatus(DataDictionaryConstant.SHIPBILL_STATUS_SD);
					shipbillOperateLogService.addShipbillOperateLogNewData(shipbillOperateLogSaveNewVO);
				}

				// 运单节点保存
				shipbillNodeTrackingSaveNewVO.setStatus(DataDictionaryConstant.SHIPBILL_STATUS_SD);
				shipbillNodeTrackingSaveNewVO.setNodeEvent(DataDictionaryConstant.SHIPBILL_STATUSNAME_SD);
				shipbillNodeTrackingSaveNewVO.setPicUrl(GoodsPhoto);
				shipbillNodeTrackingService.addShipbillNodeTrackingNewData(shipbillNodeTrackingSaveNewVO);

				// 运单日志保存
				shipbillOperateLogSaveNewVO.setOperateEvent(DataDictionaryConstant.SHIPBILL_STATUSNAME_SD);
				shipbillOperateLogSaveNewVO.setOldStatus(DataDictionaryConstant.SHIPBILL_STATUS_QY);
				shipbillOperateLogSaveNewVO.setNewStatus(DataDictionaryConstant.SHIPBILL_STATUS_SD);
				shipbillOperateLogService.addShipbillOperateLogNewData(shipbillOperateLogSaveNewVO);

				// 回单日志
				if (ToolKits.isNotEmpty(ReceiptPhoto)) {
					// 运单节点保存
					shipbillNodeTrackingSaveNewVO.setStatus(DataDictionaryConstant.SHIPBILL_STATUS_HD_PIC);
					shipbillNodeTrackingSaveNewVO.setNodeEvent(DataDictionaryConstant.SHIPBILL_STATUSNAME_HD_PIC);
					shipbillNodeTrackingSaveNewVO.setPicUrl(ReceiptPhoto);
					shipbillNodeTrackingService.addShipbillNodeTrackingNewData(shipbillNodeTrackingSaveNewVO);

					// 运单日志保存
					shipbillOperateLogSaveNewVO.setOperateEvent(DataDictionaryConstant.SHIPBILL_STATUSNAME_HD_PIC);
					shipbillOperateLogSaveNewVO.setOldStatus(DataDictionaryConstant.SHIPBILL_STATUS_SD);
					shipbillOperateLogSaveNewVO.setNewStatus(DataDictionaryConstant.SHIPBILL_STATUS_HD_PIC);
					shipbillOperateLogService.addShipbillOperateLogNewData(shipbillOperateLogSaveNewVO);

				}

				return fatherShipbillHeaderModel.getShipbillId();
			} else {
				return null;
			}
		}
		return null;
	}

	/**
	 * 运单客服反馈
	 *
	 * @param storageHalfwayFeedBackByShipbillVO
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void shipbillFeedBackData(StorageHalfwayFeedBackByShipbillVO storageHalfwayFeedBackByShipbillVO) {
		ToolKits.isParamNull(storageHalfwayFeedBackByShipbillVO.getShipbillIds(), "运单ID不能为空");
		ToolKits.isParamNull(storageHalfwayFeedBackByShipbillVO.getFeedbackContent(), "反馈内容不能为空");
		ToolKits.isParamNull(storageHalfwayFeedBackByShipbillVO.getFeedbackDate(), "反馈日期不能为空");

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

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

		// 节点内容
		StringBuffer nodeEvent = new StringBuffer();
		nodeEvent.append("客服反馈 反馈内容:");
		nodeEvent.append(storageHalfwayFeedBackByShipbillVO.getFeedbackContent());
		nodeEvent.append(" 实时地点:");
		nodeEvent.append(storageHalfwayFeedBackByShipbillVO.getAddress());

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

		for (TmsShipbillHeaderModel tmsShipbillHeaderModel : tmsShipbillHeaderModelList) {

			// 运单节点信息
			ShipbillNodeTrackingSaveNewVO shipbillNodeTrackingSaveNewVO = new ShipbillNodeTrackingSaveNewVO();
			shipbillNodeTrackingSaveNewVO.setNodeDate(date);
			shipbillNodeTrackingSaveNewVO.setShipbillId(tmsShipbillHeaderModel.getShipbillId());
			shipbillNodeTrackingSaveNewVO.setShipbillNo(tmsShipbillHeaderModel.getShipbillId());
			shipbillNodeTrackingSaveNewVO.setUserId(user.getUserid());
			shipbillNodeTrackingSaveNewVO.setUserName(user.getNickname());
			shipbillNodeTrackingSaveNewVO.setEnterpriseId(user.getEnterpriseId());
			shipbillNodeTrackingSaveNewVO.setEnterpriseName(user.getEnterpriseName());
			shipbillNodeTrackingSaveNewVO.setStatus(tmsShipbillHeaderModel.getStatus());
			shipbillNodeTrackingSaveNewVO.setNodeEvent(nodeEvent.toString());
			shipbillNodeTrackingService.addShipbillNodeTrackingNewData(shipbillNodeTrackingSaveNewVO);

			// 运单日志信息
			ShipbillOperateLogSaveNewVO shipbillOperateLogSaveNewVO = new ShipbillOperateLogSaveNewVO();
			shipbillOperateLogSaveNewVO.setShipbillId(tmsShipbillHeaderModel.getShipbillId());
			shipbillOperateLogSaveNewVO.setShipbillNo(tmsShipbillHeaderModel.getShipbillId());
			shipbillOperateLogSaveNewVO.setOperateDate(date);
			shipbillOperateLogSaveNewVO.setEnterpriseId(user.getEnterpriseId());
			shipbillOperateLogSaveNewVO.setEnterpriseName(user.getEnterpriseName());
			shipbillOperateLogSaveNewVO.setUserId(user.getUserid());
			shipbillOperateLogSaveNewVO.setUserName(user.getNickname());
			shipbillOperateLogSaveNewVO.setOperateEvent(DataDictionaryConstant.SHIPBILL_STATUSNAME_KFFK);
			shipbillOperateLogSaveNewVO.setOldStatus(tmsShipbillHeaderModel.getStatus());
			shipbillOperateLogSaveNewVO.setNewStatus(tmsShipbillHeaderModel.getStatus());
			shipbillOperateLogService.addShipbillOperateLogNewData(shipbillOperateLogSaveNewVO);

			// 父运单的同步送达
			String fatherShipbillId = tmsShipbillHeaderModel.getShipbillId();
			while (ToolKits.isNotEmpty(fatherShipbillId)) {
				fatherShipbillId = fatherFeedBack(fatherShipbillId, date, user, shipbillNodeTrackingSaveNewVO);
			}
		}
	}

	/**
	 * 父级运单客服反馈
	 * 
	 * @param shipbillId
	 * @param date
	 * @param user
	 * @return
	 */
	private String fatherFeedBack(String shipbillId, Date date, UserEntity user, ShipbillNodeTrackingSaveNewVO shipbillNodeTrackingSaveNewVO) {
		// 查询运单
		TmsShipbillHeaderModel tmsShipbillHeaderModel = tmsShipbillHeaderMapper.findById(shipbillId, TmsShipbillHeaderModel.class);

		// 判断是否为原始单号
		if (ToolKits.isNotEmpty(tmsShipbillHeaderModel.getFatherShipbillId()) && !tmsShipbillHeaderModel.getFatherShipbillId().equals(shipbillId)) {
			// 查找父级单号
			TmsShipbillHeaderModel fatherShipbillHeaderModel = tmsShipbillHeaderMapper.findById(tmsShipbillHeaderModel.getFatherShipbillId(), TmsShipbillHeaderModel.class);
			// 运单节点信息
			shipbillNodeTrackingSaveNewVO.setShipbillId(fatherShipbillHeaderModel.getShipbillId());
			shipbillNodeTrackingSaveNewVO.setShipbillNo(fatherShipbillHeaderModel.getShipbillId());
			shipbillNodeTrackingSaveNewVO.setStatus(fatherShipbillHeaderModel.getStatus());
			shipbillNodeTrackingService.addShipbillNodeTrackingNewData(shipbillNodeTrackingSaveNewVO);

			// 运单日志信息
			ShipbillOperateLogSaveNewVO shipbillOperateLogSaveNewVO = new ShipbillOperateLogSaveNewVO();
			shipbillOperateLogSaveNewVO.setShipbillId(fatherShipbillHeaderModel.getShipbillId());
			shipbillOperateLogSaveNewVO.setShipbillNo(fatherShipbillHeaderModel.getShipbillId());
			shipbillOperateLogSaveNewVO.setOperateDate(date);
			shipbillOperateLogSaveNewVO.setEnterpriseId(user.getEnterpriseId());
			shipbillOperateLogSaveNewVO.setEnterpriseName(user.getEnterpriseName());
			shipbillOperateLogSaveNewVO.setUserId(user.getUserid());
			shipbillOperateLogSaveNewVO.setUserName(user.getNickname());
			shipbillOperateLogSaveNewVO.setOperateEvent(DataDictionaryConstant.SHIPBILL_STATUSNAME_KFFK);
			shipbillOperateLogSaveNewVO.setOldStatus(fatherShipbillHeaderModel.getStatus());
			shipbillOperateLogSaveNewVO.setNewStatus(fatherShipbillHeaderModel.getStatus());
			shipbillOperateLogService.addShipbillOperateLogNewData(shipbillOperateLogSaveNewVO);

			return fatherShipbillHeaderModel.getShipbillId();
		}
		return null;
	}

	/**
	 * 运单异常登记
	 *
	 * @param storageHalfwayAbnormalRegisterByShipbillVO
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void shipbillAbnormalRegisterData(StorageHalfwayAbnormalRegisterByShipbillVO storageHalfwayAbnormalRegisterByShipbillVO) {
		ToolKits.isParamNull(storageHalfwayAbnormalRegisterByShipbillVO.getShipbillIds(), "运单ID不能为空");
		ToolKits.isParamNull(storageHalfwayAbnormalRegisterByShipbillVO.getAbnormalTime(), "异常发生时间不能为空");
		ToolKits.isParamNull(storageHalfwayAbnormalRegisterByShipbillVO.getAbnormalType(), "异常类型不能为空");
		ToolKits.isParamNull(storageHalfwayAbnormalRegisterByShipbillVO.getAbnormalEvent(), "异常事件不能为空");

		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.ABNORMAL_TYPE, null, null, null);
		if (!restMessage1.isSuccess()) {
			throw new RuntimeException("已派车状态翻译失败!");
		} else {
			data1 = restMessage1.getData();
		}

		// 异常事件
		RestMessage<List<Map<String, Object>>> restMessage2 = maindataTmsResource.getDropDownById(DataDictionaryConstant.ABNORMAL_EVENT, null, null, null);
		if (!restMessage2.isSuccess()) {
			throw new RuntimeException("已派车状态翻译失败!");
		} else {
			data2 = restMessage2.getData();
		}

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

		// 节点内容
		StringBuffer nodeEvent = new StringBuffer();
		nodeEvent.append("异常登记,异常类型:");
		nodeEvent.append(PublicMethods.change(data1, String.valueOf(storageHalfwayAbnormalRegisterByShipbillVO.getAbnormalType())));
		nodeEvent.append(",异常事件:");
		nodeEvent.append(PublicMethods.change(data2, String.valueOf(storageHalfwayAbnormalRegisterByShipbillVO.getAbnormalEvent())));
		if (ToolKits.isNotEmpty(storageHalfwayAbnormalRegisterByShipbillVO.getAbnormalContent())) {
			nodeEvent.append(",异常内容为:");
			nodeEvent.append(storageHalfwayAbnormalRegisterByShipbillVO.getAbnormalContent());
		}

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

		for (TmsShipbillHeaderModel tmsShipbillHeaderModel : tmsShipbillHeaderModelList) {

			// 运单节点信息
			ShipbillNodeTrackingSaveNewVO shipbillNodeTrackingSaveNewVO = new ShipbillNodeTrackingSaveNewVO();
			shipbillNodeTrackingSaveNewVO.setNodeDate(storageHalfwayAbnormalRegisterByShipbillVO.getAbnormalTime());
			shipbillNodeTrackingSaveNewVO.setShipbillId(tmsShipbillHeaderModel.getShipbillId());
			shipbillNodeTrackingSaveNewVO.setShipbillNo(tmsShipbillHeaderModel.getShipbillId());
			shipbillNodeTrackingSaveNewVO.setUserId(user.getUserid());
			shipbillNodeTrackingSaveNewVO.setUserName(user.getNickname());
			shipbillNodeTrackingSaveNewVO.setEnterpriseId(user.getEnterpriseId());
			shipbillNodeTrackingSaveNewVO.setEnterpriseName(user.getEnterpriseName());
			shipbillNodeTrackingSaveNewVO.setStatus(tmsShipbillHeaderModel.getStatus());
			shipbillNodeTrackingSaveNewVO.setNodeEvent(nodeEvent.toString());
			shipbillNodeTrackingSaveNewVO.setPicUrl(storageHalfwayAbnormalRegisterByShipbillVO.getAbnormalPhoto());
			shipbillNodeTrackingService.addShipbillNodeTrackingNewData(shipbillNodeTrackingSaveNewVO);

			// 运单日志信息
			ShipbillOperateLogSaveNewVO shipbillOperateLogSaveNewVO = new ShipbillOperateLogSaveNewVO();
			shipbillOperateLogSaveNewVO.setShipbillId(tmsShipbillHeaderModel.getShipbillId());
			shipbillOperateLogSaveNewVO.setShipbillNo(tmsShipbillHeaderModel.getShipbillId());
			shipbillOperateLogSaveNewVO.setOperateDate(date);
			shipbillOperateLogSaveNewVO.setEnterpriseId(user.getEnterpriseId());
			shipbillOperateLogSaveNewVO.setEnterpriseName(user.getEnterpriseName());
			shipbillOperateLogSaveNewVO.setUserId(user.getUserid());
			shipbillOperateLogSaveNewVO.setUserName(user.getNickname());
			shipbillOperateLogSaveNewVO.setOperateEvent(DataDictionaryConstant.SHIPBILL_STATUSNAME_YCDJ);
			shipbillOperateLogSaveNewVO.setOldStatus(tmsShipbillHeaderModel.getStatus());
			shipbillOperateLogSaveNewVO.setNewStatus(tmsShipbillHeaderModel.getStatus());
			shipbillOperateLogService.addShipbillOperateLogNewData(shipbillOperateLogSaveNewVO);

			// 父运单的异常登记
			String fatherShipbillId = tmsShipbillHeaderModel.getShipbillId();
			while (ToolKits.isNotEmpty(fatherShipbillId)) {
				fatherShipbillId = fatherAbnormalRegister(fatherShipbillId, date, user, shipbillNodeTrackingSaveNewVO);
			}
		}
	}

	/**
	 * 父级运单异常登记
	 *
	 * @param shipbillId
	 * @param date
	 * @param user
	 * @param shipbillNodeTrackingSaveNewVO
	 * @return
	 */
	private String fatherAbnormalRegister(String shipbillId, Date date, UserEntity user, ShipbillNodeTrackingSaveNewVO shipbillNodeTrackingSaveNewVO) {
		// 查询运单
		TmsShipbillHeaderModel tmsShipbillHeaderModel = tmsShipbillHeaderMapper.findById(shipbillId, TmsShipbillHeaderModel.class);

		// 判断是否为原始单号
		if (ToolKits.isNotEmpty(tmsShipbillHeaderModel.getFatherShipbillId()) && !tmsShipbillHeaderModel.getFatherShipbillId().equals(shipbillId)) {
			// 查找父级单号
			TmsShipbillHeaderModel fatherShipbillHeaderModel = tmsShipbillHeaderMapper.findById(tmsShipbillHeaderModel.getFatherShipbillId(), TmsShipbillHeaderModel.class);

			// 运单节点信息
			shipbillNodeTrackingSaveNewVO.setShipbillId(fatherShipbillHeaderModel.getShipbillId());
			shipbillNodeTrackingSaveNewVO.setShipbillNo(fatherShipbillHeaderModel.getShipbillId());
			shipbillNodeTrackingSaveNewVO.setStatus(fatherShipbillHeaderModel.getStatus());
			shipbillNodeTrackingService.addShipbillNodeTrackingNewData(shipbillNodeTrackingSaveNewVO);

			// 运单日志信息
			ShipbillOperateLogSaveNewVO shipbillOperateLogSaveNewVO = new ShipbillOperateLogSaveNewVO();
			shipbillOperateLogSaveNewVO.setShipbillId(fatherShipbillHeaderModel.getShipbillId());
			shipbillOperateLogSaveNewVO.setShipbillNo(fatherShipbillHeaderModel.getShipbillId());
			shipbillOperateLogSaveNewVO.setOperateDate(date);
			shipbillOperateLogSaveNewVO.setEnterpriseId(user.getEnterpriseId());
			shipbillOperateLogSaveNewVO.setEnterpriseName(user.getEnterpriseName());
			shipbillOperateLogSaveNewVO.setUserId(user.getUserid());
			shipbillOperateLogSaveNewVO.setUserName(user.getNickname());
			shipbillOperateLogSaveNewVO.setOperateEvent(DataDictionaryConstant.SHIPBILL_STATUSNAME_YCDJ);
			shipbillOperateLogSaveNewVO.setOldStatus(fatherShipbillHeaderModel.getStatus());
			shipbillOperateLogSaveNewVO.setNewStatus(fatherShipbillHeaderModel.getStatus());
			shipbillOperateLogService.addShipbillOperateLogNewData(shipbillOperateLogSaveNewVO);

			return fatherShipbillHeaderModel.getShipbillId();
		}
		return null;
	}

	/**
	 * 派车单送达确认
	 *
	 * @param storageHalfwayDeliveredConfirmVO
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void deliveredConfirmData(StorageHalfwayDeliveredConfirmVO storageHalfwayDeliveredConfirmVO) {
		ToolKits.isParamNull(storageHalfwayDeliveredConfirmVO.getLoadbillIds(), "派车单ID不能为空");
		ToolKits.isParamNull(storageHalfwayDeliveredConfirmVO.getDeliveryTime(), "送达时间不能为空");
		ToolKits.isParamNull(storageHalfwayDeliveredConfirmVO.getDeliveryStatus(), "配送状态不能为空");

		// 判断配送状态是滞留还是失败
		if (storageHalfwayDeliveredConfirmVO.getDeliveryStatus() == DataDictionaryConstant.DELIVERY_STATUS_STAY) {
			ToolKits.isParamNull(storageHalfwayDeliveredConfirmVO.getDeliveryStrandedReason(), "送达滞留原因不能为空");
		} else if (storageHalfwayDeliveredConfirmVO.getDeliveryStatus() == DataDictionaryConstant.DELIVERY_STATUS_SUCCESS) {
			ToolKits.isParamNull(storageHalfwayDeliveredConfirmVO.getDeliveryFailureReason(), "送达失败原因不能为空");
		}

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

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

		// 当前时间
		Date date = DateUtils.nowDate();
		// 签到时间是否为空
		boolean deliverySignTime = false;
		// 货物图片
		String GoodsPhoto = "";
		// 回单图片
		String ReceiptPhoto = "";

		// 节点内容
		StringBuffer nodeEvent = new StringBuffer();
		nodeEvent.append("送达确认 送达签收人:");
		nodeEvent.append(ToolKits.isEmpty(storageHalfwayDeliveredConfirmVO.getDeliverySignPerson()) ? "" : storageHalfwayDeliveredConfirmVO.getDeliverySignPerson());
		nodeEvent.append(" 送达备注:");
		nodeEvent.append(ToolKits.isEmpty(storageHalfwayDeliveredConfirmVO.getDeliveryMemo()) ? "" : storageHalfwayDeliveredConfirmVO.getDeliveryMemo());

		// 查询派车单明细
		Criteria criteriaDetail = Criteria.forClass(TmsLoadingBillDetailModel.class);
		Restriction r1 = Restrictions.in("loadingBillId", storageHalfwayDeliveredConfirmVO.getLoadbillIds().toArray());
		criteriaDetail.setRestriction(r1);

		List<TmsLoadingBillDetailModel> tmsLoadingBillDetailModelList = tmsLoadingBillDetailMapper.findByCriteria(criteriaDetail);
		ToolKits.isParamNull(tmsLoadingBillDetailModelList, "派车单有误,未查询到对应的运单数据");

		// 判断签到时间是否需要必填
		List<TmsLoadingBillDetailModel> tmsLoadingBillDetailModels = tmsLoadingBillDetailModelList.stream().filter(o -> StatusConstant.WHETHER_YES == o.getConsigneeDeliverySign()).collect(Collectors.toList());
		if (ToolKits.isNotEmpty(tmsLoadingBillDetailModels)) {
			ToolKits.isParamNull(storageHalfwayDeliveredConfirmVO.getDeliverySignTime(), "签到时间不能为空");
		}

		// 判断货物图片是否需要必填
		List<TmsLoadingBillDetailModel> tmsLoadingBillDetailModels2 = tmsLoadingBillDetailModelList.stream().filter(o -> StatusConstant.WHETHER_YES == o.getConsigneeDeliveryPicture()).collect(Collectors.toList());
		if (ToolKits.isNotEmpty(tmsLoadingBillDetailModels2)) {
			ToolKits.isParamNull(storageHalfwayDeliveredConfirmVO.getGoodsPhoto(), "货物图片不能为空");
			GoodsPhoto = storageHalfwayDeliveredConfirmVO.getGoodsPhoto();
		}

		Criteria criteriaTransport = Criteria.forClass(TmsShipbillTransLogModel.class);
		Map<String, Object> mapTransportLogUpdate = Maps.newHashMap();
		mapTransportLogUpdate.put("updateperson", user.getNickname());
		mapTransportLogUpdate.put("updatetime", date);
		// 送达时间
		mapTransportLogUpdate.put("deliveryTime", storageHalfwayDeliveredConfirmVO.getDeliveryTime());
		// 配送状态
		mapTransportLogUpdate.put("deliveryStatus", storageHalfwayDeliveredConfirmVO.getDeliveryStatus());
		// 签到时间
		if (ToolKits.isNotEmpty(storageHalfwayDeliveredConfirmVO.getDeliverySignTime())) {
			mapTransportLogUpdate.put("deliverySignTime", storageHalfwayDeliveredConfirmVO.getDeliverySignTime());
		}
		// 备注
		if (ToolKits.isNotEmpty(storageHalfwayDeliveredConfirmVO.getDeliveryMemo())) {
			mapTransportLogUpdate.put("deliveryMemo", storageHalfwayDeliveredConfirmVO.getDeliveryMemo());
		}
		// 签到时间
		if (ToolKits.isNotEmpty(storageHalfwayDeliveredConfirmVO.getDeliveryFailureReason())) {
			mapTransportLogUpdate.put("deliveryFailureReason", storageHalfwayDeliveredConfirmVO.getDeliveryFailureReason());
		}
		// 送达滞留原因
		if (ToolKits.isNotEmpty(storageHalfwayDeliveredConfirmVO.getDeliveryStrandedReason())) {
			mapTransportLogUpdate.put("deliveryStrandedReason", storageHalfwayDeliveredConfirmVO.getDeliveryStrandedReason());
		}

		for (TmsLoadingBillDetailModel tmsLoadingBillDetailModel : tmsLoadingBillDetailModelList) {
			Map<String, Object> mapUpdate = Maps.newHashMap();

			// 修改运单
			tmsLoadingBillDetailModel.setStatus(DataDictionaryConstant.SHIPBILL_STATUS_SD);
			tmsLoadingBillDetailModel.setTransportStatus(DataDictionaryConstant.TRANSPORT_STATUS_ARRIVED);
			tmsLoadingBillDetailModel.setUpdateperson(user.getNickname());
			tmsLoadingBillDetailModel.setUpdatetime(date);

			r1 = Restrictions.eq("shipbillId", tmsLoadingBillDetailModel.getShipbillId());
			criteriaTransport.setRestriction(r1);
			// 更新订单运输记录表
			tmsShipbillTransportLogMapper.updateMapByCriteria(mapTransportLogUpdate, criteriaTransport);

			// 运单节点信息
			ShipbillNodeTrackingSaveNewVO shipbillNodeTrackingSaveNewVO = new ShipbillNodeTrackingSaveNewVO();
			shipbillNodeTrackingSaveNewVO.setNodeDate(date);
			shipbillNodeTrackingSaveNewVO.setShipbillId(tmsLoadingBillDetailModel.getShipbillId());
			shipbillNodeTrackingSaveNewVO.setShipbillNo(tmsLoadingBillDetailModel.getShipbillId());
			shipbillNodeTrackingSaveNewVO.setUserId(user.getUserid());
			shipbillNodeTrackingSaveNewVO.setUserName(user.getNickname());
			shipbillNodeTrackingSaveNewVO.setEnterpriseId(user.getEnterpriseId());
			shipbillNodeTrackingSaveNewVO.setEnterpriseName(user.getEnterpriseName());

			// 运单日志信息
			ShipbillOperateLogSaveNewVO shipbillOperateLogSaveNewVO = new ShipbillOperateLogSaveNewVO();
			shipbillOperateLogSaveNewVO.setShipbillId(tmsLoadingBillDetailModel.getShipbillId());
			shipbillOperateLogSaveNewVO.setShipbillNo(tmsLoadingBillDetailModel.getShipbillId());
			shipbillOperateLogSaveNewVO.setOperateDate(date);
			shipbillOperateLogSaveNewVO.setEnterpriseId(user.getEnterpriseId());
			shipbillOperateLogSaveNewVO.setEnterpriseName(user.getEnterpriseName());
			shipbillOperateLogSaveNewVO.setUserId(user.getUserid());
			shipbillOperateLogSaveNewVO.setUserName(user.getNickname());

			if (ToolKits.isNotEmpty(storageHalfwayDeliveredConfirmVO.getDeliverySignTime())) {
				// 运单节点保存
				shipbillNodeTrackingSaveNewVO.setStatus(DataDictionaryConstant.SHIPBILL_STATUS_SD);
				shipbillNodeTrackingSaveNewVO.setNodeEvent(DataDictionaryConstant.SHIPBILL_STATUSNAME_SDQD);
				shipbillNodeTrackingService.addShipbillNodeTrackingNewData(shipbillNodeTrackingSaveNewVO);

				// 运单日志保存
				shipbillOperateLogSaveNewVO.setOperateEvent(DataDictionaryConstant.SHIPBILL_STATUSNAME_SDQD);
				shipbillOperateLogSaveNewVO.setOldStatus(DataDictionaryConstant.SHIPBILL_STATUS_QY);
				shipbillOperateLogSaveNewVO.setNewStatus(DataDictionaryConstant.SHIPBILL_STATUS_SD);
				shipbillOperateLogService.addShipbillOperateLogNewData(shipbillOperateLogSaveNewVO);

				deliverySignTime = true;
			}

			// 运单节点保存
			shipbillNodeTrackingSaveNewVO.setStatus(DataDictionaryConstant.SHIPBILL_STATUS_SD);
			shipbillNodeTrackingSaveNewVO.setNodeEvent(nodeEvent.toString());
			shipbillNodeTrackingSaveNewVO.setPicUrl(storageHalfwayDeliveredConfirmVO.getGoodsPhoto());
			shipbillNodeTrackingService.addShipbillNodeTrackingNewData(shipbillNodeTrackingSaveNewVO);

			// 运单日志保存
			shipbillOperateLogSaveNewVO.setOperateEvent(DataDictionaryConstant.SHIPBILL_STATUSNAME_SD);
			shipbillOperateLogSaveNewVO.setOldStatus(DataDictionaryConstant.SHIPBILL_STATUS_QY);
			shipbillOperateLogSaveNewVO.setNewStatus(DataDictionaryConstant.SHIPBILL_STATUS_SD);
			shipbillOperateLogService.addShipbillOperateLogNewData(shipbillOperateLogSaveNewVO);

			if (ToolKits.isNotEmpty(storageHalfwayDeliveredConfirmVO.getReceiptPhoto())) {
				// 运单节点保存
				shipbillNodeTrackingSaveNewVO.setStatus(DataDictionaryConstant.SHIPBILL_STATUS_HD_PIC);
				shipbillNodeTrackingSaveNewVO.setNodeEvent(DataDictionaryConstant.SHIPBILL_STATUSNAME_HD_PIC);
				shipbillNodeTrackingSaveNewVO.setPicUrl(storageHalfwayDeliveredConfirmVO.getReceiptPhoto());
				shipbillNodeTrackingService.addShipbillNodeTrackingNewData(shipbillNodeTrackingSaveNewVO);

				// 运单日志保存
				shipbillOperateLogSaveNewVO.setOperateEvent(DataDictionaryConstant.SHIPBILL_STATUSNAME_HD_PIC);
				shipbillOperateLogSaveNewVO.setOldStatus(DataDictionaryConstant.SHIPBILL_STATUS_QY);
				shipbillOperateLogSaveNewVO.setNewStatus(DataDictionaryConstant.SHIPBILL_STATUS_HD_PIC);
				shipbillOperateLogService.addShipbillOperateLogNewData(shipbillOperateLogSaveNewVO);

				ReceiptPhoto = storageHalfwayDeliveredConfirmVO.getReceiptPhoto();

				tmsLoadingBillDetailModel.setStatus(DataDictionaryConstant.SHIPBILL_STATUS_HD_PIC);
				mapUpdate.put("status", DataDictionaryConstant.SHIPBILL_STATUS_HD_PIC);
			} else {
				mapUpdate.put("status", DataDictionaryConstant.SHIPBILL_STATUS_SD);
			}

			// 派车单修改
			tmsLoadingBillDetailMapper.update(tmsLoadingBillDetailModel);

			// 修改运单
			criteriaDetail = Criteria.forClass(TmsShipbillHeaderModel.class);
			r1 = Restrictions.eq("shipbillId", tmsLoadingBillDetailModel.getShipbillId());
			criteriaDetail.setRestriction(r1);

			mapUpdate.put("transportStatus", DataDictionaryConstant.TRANSPORT_STATUS_ARRIVED);
			mapUpdate.put("updateperson", user.getNickname());
			mapUpdate.put("updatetime", date);

			tmsShipbillHeaderMapper.updateMapByCriteria(mapUpdate, criteriaDetail);

			// 父运单的同步送达
			String fatherShipbillId = tmsLoadingBillDetailModel.getShipbillId();
			while (ToolKits.isNotEmpty(fatherShipbillId)) {
				fatherShipbillId = fatherDeliveredConfirm(fatherShipbillId, date, user, deliverySignTime, GoodsPhoto, ReceiptPhoto, mapTransportLogUpdate);
				deliverySignTime = false;
			}
			MessageUtil.addMessage(new SendMessageDTO(MessageOrderTypeEnum.SHIP_NO.getCode(), MessageTypeEnum.DELIVERY.getCode(), Lists.newArrayList(tmsLoadingBillDetailModel.getShipbillId())));
		}
	}

	/**
	 * 派车单客服反馈
	 *
	 * @param storageHalfwayFeedBackVO
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void feedBackData(StorageHalfwayFeedBackVO storageHalfwayFeedBackVO) {
		ToolKits.isParamNull(storageHalfwayFeedBackVO.getLoadbillIds(), "派车单ID不能为空");
		ToolKits.isParamNull(storageHalfwayFeedBackVO.getFeedbackContent(), "反馈内容不能为空");
		ToolKits.isParamNull(storageHalfwayFeedBackVO.getFeedbackDate(), "反馈日期不能为空");

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

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

		// 节点内容
		StringBuffer nodeEvent = new StringBuffer();
		nodeEvent.append("客服反馈 反馈内容:");
		nodeEvent.append(storageHalfwayFeedBackVO.getFeedbackContent());
		nodeEvent.append(" 实时地点:");
		nodeEvent.append(storageHalfwayFeedBackVO.getAddress());

		Criteria criteriaDetail = Criteria.forClass(TmsLoadingBillDetailModel.class);
		Restriction r1 = Restrictions.in("loadingBillId", storageHalfwayFeedBackVO.getLoadbillIds().toArray());
		criteriaDetail.setRestriction(r1);

		List<TmsLoadingBillDetailModel> tmsLoadingBillDetailModelList = tmsLoadingBillDetailMapper.findByCriteria(criteriaDetail);
		ToolKits.isParamNull(tmsLoadingBillDetailModelList, "派车单有误,未查询到对应的运单数据");

		for (TmsLoadingBillDetailModel tmsLoadingBillDetailModel : tmsLoadingBillDetailModelList) {

			// 运单节点信息
			ShipbillNodeTrackingSaveNewVO shipbillNodeTrackingSaveNewVO = new ShipbillNodeTrackingSaveNewVO();
			shipbillNodeTrackingSaveNewVO.setNodeDate(storageHalfwayFeedBackVO.getFeedbackDate());
			shipbillNodeTrackingSaveNewVO.setShipbillId(tmsLoadingBillDetailModel.getShipbillId());
			shipbillNodeTrackingSaveNewVO.setShipbillNo(tmsLoadingBillDetailModel.getShipbillId());
			shipbillNodeTrackingSaveNewVO.setUserId(user.getUserid());
			shipbillNodeTrackingSaveNewVO.setUserName(user.getNickname());
			shipbillNodeTrackingSaveNewVO.setEnterpriseId(user.getEnterpriseId());
			shipbillNodeTrackingSaveNewVO.setEnterpriseName(user.getEnterpriseName());
			shipbillNodeTrackingSaveNewVO.setStatus(tmsLoadingBillDetailModel.getStatus());
			shipbillNodeTrackingSaveNewVO.setNodeEvent(nodeEvent.toString());
			shipbillNodeTrackingSaveNewVO.setPicUrl(storageHalfwayFeedBackVO.getFeedbackPicture());
			shipbillNodeTrackingService.addShipbillNodeTrackingNewData(shipbillNodeTrackingSaveNewVO);

			// 运单日志信息
			ShipbillOperateLogSaveNewVO shipbillOperateLogSaveNewVO = new ShipbillOperateLogSaveNewVO();
			shipbillOperateLogSaveNewVO.setShipbillId(tmsLoadingBillDetailModel.getShipbillId());
			shipbillOperateLogSaveNewVO.setShipbillNo(tmsLoadingBillDetailModel.getShipbillId());
			shipbillOperateLogSaveNewVO.setOperateDate(date);
			shipbillOperateLogSaveNewVO.setEnterpriseId(user.getEnterpriseId());
			shipbillOperateLogSaveNewVO.setEnterpriseName(user.getEnterpriseName());
			shipbillOperateLogSaveNewVO.setUserId(user.getUserid());
			shipbillOperateLogSaveNewVO.setUserName(user.getNickname());
			shipbillOperateLogSaveNewVO.setOperateEvent(DataDictionaryConstant.SHIPBILL_STATUSNAME_KFFK);
			shipbillOperateLogSaveNewVO.setOldStatus(tmsLoadingBillDetailModel.getStatus());
			shipbillOperateLogSaveNewVO.setNewStatus(tmsLoadingBillDetailModel.getStatus());
			shipbillOperateLogService.addShipbillOperateLogNewData(shipbillOperateLogSaveNewVO);

			// 父运单的同步送达
			String fatherShipbillId = tmsLoadingBillDetailModel.getShipbillId();
			while (ToolKits.isNotEmpty(fatherShipbillId)) {
				fatherShipbillId = fatherFeedBack(fatherShipbillId, date, user, shipbillNodeTrackingSaveNewVO);
			}
		}
	}

	/**
	 * 派车单异常登记
	 *
	 * @param storageHalfwayAbnormalRegisterVO
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void abnormalRegisterData(StorageHalfwayAbnormalRegisterVO storageHalfwayAbnormalRegisterVO) {
		ToolKits.isParamNull(storageHalfwayAbnormalRegisterVO.getLoadbillIds(), "派车单ID不能为空");
		ToolKits.isParamNull(storageHalfwayAbnormalRegisterVO.getAbnormalTime(), "异常发生时间不能为空");
		ToolKits.isParamNull(storageHalfwayAbnormalRegisterVO.getAbnormalType(), "异常类型不能为空");
		ToolKits.isParamNull(storageHalfwayAbnormalRegisterVO.getAbnormalEvent(), "异常事件不能为空");

		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.ABNORMAL_TYPE, null, null, null);
		if (!restMessage1.isSuccess()) {
			throw new RuntimeException("已派车状态翻译失败!");
		} else {
			data1 = restMessage1.getData();
		}

		// 异常事件
		RestMessage<List<Map<String, Object>>> restMessage2 = maindataTmsResource.getDropDownById(DataDictionaryConstant.ABNORMAL_EVENT, null, null, null);
		if (!restMessage2.isSuccess()) {
			throw new RuntimeException("已派车状态翻译失败!");
		} else {
			data2 = restMessage2.getData();
		}

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

		// 节点内容
		StringBuffer nodeEvent = new StringBuffer();
		nodeEvent.append("异常登记 异常类型:");
		nodeEvent.append(PublicMethods.change(data1, String.valueOf(storageHalfwayAbnormalRegisterVO.getAbnormalType())));
		nodeEvent.append(" 异常事件:");
		nodeEvent.append(PublicMethods.change(data2, String.valueOf(storageHalfwayAbnormalRegisterVO.getAbnormalEvent())));
		if (ToolKits.isNotEmpty(storageHalfwayAbnormalRegisterVO.getAbnormalContent())) {
			nodeEvent.append(",异常内容为:");
			nodeEvent.append(storageHalfwayAbnormalRegisterVO.getAbnormalContent());
		}

		Criteria criteriaDetail = Criteria.forClass(TmsLoadingBillDetailModel.class);
		Restriction r1 = Restrictions.in("loadingBillId", storageHalfwayAbnormalRegisterVO.getLoadbillIds().toArray());
		criteriaDetail.setRestriction(r1);

		List<TmsLoadingBillDetailModel> tmsLoadingBillDetailModelList = tmsLoadingBillDetailMapper.findByCriteria(criteriaDetail);
		ToolKits.isParamNull(tmsLoadingBillDetailModelList, "派车单有误,未查询到对应的运单数据");

		for (TmsLoadingBillDetailModel tmsLoadingBillDetailModel : tmsLoadingBillDetailModelList) {

			// 运单节点信息
			ShipbillNodeTrackingSaveNewVO shipbillNodeTrackingSaveNewVO = new ShipbillNodeTrackingSaveNewVO();
			shipbillNodeTrackingSaveNewVO.setNodeDate(storageHalfwayAbnormalRegisterVO.getAbnormalTime());
			shipbillNodeTrackingSaveNewVO.setShipbillId(tmsLoadingBillDetailModel.getShipbillId());
			shipbillNodeTrackingSaveNewVO.setShipbillNo(tmsLoadingBillDetailModel.getShipbillId());
			shipbillNodeTrackingSaveNewVO.setUserId(user.getUserid());
			shipbillNodeTrackingSaveNewVO.setUserName(user.getNickname());
			shipbillNodeTrackingSaveNewVO.setEnterpriseId(user.getEnterpriseId());
			shipbillNodeTrackingSaveNewVO.setEnterpriseName(user.getEnterpriseName());
			shipbillNodeTrackingSaveNewVO.setStatus(tmsLoadingBillDetailModel.getStatus());
			shipbillNodeTrackingSaveNewVO.setNodeEvent(nodeEvent.toString());
			shipbillNodeTrackingSaveNewVO.setPicUrl(storageHalfwayAbnormalRegisterVO.getAbnormalPhoto());
			shipbillNodeTrackingService.addShipbillNodeTrackingNewData(shipbillNodeTrackingSaveNewVO);

			// 运单日志信息
			ShipbillOperateLogSaveNewVO shipbillOperateLogSaveNewVO = new ShipbillOperateLogSaveNewVO();
			shipbillOperateLogSaveNewVO.setShipbillId(tmsLoadingBillDetailModel.getShipbillId());
			shipbillOperateLogSaveNewVO.setShipbillNo(tmsLoadingBillDetailModel.getShipbillId());
			shipbillOperateLogSaveNewVO.setOperateDate(date);
			shipbillOperateLogSaveNewVO.setEnterpriseId(user.getEnterpriseId());
			shipbillOperateLogSaveNewVO.setEnterpriseName(user.getEnterpriseName());
			shipbillOperateLogSaveNewVO.setUserId(user.getUserid());
			shipbillOperateLogSaveNewVO.setUserName(user.getNickname());
			shipbillOperateLogSaveNewVO.setOperateEvent(DataDictionaryConstant.SHIPBILL_STATUSNAME_YCDJ);
			shipbillOperateLogSaveNewVO.setOldStatus(tmsLoadingBillDetailModel.getStatus());
			shipbillOperateLogSaveNewVO.setNewStatus(tmsLoadingBillDetailModel.getStatus());
			shipbillOperateLogService.addShipbillOperateLogNewData(shipbillOperateLogSaveNewVO);

			// 父运单的同步送达
			String fatherShipbillId = tmsLoadingBillDetailModel.getShipbillId();
			while (ToolKits.isNotEmpty(fatherShipbillId)) {
				fatherShipbillId = fatherAbnormalRegister(fatherShipbillId, date, user, shipbillNodeTrackingSaveNewVO);
			}
		}
	}

	/**
	 * 导出所有数据
	 *
	 * @param storageHalfwayExportAllVO
	 * @return
	 */
	@Override
	public List<StorageHalfwayExportDTO> exportAllData(StorageHalfwayExportAllVO storageHalfwayExportAllVO) {
		UserEntity user = PlgFxUsrUtils.getUserEntity();
		ToolKits.isParamNull(user, "当前人员没有操作权限");

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

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

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

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

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

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

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

			// 状态翻译
			dto.setStatusName(PublicMethods.change(data1, String.valueOf(tmsLoadingBillHeaderModel.getStatus())));

			storageHalfwayExportDTOS.add(dto);
		}

		return storageHalfwayExportDTOS;
	}

	/**
	 * 导出当前页数据
	 *
	 * @param storageHalfwayExportPageVO
	 * @return
	 */
	@Override
	public List<StorageHalfwayExportDTO> exportPageData(StorageHalfwayExportPageVO storageHalfwayExportPageVO) {
		ToolKits.isParamNull(storageHalfwayExportPageVO.getPageNum(), "当前页码不为空");
		ToolKits.isParamNull(storageHalfwayExportPageVO.getPageSize(), "每页条数不为空");
		UserEntity user = PlgFxUsrUtils.getUserEntity();
		ToolKits.isParamNull(user, "当前人员没有操作权限");

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

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

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

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

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

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

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

			// 状态翻译
			dto.setStatusName(PublicMethods.change(data1, String.valueOf(tmsLoadingBillHeaderModel.getStatus())));

			storageHalfwayExportDTOS.add(dto);
		}

		return storageHalfwayExportDTOS;
	}

	/**
	 * 导出选择行数据
	 *
	 * @param loadbillIds
	 * @return
	 */
	@Override
	public List<StorageHalfwayExportDTO> exportSelectLineData(List<String> loadbillIds) {
		ToolKits.isParamNull(loadbillIds, "派车单ID不能为空");

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

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

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

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

		// 添加查询条件
		Criteria criteria = Criteria.forClass(TmsLoadingBillHeaderModel.class);
		Restriction r1 = Restrictions.eq("loadingBillId", loadbillIds.toArray());
		Restriction r2 = Restrictions.eq("carrierType", DataDictionaryConstant.LINE_CARRIER_TYPE_SJ);
		Restriction r3 = Restrictions.eq("loadingBillType", DataDictionaryConstant.LOADING_BILL_TYPE_RK);
		Restriction r4 = Restrictions.eq("enterpriseId", user.getEnterpriseId());
		Restriction r5 = null;
		Restriction r6 = Restrictions.in("departmentId", user.getDepts().stream().toArray(String[]::new));
		if (user.getUserType().equals(BussinessConstant.USER_TYPE_ZY)) {
			r5 = Restrictions.eq("scheduleType", DataDictionaryConstant.SCHEDULE_TYPE_ZY);
		} else {
			r5 = Restrictions.eq("scheduleType", DataDictionaryConstant.SCHEDULE_TYPE_CYS);
		}
		criteria.setRestriction(Restrictions.and(r1, r2, r3, r4, r5, r6));
		criteria.setOrder(Order.newInstance().desc(new String[] { "updatetime" }));

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

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

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

			// 状态翻译
			dto.setStatusName(PublicMethods.change(data1, String.valueOf(tmsLoadingBillHeaderModel.getStatus())));

			storageHalfwayExportDTOS.add(dto);
		}

		return storageHalfwayExportDTOS;
	}

	/**
	 * 入库在途打印
	 *
	 * @param loadbillIds
	 * @return
	 */
	@Override
	public Map<String, Object> printStorageHalfwayData(List<String> loadbillIds) {
		ToolKits.isParamNull(loadbillIds, "派车单ID不为空");

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

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

		for (TmsLoadingBillHeaderModel tmsLoadingBillHeaderModel : tmsLoadingBillHeaderModels) {
			StorageHalfwayPrintHeadDTO storageHalfwayPrintHeadDTO = new StorageHalfwayPrintHeadDTO();
			BeanUtils.copyProperties(tmsLoadingBillHeaderModel, storageHalfwayPrintHeadDTO);

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

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

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

				storageHalfwayPrintTableDTOS.add(dto);
			}

		}

		// TODO print

		return null;
	}

}
