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

import java.util.ArrayList;
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.ToolKits;
import com.prolog.framework.common.message.RestMessage;
import com.prolog.framework.core.exception.PrologException;
import com.prolog.framework.core.pojo.Page;
import com.prolog.framework.core.restriction.Criteria;
import com.prolog.framework.core.restriction.Order;
import com.prolog.framework.core.restriction.Restriction;
import com.prolog.framework.core.restriction.Restrictions;
import com.prolog.framework.dao.util.PageUtils;
import com.prolog.product.core.framework.entity.UserEntity;
import com.prolog.product.core.framework.util.PlgFxUsrUtils;
import com.prolog.rdc.tms.constant.BussinessConstant;
import com.prolog.rdc.tms.constant.DataDictionaryConstant;
import com.prolog.rdc.tms.constant.StatusConstant;
import com.prolog.rdc.tms.dao.mapper.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.OutsourceTrackExportDTO;
import com.prolog.rdc.tms.model.dto.OutsourceTrackItemDTO;
import com.prolog.rdc.tms.model.dto.OutsourceTrackPackageDTO;
import com.prolog.rdc.tms.model.dto.OutsourceTrackPageDTO;
import com.prolog.rdc.tms.model.dto.OutsourceTrackShipbillDTO;
import com.prolog.rdc.tms.model.dto.message.SendMessageDTO;
import com.prolog.rdc.tms.model.entity.SysRefdatadModel;
import com.prolog.rdc.tms.model.entity.TmsLoadingBillDetailModel;
import com.prolog.rdc.tms.model.entity.TmsLoadingBillHeaderModel;
import com.prolog.rdc.tms.model.entity.TmsShipbillDetailModel;
import com.prolog.rdc.tms.model.entity.TmsShipbillHeaderModel;
import com.prolog.rdc.tms.model.entity.TmsShipbillPackageModel;
import com.prolog.rdc.tms.model.entity.TmsShipbillTransLogModel;
import com.prolog.rdc.tms.model.enums.MessageOrderTypeEnum;
import com.prolog.rdc.tms.model.enums.MessageTypeEnum;
import com.prolog.rdc.tms.model.vo.ConsignmentHandoverVO;
import com.prolog.rdc.tms.model.vo.OutsourceTrackAdvancedQueryVO;
import com.prolog.rdc.tms.model.vo.OutsourceTrackExportVO;
import com.prolog.rdc.tms.model.vo.OutsourceTrackItemQueryVO;
import com.prolog.rdc.tms.model.vo.OutsourceTrackPackageQueryVO;
import com.prolog.rdc.tms.model.vo.OutsourceTrackQueryVO;
import com.prolog.rdc.tms.model.vo.OutsourceTrackShipbillQueryVO;
import com.prolog.rdc.tms.model.vo.ReturnOrderConfirmVO;
import com.prolog.rdc.tms.model.vo.ShipbillNodeTrackingSaveNewVO;
import com.prolog.rdc.tms.model.vo.ShipbillOperateLogSaveNewVO;
import com.prolog.rdc.tms.rmi.feign.MaindataFeign;
import com.prolog.rdc.tms.service.OutsourceTrackService;
import com.prolog.rdc.tms.service.ShipbillNodeTrackingService;
import com.prolog.rdc.tms.service.ShipbillOperateLogService;
import com.prolog.rdc.tms.util.ConvertorUtil;
import com.prolog.rdc.tms.util.MessageUtil;
import com.prolog.rdc.tms.util.PublicMethods;

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

/**
 * 运输管理——外包跟踪实现层 Company: 湖北普罗格科技股份有限公司
 *
 * @author xyf
 * @since 2022/4/18 12:43
 */
@Service
public class OutsourceTrackServiceImpl implements OutsourceTrackService {

	@Autowired
	private TmsLoadingBillHeaderMapper tmsLoadingBillHeaderMapper;

	@Autowired
	private TmsLoadingBillDetailMapper tmsLoadingBillDetailMapper;

	@Autowired
	private TmsShipbillDetailMapper tmsShipbillDetailMapper;

	@Autowired
	private TmsShipbillPackageMapper tmsShipbillPackageMapper;

	@Autowired
	private MaindataFeign maindataTmsResource;

	@Autowired
	private TmsShipbillHeaderMapper tmsShipbillHeaderMapper;

	@Autowired
	private ShipbillNodeTrackingService shipbillNodeTrackingService;

	@Autowired
	private ShipbillOperateLogService shipbillOperateLogService;

	@Autowired
	private TmsShipbillTransportLogMapper tmsShipbillTransportLogMapper;

	@Autowired
	private ConvertorUtil convertorUtil;

	/**
	 * 主界面分页查询
	 *
	 * @param
	 * @return outsourceTrackPageDTO
	 */
	@Override
	public Page<OutsourceTrackPageDTO> queryOutsourceTrackPage(OutsourceTrackQueryVO vo) throws Exception {
		UserEntity user = PlgFxUsrUtils.getUserEntity();
		ToolKits.isParamNull(user, "当前人员没有操作权限");

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

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

		PageUtils.startPage(vo.getPageNum(), vo.getPageSize());
		List<OutsourceTrackPageDTO> list = tmsLoadingBillHeaderMapper.queryOutsourceTrackPage(vo);

		for (OutsourceTrackPageDTO dto : list) {
			dto.setStatusName(ConvertorUtil.getName(dicData, DataDictionaryConstant.LOADING_BILL_STATUS, String.valueOf(dto.getStatus())));
		}
		return PageUtils.getPage(list);
	}

	/**
	 * 主界面高级查询
	 *
	 * @param vo
	 * @return
	 */
	@Override
	public Page<OutsourceTrackPageDTO> advancedQueryPage(OutsourceTrackAdvancedQueryVO vo) {
		ToolKits.isParamNull(vo, "汇总查询请求不为空");
		ToolKits.isParamNull(vo.getPageNum(), "当前页码不为空");
		ToolKits.isParamNull(vo.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, "当前人员没有操作权限");
		}

		// 权限控制
		vo.setEnterpriseId(user.getEnterpriseId());
		vo.setDepts(user.getDepts().stream().toArray(String[]::new));
		vo.setScheduleType(DataDictionaryConstant.SCHEDULE_TYPE_ZY);

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

