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

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

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.prolog.rdc.tms.model.entity.TmsLoadingBillDetailModel;
import lombok.extern.slf4j.Slf4j;
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.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.prolog.common.util.DateUtils;
import com.prolog.common.util.ToolKits;
import com.prolog.framework.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.TmsBusinessFlowConditionMapper;
import com.prolog.rdc.tms.dao.mapper.TmsBusinessFlowMapper;
import com.prolog.rdc.tms.model.dto.basicConfigure.BusinessFlowConditionViewDTO;
import com.prolog.rdc.tms.model.dto.basicConfigure.BusinessFlowQueryDTO;
import com.prolog.rdc.tms.model.dto.basicConfigure.BusinessFlowViewDTO;
import com.prolog.rdc.tms.model.dto.basicConfigure.ShipbillFitBusinessFlowDTO;
import com.prolog.rdc.tms.model.entity.TmsBusinFlowConditionModel;
import com.prolog.rdc.tms.model.entity.TmsBusinessFlowModel;
import com.prolog.rdc.tms.model.vo.basicConfigure.BusinessFlowAddVO;
import com.prolog.rdc.tms.model.vo.basicConfigure.BusinessFlowConditionAddVO;
import com.prolog.rdc.tms.model.vo.basicConfigure.BusinessFlowConditionUpdateVO;
import com.prolog.rdc.tms.model.vo.basicConfigure.BusinessFlowQueryVO;
import com.prolog.rdc.tms.model.vo.basicConfigure.BusinessFlowShipbillVO;
import com.prolog.rdc.tms.model.vo.basicConfigure.BusinessFlowUpdateVO;
import com.prolog.rdc.tms.service.SysCodeengineService;
import com.prolog.rdc.tms.service.SysRefdatadService;
import com.prolog.rdc.tms.service.basicConfigure.BusinessFlowService;
import com.prolog.rdc.tms.util.PublicMethods;

/**
 * 业务流程实现层
 *
 * @author :lhb
 * @version :1.0.0
 * @className :BusinessFlowServiceImpl
 * @creationTime :2022/06/16
 * @description :
 * @modifier :
 * @modifyTime :
 * @reviseRemarks:
 */
@Service
@Slf4j
public class BusinessFlowServiceImpl implements BusinessFlowService {

	@Autowired
	private TmsBusinessFlowMapper tmsBusinessFlowMapper;

	@Autowired
	private TmsBusinessFlowConditionMapper tmsBusinessFlowConditionMapper;

	@Autowired
	private SysRefdatadService sysRefdatadService;

	@Autowired
	private SysCodeengineService sysCodeengineService;

