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

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.prolog.rdc.tms.model.dto.basicConfigure.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.prolog.common.util.ToolKits;
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.DataDictionaryConstant;
import com.prolog.rdc.tms.constant.SeriaNnumberConstant;
import com.prolog.rdc.tms.dao.mapper.TmsLineConsigneeLinkMapper;
import com.prolog.rdc.tms.dao.mapper.TmsLineMthStrategyCtMapper;
import com.prolog.rdc.tms.dao.mapper.TmsLineMthStrategyMapper;
import com.prolog.rdc.tms.dao.mapper.TmsLineShipperLinkMapper;
import com.prolog.rdc.tms.model.dto.basicData.ShipbillMatchLineQueryDTO;
import com.prolog.rdc.tms.model.entity.TmsLineMthStyCtModel;
import com.prolog.rdc.tms.model.entity.TmsLineMthStyModel;
import com.prolog.rdc.tms.model.entity.line.TmsLineConsigneeLinkModel;
import com.prolog.rdc.tms.model.entity.line.TmsLineShipperLinkModel;
import com.prolog.rdc.tms.model.vo.basicConfigure.LineMthStrategyCtSaveVO;
import com.prolog.rdc.tms.model.vo.basicConfigure.LineMthStrategyCtUpdateVO;
import com.prolog.rdc.tms.model.vo.basicConfigure.LineMthStrategyPageVO;
import com.prolog.rdc.tms.model.vo.basicConfigure.LineMthStrategySaveVO;
import com.prolog.rdc.tms.model.vo.basicConfigure.LineMthStrategyUpdateVO;
import com.prolog.rdc.tms.model.vo.basicConfigure.LineMthStrategyViewVO;
import com.prolog.rdc.tms.model.vo.basicConfigure.ShipbillMatchLineVO;
import com.prolog.rdc.tms.model.vo.basicData.ShipbillMatchLineQueryVO;
import com.prolog.rdc.tms.service.SysCodeengineService;
import com.prolog.rdc.tms.service.SysRefdatadService;
import com.prolog.rdc.tms.service.basicConfigure.LineMthStrategyService;
import com.prolog.rdc.tms.service.basicData.TranslineService;
import com.prolog.rdc.tms.util.PublicMethods;

import cn.hutool.core.date.DateUtil;
import lombok.extern.slf4j.Slf4j;

/**
 * 线路匹配策略业务实现层
 *
 * @author :lhb
 * @version :1.0.0
 * @className :LineMthStrategyServiceImpl
 * @creationTime :2022/05/07
 * @description :
 * @modifier :
 * @modifyTime :
 * @reviseRemarks:
 */
@Service
@Slf4j
public class LineMthStrategyServiceImpl implements LineMthStrategyService {

	@Autowired
	private TmsLineMthStrategyMapper tmsLineMthStrategyMapper;

	@Autowired
	private TmsLineMthStrategyCtMapper tmsLineMthStrategyCtMapper;

	@Autowired
	private SysCodeengineService sysCodeengineService;

	@Autowired
	private SysRefdatadService sysRefdatadService;

	@Autowired
	private TmsLineConsigneeLinkMapper tmsLineConsigneeLinkMapper;

	@Autowired
	private TmsLineShipperLinkMapper tmsLineShipperLinkMapper;

	@Autowired
	private TranslineService translineService;