		PageUtils.startPage(vo.getPageNum(), vo.getPageSize());
		List<OutsourceTrackPageDTO> outsourceTrackPageDTOS = tmsLoadingBillHeaderMapper.outsourceTrackAdvancedQuery(vo);

		return PageUtils.getPage(outsourceTrackPageDTOS);
	}

	/**
	 * 配载运单分页查询
	 *
	 * @param
	 * @return outsourceTrackShipbillDTO
	 */
	@SuppressWarnings("resource")
	@Override
	public Page<OutsourceTrackShipbillDTO> queryOutsourceTrackShipbill(OutsourceTrackShipbillQueryVO vo) throws Exception {
		UserEntity user = PlgFxUsrUtils.getUserEntity();
		ToolKits.isParamNull(user, "当前人员没有操作权限");

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

		// 订单类型
		RestMessage<List<Map<String, Object>>> restMessage1 = maindataTmsResource.getDropDownById(DataDictionaryConstant.ORDER_TYPE, null, null, null);
		if (!restMessage1.isSuccess()) {
			throw new PrologException("订单类型翻译失败!");
		} else {
			data1 = restMessage1.getData();
		}
		// 订单业务类型
		RestMessage<List<Map<String, Object>>> restMessage2 = maindataTmsResource.getDropDownById(DataDictionaryConstant.ORDER_BUSINESS_TYPE, null, null, null);
		if (!restMessage2.isSuccess()) {
			throw new PrologException("订单业务类型翻译失败!");
		} else {
			data2 = restMessage2.getData();
		}
		// 配送方式
		RestMessage<List<Map<String, Object>>> restMessage3 = maindataTmsResource.getDropDownById(DataDictionaryConstant.DELIVERY_METHOD_TYPE, null, null, null);
		if (!restMessage3.isSuccess()) {
			throw new PrologException("配送方式翻译失败!");
		} else {
			data3 = restMessage3.getData();
		}
		// 运输类型(运输模式)
		RestMessage<List<Map<String, Object>>> restMessage4 = maindataTmsResource.getDropDownById(DataDictionaryConstant.TRANSPORT_TYPE, null, null, null);
		if (!restMessage4.isSuccess()) {
			throw new PrologException("运输类型(运输模式)翻译失败!");
		} else {
			data4 = restMessage4.getData();
		}
		// 温度要求
		RestMessage<List<Map<String, Object>>> restMessage5 = maindataTmsResource.getDropDownById(DataDictionaryConstant.TEMPERATURE_REQUIREMENT, null, null, null);
		if (!restMessage5.isSuccess()) {
			throw new PrologException("温度要求翻译失败!");
		} else {
			data5 = restMessage5.getData();
		}
		// 发货方类型
		RestMessage<List<Map<String, Object>>> restMessage6 = maindataTmsResource.getDropDownById(DataDictionaryConstant.SHIPPER_TYPE, null, null, null);
		if (!restMessage6.isSuccess()) {
			throw new PrologException("发货方类型翻译失败!");
		} else {
			data6 = restMessage6.getData();
		}
		// 收货方类型
		RestMessage<List<Map<String, Object>>> restMessage7 = maindataTmsResource.getDropDownById(DataDictionaryConstant.CONSIGNEE_TYPE, null, null, null);
		if (!restMessage7.isSuccess()) {
			throw new PrologException("收货方类型翻译失败!");
		} else {
			data7 = restMessage7.getData();
		}
		// 运单状态
		RestMessage<List<Map<String, Object>>> restMessage8 = maindataTmsResource.getDropDownById(DataDictionaryConstant.SHIPBILL_STATUS, null, null, null);
		if (!restMessage8.isSuccess()) {
			throw new PrologException("运单状态翻译失败!");
		} else {
			data8 = restMessage8.getData();
		}
		// 承运商类型
		RestMessage<List<Map<String, Object>>> restMessage9 = maindataTmsResource.getDropDownById(DataDictionaryConstant.LINE_CARRIER_TYPE, null, null, null);
		if (!restMessage9.isSuccess()) {
			throw new PrologException("承运商类型翻译失败!");
		} else {
			data9 = restMessage9.getData();
		}

		// 封装运单明细查询
		Criteria criteria = Criteria.forClass(TmsLoadingBillDetailModel.class);
		Restriction r1 = Restrictions.eq("loadingBillId", vo.getLoadingBillId());
		criteria.setRestriction(r1);
		criteria.setOrder(Order.newInstance().asc(new String[] { "shippingOrder" }));
		PageUtils.startPage(vo.getPageNum(), vo.getPageSize());
		List<TmsLoadingBillDetailModel> tmsLoadingBillDetailModels = tmsLoadingBillDetailMapper.findByCriteria(criteria);

		// 返回数据集合
		List<OutsourceTrackShipbillDTO> dtos = Lists.newArrayList();

		for (TmsLoadingBillDetailModel model : tmsLoadingBillDetailModels) {
			OutsourceTrackShipbillDTO dto = new OutsourceTrackShipbillDTO();
			BeanUtils.copyProperties(model, dto);
			// 收货方位置(经纬度判断)
			if (ToolKits.isNotEmpty(model.getConsigneeLongitude()) && ToolKits.isNotEmpty(model.getConsigneeLatitude())) {
				dto.setConsigneePositioning(StatusConstant.POSITIONING_YDW);
			} else {
				dto.setConsigneePositioning(StatusConstant.POSITIONING_WDW);
			}
			// 发货方位置(经纬度判断)
			if (ToolKits.isNotEmpty(model.getShipperLongitude()) && ToolKits.isNotEmpty(model.getShipperLatitude())) {
				dto.setShipperPositioning(StatusConstant.POSITIONING_YDW);
			} else {
				dto.setShipperPositioning(StatusConstant.POSITIONING_WDW);
			}

			// 字典转义
			dto.setOrderTypeName(PublicMethods.change(data1, String.valueOf(dto.getOrderType())));
			dto.setOrderBusinessTypeName(PublicMethods.change(data2, String.valueOf(dto.getOrderBusinessType())));
			dto.setDeliveryMethodTypeName(PublicMethods.change(data3, String.valueOf(dto.getDeliveryMethodType())));
			dto.setTransportTypeName(PublicMethods.change(data4, String.valueOf(dto.getTransportType())));
			dto.setTemperatureRequirementName(PublicMethods.change(data5, String.valueOf(dto.getTemperatureRequirement())));
			dto.setShipperTypeName(PublicMethods.change(data6, String.valueOf(dto.getShipperType())));
			dto.setConsigneeTypeName(PublicMethods.change(data7, String.valueOf(dto.getConsigneeType())));
			dto.setStatusName(PublicMethods.change(data8, String.valueOf(dto.getStatus())));
			dto.setCarrierTypeName(PublicMethods.change(data9, String.valueOf(dto.getCarrierType())));
			dtos.add(dto);
		}

		Page<OutsourceTrackShipbillDTO> page = PageUtils.getPage(dtos);
		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
	 * @return outsourceTrackItemDTO
	 */
	@SuppressWarnings("resource")
	@Override
	public Page<OutsourceTrackItemDTO> queryOutsourceTrackItem(OutsourceTrackItemQueryVO vo) throws Exception {
		UserEntity user = PlgFxUsrUtils.getUserEntity();
		ToolKits.isParamNull(user, "当前人员没有操作权限");

		List<SysRefdatadModel> dicData = convertorUtil.getDictionary(new String[] { DataDictionaryConstant.PACK_TYPE, // 包装类型
				DataDictionaryConstant.CARGO_THERMOSPHERE// 货物温存
		});

		Map<String, Object> queryMap = Maps.newHashMap();
		queryMap.put("loadingBillId", vo.getLoadingBillId());
		List<TmsLoadingBillDetailModel> tmsLoadingBillDetails = tmsLoadingBillDetailMapper.findByMap(queryMap, TmsLoadingBillDetailModel.class);

		List<String> shipbillids = Lists.newArrayList();
		for (TmsLoadingBillDetailModel tmsLoadingBillDetail : tmsLoadingBillDetails) {
			shipbillids.add(tmsLoadingBillDetail.getShipbillId());
		}

		Criteria criteria = Criteria.forClass(TmsShipbillDetailModel.class);
		Restriction r1 = Restrictions.in("shipbillId", shipbillids.toArray());
		Restriction r2 = Restrictions.eq("enterpriseId", user.getEnterpriseId());
		criteria.setRestriction(Restrictions.and(r1, r2));
		criteria.setOrder(Order.newInstance().desc(new String[] { "updatetime" }));
		PageUtils.startPage(vo.getPageNum(), vo.getPageSize());
		List<TmsShipbillDetailModel> tmsShipbillDetailModels = tmsShipbillDetailMapper.findByCriteria(criteria);

		List<OutsourceTrackItemDTO> dtos = new ArrayList<OutsourceTrackItemDTO>();
		if (ToolKits.isNotEmpty(tmsShipbillDetailModels)) {
			for (TmsShipbillDetailModel tmsShipbillDetailModel : tmsShipbillDetailModels) {
				OutsourceTrackItemDTO dto = new OutsourceTrackItemDTO();
				BeanUtils.copyProperties(tmsShipbillDetailModel, dto);
				dto.setPackTypeName(ConvertorUtil.getName(dicData, DataDictionaryConstant.PACK_TYPE, String.valueOf(dto.getPackType())));
				dto.setCargoThermosphereName(ConvertorUtil.getName(dicData, DataDictionaryConstant.CARGO_THERMOSPHERE, String.valueOf(dto.getCargoThermosphere())));
				dtos.add(dto);
			}
		}

		Page<OutsourceTrackItemDTO> page = PageUtils.getPage(dtos);
		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
	 * @return outsourceTrackItemDTO
	 */
	@SuppressWarnings("resource")
	@Override
	public Page<OutsourceTrackPackageDTO> queryOutsourceTrackPackage(OutsourceTrackPackageQueryVO vo) throws Exception {
		UserEntity user = PlgFxUsrUtils.getUserEntity();
		ToolKits.isParamNull(user, "当前人员没有操作权限");

		List<SysRefdatadModel> dicData = convertorUtil.getDictionary(new String[] { DataDictionaryConstant.PACKAGE_TYPE, // 包裹类型
				DataDictionaryConstant.DEVICE_COMPANY// 设备生产厂商
		});

		Criteria criteria = Criteria.forClass(TmsShipbillPackageModel.class);
		Restriction r1 = Restrictions.eq("shipbillId", vo.getLoadingBillId());
		Restriction r2 = Restrictions.eq("enterpriseId", user.getEnterpriseId());
		criteria.setRestriction(Restrictions.and(r1, r2));
		criteria.setOrder(Order.newInstance().desc(new String[] { "updatetime" }));
		List<TmsShipbillPackageModel> tmsShipbillPackageModels = tmsShipbillPackageMapper.findByCriteria(criteria);
		List<OutsourceTrackPackageDTO> dtos = new ArrayList<OutsourceTrackPackageDTO>();

		if (ToolKits.isNotEmpty(tmsShipbillPackageModels)) {
			for (TmsShipbillPackageModel tmsShipbillPackageModel : tmsShipbillPackageModels) {
				OutsourceTrackPackageDTO dto = new OutsourceTrackPackageDTO();
				BeanUtils.copyProperties(tmsShipbillPackageModel, dto);
				dto.setPackageTypeName(ConvertorUtil.getName(dicData, DataDictionaryConstant.PACKAGE_TYPE, String.valueOf(dto.getPackageType())));
				dto.setDeviceCompanyName(ConvertorUtil.getName(dicData, DataDictionaryConstant.DEVICE_COMPANY, String.valueOf(dto.getDeviceCompany())));
				dtos.add(dto);
			}
		}

		Page<OutsourceTrackPackageDTO> page = PageUtils.getPage(dtos);
		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
	 * @return
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void consignmentHandover(ConsignmentHandoverVO vo) throws Exception {
		UserEntity user = PlgFxUsrUtils.getUserEntity();
		ToolKits.isParamNull(user, "当前人员没有操作权限");
		ToolKits.isParamNull(vo.getIds(), "请选择要操作的数据");

		StringBuffer nodeEvent = new StringBuffer();
		nodeEvent.append("托运交接 备注:");
		nodeEvent.append(vo.getMemo());

		for (String id : vo.getIds()) {
			TmsLoadingBillHeaderModel tmsLoadingBillHeader = tmsLoadingBillHeaderMapper.findById(id, TmsLoadingBillHeaderModel.class);
			if (ToolKits.isNotEmpty(tmsLoadingBillHeader)) {
				if (!tmsLoadingBillHeader.getStatus().equals(DataDictionaryConstant.LOADING_BILL_STATUS_YSH)) {
					throw new PrologException("调度单【"+tmsLoadingBillHeader.getLoadingBillId()+"】已托运交接了");
				}
				// 修改托运单的状态为【托运交接】
				tmsLoadingBillHeader.setStatus(DataDictionaryConstant.LOADING_BILL_STATUS_CONSIGNMENT_HANDOVER);
				tmsLoadingBillHeader.setUpdateperson(user.getNickname());
				tmsLoadingBillHeader.setUpdatetime(DateUtil.date());
				tmsLoadingBillHeader.setConsignmentAgen(vo.getConsignmentAgen());
				tmsLoadingBillHeader.setAgenContactPhoneNumber(vo.getAgenContacPhoneNumber());
				tmsLoadingBillHeader.setDriverId(vo.getDriverId());
				tmsLoadingBillHeader.setDriverCode(vo.getDriverCode());
				tmsLoadingBillHeader.setDriverName(vo.getDriverName());
				tmsLoadingBillHeader.setPictureUrl(vo.getPictureUrl());
				tmsLoadingBillHeader.setDriverIdCard(vo.getDriverIdCard());
				tmsLoadingBillHeader.setVehiclePlateNumber(vo.getVehiclePlateNumber());
				tmsLoadingBillHeader.setConsignmentHandoverDate(vo.getConsignmentHandoverTime());
				List<String> memo = Lists.newArrayList();
				if (ToolKits.isNotEmpty(tmsLoadingBillHeader.getMemo())) {
					memo.add(tmsLoadingBillHeader.getMemo());
				}
				if (ToolKits.isNotEmpty(vo.getMemo())) {
					memo.add(vo.getMemo());
				}
				if (ToolKits.isNotEmpty(memo)) {
					tmsLoadingBillHeader.setMemo(memo.stream().collect(Collectors.joining(",")));
				}
				tmsLoadingBillHeaderMapper.update(tmsLoadingBillHeader);

				Map<String, Object> queryMap = Maps.newHashMap();
				queryMap.put("loadingBillId", tmsLoadingBillHeader.getLoadingBillId());
				List<TmsLoadingBillDetailModel> tmsLoadingBillDetails = tmsLoadingBillDetailMapper.findByMap(queryMap, TmsLoadingBillDetailModel.class);
				for (TmsLoadingBillDetailModel tmsLoadingBillDetail : tmsLoadingBillDetails) {
					TmsShipbillHeaderModel tmsShipbillHeader = tmsShipbillHeaderMapper.findById(tmsLoadingBillDetail.getShipbillId(), TmsShipbillHeaderModel.class);
					if (ToolKits.isNotEmpty(tmsShipbillHeader)) {
						// 更新托运单下运单状态为【托运交接】
						/*tmsShipbillHeader.setUpdateperson(user.getNickname());
						tmsShipbillHeader.setUpdatetime(DateUtil.date());
						tmsShipbillHeader.setStatus(DataDictionaryConstant.SHIPBILL_STATUS_CONSIGNMENT_HANDOVER);
						tmsShipbillHeaderMapper.update(tmsShipbillHeader);*/

						// 同步更新托运单明细
						/*tmsLoadingBillDetail.setUpdateperson(user.getNickname());
						tmsLoadingBillDetail.setUpdatetime(DateUtil.date());
						tmsLoadingBillDetail.setStatus(DataDictionaryConstant.SHIPBILL_STATUS_CONSIGNMENT_HANDOVER);
						tmsLoadingBillDetailMapper.update(tmsLoadingBillDetail);*/

						// 更新运单运输记录
						Map<String, Object> queryMap2 = Maps.newHashMap();
						queryMap2.put("shipbillId", tmsShipbillHeader.getShipbillId());
						List<TmsShipbillTransLogModel> tmsShipbillTransportLogs = tmsShipbillTransportLogMapper.findByMap(queryMap2, TmsShipbillTransLogModel.class);
						if (ToolKits.isNotEmpty(tmsShipbillTransportLogs) && tmsShipbillTransportLogs.size() > 0) {
							TmsShipbillTransLogModel tmsShipbillTransportLog = tmsShipbillTransportLogs.get(0);
							tmsShipbillTransportLog.setConsignmentHandoverTime(vo.getConsignmentHandoverTime());
							tmsShipbillTransportLog.setConsignmentHandoverPerson(vo.getConsignmentAgen());
							tmsShipbillTransportLog.setConsignmentHandoverMemo(vo.getMemo());
							tmsShipbillTransportLogMapper.update(tmsShipbillTransportLog);
						}

						ShipbillNodeTrackingSaveNewVO shipbillNodeTrackingSaveNewVO = new ShipbillNodeTrackingSaveNewVO();
						ShipbillOperateLogSaveNewVO shipbillOperateLogSaveNewVO = new ShipbillOperateLogSaveNewVO();

						// 运单节点保存
						shipbillNodeTrackingSaveNewVO.setNodeDate(DateUtil.date());
						shipbillNodeTrackingSaveNewVO.setShipbillId(tmsShipbillHeader.getShipbillId());
						shipbillNodeTrackingSaveNewVO.setShipbillNo(tmsShipbillHeader.getShipbillId());
						shipbillNodeTrackingSaveNewVO.setStatus(DataDictionaryConstant.SHIPBILL_STATUS_CONSIGNMENT_HANDOVER);
						shipbillNodeTrackingSaveNewVO.setNodeEvent(nodeEvent.toString());
						shipbillNodeTrackingSaveNewVO.setUserId(user.getUserid());
						shipbillNodeTrackingSaveNewVO.setUserName(user.getNickname());
						shipbillNodeTrackingSaveNewVO.setEnterpriseId(user.getEnterpriseId());
						shipbillNodeTrackingSaveNewVO.setEnterpriseName(user.getEnterpriseName());
						shipbillNodeTrackingService.addShipbillNodeTrackingNewData(shipbillNodeTrackingSaveNewVO);

						// 运单日志保存
						shipbillOperateLogSaveNewVO.setShipbillId(tmsShipbillHeader.getShipbillId());
						shipbillOperateLogSaveNewVO.setShipbillNo(tmsShipbillHeader.getShipbillId());
						shipbillOperateLogSaveNewVO.setOperateEvent(DataDictionaryConstant.SHIPBILL_STATUSNAME_TYJJ);
						shipbillOperateLogSaveNewVO.setOldStatus(tmsShipbillHeader.getStatus());
						shipbillOperateLogSaveNewVO.setNewStatus(DataDictionaryConstant.SHIPBILL_STATUS_CONSIGNMENT_HANDOVER);
						shipbillOperateLogSaveNewVO.setOperateDate(DateUtil.date());
						shipbillOperateLogSaveNewVO.setEnterpriseId(user.getEnterpriseId());
						shipbillOperateLogSaveNewVO.setEnterpriseName(user.getEnterpriseName());
						shipbillOperateLogSaveNewVO.setUserId(user.getUserid());
						shipbillOperateLogSaveNewVO.setUserName(user.getNickname());
						shipbillOperateLogService.addShipbillOperateLogNewData(shipbillOperateLogSaveNewVO);

						// 递归更新运单主单信息
						String fatherShipbillId = tmsShipbillHeader.getShipbillId();
						while (ToolKits.isNotEmpty(fatherShipbillId)) {
							fatherShipbillId = consignmentHandoverFather(fatherShipbillId, DateUtil.date(), user, shipbillNodeTrackingSaveNewVO, shipbillOperateLogSaveNewVO, vo);
						}
					}
				}
			} else {
				continue;
			}
		}
	}

	/**
	 * 托运交接递归父运单
	 *
	 * @param shipbillId
	 * @param date
	 * @param user
	 * @return
	 */
	private String consignmentHandoverFather(String shipbillId, Date date, UserEntity user, ShipbillNodeTrackingSaveNewVO shipbillNodeTrackingSaveNewVO, ShipbillOperateLogSaveNewVO shipbillOperateLogSaveNewVO, ConsignmentHandoverVO vo) {
		// 查询托运单明细
//		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);
//		TmsLoadingBillHeaderModel tmsLoadingBillHeaderModel = tmsLoadingBillHeaderMapper.findById(tmsLoadingBillDetailModel.getLoadingBillId(), TmsLoadingBillHeaderModel.class);
//
//		if (ObjectUtil.notEqual(tmsLoadingBillHeaderModel.getStatus(), DataDictionaryConstant.LOADING_BILL_STATUS_CONSIGNMENT_HANDOVER)) {
//			// 修改托运单的状态为【托运交接】
//			tmsLoadingBillHeaderModel.setStatus(DataDictionaryConstant.LOADING_BILL_STATUS_CONSIGNMENT_HANDOVER);
//			tmsLoadingBillHeaderModel.setUpdateperson(user.getNickname());
//			tmsLoadingBillHeaderModel.setUpdatetime(date);
//			tmsLoadingBillHeaderMapper.update(tmsLoadingBillHeaderModel);
//		}

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

			// 判断父级单号的状态是否为【托运交接】
			if (ObjectUtil.notEqual(fatherShipbillHeaderModel.getStatus(), DataDictionaryConstant.SHIPBILL_STATUS_CONSIGNMENT_HANDOVER)) {
				// 修改父运单状态
				/*fatherShipbillHeaderModel.setStatus(DataDictionaryConstant.SHIPBILL_STATUS_CONSIGNMENT_HANDOVER);
				fatherShipbillHeaderModel.setUpdatetime(date);
				fatherShipbillHeaderModel.setUpdateperson(user.getNickname());
				tmsShipbillHeaderMapper.update(fatherShipbillHeaderModel);*/

				// 更新父运单运输记录
				Map<String, Object> queryMap = Maps.newHashMap();
				queryMap.put("shipbillId", fatherShipbillHeaderModel.getShipbillId());
				List<TmsShipbillTransLogModel> tmsShipbillTransportLogs = tmsShipbillTransportLogMapper.findByMap(queryMap, TmsShipbillTransLogModel.class);
				if (ToolKits.isNotEmpty(tmsShipbillTransportLogs) && tmsShipbillTransportLogs.size() > 0) {
					TmsShipbillTransLogModel tmsShipbillTransportLog = tmsShipbillTransportLogs.get(0);
					tmsShipbillTransportLog.setConsignmentHandoverTime(vo.getConsignmentHandoverTime());
					tmsShipbillTransportLog.setConsignmentHandoverPerson(vo.getConsignmentAgen());
					tmsShipbillTransportLog.setConsignmentHandoverMemo(vo.getMemo());
					tmsShipbillTransportLogMapper.update(tmsShipbillTransportLog);
				}

				// 运单节点保存
				shipbillNodeTrackingSaveNewVO.setNodeDate(DateUtil.date());
				shipbillNodeTrackingSaveNewVO.setShipbillId(fatherShipbillHeaderModel.getShipbillId());
				shipbillNodeTrackingSaveNewVO.setShipbillNo(fatherShipbillHeaderModel.getShipbillId());
				shipbillNodeTrackingService.addShipbillNodeTrackingNewData(shipbillNodeTrackingSaveNewVO);

				// 运单日志保存
				shipbillOperateLogSaveNewVO.setOperateDate(DateUtil.date());
				shipbillOperateLogSaveNewVO.setShipbillId(fatherShipbillHeaderModel.getShipbillId());
				shipbillOperateLogSaveNewVO.setShipbillNo(fatherShipbillHeaderModel.getShipbillId());
				shipbillOperateLogService.addShipbillOperateLogNewData(shipbillOperateLogSaveNewVO);
				return fatherShipbillHeaderModel.getShipbillId();
			}
		}
		return null;
	}

	/**
	 * 主界面导出
	 *
	 * @param
	 * @return outsourceTrackPageDTO
	 */
	@Override
	public List<OutsourceTrackExportDTO> exportAllOutsourceTrack(OutsourceTrackExportVO vo) throws Exception {
		UserEntity user = PlgFxUsrUtils.getUserEntity();
		ToolKits.isParamNull(user, "当前人员没有操作权限");

		// 权限控制 仅支持自有账号
		if (ObjectUtil.notEqual(user.getUserType(), BussinessConstant.USER_TYPE_ZY)) {
			throw new PrologException("当前人员没有操作权限");
		}

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

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

		List<OutsourceTrackExportDTO> exportDtos = Lists.newArrayList();
		for (OutsourceTrackPageDTO dto : list) {
			OutsourceTrackExportDTO exportDto = new OutsourceTrackExportDTO();
			BeanUtils.copyProperties(dto, exportDto);
			exportDto.setStatus(PublicMethods.change(data, String.valueOf(exportDto.getStatus())));
			exportDtos.add(exportDto);
		}
		return exportDtos;
	}

	/**
	 * 主界面分页导出
	 *
	 * @param vo
	 * @return
	 */
	@SuppressWarnings("resource")
	@Override
	public List<OutsourceTrackExportDTO> exportPageOutsourceTrack(OutsourceTrackExportVO vo) throws Exception {
		UserEntity user = PlgFxUsrUtils.getUserEntity();
		ToolKits.isParamNull(user, "当前人员没有操作权限");

		// 权限控制 仅支持自有账号
		if (ObjectUtil.notEqual(user.getUserType(), BussinessConstant.USER_TYPE_ZY)) {
			throw new PrologException("当前人员没有操作权限");
		}

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

		PageUtils.startPage(vo.getPageNum(), vo.getPageSize());
		List<OutsourceTrackPageDTO> list = tmsLoadingBillHeaderMapper.queryOutsourceTrackPage(queryVo);

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

		List<OutsourceTrackExportDTO> exportDtos = Lists.newArrayList();
		for (OutsourceTrackPageDTO dto : list) {
			OutsourceTrackExportDTO exportDto = new OutsourceTrackExportDTO();
			BeanUtils.copyProperties(dto, exportDto);
			exportDto.setStatus(PublicMethods.change(data, String.valueOf(exportDto.getStatus())));
			exportDtos.add(exportDto);
		}
		Page<OutsourceTrackExportDTO> page = PageUtils.getPage(exportDtos);
		if (list instanceof com.github.pagehelper.Page) {
			com.github.pagehelper.Page<OutsourceTrackPageDTO> p0 = (com.github.pagehelper.Page<OutsourceTrackPageDTO>) list;
			page.setPageCount(p0.getPages());
			page.setPageNum(p0.getPageNum());
			page.setPageSize(p0.getPageSize());
			page.setTotalCount(p0.getTotal());
			page.setStartRow(p0.getStartRow());
			page.setEndRow(p0.getEndRow());
		}
		return page.getList();
	}

	/**
	 * 主界面导出
	 *
	 * @param ids
	 * @return
	 */
	@Override
	public List<OutsourceTrackExportDTO> exportSelected(List<String> ids) throws Exception {
		UserEntity user = PlgFxUsrUtils.getUserEntity();
		ToolKits.isParamNull(user, "当前人员没有操作权限");

		// 权限控制 仅支持自有账号
		if (ObjectUtil.notEqual(user.getUserType(), BussinessConstant.USER_TYPE_ZY)) {
			throw new PrologException("当前人员没有操作权限");
		}

		List<TmsLoadingBillHeaderModel> list = tmsLoadingBillHeaderMapper.findByIds(TmsLoadingBillHeaderModel.class, ids.stream().toArray(String[]::new), null);

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

		List<OutsourceTrackExportDTO> exportDtos = Lists.newArrayList();
		for (TmsLoadingBillHeaderModel dto : list) {
			OutsourceTrackExportDTO exportDto = new OutsourceTrackExportDTO();
			BeanUtils.copyProperties(dto, exportDto);
			exportDto.setStatus(PublicMethods.change(data, String.valueOf(exportDto.getStatus())));
			exportDtos.add(exportDto);
		}
		return exportDtos;
	}

	/**
	 *
	 * 正本回单确认
	 * 
	 * @param
	 * @return
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void returnOrderConfirm(ReturnOrderConfirmVO vo) throws Exception {
		UserEntity user = PlgFxUsrUtils.getUserEntity();
		ToolKits.isParamNull(user, "当前人员没有操作权限");
		ToolKits.isParamNull(vo.getIds(), "请选择要操作的数据");

		StringBuffer nodeEvent = new StringBuffer();
		nodeEvent.append("正本回单确认");
		nodeEvent.append(" 回单状态:");
		nodeEvent.append(vo.getReturnOrderStatus());
		nodeEvent.append(" 回单类型:");
		nodeEvent.append(vo.getReturnOrderType());
		nodeEvent.append(" 回单时效:");
		nodeEvent.append(vo.getPrescription());
		nodeEvent.append(" 接收人:");
		nodeEvent.append(vo.getReceiver());
		nodeEvent.append(" 接收份数：");
		nodeEvent.append(vo.getCounts());
		nodeEvent.append(" 备注:");
		nodeEvent.append(vo.getMemo());

		for (String id : vo.getIds()) {
			TmsShipbillHeaderModel tmsShipbillHeader = tmsShipbillHeaderMapper.findById(id, TmsShipbillHeaderModel.class);
			if (ToolKits.isNotEmpty(tmsShipbillHeader)) {
				if (ObjectUtil.notEqual(tmsShipbillHeader.getStatus(), DataDictionaryConstant.SHIPBILL_STATUS_END)) {
					// 更新运单
					tmsShipbillHeader.setUpdateperson(user.getNickname());
					tmsShipbillHeader.setUpdatetime(DateUtil.date());
					tmsShipbillHeader.setStatus(DataDictionaryConstant.SHIPBILL_STATUS_END);
					tmsShipbillHeaderMapper.update(tmsShipbillHeader);

					// 同步更新托运单明细
					Map<String, Object> queryMap = Maps.newHashMap();
					queryMap.put("shipbillId", id);
					List<TmsLoadingBillDetailModel> tmsLoadingBillDetails = tmsLoadingBillDetailMapper.findByMap(queryMap, TmsLoadingBillDetailModel.class);
					if (ToolKits.isNotEmpty(tmsLoadingBillDetails) && tmsLoadingBillDetails.size() > 0) {
						TmsLoadingBillDetailModel tmsLoadingBillDetail = tmsLoadingBillDetails.get(0);
						tmsLoadingBillDetail.setUpdateperson(user.getNickname());
						tmsLoadingBillDetail.setUpdatetime(DateUtil.date());
						tmsLoadingBillDetail.setStatus(DataDictionaryConstant.SHIPBILL_STATUS_END);
						tmsLoadingBillDetailMapper.update(tmsLoadingBillDetail);
					}

					// 如果托运单的明细全部正本回单,则更新托运单汇总
					Map<String, Object> queryMap3 = Maps.newHashMap();
					queryMap3.put("loadingBillId", tmsLoadingBillDetails.get(0).getLoadingBillId());
					List<TmsLoadingBillDetailModel> tmsLoadingBillDetails2 = tmsLoadingBillDetailMapper.findByMap(queryMap3, TmsLoadingBillDetailModel.class);
					if (ToolKits.isNotEmpty(tmsLoadingBillDetails2)) {
						List<TmsLoadingBillDetailModel> filterList = tmsLoadingBillDetails2.stream().filter(dto -> DataDictionaryConstant.SHIPBILL_STATUS_END.equals(dto.getStatus())).collect(Collectors.toList());
						if (filterList.size() == tmsLoadingBillDetails2.size()) {
							Map<String, Object> updateMap = Maps.newHashMap();
							updateMap.put("updateperson", user.getNickname());
							updateMap.put("updatetime", DateUtil.date());
							updateMap.put("status", DataDictionaryConstant.LOADING_BILL_SHIPBILL_STATUS_END);
							tmsLoadingBillHeaderMapper.updateMapById(tmsLoadingBillDetails.get(0).getLoadingBillId(), updateMap, TmsLoadingBillHeaderModel.class);
						}
					}

					// 更新运单运输记录
					Map<String, Object> queryMap2 = Maps.newHashMap();
					queryMap2.put("shipbillId", id);
					List<TmsShipbillTransLogModel> tmsShipbillTransportLogs = tmsShipbillTransportLogMapper.findByMap(queryMap2, TmsShipbillTransLogModel.class);
					if (ToolKits.isNotEmpty(tmsShipbillTransportLogs) && tmsShipbillTransportLogs.size() > 0) {
						TmsShipbillTransLogModel tmsShipbillTransportLog = tmsShipbillTransportLogs.get(0);
						tmsShipbillTransportLog.setOrigReceiptReturnTime(vo.getReturnOrderDate());
						tmsShipbillTransportLog.setOrigReceiptStatus(vo.getReturnOrderStatus());
						tmsShipbillTransportLog.setOrigReceiptType(vo.getReturnOrderType());
						tmsShipbillTransportLog.setOrigReceiptAging(vo.getPrescription());
						tmsShipbillTransportLog.setOrigReceiptReceivePerson(vo.getReceiver());
						tmsShipbillTransportLog.setOrigReceiptNum(vo.getCounts());
						tmsShipbillTransportLog.setOrigReceiptMemo(vo.getMemo());
						tmsShipbillTransportLogMapper.update(tmsShipbillTransportLog);
					}

					// 运单节点保存
					ShipbillNodeTrackingSaveNewVO shipbillNodeTrackingSaveNewVO = new ShipbillNodeTrackingSaveNewVO();
					shipbillNodeTrackingSaveNewVO.setNodeDate(DateUtil.date());
					shipbillNodeTrackingSaveNewVO.setShipbillId(tmsShipbillHeader.getShipbillId());
					shipbillNodeTrackingSaveNewVO.setShipbillNo(tmsShipbillHeader.getShipbillId());
					shipbillNodeTrackingSaveNewVO.setStatus(DataDictionaryConstant.SHIPBILL_STATUS_HD_ZB);
					shipbillNodeTrackingSaveNewVO.setNodeEvent(nodeEvent.toString());
					shipbillNodeTrackingSaveNewVO.setUserId(user.getUserid());
					shipbillNodeTrackingSaveNewVO.setUserName(user.getNickname());
					shipbillNodeTrackingSaveNewVO.setEnterpriseId(user.getEnterpriseId());
					shipbillNodeTrackingSaveNewVO.setEnterpriseName(user.getEnterpriseName());
					shipbillNodeTrackingService.addShipbillNodeTrackingNewData(shipbillNodeTrackingSaveNewVO);

					// 运单日志保存
					ShipbillOperateLogSaveNewVO shipbillOperateLogSaveNewVO = new ShipbillOperateLogSaveNewVO();
					shipbillOperateLogSaveNewVO.setShipbillId(tmsShipbillHeader.getShipbillId());
					shipbillOperateLogSaveNewVO.setShipbillNo(tmsShipbillHeader.getShipbillId());
					shipbillOperateLogSaveNewVO.setOperateEvent(DataDictionaryConstant.SHIPBILL_STATUSNAME_HD_ZB);
					shipbillOperateLogSaveNewVO.setOldStatus(tmsShipbillHeader.getStatus());
					shipbillOperateLogSaveNewVO.setNewStatus(DataDictionaryConstant.SHIPBILL_STATUS_HD_ZB);
					shipbillOperateLogSaveNewVO.setOperateDate(DateUtil.date());
					shipbillOperateLogSaveNewVO.setEnterpriseId(user.getEnterpriseId());
					shipbillOperateLogSaveNewVO.setEnterpriseName(user.getEnterpriseName());
					shipbillOperateLogSaveNewVO.setUserId(user.getUserid());
					shipbillOperateLogSaveNewVO.setUserName(user.getNickname());
					shipbillOperateLogService.addShipbillOperateLogNewData(shipbillOperateLogSaveNewVO);

					// 正本回单确认递归
					String fatherShipbillId = tmsShipbillHeader.getShipbillId();
					while (ToolKits.isNotEmpty(fatherShipbillId)) {
						fatherShipbillId = returnOrderConfirmFather(fatherShipbillId, user, shipbillNodeTrackingSaveNewVO, shipbillOperateLogSaveNewVO, vo);
					}
				} else {
					throw new PrologException("运单【" + tmsShipbillHeader.getShipbillId() + "】已正本回单确认");
				}
			}
			MessageUtil.addMessage(new SendMessageDTO(MessageOrderTypeEnum.SHIP_NO.getCode(), MessageTypeEnum.ORIGINAL_RECEIPT.getCode(), Lists.newArrayList(id)));
		}
		/*
		 * if(null!=loadingBillId){ Map<String,Object> updateMap=Maps.newHashMap();
		 * updateMap.put("updateperson",user.getNickname());
		 * updateMap.put("updatetime",DateUtil.date());
		 * updateMap.put("status",DataDictionaryConstant.
		 * LOADING_BILL_SHIPBILL_STATUS_END);
		 * tmsLoadingBillHeaderMapper.updateMapById(loadingBillId,updateMap,
		 * TmsLoadingBillHeaderModel.class); }
		 */
	}

	/**
	 * 正本回单确认递归父运单
	 *
	 */
	private String returnOrderConfirmFather(String shipbillId, UserEntity user, ShipbillNodeTrackingSaveNewVO shipbillNodeTrackingSaveNewVO, ShipbillOperateLogSaveNewVO shipbillOperateLogSaveNewVO, ReturnOrderConfirmVO vo) {
		TmsShipbillHeaderModel tmsShipbillHeaderModel = tmsShipbillHeaderMapper.findById(shipbillId, TmsShipbillHeaderModel.class);
		TmsShipbillHeaderModel fatherShipbill = tmsShipbillHeaderMapper.findById(tmsShipbillHeaderModel.getFatherShipbillId(), TmsShipbillHeaderModel.class);
		if (ToolKits.isNotEmpty(tmsShipbillHeaderModel.getFatherShipbillId()) && !tmsShipbillHeaderModel.getFatherShipbillId().equals(shipbillId)) {
			// 查找父单下面的所有子单
			Criteria criteriaFatherShipbillHeader = Criteria.forClass(TmsShipbillHeaderModel.class);
			Restriction r3 = Restrictions.eq("fatherShipbillId", tmsShipbillHeaderModel.getFatherShipbillId());
			Restriction r4 = Restrictions.eq("enterpriseId", user.getEnterpriseId());
			criteriaFatherShipbillHeader.setRestriction(Restrictions.and(r3, r4));
			List<TmsShipbillHeaderModel> tmsShipbillHeaderModels = tmsShipbillHeaderMapper.findByCriteria(criteriaFatherShipbillHeader);

			if (ToolKits.isNotEmpty(tmsShipbillHeaderModels)) {
				List<TmsShipbillHeaderModel> filterList = tmsShipbillHeaderModels.stream().filter(dto -> DataDictionaryConstant.SHIPBILL_STATUS_END.equals(dto.getStatus())).collect(Collectors.toList());
				// 所有子单都正本回单了
				if (ToolKits.isNotEmpty(filterList) && filterList.size() == tmsShipbillHeaderModels.size()) {
					// 更新运单
					fatherShipbill.setUpdatetime(DateUtil.date());
					fatherShipbill.setUpdateperson(user.getNickname());
					fatherShipbill.setStatus(DataDictionaryConstant.SHIPBILL_STATUS_END);
					tmsShipbillHeaderMapper.update(fatherShipbill);

					// 更新托运单明细
					Map<String, Object> queryMap = Maps.newHashMap();
					queryMap.put("shipbillId", fatherShipbill.getShipbillId());
					List<TmsLoadingBillDetailModel> tmsLoadingBillDetails = tmsLoadingBillDetailMapper.findByMap(queryMap, TmsLoadingBillDetailModel.class);
					if (ToolKits.isNotEmpty(tmsLoadingBillDetails) && tmsLoadingBillDetails.size() > 0) {
						TmsLoadingBillDetailModel tmsLoadingBillDetail = tmsLoadingBillDetails.get(0);
						tmsLoadingBillDetail.setUpdateperson(user.getNickname());
						tmsLoadingBillDetail.setUpdatetime(DateUtil.date());
						tmsLoadingBillDetail.setStatus(DataDictionaryConstant.SHIPBILL_STATUS_END);
						tmsLoadingBillDetailMapper.update(tmsLoadingBillDetail);
					}

					// 更新运单运输记录
					Map<String, Object> queryMap2 = Maps.newHashMap();
					queryMap2.put("shipbillId", fatherShipbill.getShipbillId());
					List<TmsShipbillTransLogModel> tmsShipbillTransportLogs = tmsShipbillTransportLogMapper.findByMap(queryMap2, TmsShipbillTransLogModel.class);
					if (ToolKits.isNotEmpty(tmsShipbillTransportLogs) && tmsShipbillTransportLogs.size() > 0) {
						TmsShipbillTransLogModel tmsShipbillTransportLog = tmsShipbillTransportLogs.get(0);
						tmsShipbillTransportLog.setOrigReceiptReturnTime(vo.getReturnOrderDate());
						tmsShipbillTransportLog.setOrigReceiptStatus(vo.getReturnOrderStatus());
						tmsShipbillTransportLog.setOrigReceiptType(vo.getReturnOrderType());
						tmsShipbillTransportLog.setOrigReceiptAging(vo.getPrescription());
						tmsShipbillTransportLog.setOrigReceiptReceivePerson(vo.getReceiver());
						tmsShipbillTransportLog.setOrigReceiptNum(vo.getCounts());
						tmsShipbillTransportLog.setOrigReceiptMemo(vo.getMemo());
						tmsShipbillTransportLogMapper.update(tmsShipbillTransportLog);
					}

					// 运单节点保存
					shipbillNodeTrackingSaveNewVO.setNodeDate(DateUtil.date());
					shipbillNodeTrackingSaveNewVO.setShipbillId(fatherShipbill.getShipbillId());
					shipbillNodeTrackingSaveNewVO.setShipbillNo(fatherShipbill.getShipbillId());
					shipbillNodeTrackingService.addShipbillNodeTrackingNewData(shipbillNodeTrackingSaveNewVO);

					// 运单日志保存
					shipbillOperateLogSaveNewVO.setOperateDate(DateUtil.date());
					shipbillOperateLogSaveNewVO.setShipbillId(fatherShipbill.getShipbillId());
					shipbillOperateLogSaveNewVO.setShipbillNo(fatherShipbill.getShipbillId());
					shipbillOperateLogService.addShipbillOperateLogNewData(shipbillOperateLogSaveNewVO);
					return fatherShipbill.getShipbillId();
				}
			}
		}
		return null;
	}

}