	/**
	 * 业务流程分页查询
	 *
	 * @param businessFlowQueryVO
	 * @return
	 */
	@SuppressWarnings("resource")
	public Page<BusinessFlowQueryDTO> queryBusinessFlow(BusinessFlowQueryVO businessFlowQueryVO) {
		ToolKits.isParamNull(businessFlowQueryVO, "业务流程查询请求不为空");
		ToolKits.isParamNull(businessFlowQueryVO.getPageNum(), "页码不为空");
		ToolKits.isParamNull(businessFlowQueryVO.getPageSize(), "页码大小不为空");

		UserEntity user = PlgFxUsrUtils.getUserEntity();
		ToolKits.isParamNull(user, "没有操作权限！");

		// 响应集合
		List<BusinessFlowQueryDTO> businessFlowQueryDTOs = new ArrayList<>();

		// 审批流程类型名称
		List<Map<String, Object>> restMessageFlowType = sysRefdatadService.getDropDownById(DataDictionaryConstant.FLOW_TYPE, null, null, null);
		// 配送方式
		List<Map<String, Object>> restMessageDeliveryMethodType = sysRefdatadService.getDropDownById(DataDictionaryConstant.DELIVERY_METHOD_TYPE, null, null, null);
		// 收货方类型
		List<Map<String, Object>> restMessageConsigneeType = sysRefdatadService.getDropDownById(DataDictionaryConstant.CONSIGNEE_TYPE, null, null, null);
		// 发货方类型
		List<Map<String, Object>> restMessageShipperType = sysRefdatadService.getDropDownById(DataDictionaryConstant.SHIPPER_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>> restMsgTemperature = sysRefdatadService.getDropDownById(DataDictionaryConstant.TEMPERATURE_REQUIREMENT, null, null, null);

		// 流程配置
		List<Map<String, Object>> restMsgFlowConfig = sysRefdatadService.getDropDownById(DataDictionaryConstant.FLOW_CONFIG, null, null, null);

		Criteria flowCriteria = Criteria.forClass(TmsBusinessFlowModel.class);
		Restriction r1 = ToolKits.isEmpty(businessFlowQueryVO.getFlowName()) ? null : Restrictions.like("flowName", "%" + businessFlowQueryVO.getFlowName() + "%");
		Restriction r2 = Restrictions.eq("enterpriseId", user.getEnterpriseId());
		flowCriteria.setOrder(Order.newInstance().asc(new String[] { "priorityLevel" }));
		flowCriteria.setRestriction(Restrictions.and(r1, r2));
		PageUtils.startPage(businessFlowQueryVO.getPageNum(), businessFlowQueryVO.getPageSize());
		List<TmsBusinessFlowModel> tmsBusinessFlowModels = tmsBusinessFlowMapper.findByCriteria(flowCriteria);

		Criteria flowConditionCriteria = Criteria.forClass(TmsBusinFlowConditionModel.class);
		for (TmsBusinessFlowModel flowModel : tmsBusinessFlowModels) {
			BusinessFlowQueryDTO businessFlowQueryDTO = new BusinessFlowQueryDTO();
			BeanUtils.copyProperties(flowModel, businessFlowQueryDTO);
			String[] FlowConfigArr = businessFlowQueryDTO.getFlowConfig().split(",");
			List<String> FlowConfigList = Arrays.stream(FlowConfigArr).map(flowConfig -> PublicMethods.change(restMsgFlowConfig, flowConfig)).collect(Collectors.toList());
			// 流程配置名称restMsgFlowConfig
			businessFlowQueryDTO.setFlowConfigName(FlowConfigList.stream().collect(Collectors.joining("-->")));

			businessFlowQueryDTO.setFlowTypeName(PublicMethods.change(restMessageFlowType, String.valueOf(businessFlowQueryDTO.getFlowType())));

			// 查询业务流程条件表
			r1 = Restrictions.eq("businessFlowId", flowModel.getId());
			r2 = Restrictions.eq("enterpriseId", user.getEnterpriseId());
			flowConditionCriteria.setRestriction(Restrictions.and(r1, r2));
			flowConditionCriteria.setOrder(Order.newInstance().asc(new String[] { "flowConditionCategory" }));
			List<TmsBusinFlowConditionModel> tmsBusinFlowConditionModels = tmsBusinessFlowConditionMapper.findByCriteria(flowConditionCriteria);
			StringBuffer meetConditionsBuff = new StringBuffer();
			StringBuffer excludedConditionsBuff = new StringBuffer();
			List<String> conditionIds = Lists.newArrayList();
			for (TmsBusinFlowConditionModel conditionModel : tmsBusinFlowConditionModels) {
				List<String> conditions = Lists.newArrayList();
				if (ToolKits.isNotEmpty(conditionModel.getFlowConditionValue())) {
					conditions = Arrays.stream(conditionModel.getFlowConditionValue().split(",")).collect(Collectors.toList());
				}
				if (conditionModel.getFlowConditionCategory().equals(DataDictionaryConstant.FLOW_CONDITION_CATEGORY_MEET)) {
					// 满足条件
					switch (conditionModel.getFlowConditionType().intValue()) {
						case 1:
							// 1配送方式
							meetConditionsBuff.append("配送方式 ");
							meetConditionsBuff.append(PublicMethods.change(restMessageDeliveryMethodType, String.valueOf(conditionModel.getFlowConditionValue())) + " ");
							break;
						case 2:
							// 2发货方类型
							meetConditionsBuff.append("发货方类型 ");
							meetConditionsBuff.append(PublicMethods.change(restMessageShipperType, String.valueOf(conditionModel.getFlowConditionValue())) + " " + conditionModel.getUnitName() + " ");
							break;
						case 3:
							// 3收货方类型
							meetConditionsBuff.append("收货方类型 ");
							meetConditionsBuff.append(PublicMethods.change(restMessageConsigneeType, String.valueOf(conditionModel.getFlowConditionValue())) + " " + conditionModel.getUnitName() + " ");
							break;
						case 4:
							// 订单类型
							meetConditionsBuff.append("订单类型 ");
							for (String condition : conditions) {
								meetConditionsBuff.append(PublicMethods.change(restMsgOrderType, condition) + " ");
							}
							break;
						case 5:
							// 订单业务类型
							meetConditionsBuff.append("订单业务类型 ");
							for (String condition : conditions) {
								meetConditionsBuff.append(PublicMethods.change(restMsgOrderBusinessType, condition) + " ");
							}
							break;
						case 6:
							// 运输模式
							meetConditionsBuff.append("运输模式 ");
							for (String condition : conditions) {
								meetConditionsBuff.append(PublicMethods.change(restMsgTransportType, condition) + " ");
							}
							break;
						case 7:
							// 温度要求
							meetConditionsBuff.append("温度要求 ");
							for (String condition : conditions) {
								meetConditionsBuff.append(PublicMethods.change(restMsgTemperature, condition) + " ");
							}
							break;
						case 8:
							// 货主
							meetConditionsBuff.append("货主 ");
							meetConditionsBuff.append(conditionModel.getUnitName() + " ");
							break;
					}
				} else {
					// 排除条件
					switch (conditionModel.getFlowConditionType().intValue()) {
						case 1:
							// 1配送方式
							excludedConditionsBuff.append("配送方式 ");
							excludedConditionsBuff.append(PublicMethods.change(restMessageDeliveryMethodType, String.valueOf(conditionModel.getFlowConditionValue())) + " ");
							break;
						case 2:
							// 2发货方类型
							excludedConditionsBuff.append("发货方类型 ");
							excludedConditionsBuff.append(PublicMethods.change(restMessageShipperType, String.valueOf(conditionModel.getFlowConditionValue())) + " " + conditionModel.getUnitName() + " ");
							break;
						case 3:
							// 3收货方类型
							excludedConditionsBuff.append("收货方类型 ");
							excludedConditionsBuff.append(PublicMethods.change(restMessageConsigneeType, String.valueOf(conditionModel.getFlowConditionValue())) + " " + conditionModel.getUnitName() + " ");
							break;
						case 4:
							// 订单类型
							excludedConditionsBuff.append("订单类型 ");
							for (String condition : conditions) {
								excludedConditionsBuff.append(PublicMethods.change(restMsgOrderType, condition) + " ");
							}
							break;
						case 5:
							// 订单业务类型
							excludedConditionsBuff.append("订单业务类型 ");
							for (String condition : conditions) {
								excludedConditionsBuff.append(PublicMethods.change(restMsgOrderBusinessType, condition) + " ");
							}
							break;
						case 6:
							// 运输模式
							excludedConditionsBuff.append("运输模式 ");
							for (String condition : conditions) {
								excludedConditionsBuff.append(PublicMethods.change(restMsgTransportType, condition) + " ");
							}
							break;
						case 7:
							// 温度要求
							excludedConditionsBuff.append("温度要求 ");
							for (String condition : conditions) {
								excludedConditionsBuff.append(PublicMethods.change(restMsgTemperature, condition) + " ");
							}
							break;
						case 8:
							// 货主
							excludedConditionsBuff.append("货主 ");
							excludedConditionsBuff.append(conditionModel.getUnitName().replaceAll(","," ") + " ");
							break;
					}
				}
				conditionIds.add(String.valueOf(conditionModel.getId()));
			}
			businessFlowQueryDTO.setMeetConditions("满足以下条件：" + meetConditionsBuff.toString());
			if (ToolKits.isNotEmpty(excludedConditionsBuff) && excludedConditionsBuff.toString().length() > 0) {
				businessFlowQueryDTO.setExcludedConditions("排除以下条件：" + excludedConditionsBuff.toString());
			} else {
				businessFlowQueryDTO.setExcludedConditions("-");
			}
			// 保存流程条件表的id
			businessFlowQueryDTO.setConditionIds(conditionIds.stream().collect(Collectors.joining(",")));

			businessFlowQueryDTOs.add(businessFlowQueryDTO);
		}

		Page<BusinessFlowQueryDTO> page = PageUtils.getPage(businessFlowQueryDTOs);
		if (tmsBusinessFlowModels instanceof com.github.pagehelper.Page) {
			com.github.pagehelper.Page<TmsBusinessFlowModel> p0 = (com.github.pagehelper.Page<TmsBusinessFlowModel>) tmsBusinessFlowModels;
			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 businessFlowAddVO
	 * @return
	 */
	@Transactional(rollbackFor = Exception.class)
	public void add(BusinessFlowAddVO businessFlowAddVO) {
		ToolKits.isParamNull(businessFlowAddVO, "业务流程新增请求不为空");
		ToolKits.isParamNull(businessFlowAddVO.getFlowName(), "业务流程名称不为空");
		ToolKits.isParamNull(businessFlowAddVO.getFlowConfig(), "业务流程配置不为空");
		ToolKits.isParamNull(businessFlowAddVO.getFlowConditions(), "业务流程配置条件不为空");
		ToolKits.isParamNull(businessFlowAddVO.getPriorityLevel(), "业务流程优先级不为空");

		UserEntity user = PlgFxUsrUtils.getUserEntity();
		ToolKits.isParamNull(user, "没有操作权限！");
		Date date = DateUtils.nowDate();

		// 判定是否有重复流程
		Criteria flowCriteria = Criteria.forClass(TmsBusinessFlowModel.class);
		Restriction r1 = Restrictions.eq(TmsBusinessFlowModel::getPriorityLevel, businessFlowAddVO.getPriorityLevel());
		Restriction r2 = Restrictions.eq(TmsBusinessFlowModel::getEnterpriseId, user.getEnterpriseId());
		Restriction r3 = Restrictions.eq(TmsBusinessFlowModel::getFlowType, businessFlowAddVO.getFlowType());
		flowCriteria.setRestriction(Restrictions.and(r1, r2, r3));
		List<TmsBusinessFlowModel> flowPriorityLevel = tmsBusinessFlowMapper.findByCriteria(flowCriteria);
		if (ToolKits.isNotEmpty(flowPriorityLevel)) {
			throw new RuntimeException("优先级为【"+businessFlowAddVO.getPriorityLevel()+ "】的流程已存在,请重新设定优先级");
		}
		r1 = Restrictions.eq(TmsBusinessFlowModel::getFlowName, businessFlowAddVO.getFlowName());
		r2 = Restrictions.eq(TmsBusinessFlowModel::getEnterpriseId, user.getEnterpriseId());
		flowCriteria.setRestriction(Restrictions.and(r1, r2));
		List<TmsBusinessFlowModel> flowNames = tmsBusinessFlowMapper.findByCriteria(flowCriteria);
		if (ToolKits.isNotEmpty(flowNames)) {
			throw new RuntimeException("流程名称【" + businessFlowAddVO.getFlowName() + "】已存在");
		}

		long cnt = businessFlowAddVO.getFlowConditions().stream().filter(flow->flow.getFlowConditionType().equals(DataDictionaryConstant.FLOW_CONDITION_TYPE_DELIVERY)).collect(Collectors.toList()).size();
		if (cnt == 0) {
			throw new PrologException("流程配置条件中必须有配送方式!");
		}
		// 保存业务流程表
		String id = sysCodeengineService.getCodeNumberByCode(SeriaNnumberConstant.TMS_BUSINESS_FLOW_ID, "L");
		ToolKits.isParamNull(id, "获取业务流程ID失败！");
		TmsBusinessFlowModel flowmodel = new TmsBusinessFlowModel();
		BeanUtils.copyProperties(businessFlowAddVO, flowmodel);
		// 设置ID
		flowmodel.setId(Long.valueOf(id));
		// 设置企业
		flowmodel.setEnterpriseId(user.getEnterpriseId());
		flowmodel.setEnterpriseName(user.getEnterpriseName());
		// 设置创建人
		flowmodel.setCreatetime(date);
		flowmodel.setCreateperson(user.getNickname());
		flowmodel.setUpdatetime(date);
		flowmodel.setUpdateperson(user.getNickname());
		tmsBusinessFlowMapper.save(flowmodel);

		// 满足条件保存业务流程条件表
		for (BusinessFlowConditionAddVO conditionVO : businessFlowAddVO.getFlowConditions()) {
			// 取id可以批量取
			String conditionId = sysCodeengineService.getCodeNumberByCode(SeriaNnumberConstant.TMS_BUSINESS_FLOW_CONDITION_ID, "L");
			ToolKits.isParamNull(conditionId, "获取业务流程条件ID失败！");

			TmsBusinFlowConditionModel flowConditionModel = new TmsBusinFlowConditionModel();
			BeanUtils.copyProperties(conditionVO, flowConditionModel);

			flowConditionModel.setId(Long.valueOf(conditionId));
			flowConditionModel.setBusinessFlowId(Long.valueOf(id));
			// 设置企业
			flowConditionModel.setEnterpriseId(user.getEnterpriseId());
			flowConditionModel.setEnterpriseName(user.getEnterpriseName());
			// 设置创建人
			flowConditionModel.setCreatetime(date);
			flowConditionModel.setCreateperson(user.getNickname());
			flowConditionModel.setUpdatetime(date);
			flowConditionModel.setUpdateperson(user.getNickname());
			flowConditionModel.setFlowConditionCategory(DataDictionaryConstant.FLOW_CONDITION_CATEGORY_MEET);
			tmsBusinessFlowConditionMapper.save(flowConditionModel);
		}

		// 排除条件保存业务流程条件表
		if (ToolKits.isNotEmpty(businessFlowAddVO.getExcludedFlowConditions())) {
			for (BusinessFlowConditionAddVO conditionVO : businessFlowAddVO.getExcludedFlowConditions()) {
				// 取id可以批量取
				String conditionId = sysCodeengineService.getCodeNumberByCode(SeriaNnumberConstant.TMS_BUSINESS_FLOW_CONDITION_ID, "L");
				ToolKits.isParamNull(conditionId, "获取业务流程条件ID失败！");

				TmsBusinFlowConditionModel flowConditionModel = new TmsBusinFlowConditionModel();
				BeanUtils.copyProperties(conditionVO, flowConditionModel);

				flowConditionModel.setId(Long.valueOf(conditionId));
				flowConditionModel.setBusinessFlowId(Long.valueOf(id));
				// 设置企业
				flowConditionModel.setEnterpriseId(user.getEnterpriseId());
				flowConditionModel.setEnterpriseName(user.getEnterpriseName());
				// 设置创建人
				flowConditionModel.setCreatetime(date);
				flowConditionModel.setCreateperson(user.getNickname());
				flowConditionModel.setUpdatetime(date);
				flowConditionModel.setUpdateperson(user.getNickname());
				flowConditionModel.setFlowConditionCategory(DataDictionaryConstant.FLOW_CONDITION_CATEGORY_EXCLUSION);
				tmsBusinessFlowConditionMapper.save(flowConditionModel);
			}
		}
	}

	/**
	 * 业务流程修改
	 *
	 * @param businessFlowUpdateVO
	 * @return
	 */
	@Transactional(rollbackFor = Exception.class)
	public void update(BusinessFlowUpdateVO businessFlowUpdateVO) {
		ToolKits.isParamNull(businessFlowUpdateVO, "业务流程修改请求不为空");
		ToolKits.isParamNull(businessFlowUpdateVO.getId(), "业务流程修改ID不为空");
		ToolKits.isParamNull(businessFlowUpdateVO.getFlowName(), "业务流程名称不为空");
		ToolKits.isParamNull(businessFlowUpdateVO.getFlowConfig(), "业务流程配置不为空");
		ToolKits.isParamNull(businessFlowUpdateVO.getFlowConditions(), "业务流程配置条件不为空");
		ToolKits.isParamNull(businessFlowUpdateVO.getPriorityLevel(), "业务流程优先级不为空");

		UserEntity user = PlgFxUsrUtils.getUserEntity();
		ToolKits.isParamNull(user, "没有操作权限！");
		Date date = DateUtils.nowDate();

		// 判定是否有重复条件流程
		Criteria flowCriteria = Criteria.forClass(TmsBusinessFlowModel.class);
		Restriction r1 = Restrictions.eq(TmsBusinessFlowModel::getPriorityLevel, businessFlowUpdateVO.getPriorityLevel());
		Restriction r2 = Restrictions.eq(TmsBusinessFlowModel::getEnterpriseId, user.getEnterpriseId());
		Restriction r3 = Restrictions.eq(TmsBusinessFlowModel::getFlowType, businessFlowUpdateVO.getFlowType());
		Restriction r4 = Restrictions.ne(TmsBusinessFlowModel::getId, businessFlowUpdateVO.getId());
		flowCriteria.setRestriction(Restrictions.and(r1, r2, r3, r4));
		List<TmsBusinessFlowModel> flowPriorityLevel = tmsBusinessFlowMapper.findByCriteria(flowCriteria);
		if (ToolKits.isNotEmpty(flowPriorityLevel)) {
			throw new RuntimeException("优先级为【"+businessFlowUpdateVO.getPriorityLevel()+ "】的流程已存在,请重新设定优先级");
		}
		long cnt = businessFlowUpdateVO.getFlowConditions().stream().filter(flow->flow.getFlowConditionType().equals(DataDictionaryConstant.FLOW_CONDITION_TYPE_DELIVERY)).collect(Collectors.toList()).size();
		if (cnt == 0) {
			throw new PrologException("流程配置条件中必须有配送方式!");
		}

		// 修改业务流程表
		Map<String, Object> mapFlowUpdate = Maps.newHashMap();
		mapFlowUpdate.put("flowConfig", businessFlowUpdateVO.getFlowConfig());
		mapFlowUpdate.put("updateperson", user.getNickname());
		mapFlowUpdate.put("updatetime", date);
		mapFlowUpdate.put("priorityLevel", businessFlowUpdateVO.getPriorityLevel());
		tmsBusinessFlowMapper.updateMapById(businessFlowUpdateVO.getId(), mapFlowUpdate, TmsBusinessFlowModel.class);

		// 修改业务流程条件表
		Criteria flowConditionCriteria = Criteria.forClass(TmsBusinFlowConditionModel.class);
		Restriction r7 = Restrictions.eq(TmsBusinFlowConditionModel::getBusinessFlowId, businessFlowUpdateVO.getId());
		flowConditionCriteria.setRestriction(Restrictions.and(r7));
		tmsBusinessFlowConditionMapper.deleteByCriteria(flowConditionCriteria);

		for (BusinessFlowConditionUpdateVO conditionUpdateVO : businessFlowUpdateVO.getFlowConditions()) {
			// 取id可以批量取
			String conditionId = sysCodeengineService.getCodeNumberByCode(SeriaNnumberConstant.TMS_BUSINESS_FLOW_CONDITION_ID, "L");
			ToolKits.isParamNull(conditionId, "获取业务流程条件ID失败！");

			TmsBusinFlowConditionModel flowConditionModel = new TmsBusinFlowConditionModel();
			BeanUtils.copyProperties(conditionUpdateVO, flowConditionModel);

			flowConditionModel.setId(Long.valueOf(conditionId));
			flowConditionModel.setBusinessFlowId(Long.valueOf(businessFlowUpdateVO.getId()));
			// 设置企业
			flowConditionModel.setEnterpriseId(user.getEnterpriseId());
			flowConditionModel.setEnterpriseName(user.getEnterpriseName());
			// 设置创建人
			flowConditionModel.setCreatetime(date);
			flowConditionModel.setCreateperson(user.getNickname());
			flowConditionModel.setUpdatetime(date);
			flowConditionModel.setUpdateperson(user.getNickname());
			flowConditionModel.setFlowConditionCategory(DataDictionaryConstant.FLOW_CONDITION_CATEGORY_MEET);
			tmsBusinessFlowConditionMapper.save(flowConditionModel);
		}
		// 排除条件
		if (ToolKits.isNotEmpty(businessFlowUpdateVO.getExcludedFlowConditions())) {
			for (BusinessFlowConditionUpdateVO conditionUpdateVO : businessFlowUpdateVO.getExcludedFlowConditions()) {
				// 取id可以批量取
				String conditionId = sysCodeengineService.getCodeNumberByCode(SeriaNnumberConstant.TMS_BUSINESS_FLOW_CONDITION_ID, "L");
				ToolKits.isParamNull(conditionId, "获取业务流程条件ID失败！");

				TmsBusinFlowConditionModel flowConditionModel = new TmsBusinFlowConditionModel();
				BeanUtils.copyProperties(conditionUpdateVO, flowConditionModel);

				flowConditionModel.setId(Long.valueOf(conditionId));
				flowConditionModel.setBusinessFlowId(Long.valueOf(businessFlowUpdateVO.getId()));
				// 设置企业
				flowConditionModel.setEnterpriseId(user.getEnterpriseId());
				flowConditionModel.setEnterpriseName(user.getEnterpriseName());
				// 设置创建人
				flowConditionModel.setCreatetime(date);
				flowConditionModel.setCreateperson(user.getNickname());
				flowConditionModel.setUpdatetime(date);
				flowConditionModel.setUpdateperson(user.getNickname());
				flowConditionModel.setFlowConditionCategory(DataDictionaryConstant.FLOW_CONDITION_CATEGORY_EXCLUSION);
				tmsBusinessFlowConditionMapper.save(flowConditionModel);
			}
		}
	}

	/**
	 * 业务流程删除
	 *
	 * @param ids
	 * @return
	 */
	@Transactional(rollbackFor = Exception.class)
	public void delete(List<Long> ids) {
		ToolKits.isParamNull(ids, "业务流程删除请求不为空");
		UserEntity user = PlgFxUsrUtils.getUserEntity();
		ToolKits.isParamNull(user, "没有操作权限！");

		// 删除业务流程表
		Criteria flowCriteria = Criteria.forClass(TmsBusinessFlowModel.class);
		Restriction r1 = Restrictions.in("id", ids.stream().toArray());
		Restriction r2 = Restrictions.eq("enterpriseId", user.getEnterpriseId());
		flowCriteria.setRestriction(Restrictions.and(r1, r2));
		tmsBusinessFlowMapper.deleteByCriteria(flowCriteria);

		// 删除业务流程条件表
		Criteria flowConditionCriteria = Criteria.forClass(TmsBusinFlowConditionModel.class);
		r1 = Restrictions.in("businessFlowId", ids.stream().toArray());
		r2 = Restrictions.eq("enterpriseId", user.getEnterpriseId());
		flowConditionCriteria.setRestriction(Restrictions.and(r1, r2));
		tmsBusinessFlowConditionMapper.deleteByCriteria(flowConditionCriteria);
	}

	/**
	 * 业务流程查看
	 *
	 * @param id
	 * @return
	 */
	public BusinessFlowViewDTO view(Long id) {
		ToolKits.isParamNull(id, "业务流程查看请求不为空");
		UserEntity user = PlgFxUsrUtils.getUserEntity();
		ToolKits.isParamNull(user, "没有操作权限！");

		// 流程条件类型
		List<Map<String, Object>> restMsgFlowConditionType = sysRefdatadService.getDropDownById(DataDictionaryConstant.FLOW_CONDITION_TYPE, null, null, null);
		// 配送方式
		List<Map<String, Object>> restMsgDeliveryMethodType = sysRefdatadService.getDropDownById(DataDictionaryConstant.DELIVERY_METHOD_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>> 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>> restMsgTemperature = sysRefdatadService.getDropDownById(DataDictionaryConstant.TEMPERATURE_REQUIREMENT, null, null, null);

		TmsBusinessFlowModel tmsBusinessFlowModel = tmsBusinessFlowMapper.findById(id, TmsBusinessFlowModel.class);

		BusinessFlowViewDTO businessFlowViewDTO = new BusinessFlowViewDTO();

		if (ToolKits.isNotEmpty(tmsBusinessFlowModel)) {
			BeanUtils.copyProperties(tmsBusinessFlowModel, businessFlowViewDTO);

			Criteria flowConditionCriteria = Criteria.forClass(TmsBusinFlowConditionModel.class);
			Restriction r1 = Restrictions.eq("businessFlowId", tmsBusinessFlowModel.getId());
			Restriction r2 = Restrictions.eq("enterpriseId", user.getEnterpriseId());
			flowConditionCriteria.setRestriction(Restrictions.and(r1, r2));
			flowConditionCriteria.setOrder(Order.newInstance().asc(new String[] { "flowConditionCategory" }));
			List<TmsBusinFlowConditionModel> tmsBusinFlowConditionModels = tmsBusinessFlowConditionMapper.findByCriteria(flowConditionCriteria);

			List<BusinessFlowConditionViewDTO> businessFlowConditionViewDTOs = Lists.newArrayList();
			List<BusinessFlowConditionViewDTO> excludedBusinessFlowConditionViewDTOs = Lists.newArrayList();
			for (TmsBusinFlowConditionModel conditionModel : tmsBusinFlowConditionModels) {
				BusinessFlowConditionViewDTO conditionViewDTO = new BusinessFlowConditionViewDTO();
				BeanUtils.copyProperties(conditionModel, conditionViewDTO);
				List<String> conditions = Lists.newArrayList();
				List<String> conditionNames = Lists.newArrayList();
				if (ToolKits.isNotEmpty(conditionModel.getFlowConditionValue())) {
					conditions = Arrays.stream(conditionModel.getFlowConditionValue().split(",")).collect(Collectors.toList());
				}
				// 流程类型名称
				conditionViewDTO.setFlowConditionTypeName(PublicMethods.change(restMsgFlowConditionType, String.valueOf(conditionModel.getFlowConditionType())));
					// 满足条件
					switch (conditionModel.getFlowConditionType().intValue()) {
						case 1:
							// 1配送方式
							conditionViewDTO.setFlowConditionValueName(PublicMethods.change(restMsgDeliveryMethodType, String.valueOf(conditionModel.getFlowConditionValue())));
							break;
						case 2:
							// 2发货方类型
							conditionViewDTO.setFlowConditionValueName(PublicMethods.change(restMsgShipperType, String.valueOf(conditionModel.getFlowConditionValue())));
							break;
						case 3:
							// 3收货方类型
							conditionViewDTO.setFlowConditionValueName(PublicMethods.change(restMsgConsigneeType, String.valueOf(conditionModel.getFlowConditionValue())));
							break;
						case 4:
							// 4订单类型
							for (String condition : conditions) {
								conditionNames.add(PublicMethods.change(restMsgOrderType, condition));
							}
							conditionViewDTO.setFlowConditionValueName(conditionNames.stream().collect(Collectors.joining(",")));
							break;
						case 5:
							// 5订单业务类型
							for (String condition : conditions) {
								conditionNames.add(PublicMethods.change(restMsgOrderBusinessType, condition));
							}
							conditionViewDTO.setFlowConditionValueName(conditionNames.stream().collect(Collectors.joining(",")));
							break;
						case 6:
							// 6运输模式
							for (String condition : conditions) {
								conditionNames.add(PublicMethods.change(restMsgTransportType, condition));
							}
							conditionViewDTO.setFlowConditionValueName(conditionNames.stream().collect(Collectors.joining(",")));
							break;
						case 7:
							// 7温度要求
							for (String condition : conditions) {
								conditionNames.add(PublicMethods.change(restMsgTemperature, condition));
							}
							conditionViewDTO.setFlowConditionValueName(conditionNames.stream().collect(Collectors.joining(",")));
							break;
					}
					if (conditionModel.getFlowConditionCategory().equals(DataDictionaryConstant.FLOW_CONDITION_CATEGORY_MEET)) {
						businessFlowConditionViewDTOs.add(conditionViewDTO);
					} else {
						excludedBusinessFlowConditionViewDTOs.add(conditionViewDTO);
					}
			}
			businessFlowViewDTO.setBusinessFlowConditionViewDTOs(businessFlowConditionViewDTOs);
			businessFlowViewDTO.setExcludedBusinessFlowConditionViewDTOs(excludedBusinessFlowConditionViewDTOs);
		}
		return businessFlowViewDTO;
	}

	/**
	 * 运单适用业务流程查询
	 *
	 * @param businessFlowShipbillVO
	 * @return
	 */
	@Override
	public ShipbillFitBusinessFlowDTO shipbillMatchQuery(BusinessFlowShipbillVO businessFlowShipbillVO) {
		log.info("运单适用业务流程处理开始:" + JSON.toJSONString(businessFlowShipbillVO));
		ToolKits.isParamNull(businessFlowShipbillVO, "业务流程查看请求不为空");
		ToolKits.isParamNull(businessFlowShipbillVO.getFlowType(), "业务流程类型请求不为空");
		UserEntity user;
		if (ObjectUtil.isNotNull(businessFlowShipbillVO.getUser())) {
			user = businessFlowShipbillVO.getUser();
		} else {
			user = PlgFxUsrUtils.getUserEntity();
		}
		ToolKits.isParamNull(user, "没有操作权限！");
		ShipbillFitBusinessFlowDTO shipbillFitBusinessFlowDTO = new ShipbillFitBusinessFlowDTO();

		Criteria flowCriteria = Criteria.forClass(TmsBusinessFlowModel.class);
		// 流程类型
		Restriction r1 = Restrictions.eq(TmsBusinessFlowModel::getFlowType, businessFlowShipbillVO.getFlowType());
		Restriction r2 = Restrictions.eq(TmsBusinessFlowModel::getEnterpriseId, user.getEnterpriseId());
		flowCriteria.setRestriction(Restrictions.and(r1, r2));
		flowCriteria.setOrder(Order.newInstance().asc(new String[] { "priorityLevel" }));
		List<TmsBusinessFlowModel> tmsBusinessFlowModels = tmsBusinessFlowMapper.findByCriteria(flowCriteria);

		if (ToolKits.isEmpty(tmsBusinessFlowModels)) {
			return shipbillFitBusinessFlowDTO;
		}
		Criteria flowConditionCriteria = Criteria.forClass(TmsBusinFlowConditionModel.class);
		// 运单匹配条件集合
		Map<Integer, String> conditionMap = Maps.newHashMap();
		// 配送方式
		if (ToolKits.isNotEmpty(businessFlowShipbillVO.getDeliveryMethodType())) {
			conditionMap.put(DataDictionaryConstant.FLOW_CONDITION_TYPE_DELIVERY, DataDictionaryConstant.FLOW_CONDITION_TYPE_DELIVERY+"_" +String.valueOf(businessFlowShipbillVO.getDeliveryMethodType()));
		}
		// 订单类型
		if (ToolKits.isNotEmpty(businessFlowShipbillVO.getOrderType())) {
			conditionMap.put(DataDictionaryConstant.FLOW_CONDITION_TYPE_ORDER, DataDictionaryConstant.FLOW_CONDITION_TYPE_ORDER+"_" +String.valueOf(businessFlowShipbillVO.getOrderType()));
		}
		// 订单业务类型
		if (ToolKits.isNotEmpty(businessFlowShipbillVO.getOrderBusinessType())) {
			conditionMap.put(DataDictionaryConstant.FLOW_CONDITION_TYPE_ORDER_BUSINESS, DataDictionaryConstant.FLOW_CONDITION_TYPE_ORDER_BUSINESS+"_" +String.valueOf(businessFlowShipbillVO.getOrderBusinessType()));
		}
		// 运输模式
		if (ToolKits.isNotEmpty(businessFlowShipbillVO.getTransportType())) {
			conditionMap.put(DataDictionaryConstant.FLOW_CONDITION_TYPE_TRANSPORT, DataDictionaryConstant.FLOW_CONDITION_TYPE_TRANSPORT+"_" +String.valueOf(businessFlowShipbillVO.getTransportType()));
		}
		// 温度要求
		if (ToolKits.isNotEmpty(businessFlowShipbillVO.getTemperatureRequirement())) {
			conditionMap.put(DataDictionaryConstant.FLOW_CONDITION_TYPE_TEMPERATURE, DataDictionaryConstant.FLOW_CONDITION_TYPE_TEMPERATURE+"_" +String.valueOf(businessFlowShipbillVO.getTemperatureRequirement()));
		}
		// 货主ID
		if (ToolKits.isNotEmpty(businessFlowShipbillVO.getCargoOwnerId())) {
			conditionMap.put(DataDictionaryConstant.FLOW_CONDITION_TYPE_CARGO_OWNER, String.valueOf(businessFlowShipbillVO.getCargoOwnerId()));
		}
		// 发货方类型
		if (ToolKits.isNotEmpty(businessFlowShipbillVO.getShipperType())) {
			conditionMap.put(DataDictionaryConstant.FLOW_CONDITION_TYPE_SHIPPER, String.valueOf(businessFlowShipbillVO.getShipperType()) + "," + String.valueOf(businessFlowShipbillVO.getShipperUnitId()));
		}
		// 收货方类型
		if (ToolKits.isNotEmpty(businessFlowShipbillVO.getConsigneeType())) {
			conditionMap.put(DataDictionaryConstant.FLOW_CONDITION_TYPE_CONSIGNEE, String.valueOf(businessFlowShipbillVO.getConsigneeType()) + "," + String.valueOf(businessFlowShipbillVO.getConsigneeUnitId()));
		}

		// 承运商类型
		if (ToolKits.isNotEmpty(businessFlowShipbillVO.getCarriersType())) {
			conditionMap.put(DataDictionaryConstant.FLOW_CONDITION_TYPE_CARRIERS_TYPE, DataDictionaryConstant.FLOW_CONDITION_TYPE_CARRIERS_TYPE+"_" +String.valueOf(businessFlowShipbillVO.getCarriersType()));
		}

		for (TmsBusinessFlowModel flowModel : tmsBusinessFlowModels) {
            // 排除条件
            r1 = Restrictions.eq(TmsBusinFlowConditionModel::getBusinessFlowId, flowModel.getId());
            Restriction r3 = Restrictions.eq(TmsBusinFlowConditionModel::getFlowConditionCategory, DataDictionaryConstant.FLOW_CONDITION_CATEGORY_EXCLUSION);
            flowConditionCriteria.setRestriction(Restrictions.and(r1, r2, r3));
            List<TmsBusinFlowConditionModel> excludedBusinFlowConditionModels = tmsBusinessFlowConditionMapper.findByCriteria(flowConditionCriteria);
            if (ToolKits.isNotEmpty(excludedBusinFlowConditionModels)) {
                log.info("排除条件: " + JSON.toJSONString(excludedBusinFlowConditionModels));
                int excludedCnt = 0;
                for (TmsBusinFlowConditionModel flowConditionModel : excludedBusinFlowConditionModels) {
                    switch (flowConditionModel.getFlowConditionType().intValue()) {
                        case 1:
                            if (flowConditionModel.getFlowConditionValue().equals(String.valueOf(businessFlowShipbillVO.getDeliveryMethodType()))) {
                                excludedCnt++;
                            }
                            break;
                        case 2:
                        case 3:
                            String[] cmpStr1 = conditionMap.get(flowConditionModel.getFlowConditionType()).split(",");
                            if (cmpStr1[0].equals(String.valueOf(flowConditionModel.getFlowConditionValue())) && flowConditionModel.getUnitId().contains(cmpStr1[1])) {
                                excludedCnt++;
                            }
                            break;
                        case 8:
                            if (flowConditionModel.getUnitId().contains(conditionMap.get(flowConditionModel.getFlowConditionType()))) {
                                excludedCnt++;
                            }
                            break;
						case 9:
							if (flowConditionModel.getFlowConditionValue().equals(String.valueOf(businessFlowShipbillVO.getCarriersType()))) {
								excludedCnt++;
							}
							break;
                        default:
                            // 4订单类型 5订单业务类型 6运输模式 7温度要求 支持多选
                            if (ToolKits.isNotEmpty(flowConditionModel.getFlowConditionValue())) {
                                List<String> conditionValues = Arrays.stream(flowConditionModel.getFlowConditionValue().split(",")).collect(Collectors.toList());
                                for (String val:conditionValues) {
                                    if (conditionMap.containsValue(flowConditionModel.getFlowConditionType() + "_" + val)) {
                                        excludedCnt++;
                                        break;
                                    }
                                }
                            }
                            break;
                    }
                    if (excludedCnt > 0) {
                        break;
                    }
                }
                if (excludedCnt > 0) {
                    // 排除条件匹配到了，当前流程不适用
                    continue;
                }
            }
			// 满足条件
			r1 = Restrictions.eq(TmsBusinFlowConditionModel::getBusinessFlowId, flowModel.getId());
            r3 = Restrictions.eq(TmsBusinFlowConditionModel::getFlowConditionCategory, DataDictionaryConstant.FLOW_CONDITION_CATEGORY_MEET);
			flowConditionCriteria.setRestriction(Restrictions.and(r1, r2, r3));
			List<TmsBusinFlowConditionModel> meetBusinFlowConditionModels = tmsBusinessFlowConditionMapper.findByCriteria(flowConditionCriteria);
			if (ToolKits.isEmpty(meetBusinFlowConditionModels)) {
				continue;
			}
			// 首先匹配配送方式
			List<TmsBusinFlowConditionModel> matchDeliverys = meetBusinFlowConditionModels.stream().filter(o -> o.getFlowConditionType().equals(DataDictionaryConstant.FLOW_CONDITION_TYPE_DELIVERY) && o.getFlowConditionValue().equals(String.valueOf(businessFlowShipbillVO.getDeliveryMethodType()))).collect(Collectors.toList());
			if (ToolKits.isEmpty(matchDeliverys)) {
				continue;
			}
			// 判定满足条件
			int fitCnt = 0;
			for (TmsBusinFlowConditionModel flowConditionModel : meetBusinFlowConditionModels) {
				switch (flowConditionModel.getFlowConditionType().intValue()) {
				case 2:
				case 3:
					String[] cmpStr1 = conditionMap.get(flowConditionModel.getFlowConditionType()).split(",");
					if (cmpStr1[0].equals(String.valueOf(flowConditionModel.getFlowConditionValue())) && flowConditionModel.getUnitId().contains(cmpStr1[1])) {
						fitCnt++;
					}
					break;
				case 8:
					if (flowConditionModel.getUnitId().contains(conditionMap.get(flowConditionModel.getFlowConditionType()))) {
						fitCnt++;
					}
					break;
				default:
                    // 4订单类型 5订单业务类型 6运输模式 7温度要求 支持多选
                    if (ToolKits.isNotEmpty(flowConditionModel.getFlowConditionValue())) {
                        List<String> conditionValues = Arrays.stream(flowConditionModel.getFlowConditionValue().split(",")).collect(Collectors.toList());
                        for (String val:conditionValues) {
                            if (conditionMap.containsValue(flowConditionModel.getFlowConditionType() + "_" + val)) {
                                fitCnt++;
                                break;
                            }
                        }
                    }
					break;
				}
			}
			// 匹配到了业务流程
			if (fitCnt > 0 && fitCnt == meetBusinFlowConditionModels.size()) {
				log.info("运单适用业务流程名称:" + JSON.toJSONString(flowModel.getFlowName()));
				shipbillFitBusinessFlowDTO.setFlowConfig(flowModel.getFlowConfig());
				shipbillFitBusinessFlowDTO.setFlowName(flowModel.getFlowName());
				break;
			}
		}
		log.info("运单适用业务流程处理结束:" + JSON.toJSONString(shipbillFitBusinessFlowDTO));
		return shipbillFitBusinessFlowDTO;
	}
}