	/**
	 * 线路匹配策略分页查询
	 *
	 * @param pageVO
	 * @return
	 */
	@SuppressWarnings("resource")
	@Override
	public Page<LineMthStrategyPageDTO> pageQuery(LineMthStrategyPageVO pageVO) {
		ToolKits.isParamNull(pageVO, "线路匹配策略分页查询请求不为空");
		ToolKits.isParamNull(pageVO.getPageNum(), "分页页码不为空");
		ToolKits.isParamNull(pageVO.getPageSize(), "分页页码大小不为空");

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

		Criteria lineCriteria = Criteria.forClass(TmsLineMthStyModel.class);
		Restriction r1 = ToolKits.isEmpty(pageVO.getStrategyName()) ? null : Restrictions.like(TmsLineMthStyModel::getName, "%" + pageVO.getStrategyName() + "%");
		Restriction r2 = ToolKits.isEmpty(pageVO.getStatus()) ? null : Restrictions.eq(TmsLineMthStyModel::getStatus, pageVO.getStatus());
		Restriction r3 = Restrictions.eq(TmsLineMthStyModel::getEnterpriseId, user.getEnterpriseId());
		lineCriteria.setRestriction(Restrictions.and(r1, r2, r3));
		lineCriteria.setOrder(Order.newInstance().desc(new String[] { "updatetime" }));

		PageUtils.startPage(pageVO.getPageNum(), pageVO.getPageSize());
		List<TmsLineMthStyModel> mthStyModels = tmsLineMthStrategyMapper.findByCriteria(lineCriteria);

		// 状态
		List<Map<String, Object>> status = sysRefdatadService.getDropDownById(DataDictionaryConstant.GENERAL_STATUS, null, null, null);
		// 策略条件类型
		List<Map<String, Object>> restMsgStyConditionType = sysRefdatadService.getDropDownById(DataDictionaryConstant.STRATEGY_CONDITION_TYPE, null, null, null);
		// 配送方式
		List<Map<String, Object>> restMsgDeliveryMethodType = sysRefdatadService.getDropDownById(DataDictionaryConstant.DELIVERY_METHOD_TYPE, null, null, null);
		// 订单类型
		List<Map<String, Object>> restMsgOrderType = sysRefdatadService.getDropDownById(DataDictionaryConstant.ORDER_TYPE, null, null, null);
		// 订单业务类型
		List<Map<String, Object>> restMsgOrderBusinessType = sysRefdatadService.getDropDownById(DataDictionaryConstant.ORDER_BUSINESS_TYPE, null, null, null);
		// 运输类型(运输模式)
		List<Map<String, Object>> restMsgTransportType = sysRefdatadService.getDropDownById(DataDictionaryConstant.TRANSPORT_TYPE, null, null, null);
		// 收货方类型
		List<Map<String, Object>> restMsgConsigneeType = sysRefdatadService.getDropDownById(DataDictionaryConstant.CONSIGNEE_TYPE, null, null, null);
		// 发货方类型
		List<Map<String, Object>> restMsgShipperType = sysRefdatadService.getDropDownById(DataDictionaryConstant.SHIPPER_TYPE, null, null, null);
		// 温度要求
		List<Map<String, Object>> restMsgTemperature = sysRefdatadService.getDropDownById(DataDictionaryConstant.TEMPERATURE_REQUIREMENT, null, null, null);

		List<LineMthStrategyPageDTO> pageDTOS = Lists.newArrayList();
		for (TmsLineMthStyModel mthStyModel : mthStyModels) {
			LineMthStrategyPageDTO strategyPageDTO = new LineMthStrategyPageDTO();
			BeanUtils.copyProperties(mthStyModel, strategyPageDTO);
			strategyPageDTO.setStrategyName(mthStyModel.getName());

			List<LineMthStrategyPrioDTO> prioDTOS = Lists.newArrayList();
			LineMthStrategyPrioDTO prio1DTO = new LineMthStrategyPrioDTO();
			prio1DTO.setMatchTypeItem("按行政区域-行政区域");
			prio1DTO.setNum(mthStyModel.getAdminToAdmin());
			prioDTOS.add(prio1DTO);

			LineMthStrategyPrioDTO prio2DTO = new LineMthStrategyPrioDTO();
			prio2DTO.setMatchTypeItem("按行政区域-收货方");
			prio2DTO.setNum(mthStyModel.getAdminToConsignor());
			prioDTOS.add(prio2DTO);

			LineMthStrategyPrioDTO prio3DTO = new LineMthStrategyPrioDTO();
			prio3DTO.setMatchTypeItem("按仓库-行政区域");
			prio3DTO.setNum(mthStyModel.getBranchToAdmin());
			prioDTOS.add(prio3DTO);

			LineMthStrategyPrioDTO prio4DTO = new LineMthStrategyPrioDTO();
			prio4DTO.setMatchTypeItem("按仓库-收货方");
			prio4DTO.setNum(mthStyModel.getBranchToConsignor());
			prioDTOS.add(prio4DTO);

			List<LineMthStrategyPrioDTO> list = prioDTOS.stream().sorted(Comparator.comparing(LineMthStrategyPrioDTO::getNum)).collect(Collectors.toList());

			// 匹配优先级
			strategyPageDTO.setMatchPrioItems(list.stream().map(item -> item.getMatchTypeItem()).collect(Collectors.joining(",")));
			strategyPageDTO.setStatusName(PublicMethods.change(status, String.valueOf(mthStyModel.getStatus())));

			// 满足条件
			List<String> conditions = Lists.newArrayList();
			Criteria carrierCtCriteria = Criteria.forClass(TmsLineMthStyCtModel.class);
			Restriction r4 = Restrictions.eq(TmsLineMthStyCtModel::getStrategyId, mthStyModel.getId());
			Restriction r5 = Restrictions.eq(TmsLineMthStyCtModel::getEnterpriseId, user.getEnterpriseId());
			carrierCtCriteria.setRestriction(Restrictions.and(r4, r5));
			carrierCtCriteria.setOrder(Order.newInstance().asc(new String[] { "strategyConditionType" }));
			List<TmsLineMthStyCtModel> mthStyCtModels = tmsLineMthStrategyCtMapper.findByCriteria(carrierCtCriteria);

			for (TmsLineMthStyCtModel mthStyCtModel : mthStyCtModels) {
				conditions.add(PublicMethods.change(restMsgStyConditionType, String.valueOf(mthStyCtModel.getStrategyConditionType())));
				// 满足条件
				switch (mthStyCtModel.getStrategyConditionType().intValue()) {
				case 1:
					// 1配送方式
					conditions.add(PublicMethods.change(restMsgDeliveryMethodType, String.valueOf(mthStyCtModel.getStrategyConditionValue())));
					break;
				case 2:
					// 2发货方类型
					conditions.add(PublicMethods.change(restMsgShipperType, String.valueOf(mthStyCtModel.getStrategyConditionValue())));
					break;
				case 3:
					// 3收货方类型
					conditions.add(PublicMethods.change(restMsgConsigneeType, String.valueOf(mthStyCtModel.getStrategyConditionValue())));
					break;
				case 4:
					// 4订单类型
					conditions.add(PublicMethods.change(restMsgOrderType, String.valueOf(mthStyCtModel.getStrategyConditionValue())));
					break;
				case 5:
					// 5订单业务类型
					conditions.add(PublicMethods.change(restMsgOrderBusinessType, String.valueOf(mthStyCtModel.getStrategyConditionValue())));
					break;
				case 6:
					// 6运输模式
					conditions.add(PublicMethods.change(restMsgTransportType, String.valueOf(mthStyCtModel.getStrategyConditionValue())));
					break;
				case 7:
					// 7温度要求
					conditions.add(PublicMethods.change(restMsgTemperature, String.valueOf(mthStyCtModel.getStrategyConditionValue())));
					break;
				}
			}
			strategyPageDTO.setStrategyConditions(conditions.stream().collect(Collectors.joining(",")));
			pageDTOS.add(strategyPageDTO);
		}

		Page<LineMthStrategyPageDTO> page = PageUtils.getPage(pageDTOS);
		if (mthStyModels instanceof com.github.pagehelper.Page) {
			com.github.pagehelper.Page<TmsLineMthStyModel> p0 = (com.github.pagehelper.Page<TmsLineMthStyModel>) mthStyModels;
			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 lineMthStrategySaveVO
	 * @return
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void save(LineMthStrategySaveVO lineMthStrategySaveVO) {
		ToolKits.isParamNull(lineMthStrategySaveVO, "线路匹配策略保存请求不为空");
		ToolKits.isParamNull(lineMthStrategySaveVO.getStrategyName(), "策略名称不为空");
		ToolKits.isParamNull(lineMthStrategySaveVO.getAdminToAdmin(), "按行政区域-行政区域顺序不为空");
		ToolKits.isParamNull(lineMthStrategySaveVO.getAdminToConsignor(), "按行政区域-收货方顺序不为空");
		ToolKits.isParamNull(lineMthStrategySaveVO.getBranchToAdmin(), "按仓库-行政区域顺序不为空");
		ToolKits.isParamNull(lineMthStrategySaveVO.getBranchToConsignor(), "按仓库-收货方顺序不为空");
		ToolKits.isParamNull(lineMthStrategySaveVO.getStrategyCtSaveVOList(), "线路匹配策略条件不为空");

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

		// 运单匹配条件集合
		Map<Integer, String> conditionMap = Maps.newHashMap();
		for (LineMthStrategyCtSaveVO conditionVO : lineMthStrategySaveVO.getStrategyCtSaveVOList()) {
			// 配送方式
			if (conditionVO.getStrategyConditionType().equals(DataDictionaryConstant.STRATEGY_CONDITION_TYPE_DELIVERY)) {
				conditionMap.put(DataDictionaryConstant.STRATEGY_CONDITION_TYPE_DELIVERY, String.valueOf(DataDictionaryConstant.STRATEGY_CONDITION_TYPE_DELIVERY) + "_" + String.valueOf(conditionVO.getStrategyConditionValue()));
				continue;
			}
			// 订单类型
			if (conditionVO.getStrategyConditionType().equals(DataDictionaryConstant.STRATEGY_CONDITION_TYPE_ORDER)) {
				conditionMap.put(DataDictionaryConstant.STRATEGY_CONDITION_TYPE_ORDER, String.valueOf(DataDictionaryConstant.STRATEGY_CONDITION_TYPE_ORDER) + "_" + String.valueOf(conditionVO.getStrategyConditionValue()));
				continue;
			}
			// 订单业务类型
			if (conditionVO.getStrategyConditionType().equals(DataDictionaryConstant.STRATEGY_CONDITION_TYPE_ORDER_BUSINESS)) {
				conditionMap.put(DataDictionaryConstant.STRATEGY_CONDITION_TYPE_ORDER_BUSINESS, String.valueOf(DataDictionaryConstant.STRATEGY_CONDITION_TYPE_ORDER_BUSINESS) + "_" + String.valueOf(conditionVO.getStrategyConditionValue()));
				continue;
			}
			// 运输模式
			if (conditionVO.getStrategyConditionType().equals(DataDictionaryConstant.STRATEGY_CONDITION_TYPE_TRANSPORT)) {
				conditionMap.put(DataDictionaryConstant.STRATEGY_CONDITION_TYPE_TRANSPORT, String.valueOf(DataDictionaryConstant.STRATEGY_CONDITION_TYPE_TRANSPORT) + "_" + String.valueOf(conditionVO.getStrategyConditionValue()));
				continue;
			}
			// 温度要求
			if (conditionVO.getStrategyConditionType().equals(DataDictionaryConstant.STRATEGY_CONDITION_TYPE_TEMPERATURE)) {
				conditionMap.put(DataDictionaryConstant.STRATEGY_CONDITION_TYPE_TEMPERATURE, String.valueOf(DataDictionaryConstant.STRATEGY_CONDITION_TYPE_TEMPERATURE) + "_" + String.valueOf(conditionVO.getStrategyConditionValue()));
				continue;
			}
			// 货主ID
			if (conditionVO.getStrategyConditionType().equals(DataDictionaryConstant.STRATEGY_CONDITION_TYPE_OWNER)) {
				if (ToolKits.isEmpty(conditionVO.getUnitId())) {
					throw new PrologException("货主不为空");
				}
				String units = Arrays.stream(String.valueOf(conditionVO.getUnitId()).split(",")).sorted().collect(Collectors.joining(","));
				conditionMap.put(DataDictionaryConstant.STRATEGY_CONDITION_TYPE_OWNER, String.valueOf(DataDictionaryConstant.STRATEGY_CONDITION_TYPE_OWNER) + "_" + units);
				continue;
			}

			// 部门ID
			if (conditionVO.getStrategyConditionType().equals(DataDictionaryConstant.STRATEGY_CONDITION_TYPE_DEPARTMENT)) {
				if (ToolKits.isEmpty(conditionVO.getUnitId())) {
					throw new PrologException("部门不为空");
				}
				String units = Arrays.stream(String.valueOf(conditionVO.getUnitId()).split(",")).sorted().collect(Collectors.joining(","));
				conditionMap.put(DataDictionaryConstant.STRATEGY_CONDITION_TYPE_DEPARTMENT, String.valueOf(DataDictionaryConstant.STRATEGY_CONDITION_TYPE_DEPARTMENT) + "_" + units);
				continue;
			}
			// 收货方类型
			if (conditionVO.getStrategyConditionType().equals(DataDictionaryConstant.STRATEGY_CONDITION_TYPE_CONSIGNEE)) {
				if (ToolKits.isEmpty(conditionVO.getUnitId())) {
					throw new PrologException("收货方不为空");
				}
				String units = Arrays.stream(String.valueOf(conditionVO.getUnitId()).split(",")).sorted().collect(Collectors.joining(","));
				conditionMap.put(DataDictionaryConstant.STRATEGY_CONDITION_TYPE_CONSIGNEE, String.valueOf(DataDictionaryConstant.STRATEGY_CONDITION_TYPE_CONSIGNEE) + "_" + String.valueOf(conditionVO.getStrategyConditionValue()) + "," + units);
				continue;
			}
			// 发货方类型
			if (conditionVO.getStrategyConditionType().equals(DataDictionaryConstant.STRATEGY_CONDITION_TYPE_SHIPPER)) {
				if (ToolKits.isEmpty(conditionVO.getUnitId())) {
					throw new PrologException("发货方不为空");
				}
				String units = Arrays.stream(String.valueOf(conditionVO.getUnitId()).split(",")).sorted().collect(Collectors.joining(","));
				conditionMap.put(DataDictionaryConstant.STRATEGY_CONDITION_TYPE_SHIPPER, String.valueOf(DataDictionaryConstant.STRATEGY_CONDITION_TYPE_SHIPPER) + "_" + String.valueOf(conditionVO.getStrategyConditionValue()) + "," + units);
				continue;
			}
		}

		Criteria carrierCriteria = Criteria.forClass(TmsLineMthStyModel.class);
		Restriction r1 = Restrictions.eq(TmsLineMthStyModel::getEnterpriseId, user.getEnterpriseId());
		Restriction r2 = Restrictions.eq(TmsLineMthStyModel::getStatus, DataDictionaryConstant.GENERAL_STATUS_ENABLE);
		carrierCriteria.setRestriction(Restrictions.and(r1, r2));
		carrierCriteria.setOrder(Order.newInstance().desc(new String[] { "updatetime" }));
		List<TmsLineMthStyModel> mthStyModels = tmsLineMthStrategyMapper.findByCriteria(carrierCriteria);

		for (TmsLineMthStyModel lineMthStyModel : mthStyModels) {
			// 满足条件
			Criteria carrierCtCriteria = Criteria.forClass(TmsLineMthStyCtModel.class);
			Restriction r3 = Restrictions.eq(TmsLineMthStyCtModel::getStrategyId, lineMthStyModel.getId());
			Restriction r4 = Restrictions.eq(TmsLineMthStyCtModel::getEnterpriseId, user.getEnterpriseId());
			carrierCtCriteria.setRestriction(Restrictions.and(r3, r4));
			carrierCtCriteria.setOrder(Order.newInstance().asc(new String[] { "strategyConditionType" }));
			List<TmsLineMthStyCtModel> mthStyCtModels = tmsLineMthStrategyCtMapper.findByCriteria(carrierCtCriteria);

			// 判定满足条件
			int fitCnt = 0;
			for (TmsLineMthStyCtModel conditionModel : mthStyCtModels) {
				switch (conditionModel.getStrategyConditionType().intValue()) {
				case 2:
				case 3:
					String unit1s = Arrays.stream(String.valueOf(conditionModel.getUnitId()).split(",")).sorted().collect(Collectors.joining(","));
					if (conditionMap.containsValue(String.valueOf(conditionModel.getStrategyConditionType()) + "_" + String.valueOf(conditionModel.getStrategyConditionValue()) + "," + unit1s)) {
						fitCnt++;
					}
					break;
				case 8:
				case 9:
					String unit2s = Arrays.stream(String.valueOf(conditionModel.getUnitId()).split(",")).sorted().collect(Collectors.joining(","));

					if (conditionMap.containsValue(String.valueOf(conditionModel.getStrategyConditionType()) + "_" + unit2s)) {
						fitCnt++;
					}
					break;
				default:
					String unit3s = Arrays.stream(String.valueOf(conditionModel.getStrategyConditionValue()).split(",")).sorted().collect(Collectors.joining(","));

					if (conditionMap.containsValue(String.valueOf(conditionModel.getStrategyConditionType()) + "_" + unit3s)) {
						fitCnt++;
					}
					break;
				}
			}
			// 已经存在相同条件的线路匹配策略
			Assert.isTrue(fitCnt != mthStyCtModels.size(), "线路匹配策略的条件已经存在，请重新配置线路匹配策略条件!");
		}

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

		String id = sysCodeengineService.getCodeNumberByCode(SeriaNnumberConstant.TMS_LINE_MATCH_STRATEGY_ID, "L");
		ToolKits.isParamNull(id, "线路匹配策略ID生成失败");

		TmsLineMthStyModel lineMthStyModel = new TmsLineMthStyModel();
		BeanUtils.copyProperties(lineMthStrategySaveVO, lineMthStyModel);

		// ID赋值
		lineMthStyModel.setId(Long.valueOf(id));
		lineMthStyModel.setName(lineMthStrategySaveVO.getStrategyName());
		lineMthStyModel.setStatus(DataDictionaryConstant.GENERAL_STATUS_ENABLE);
		lineMthStyModel.setEnterpriseId(user.getEnterpriseId());
		lineMthStyModel.setEnterpriseName(user.getEnterpriseName());
		lineMthStyModel.setCreateperson(user.getNickname());
		lineMthStyModel.setCreatetime(date);
		lineMthStyModel.setUpdateperson(user.getNickname());
		lineMthStyModel.setUpdatetime(date);
		// 保存
		tmsLineMthStrategyMapper.save(lineMthStyModel);
		// 策略条件
		for (LineMthStrategyCtSaveVO strategyCtSaveVO : lineMthStrategySaveVO.getStrategyCtSaveVOList()) {
			String cid = sysCodeengineService.getCodeNumberByCode(SeriaNnumberConstant.TMS_LINE_MATCH_STRATEGY_CT_ID, "L");
			ToolKits.isParamNull(cid, "线路匹配策略条件ID生成失败");
			TmsLineMthStyCtModel carrierMthStyCtModel = new TmsLineMthStyCtModel();
			BeanUtils.copyProperties(strategyCtSaveVO, carrierMthStyCtModel);
			carrierMthStyCtModel.setId(Long.valueOf(cid));
			carrierMthStyCtModel.setStrategyId(Long.valueOf(id));

			carrierMthStyCtModel.setEnterpriseId(user.getEnterpriseId());
			carrierMthStyCtModel.setEnterpriseName(user.getEnterpriseName());
			carrierMthStyCtModel.setCreateperson(user.getNickname());
			carrierMthStyCtModel.setCreatetime(date);
			carrierMthStyCtModel.setUpdateperson(user.getNickname());
			carrierMthStyCtModel.setUpdatetime(date);
			tmsLineMthStrategyCtMapper.save(carrierMthStyCtModel);
		}
	}

	/**
	 * 线路匹配策略修改
	 *
	 * @param lineMthStrategyUpdateVO
	 * @return
	 */
	@Transactional(rollbackFor = Exception.class)
	public void update(LineMthStrategyUpdateVO lineMthStrategyUpdateVO) {
		ToolKits.isParamNull(lineMthStrategyUpdateVO, "线路匹配策略修改请求不为空");
		ToolKits.isParamNull(lineMthStrategyUpdateVO.getId(), "策略ID不为空");
		ToolKits.isParamNull(lineMthStrategyUpdateVO.getStrategyName(), "策略名称不为空");
		ToolKits.isParamNull(lineMthStrategyUpdateVO.getAdminToAdmin(), "按行政区域-行政区域顺序不为空");
		ToolKits.isParamNull(lineMthStrategyUpdateVO.getAdminToConsignor(), "按行政区域-收货方顺序不为空");
		ToolKits.isParamNull(lineMthStrategyUpdateVO.getBranchToAdmin(), "按仓库-行政区域顺序不为空");
		ToolKits.isParamNull(lineMthStrategyUpdateVO.getBranchToConsignor(), "按仓库-收货方顺序不为空");
		ToolKits.isParamNull(lineMthStrategyUpdateVO.getStrategyCtUpdateVOList(), "线路匹配策略条件不为空");

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

		// 运单匹配条件集合
		Map<Integer, String> conditionMap = Maps.newHashMap();
		for (LineMthStrategyCtUpdateVO conditionVO : lineMthStrategyUpdateVO.getStrategyCtUpdateVOList()) {
			// 配送方式
			if (conditionVO.getStrategyConditionType().equals(DataDictionaryConstant.STRATEGY_CONDITION_TYPE_DELIVERY)) {
				conditionMap.put(DataDictionaryConstant.STRATEGY_CONDITION_TYPE_DELIVERY, String.valueOf(DataDictionaryConstant.STRATEGY_CONDITION_TYPE_DELIVERY) + "_" + String.valueOf(conditionVO.getStrategyConditionValue()));
				continue;
			}
			// 订单类型
			if (conditionVO.getStrategyConditionType().equals(DataDictionaryConstant.STRATEGY_CONDITION_TYPE_ORDER)) {
				conditionMap.put(DataDictionaryConstant.STRATEGY_CONDITION_TYPE_ORDER, String.valueOf(DataDictionaryConstant.STRATEGY_CONDITION_TYPE_ORDER) + "_" + String.valueOf(conditionVO.getStrategyConditionValue()));
				continue;
			}
			// 订单业务类型
			if (conditionVO.getStrategyConditionType().equals(DataDictionaryConstant.STRATEGY_CONDITION_TYPE_ORDER_BUSINESS)) {
				conditionMap.put(DataDictionaryConstant.STRATEGY_CONDITION_TYPE_ORDER_BUSINESS, String.valueOf(DataDictionaryConstant.STRATEGY_CONDITION_TYPE_ORDER_BUSINESS) + "_" + String.valueOf(conditionVO.getStrategyConditionValue()));
				continue;
			}
			// 运输模式
			if (conditionVO.getStrategyConditionType().equals(DataDictionaryConstant.STRATEGY_CONDITION_TYPE_TRANSPORT)) {
				conditionMap.put(DataDictionaryConstant.STRATEGY_CONDITION_TYPE_TRANSPORT, String.valueOf(DataDictionaryConstant.STRATEGY_CONDITION_TYPE_TRANSPORT) + "_" + String.valueOf(conditionVO.getStrategyConditionValue()));
				continue;
			}
			// 温度要求
			if (conditionVO.getStrategyConditionType().equals(DataDictionaryConstant.STRATEGY_CONDITION_TYPE_TEMPERATURE)) {
				conditionMap.put(DataDictionaryConstant.STRATEGY_CONDITION_TYPE_TEMPERATURE, String.valueOf(DataDictionaryConstant.STRATEGY_CONDITION_TYPE_TEMPERATURE) + "_" + String.valueOf(conditionVO.getStrategyConditionValue()));
				continue;
			}
			// 货主ID
			if (conditionVO.getStrategyConditionType().equals(DataDictionaryConstant.STRATEGY_CONDITION_TYPE_OWNER)) {
				if (ToolKits.isEmpty(conditionVO.getUnitId())) {
					throw new PrologException("货主不为空");
				}
				String units = Arrays.stream(String.valueOf(conditionVO.getUnitId()).split(",")).sorted().collect(Collectors.joining(","));
				conditionMap.put(DataDictionaryConstant.STRATEGY_CONDITION_TYPE_OWNER, String.valueOf(DataDictionaryConstant.STRATEGY_CONDITION_TYPE_OWNER) + "_" + units);
				continue;
			}

			// 部门ID
			if (conditionVO.getStrategyConditionType().equals(DataDictionaryConstant.STRATEGY_CONDITION_TYPE_DEPARTMENT)) {
				if (ToolKits.isEmpty(conditionVO.getUnitId())) {
					throw new PrologException("部门不为空");
				}
				String units = Arrays.stream(String.valueOf(conditionVO.getUnitId()).split(",")).sorted().collect(Collectors.joining(","));
				conditionMap.put(DataDictionaryConstant.STRATEGY_CONDITION_TYPE_DEPARTMENT, String.valueOf(DataDictionaryConstant.STRATEGY_CONDITION_TYPE_DEPARTMENT) + "_" + units);
				continue;
			}
			// 收货方类型
			if (conditionVO.getStrategyConditionType().equals(DataDictionaryConstant.STRATEGY_CONDITION_TYPE_CONSIGNEE)) {
				if (ToolKits.isEmpty(conditionVO.getUnitId())) {
					throw new PrologException("收货方不为空");
				}
				String units = Arrays.stream(String.valueOf(conditionVO.getUnitId()).split(",")).sorted().collect(Collectors.joining(","));
				conditionMap.put(DataDictionaryConstant.STRATEGY_CONDITION_TYPE_CONSIGNEE, String.valueOf(DataDictionaryConstant.STRATEGY_CONDITION_TYPE_CONSIGNEE) + "_" + String.valueOf(conditionVO.getStrategyConditionValue()) + "," + units);
				continue;
			}
			// 发货方类型
			if (conditionVO.getStrategyConditionType().equals(DataDictionaryConstant.STRATEGY_CONDITION_TYPE_SHIPPER)) {
				if (ToolKits.isEmpty(conditionVO.getUnitId())) {
					throw new PrologException("发货方不为空");
				}
				String units = Arrays.stream(String.valueOf(conditionVO.getUnitId()).split(",")).sorted().collect(Collectors.joining(","));
				conditionMap.put(DataDictionaryConstant.STRATEGY_CONDITION_TYPE_SHIPPER, String.valueOf(DataDictionaryConstant.STRATEGY_CONDITION_TYPE_SHIPPER) + "_" + String.valueOf(conditionVO.getStrategyConditionValue()) + "," + units);
				continue;
			}
		}

		Criteria carrierCriteria = Criteria.forClass(TmsLineMthStyModel.class);
		Restriction r1 = Restrictions.eq(TmsLineMthStyModel::getEnterpriseId, user.getEnterpriseId());
		Restriction r2 = Restrictions.eq(TmsLineMthStyModel::getStatus, DataDictionaryConstant.GENERAL_STATUS_ENABLE);
		Restriction r5 = Restrictions.ne(TmsLineMthStyModel::getId, lineMthStrategyUpdateVO.getId());
		carrierCriteria.setRestriction(Restrictions.and(r1, r2, r5));
		carrierCriteria.setOrder(Order.newInstance().desc(new String[] { "updatetime" }));
		List<TmsLineMthStyModel> mthStyModels = tmsLineMthStrategyMapper.findByCriteria(carrierCriteria);

		for (TmsLineMthStyModel lineMthStyModel : mthStyModels) {
			// 满足条件
			Criteria carrierCtCriteria = Criteria.forClass(TmsLineMthStyCtModel.class);
			Restriction r3 = Restrictions.eq(TmsLineMthStyCtModel::getStrategyId, lineMthStyModel.getId());
			Restriction r4 = Restrictions.eq(TmsLineMthStyCtModel::getEnterpriseId, user.getEnterpriseId());
			carrierCtCriteria.setRestriction(Restrictions.and(r3, r4));
			carrierCtCriteria.setOrder(Order.newInstance().asc(new String[] { "strategyConditionType" }));
			List<TmsLineMthStyCtModel> mthStyCtModels = tmsLineMthStrategyCtMapper.findByCriteria(carrierCtCriteria);

			// 判定满足条件
			int fitCnt = 0;
			for (TmsLineMthStyCtModel conditionModel : mthStyCtModels) {
				switch (conditionModel.getStrategyConditionType().intValue()) {
				case 2:
				case 3:
					String unit1s = Arrays.stream(String.valueOf(conditionModel.getUnitId()).split(",")).sorted().collect(Collectors.joining(","));
					if (conditionMap.containsValue(String.valueOf(conditionModel.getStrategyConditionType()) + "_" + String.valueOf(conditionModel.getStrategyConditionValue()) + "," + unit1s)) {
						fitCnt++;
					}
					break;
				case 8:
				case 9:
					String unit2s = Arrays.stream(String.valueOf(conditionModel.getUnitId()).split(",")).sorted().collect(Collectors.joining(","));

					if (conditionMap.containsValue(String.valueOf(conditionModel.getStrategyConditionType()) + "_" + unit2s)) {
						fitCnt++;
					}
					break;
				default:
					String unit3s = Arrays.stream(String.valueOf(conditionModel.getStrategyConditionValue()).split(",")).sorted().collect(Collectors.joining(","));

					if (conditionMap.containsValue(String.valueOf(conditionModel.getStrategyConditionType()) + "_" + unit3s)) {
						fitCnt++;
					}
					break;
				}
			}
			// 已经存在相同条件的线路匹配策略
			Assert.isTrue(fitCnt != mthStyCtModels.size(), "线路匹配策略的条件已经存在，请重新配置线路匹配策略条件!");
		}
		// 当前时间
		Date date = DateUtil.date();

		Map<String, Object> mapUpdateMthStyModel = Maps.newHashMap();
		mapUpdateMthStyModel.put("status", DataDictionaryConstant.GENERAL_STATUS_ENABLE);
		mapUpdateMthStyModel.put("adminToAdmin", lineMthStrategyUpdateVO.getAdminToAdmin());
		mapUpdateMthStyModel.put("adminToConsignor", lineMthStrategyUpdateVO.getAdminToConsignor());
		mapUpdateMthStyModel.put("branchToAdmin", lineMthStrategyUpdateVO.getBranchToAdmin());
		mapUpdateMthStyModel.put("branchToConsignor", lineMthStrategyUpdateVO.getBranchToConsignor());
		mapUpdateMthStyModel.put("memo", lineMthStrategyUpdateVO.getMemo());
		mapUpdateMthStyModel.put("updateperson", user.getNickname());
		mapUpdateMthStyModel.put("updatetime", date);

		// 修改
		tmsLineMthStrategyMapper.updateMapById(lineMthStrategyUpdateVO.getId(), mapUpdateMthStyModel, TmsLineMthStyModel.class);

		// 删除条件
		Criteria flowConditionCriteria = Criteria.forClass(TmsLineMthStyCtModel.class);
		Restriction r7 = Restrictions.eq(TmsLineMthStyCtModel::getStrategyId, lineMthStrategyUpdateVO.getId());
		flowConditionCriteria.setRestriction(Restrictions.and(r7));
		tmsLineMthStrategyCtMapper.deleteByCriteria(flowConditionCriteria);

		// 策略条件修改
		for (LineMthStrategyCtUpdateVO strategyCtUpdateVO : lineMthStrategyUpdateVO.getStrategyCtUpdateVOList()) {
			String cid = sysCodeengineService.getCodeNumberByCode(SeriaNnumberConstant.TMS_LINE_MATCH_STRATEGY_CT_ID, "L");
			ToolKits.isParamNull(cid, "线路匹配策略条件ID生成失败");
			TmsLineMthStyCtModel carrierMthStyCtModel = new TmsLineMthStyCtModel();
			BeanUtils.copyProperties(strategyCtUpdateVO, carrierMthStyCtModel);
			carrierMthStyCtModel.setId(Long.valueOf(cid));
			carrierMthStyCtModel.setStrategyId(Long.valueOf(lineMthStrategyUpdateVO.getId()));

			carrierMthStyCtModel.setEnterpriseId(user.getEnterpriseId());
			carrierMthStyCtModel.setEnterpriseName(user.getEnterpriseName());
			carrierMthStyCtModel.setCreateperson(user.getNickname());
			carrierMthStyCtModel.setCreatetime(date);
			tmsLineMthStrategyCtMapper.save(carrierMthStyCtModel);
		}
	}

	/**
	 * 线路匹配策略停用
	 *
	 * @param ids
	 * @return
	 */
	@Transactional(rollbackFor = Exception.class)
	public void stop(List<Long> ids) {
		ToolKits.isParamNull(ids, "线路匹配策略停用请求不为空");

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

		// 当前时间
		Date date = DateUtil.date();
		Map<String, Object> mapUpdate = Maps.newHashMap();
		mapUpdate.put("status", DataDictionaryConstant.GENERAL_STATUS_STOP);
		mapUpdate.put("updateperson", user.getNickname());
		mapUpdate.put("updatetime", date);

		ids.forEach(id -> {
			tmsLineMthStrategyMapper.updateMapById(id, mapUpdate, TmsLineMthStyModel.class);
		});
	}

	/**
	 * 线路匹配策略启用
	 *
	 * @param ids
	 * @return
	 */
	@Transactional(rollbackFor = Exception.class)
	public void enable(List<Long> ids) {
		ToolKits.isParamNull(ids, "线路匹配策略启用请求不为空");

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

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

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

		ids.forEach(id -> {
			tmsLineMthStrategyMapper.updateMapById(id, mapUpdate, TmsLineMthStyModel.class);
		});
	}

	/**
	 * 线路匹配策略查看
	 *
	 * @param viewVO
	 * @return
	 */
	public LineMthStrategyViewDTO view(LineMthStrategyViewVO viewVO) {
		ToolKits.isParamNull(viewVO, "线路匹配策略查看请求不为空");
		ToolKits.isParamNull(viewVO.getId(), "线路匹配策略ID不为空");

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

		TmsLineMthStyModel mthStyModel = tmsLineMthStrategyMapper.findById(viewVO.getId(), TmsLineMthStyModel.class);

		if (ToolKits.isEmpty(mthStyModel)) {
			throw new PrologException("查看的运营方匹配策略不存在");
		}
		Criteria lineCtCriteria = Criteria.forClass(TmsLineMthStyCtModel.class);
		Restriction r1 = Restrictions.eq(TmsLineMthStyCtModel::getStrategyId, viewVO.getId());
		Restriction r2 = Restrictions.eq(TmsLineMthStyCtModel::getEnterpriseId, user.getEnterpriseId());
		lineCtCriteria.setRestriction(Restrictions.and(r1, r2));
		lineCtCriteria.setOrder(Order.newInstance().asc(new String[] { "strategyConditionType" }));
		List<TmsLineMthStyCtModel> mthStyCtModels = tmsLineMthStrategyCtMapper.findByCriteria(lineCtCriteria);

		LineMthStrategyViewDTO viewDTO = new LineMthStrategyViewDTO();
		viewDTO.setStrategyName(mthStyModel.getName());
		viewDTO.setMemo(mthStyModel.getMemo());

		List<LineMthStrategyPrioDTO> prioDTOS = Lists.newArrayList();
		LineMthStrategyPrioDTO prio1DTO = new LineMthStrategyPrioDTO();
		prio1DTO.setMatchTypeItem("按行政区域-行政区域");
		prio1DTO.setNum(mthStyModel.getAdminToAdmin());
		prioDTOS.add(prio1DTO);

		LineMthStrategyPrioDTO prio2DTO = new LineMthStrategyPrioDTO();
		prio2DTO.setMatchTypeItem("按行政区域-收货方");
		prio2DTO.setNum(mthStyModel.getAdminToConsignor());
		prioDTOS.add(prio2DTO);

		LineMthStrategyPrioDTO prio3DTO = new LineMthStrategyPrioDTO();
		prio3DTO.setMatchTypeItem("按仓库-行政区域");
		prio3DTO.setNum(mthStyModel.getBranchToAdmin());
		prioDTOS.add(prio3DTO);

		LineMthStrategyPrioDTO prio4DTO = new LineMthStrategyPrioDTO();
		prio4DTO.setMatchTypeItem("按仓库-收货方");
		prio4DTO.setNum(mthStyModel.getBranchToConsignor());
		prioDTOS.add(prio4DTO);

		List<LineMthStrategyPrioDTO> list = prioDTOS.stream().sorted(Comparator.comparing(LineMthStrategyPrioDTO::getNum)).collect(Collectors.toList());

		viewDTO.setLineMthStrategyPrioDTOS(list);

		// 策略条件类型
		List<Map<String, Object>> restMsgStyConditionType = sysRefdatadService.getDropDownById(DataDictionaryConstant.STRATEGY_CONDITION_TYPE, null, null, null);
		// 配送方式
		List<Map<String, Object>> restMsgDeliveryMethodType = sysRefdatadService.getDropDownById(DataDictionaryConstant.DELIVERY_METHOD_TYPE, null, null, null);
		// 订单类型
		List<Map<String, Object>> restMsgOrderType = sysRefdatadService.getDropDownById(DataDictionaryConstant.ORDER_TYPE, null, null, null);
		// 订单业务类型
		List<Map<String, Object>> restMsgOrderBusinessType = sysRefdatadService.getDropDownById(DataDictionaryConstant.ORDER_BUSINESS_TYPE, null, null, null);
		// 运输类型(运输模式)
		List<Map<String, Object>> restMsgTransportType = sysRefdatadService.getDropDownById(DataDictionaryConstant.TRANSPORT_TYPE, null, null, null);
		// 收货方类型
		List<Map<String, Object>> restMsgConsigneeType = sysRefdatadService.getDropDownById(DataDictionaryConstant.CONSIGNEE_TYPE, null, null, null);
		// 发货方类型
		List<Map<String, Object>> restMsgShipperType = sysRefdatadService.getDropDownById(DataDictionaryConstant.SHIPPER_TYPE, null, null, null);
		// 温度要求
		List<Map<String, Object>> restMsgTemperature = sysRefdatadService.getDropDownById(DataDictionaryConstant.TEMPERATURE_REQUIREMENT, null, null, null);

		List<LineMthStrategyCtViewDTO> ctViewDTOS = Lists.newArrayList();
		for (TmsLineMthStyCtModel ctModel : mthStyCtModels) {
			LineMthStrategyCtViewDTO ctViewDTO = new LineMthStrategyCtViewDTO();
			BeanUtils.copyProperties(ctModel, ctViewDTO);
			ctViewDTO.setStrategyConditionTypeName(PublicMethods.change(restMsgStyConditionType, String.valueOf(ctModel.getStrategyConditionType())));

			// 满足条件
			switch (ctModel.getStrategyConditionType().intValue()) {
			case 1:
				// 1配送方式
				ctViewDTO.setStrategyConditionValueName(PublicMethods.change(restMsgDeliveryMethodType, String.valueOf(ctModel.getStrategyConditionValue())));
				break;
			case 2:
				// 2发货方类型
				ctViewDTO.setStrategyConditionValueName(PublicMethods.change(restMsgShipperType, String.valueOf(ctModel.getStrategyConditionValue())));
				break;
			case 3:
				// 3收货方类型
				ctViewDTO.setStrategyConditionValueName(PublicMethods.change(restMsgConsigneeType, String.valueOf(ctModel.getStrategyConditionValue())));
				break;
			case 4:
				// 4订单类型
				ctViewDTO.setStrategyConditionValueName(PublicMethods.change(restMsgOrderType, String.valueOf(ctModel.getStrategyConditionValue())));
				break;
			case 5:
				// 5订单业务类型
				ctViewDTO.setStrategyConditionValueName(PublicMethods.change(restMsgOrderBusinessType, String.valueOf(ctModel.getStrategyConditionValue())));
				break;
			case 6:
				// 6运输模式
				ctViewDTO.setStrategyConditionValueName(PublicMethods.change(restMsgTransportType, String.valueOf(ctModel.getStrategyConditionValue())));
				break;
			case 7:
				// 7温度要求
				ctViewDTO.setStrategyConditionValueName(PublicMethods.change(restMsgTemperature, String.valueOf(ctModel.getStrategyConditionValue())));
				break;
			}
			ctViewDTOS.add(ctViewDTO);
		}
		viewDTO.setLineMthStrategyCtViewDTOS(ctViewDTOS);
		return viewDTO;
	}

	/**
	 * 根据运单匹配线路策略
	 *
	 * @param matchLineVO
	 * @return
	 */
	public ShipbillMatchLineDTO shipbillMatchLine(ShipbillMatchLineVO matchLineVO) {
		ToolKits.isParamNull(matchLineVO, "运单匹配线路策略请求不为空");
		ToolKits.isParamNull(matchLineVO.getDepartmentId(), "运单的部门不为空");
		ToolKits.isParamNull(matchLineVO.getCargoOwnerId(), "运单的货主不为空");
		ShipbillMatchLineDTO matchLineDTO = new ShipbillMatchLineDTO();
		log.info("运单匹配线路策略:" + JSON.toJSONString(matchLineVO));

		Criteria lineCriteria = Criteria.forClass(TmsLineMthStyModel.class);
		Restriction r1 = Restrictions.eq(TmsLineMthStyModel::getEnterpriseId, matchLineVO.getEnterpriseId());
		Restriction r2 = Restrictions.eq(TmsLineMthStyModel::getStatus, DataDictionaryConstant.GENERAL_STATUS_ENABLE);
		lineCriteria.setRestriction(Restrictions.and(r1, r2));
		List<TmsLineMthStyModel> mthStyModels = tmsLineMthStrategyMapper.findByCriteria(lineCriteria);

		if (ToolKits.isEmpty(mthStyModels)) {
			return null;
		}
		// 运单匹配条件集合
		Map<Integer, String> conditionMap = Maps.newHashMap();
		// 配送方式
		if (ToolKits.isNotEmpty(matchLineVO.getDeliveryMethodType())) {
			conditionMap.put(DataDictionaryConstant.STRATEGY_CONDITION_TYPE_DELIVERY, DataDictionaryConstant.STRATEGY_CONDITION_TYPE_DELIVERY + "_" + String.valueOf(matchLineVO.getDeliveryMethodType()));
		}
		// 订单类型
		if (ToolKits.isNotEmpty(matchLineVO.getOrderType())) {
			conditionMap.put(DataDictionaryConstant.STRATEGY_CONDITION_TYPE_ORDER, DataDictionaryConstant.STRATEGY_CONDITION_TYPE_ORDER + "_" + String.valueOf(matchLineVO.getOrderType()));
		}
		// 订单业务类型
		if (ToolKits.isNotEmpty(matchLineVO.getOrderBusinessType())) {
			conditionMap.put(DataDictionaryConstant.STRATEGY_CONDITION_TYPE_ORDER_BUSINESS, DataDictionaryConstant.STRATEGY_CONDITION_TYPE_ORDER_BUSINESS + "_" + String.valueOf(matchLineVO.getOrderBusinessType()));
		}
		// 运输模式
		if (ToolKits.isNotEmpty(matchLineVO.getTransportType())) {
			conditionMap.put(DataDictionaryConstant.STRATEGY_CONDITION_TYPE_TRANSPORT, DataDictionaryConstant.STRATEGY_CONDITION_TYPE_TRANSPORT + "_" + String.valueOf(matchLineVO.getTransportType()));
		}
		// 温度要求
		if (ToolKits.isNotEmpty(matchLineVO.getTemperatureRequirement())) {
			conditionMap.put(DataDictionaryConstant.STRATEGY_CONDITION_TYPE_TEMPERATURE, DataDictionaryConstant.STRATEGY_CONDITION_TYPE_TEMPERATURE + "_" + String.valueOf(matchLineVO.getTemperatureRequirement()));
		}
		// 货主ID
		if (ToolKits.isNotEmpty(matchLineVO.getCargoOwnerId())) {
			conditionMap.put(DataDictionaryConstant.STRATEGY_CONDITION_TYPE_OWNER, String.valueOf(matchLineVO.getCargoOwnerId()));
		}

		// 部门ID
		if (ToolKits.isNotEmpty(matchLineVO.getDepartmentId())) {
			conditionMap.put(DataDictionaryConstant.STRATEGY_CONDITION_TYPE_DEPARTMENT, String.valueOf(matchLineVO.getDepartmentId()));
		}

		// 发货方类型
		if (ToolKits.isNotEmpty(matchLineVO.getShipperType())) {
			conditionMap.put(DataDictionaryConstant.STRATEGY_CONDITION_TYPE_SHIPPER, String.valueOf(matchLineVO.getShipperType()) + "," + String.valueOf(matchLineVO.getShipperUnitId()));
		}
		// 收货方类型
		if (ToolKits.isNotEmpty(matchLineVO.getConsigneeType())) {
			conditionMap.put(DataDictionaryConstant.STRATEGY_CONDITION_TYPE_CONSIGNEE, String.valueOf(matchLineVO.getConsigneeType()) + "," + String.valueOf(matchLineVO.getConsigneeUnitId()));
		}
		for (TmsLineMthStyModel lineMthStyModel : mthStyModels) {
			// 满足条件
			Criteria lineCtCriteria = Criteria.forClass(TmsLineMthStyCtModel.class);
			Restriction r3 = Restrictions.eq(TmsLineMthStyCtModel::getStrategyId, lineMthStyModel.getId());
			Restriction r4 = Restrictions.eq(TmsLineMthStyCtModel::getEnterpriseId, matchLineVO.getEnterpriseId());
			lineCtCriteria.setRestriction(Restrictions.and(r3, r4));
			List<TmsLineMthStyCtModel> mthStyCtModels = tmsLineMthStrategyCtMapper.findByCriteria(lineCtCriteria);

			if (ToolKits.isEmpty(mthStyCtModels)) {
				continue;
			}
			// 判定满足条件
			int fitCnt = 0;
			for (TmsLineMthStyCtModel conditionModel : mthStyCtModels) {
				switch (conditionModel.getStrategyConditionType().intValue()) {
				case 2:
				case 3:
					String[] cmpStr1 = conditionMap.get(conditionModel.getStrategyConditionType()).split(",");
					if (cmpStr1[0].equals(String.valueOf(conditionModel.getStrategyConditionValue())) && conditionModel.getUnitId().contains(cmpStr1[1])) {
						fitCnt++;
					}
					break;
				case 8:
				case 9:
					if (conditionModel.getUnitId().contains(conditionMap.get(conditionModel.getStrategyConditionType()))) {
						fitCnt++;
					}
					break;
				default:
					if (conditionMap.containsValue(conditionModel.getStrategyConditionType() + "_" + String.valueOf(conditionModel.getStrategyConditionValue()))) {
						fitCnt++;
					}
					break;
				}
			}
			// 匹配到了线路匹配策略
			if (fitCnt > 0 && fitCnt == mthStyCtModels.size()) {
				log.info("匹配到的线路策略:" + JSON.toJSONString(mthStyCtModels));
				Map<Integer, String> levelMap = Maps.newHashMap();
				levelMap.put(lineMthStyModel.getAdminToAdmin(), "按行政区域-行政区域匹配线路");
				levelMap.put(lineMthStyModel.getAdminToConsignor(), "按行政区域-收货方匹配线路");
				levelMap.put(lineMthStyModel.getBranchToAdmin(), "按仓库-行政区域匹配线路");
				levelMap.put(lineMthStyModel.getBranchToConsignor(), "按仓库-收货方匹配线路");

				List<Map.Entry<Integer, String>> infoIds = new ArrayList<Map.Entry<Integer, String>>(levelMap.entrySet());

				// 对HashMap中的key 进行排序
				Collections.sort(infoIds, new Comparator<Map.Entry<Integer, String>>() {
					public int compare(Map.Entry<Integer, String> o1, Map.Entry<Integer, String> o2) {
						return (o1.getKey()).toString().compareTo(o2.getKey().toString());
					}
				});

				ShipbillMatchLineQueryVO shipbillMatchLineQueryVO = new ShipbillMatchLineQueryVO();
				shipbillMatchLineQueryVO.setEnterpriseId(matchLineVO.getEnterpriseId());
				for (Map.Entry<Integer, String> entry : infoIds) {
					if ("按行政区域-行政区域匹配线路".equals(entry.getValue())) {
						shipbillMatchLineQueryVO.setStartLineType(Integer.valueOf(2));
						shipbillMatchLineQueryVO.setDistinguishType(Integer.valueOf(2));
						List<ShipbillMatchLineQueryDTO> shipbillMatchLineQueryDTOS = translineService.shipbillMatchLineQuery(shipbillMatchLineQueryVO);

						if (ToolKits.isNotEmpty(shipbillMatchLineQueryDTOS)) {
							for (ShipbillMatchLineQueryDTO lineQueryDTO : shipbillMatchLineQueryDTOS) {
								String consigneeAreas = lineQueryDTO.getAdministrativeAreas();
								String shipperAreas = lineQueryDTO.getShipperAdministrativeAreas();
								// 线路未维护收发货方行政区域，不能匹配线路
								if (ToolKits.isNotEmpty(consigneeAreas) && ToolKits.isNotEmpty(shipperAreas)) {
									if (shipperAreas.contains(matchLineVO.getShipperDistrict())
											&& consigneeAreas.contains(matchLineVO.getConsigneeDistrict())) {
										// 查线路收货方表行政区数据
										Criteria consigneeCriteria = Criteria.forClass(TmsLineConsigneeLinkModel.class);
										r1 = Restrictions.eq(TmsLineConsigneeLinkModel::getConsigneeCode, matchLineVO.getConsigneeProvince());
										r2 = Restrictions.eq(TmsLineConsigneeLinkModel::getConsigneeCode, matchLineVO.getConsigneeCity());
										r3 = Restrictions.eq(TmsLineConsigneeLinkModel::getConsigneeCode, matchLineVO.getConsigneeDistrict());
										r4= Restrictions.or(r1,r2,r3);
										Restriction r5 = Restrictions.eq(TmsLineConsigneeLinkModel::getLineId, lineQueryDTO.getLineId());
										consigneeCriteria.setRestriction(Restrictions.and(r4, r5));
										List<TmsLineConsigneeLinkModel> tmsLineConsigneeLinkModels = tmsLineConsigneeLinkMapper.findByCriteria(consigneeCriteria);
										if (ToolKits.isNotEmpty(tmsLineConsigneeLinkModels)) {
											matchLineDTO.setShippingOrder(tmsLineConsigneeLinkModels.get(0).getDeliveryOrder());
											matchLineDTO.setConsigneeAgingTime(tmsLineConsigneeLinkModels.get(0).getConsigneeAgingTime());
											matchLineDTO.setConsigneeAgingTimeLine(tmsLineConsigneeLinkModels.get(0).getConsigneeAgingTimeLine());
										}
										// 查线路发货方表行政区数据
										Criteria shipperCriteria = Criteria.forClass(TmsLineShipperLinkModel.class);
										r1 = Restrictions.eq(TmsLineShipperLinkModel::getBranchCode, matchLineVO.getShipperProvince());
										r2 = Restrictions.eq(TmsLineShipperLinkModel::getBranchCode, matchLineVO.getShipperCity());
										r3 = Restrictions.eq(TmsLineShipperLinkModel::getBranchCode, matchLineVO.getShipperDistrict());
										r4= Restrictions.or(r1,r2,r3);
										r5 = Restrictions.eq(TmsLineConsigneeLinkModel::getLineId, lineQueryDTO.getLineId());
										consigneeCriteria.setRestriction(Restrictions.and(r4, r5));
										List<TmsLineShipperLinkModel> tmsLineShipperLinkModels = tmsLineShipperLinkMapper.findByCriteria(shipperCriteria);
										if (ToolKits.isNotEmpty(tmsLineShipperLinkModels)) {
											matchLineDTO.setPickUpOrder(tmsLineShipperLinkModels.get(0).getPickupOrder());
											matchLineDTO.setShipperAgingTime(tmsLineShipperLinkModels.get(0).getShipperAgingTime());
											matchLineDTO.setShipperAgingTimeLine(tmsLineShipperLinkModels.get(0).getShipperAgingTimeLine());
										}
										matchLineDTO.setLineId(lineQueryDTO.getLineId());
										matchLineDTO.setLineCode(lineQueryDTO.getLineCode());
										matchLineDTO.setLineName(lineQueryDTO.getLineName());
										matchLineDTO.setLineDirection(lineQueryDTO.getLineDirection());
										break;
									}
								}
							}
							if (ToolKits.isNotEmpty(matchLineDTO.getLineId())) {
								break;
							}
						}
					} else if ("按行政区域-收货方匹配线路".equals(entry.getValue())) {
						shipbillMatchLineQueryVO.setStartLineType(Integer.valueOf(2));
						shipbillMatchLineQueryVO.setDistinguishType(Integer.valueOf(1));
						List<ShipbillMatchLineQueryDTO> shipbillMatchLineQueryDTOS = translineService.shipbillMatchLineQuery(shipbillMatchLineQueryVO);

						if (ToolKits.isNotEmpty(shipbillMatchLineQueryDTOS)) {
							for (ShipbillMatchLineQueryDTO lineQueryDTO : shipbillMatchLineQueryDTOS) {
								String shipperAreas = lineQueryDTO.getShipperAdministrativeAreas();
								if (ToolKits.isNotEmpty(shipperAreas) && shipperAreas.contains(matchLineVO.getShipperDistrict())) {
									// 查线路收货方表数据
									Criteria consigneeCriteria = Criteria.forClass(TmsLineConsigneeLinkModel.class);
									r1 = Restrictions.eq(TmsLineConsigneeLinkModel::getCustomerId, matchLineVO.getConsigneeUnitId());
									r2 = Restrictions.eq(TmsLineConsigneeLinkModel::getConsigneeId, matchLineVO.getConsigneeId());
									r3 = Restrictions.eq(TmsLineConsigneeLinkModel::getLineId, lineQueryDTO.getLineId());
									consigneeCriteria.setRestriction(Restrictions.and(r1, r2, r3));
									List<TmsLineConsigneeLinkModel> tmsLineConsigneeLinkModels = tmsLineConsigneeLinkMapper.findByCriteria(consigneeCriteria);
									if (ToolKits.isNotEmpty(tmsLineConsigneeLinkModels)) {
										matchLineDTO.setLineId(tmsLineConsigneeLinkModels.get(0).getLineId());
										matchLineDTO.setLineCode(tmsLineConsigneeLinkModels.get(0).getLineCode());
										matchLineDTO.setLineName(tmsLineConsigneeLinkModels.get(0).getLineName());
										matchLineDTO.setLineDirection(lineQueryDTO.getLineDirection());
										matchLineDTO.setShippingOrder(tmsLineConsigneeLinkModels.get(0).getDeliveryOrder());
										matchLineDTO.setConsigneeAgingTime(tmsLineConsigneeLinkModels.get(0).getConsigneeAgingTime());
										matchLineDTO.setConsigneeAgingTimeLine(tmsLineConsigneeLinkModels.get(0).getConsigneeAgingTimeLine());
										break;
									}
								}
							}
							if (ToolKits.isNotEmpty(matchLineDTO.getLineId())) {
								break;
							}
						}
					} else if ("按仓库-行政区域匹配线路".equals(entry.getValue())) {
						shipbillMatchLineQueryVO.setStartLineType(Integer.valueOf(1));
						shipbillMatchLineQueryVO.setDistinguishType(Integer.valueOf(2));
						List<ShipbillMatchLineQueryDTO> shipbillMatchLineQueryDTOS = translineService.shipbillMatchLineQuery(shipbillMatchLineQueryVO);

						if (ToolKits.isNotEmpty(shipbillMatchLineQueryDTOS)) {
							for (ShipbillMatchLineQueryDTO lineQueryDTO : shipbillMatchLineQueryDTOS) {
								String consigneeAreas = lineQueryDTO.getAdministrativeAreas();
								if (ToolKits.isNotEmpty(consigneeAreas) && consigneeAreas.contains(matchLineVO.getConsigneeDistrict())) {
									// 查线路发货方表数据
									Criteria shipperCriteria = Criteria.forClass(TmsLineShipperLinkModel.class);
									r1 = Restrictions.eq(TmsLineShipperLinkModel::getBranchId, matchLineVO.getShipperUnitId());
									r2 = Restrictions.eq(TmsLineShipperLinkModel::getLineId, lineQueryDTO.getLineId());
									shipperCriteria.setRestriction(Restrictions.and(r1, r2));
									List<TmsLineShipperLinkModel> tmsLineShipperLinkModels = tmsLineShipperLinkMapper.findByCriteria(shipperCriteria);
									if (ToolKits.isNotEmpty(tmsLineShipperLinkModels)) {
										matchLineDTO.setLineId(tmsLineShipperLinkModels.get(0).getLineId());
										matchLineDTO.setLineCode(tmsLineShipperLinkModels.get(0).getLineCode());
										matchLineDTO.setLineName(tmsLineShipperLinkModels.get(0).getLineName());
										matchLineDTO.setLineDirection(lineQueryDTO.getLineDirection());

										// 查线路收货方表行政区数据
										Criteria consigneeCriteria = Criteria.forClass(TmsLineConsigneeLinkModel.class);
										r1 = Restrictions.eq(TmsLineConsigneeLinkModel::getConsigneeCode, matchLineVO.getConsigneeProvince());
										r2 = Restrictions.eq(TmsLineConsigneeLinkModel::getConsigneeCode, matchLineVO.getConsigneeCity());
										r3 = Restrictions.eq(TmsLineConsigneeLinkModel::getConsigneeCode, matchLineVO.getConsigneeDistrict());
										r4= Restrictions.or(r1,r2,r3);
										Restriction r5 = Restrictions.eq(TmsLineConsigneeLinkModel::getLineId, lineQueryDTO.getLineId());
										consigneeCriteria.setRestriction(Restrictions.and(r4, r5));
										List<TmsLineConsigneeLinkModel> tmsLineConsigneeLinkModels = tmsLineConsigneeLinkMapper.findByCriteria(consigneeCriteria);
										if (ToolKits.isNotEmpty(tmsLineConsigneeLinkModels)) {
											matchLineDTO.setShippingOrder(tmsLineConsigneeLinkModels.get(0).getDeliveryOrder());
											matchLineDTO.setConsigneeAgingTime(tmsLineConsigneeLinkModels.get(0).getConsigneeAgingTime());
											matchLineDTO.setConsigneeAgingTimeLine(tmsLineConsigneeLinkModels.get(0).getConsigneeAgingTimeLine());
										}
										break;
									}
								}
							}
							if (ToolKits.isNotEmpty(matchLineDTO.getLineId())) {
								break;
							}
						}
					} else if ("按仓库-收货方匹配线路".equals(entry.getValue())) {
						shipbillMatchLineQueryVO.setStartLineType(Integer.valueOf(1));
						shipbillMatchLineQueryVO.setDistinguishType(Integer.valueOf(1));
						List<ShipbillMatchLineQueryDTO> shipbillMatchLineQueryDTOS = translineService.shipbillMatchLineQuery(shipbillMatchLineQueryVO);

						if (ToolKits.isNotEmpty(shipbillMatchLineQueryDTOS)) {
							for (ShipbillMatchLineQueryDTO lineQueryDTO : shipbillMatchLineQueryDTOS) {
								// 查线路收货方表数据
								Criteria consigneeCriteria = Criteria.forClass(TmsLineConsigneeLinkModel.class);
								r1 = Restrictions.eq(TmsLineConsigneeLinkModel::getCustomerId, matchLineVO.getConsigneeUnitId());
								r2 = Restrictions.eq(TmsLineConsigneeLinkModel::getConsigneeId, matchLineVO.getConsigneeId());
								r3 = Restrictions.eq(TmsLineConsigneeLinkModel::getLineId, lineQueryDTO.getLineId());
								consigneeCriteria.setRestriction(Restrictions.and(r1, r2, r3));
								List<TmsLineConsigneeLinkModel> tmsLineConsigneeLinkModels = tmsLineConsigneeLinkMapper.findByCriteria(consigneeCriteria);
								if (ToolKits.isNotEmpty(tmsLineConsigneeLinkModels)) {
									// 查线路发货方表数据
									Criteria shipperCriteria = Criteria.forClass(TmsLineShipperLinkModel.class);
									r1 = Restrictions.eq(TmsLineShipperLinkModel::getBranchId, matchLineVO.getShipperUnitId());
									r2 = Restrictions.eq(TmsLineShipperLinkModel::getLineId, lineQueryDTO.getLineId());
									shipperCriteria.setRestriction(Restrictions.and(r1, r2));
									List<TmsLineShipperLinkModel> tmsLineShipperLinkModels = tmsLineShipperLinkMapper.findByCriteria(shipperCriteria);
									if (ToolKits.isNotEmpty(tmsLineShipperLinkModels)) {
										matchLineDTO.setLineId(tmsLineShipperLinkModels.get(0).getLineId());
										matchLineDTO.setLineCode(tmsLineShipperLinkModels.get(0).getLineCode());
										matchLineDTO.setLineName(tmsLineShipperLinkModels.get(0).getLineName());
										matchLineDTO.setLineDirection(lineQueryDTO.getLineDirection());
										matchLineDTO.setShippingOrder(tmsLineConsigneeLinkModels.get(0).getDeliveryOrder());
										matchLineDTO.setPickUpOrder(tmsLineShipperLinkModels.get(0).getPickupOrder());
										matchLineDTO.setConsigneeAgingTime(tmsLineConsigneeLinkModels.get(0).getConsigneeAgingTime());
										matchLineDTO.setConsigneeAgingTimeLine(tmsLineConsigneeLinkModels.get(0).getConsigneeAgingTimeLine());
										matchLineDTO.setShipperAgingTime(tmsLineShipperLinkModels.get(0).getShipperAgingTime());
										matchLineDTO.setShipperAgingTimeLine(tmsLineShipperLinkModels.get(0).getShipperAgingTimeLine());
										break;
									}
								}
							}
							if (ToolKits.isNotEmpty(matchLineDTO.getLineId())) {
								break;
							}
						}
					}
				}
			}
		}
		return matchLineDTO;
	}

	/**
	 * 运单批量匹配线路策略
	 *
	 * @param matchLineVOs
	 * @return
	 */
	public Map<String, ShipbillMatchLineDTO> shipbillMatchLineBatch(List<ShipbillMatchLineVO> matchLineVOs) {
		if (ToolKits.isEmpty(matchLineVOs)) {
			return null;
		}
		Map<String, ShipbillMatchLineDTO> rsMaps = Maps.newHashMap();
		for (ShipbillMatchLineVO lineVO:matchLineVOs) {
			ShipbillMatchLineDTO matchLineDTO = shipbillMatchLine(lineVO);
			if (ToolKits.isNotEmpty(matchLineDTO)) {
				rsMaps.put(lineVO.getShipbillId(),matchLineDTO);
			}
		}
		return rsMaps;
	}
}
