package org.springblade.flow.engine.service.impl;

import static org.springblade.flow.base.util.BpmnModelUtils.getAttributeValueByTaskDefinitionKey;
import static org.springblade.flow.base.util.BpmnModelUtils.getBpmnModelMainProcess;
import static org.springblade.flow.base.util.BpmnModelUtils.getFirstNode;
import static org.springblade.flow.base.util.BpmnModelUtils.getFlowElementsWithOutSequenceFlow;
import static org.springblade.flow.engine.custom.constants.GlobalProcessVariableConstants.APPLY_USER_ID;
import static org.springblade.flow.engine.custom.constants.GlobalProcessVariableConstants.APPLY_USER_NAME;
import static org.springblade.flow.engine.custom.constants.GlobalProcessVariableConstants.BILL_CODE;
import static org.springblade.flow.engine.custom.constants.GlobalProcessVariableConstants.BUSINESS_KEY;
import static org.springblade.flow.engine.custom.constants.GlobalProcessVariableConstants.BUSINESS_TITLE;
import static org.springblade.flow.engine.custom.constants.GlobalProcessVariableConstants.FLOW_ENGINE_ID;
import static org.springblade.flow.engine.custom.constants.GlobalProcessVariableConstants.FLOW_URGENT;
import static org.springblade.flow.engine.custom.constants.GlobalProcessVariableConstants.FORM_INFO_JSON;
import static org.springblade.flow.engine.custom.constants.GlobalProcessVariableConstants.PROCESS_CATEGORY;
import static org.springblade.flow.engine.custom.constants.GlobalProcessVariableConstants.PROCESS_STATUS;
import static org.springblade.flow.engine.custom.constants.TaskVariableConstants.REJECT_NODE;
import static org.springblade.flow.engine.custom.constants.TaskVariableConstants.TASK_STATE;
import static org.springblade.flow.engine.custom.constants.TaskVariableConstants.TASK_STATE_AUDIT;
import static org.springblade.flow.engine.custom.constants.TaskVariableConstants.TASK_STATE_REJECT;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.bpmn.model.FlowElement;
import org.flowable.bpmn.model.FlowNode;
import org.flowable.bpmn.model.Process;
import org.flowable.bpmn.model.UserTask;
import org.flowable.common.engine.impl.identity.Authentication;
import org.flowable.engine.HistoryService;
import org.flowable.engine.ManagementService;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.history.HistoricActivityInstance;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.impl.bpmn.behavior.MultiInstanceActivityBehavior;
import org.flowable.engine.impl.bpmn.behavior.NoneEndEventActivityBehavior;
import org.flowable.engine.impl.bpmn.behavior.ReceiveTaskActivityBehavior;
import org.flowable.engine.impl.bpmn.behavior.UserTaskActivityBehavior;
import org.flowable.engine.impl.persistence.entity.ExecutionEntity;
import org.flowable.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.engine.runtime.ProcessInstanceBuilder;
import org.flowable.task.api.Task;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.flowable.task.service.impl.persistence.entity.TaskEntity;
import org.springblade.flow.base.UserInfo;
import org.springblade.flow.base.service.BillRuleService;
import org.springblade.flow.base.util.ActivitiDataBaseUtils;
import org.springblade.flow.base.util.ActivitiUtils;
import org.springblade.flow.base.util.BpmnModelUtils;
import org.springblade.flow.base.util.FlowDataUtil;
import org.springblade.flow.base.util.FlowJsonUtil;
import org.springblade.flow.base.util.FlowNature;
import org.springblade.flow.base.util.FormCloumnUtil;
import org.springblade.flow.database.model.DbLinkEntity;
import org.springblade.flow.engine.assembly.CallActivityExPropertyDTO;
import org.springblade.flow.engine.assembly.GlobalExPropertyDTO;
import org.springblade.flow.engine.assembly.ManualTaskExPropertyDTO;
import org.springblade.flow.engine.assembly.UserTaskExPropertyDTO;
import org.springblade.flow.engine.assembly.prop.UserTaskAdvancedSettingDTO;
import org.springblade.flow.engine.assembly.prop.UserTaskBasicPropDTO;
import org.springblade.flow.engine.custom.behavior.impl.CustomCallActivityActivityBehavior;
import org.springblade.flow.engine.custom.behavior.impl.CustomManualTaskActivityBehavior;
import org.springblade.flow.engine.custom.cmd.execution.GetRootExecutionEntityCmd;
import org.springblade.flow.engine.custom.constants.BasicActivitiConstants;
import org.springblade.flow.engine.custom.constants.GlobalProcessVariableConstants;
import org.springblade.flow.engine.custom.helper.UserTaskNodeHelper;
import org.springblade.flow.engine.custom.variables.entity.FormDataInfo;
import org.springblade.flow.engine.entity.FlowEngineEntity;
import org.springblade.flow.engine.entity.FlowTaskCirculateEntity;
import org.springblade.flow.engine.entity.FlowTaskEntity;
import org.springblade.flow.engine.entity.FlowTaskNodeEntity;
import org.springblade.flow.engine.entity.FlowTaskOperatorEntity;
import org.springblade.flow.engine.entity.FlowTaskOperatorRecordEntity;
import org.springblade.flow.engine.enums.FlowMessageEnum;
import org.springblade.flow.engine.enums.FlowNodeEnum;
import org.springblade.flow.engine.enums.FlowNodeTypeEnum;
import org.springblade.flow.engine.enums.FlowRecordEnum;
import org.springblade.flow.engine.enums.FlowStatusEnum;
import org.springblade.flow.engine.enums.FlowTaskOperatorEnum;
import org.springblade.flow.engine.enums.FlowTaskStatusEnum;
import org.springblade.flow.engine.model.FlowHandleModel;
import org.springblade.flow.engine.model.flowbefore.FlowBeforeInfoVO;
import org.springblade.flow.engine.model.flowbefore.FlowTaskModel;
import org.springblade.flow.engine.model.flowbefore.FlowTaskNodeModel;
import org.springblade.flow.engine.model.flowbefore.FlowTaskOperatorModel;
import org.springblade.flow.engine.model.flowbefore.FlowTaskOperatorRecordModel;
import org.springblade.flow.engine.model.flowengine.FlowModel;
import org.springblade.flow.engine.model.flowengine.FlowMsgModel;
import org.springblade.flow.engine.model.flowengine.FlowOperatordModel;
import org.springblade.flow.engine.model.flowengine.shuntjson.childnode.FlowAssignModel;
import org.springblade.flow.engine.model.flowengine.shuntjson.childnode.FormOperates;
import org.springblade.flow.engine.model.flowengine.shuntjson.childnode.Properties;
import org.springblade.flow.engine.model.flowengine.shuntjson.childnode.TimeOutConfig;
import org.springblade.flow.engine.model.flowengine.shuntjson.nodejson.ChildNodeList;
import org.springblade.flow.engine.model.flowengine.shuntjson.nodejson.ConditionList;
import org.springblade.flow.engine.model.flowengine.shuntjson.nodejson.Custom;
import org.springblade.flow.engine.model.flowengine.shuntjson.nodejson.DateProperties;
import org.springblade.flow.engine.model.flowtask.FlowTableModel;
import org.springblade.flow.engine.service.FlowDelegateService;
import org.springblade.flow.engine.service.FlowEngineService;
import org.springblade.flow.engine.service.FlowTaskCirculateService;
import org.springblade.flow.engine.service.FlowTaskNewService;
import org.springblade.flow.engine.service.FlowTaskNodeService;
import org.springblade.flow.engine.service.FlowTaskOperatorRecordService;
import org.springblade.flow.engine.service.FlowTaskOperatorService;
import org.springblade.flow.engine.service.FlowTaskService;
import org.springblade.flow.exception.WorkFlowException;
import org.springblade.flow.message.enums.MessageTypeEnum;
import org.springblade.flow.message.model.message.SentMessageForm;
import org.springblade.flow.message.util.SentMessageUtil;
import org.springblade.flow.model.FormAllModel;
import org.springblade.flow.model.FormEnum;
import org.springblade.flow.model.visiual.FormDataModel;
import org.springblade.flow.model.visiual.JnpfKeyConsts;
import org.springblade.flow.model.visiual.fields.FieldsModel;
import org.springblade.flow.permission.entity.OrganizeEntity;
import org.springblade.flow.permission.entity.UserEntity;
import org.springblade.flow.permission.entity.UserRelationEntity;
import org.springblade.flow.permission.model.user.UserAllModel;
import org.springblade.flow.permission.service.OrganizeService;
import org.springblade.flow.permission.service.User4FlowService;
import org.springblade.flow.permission.service.UserRelationService;
import org.springblade.flow.util.DateUtil;
import org.springblade.flow.util.JsonUtil;
import org.springblade.flow.util.JsonUtilEx;
import org.springblade.flow.util.RandomUtil;
import org.springblade.flow.util.ReflectionUtil;
import org.springblade.flow.util.StringUtil;
import org.springblade.flow.util.UserProvider;
import org.springblade.flow.util.context.SpringContext;
import org.springblade.flow.util.wxutil.HttpUtil;
import org.springblade.flow.visual.onlinedev.common.dynamic.DataSourceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.map.MapUtil;

/**
 * 流程引擎
 *
 * @author JNPF开发平台组
 * @version V3.2.0
 * @copyright 引迈信息技术有限公司
 * @date 2021年4月27日 上午9:18
 */
@SuppressWarnings("all")
@Service
public class FlowTaskNewServiceImpl implements FlowTaskNewService {

	@Autowired
	private UserProvider userProvider;
	@Autowired
	private User4FlowService userService;
	@Autowired
	private OrganizeService organizeService;
	@Autowired
	private UserRelationService userRelationService;
	@Autowired
	private FlowDelegateService flowDelegateService;
	@Autowired
	private FlowTaskNodeService flowTaskNodeService;
	@Autowired
	private FlowTaskOperatorService flowTaskOperatorService;
	@Autowired
	private FlowTaskOperatorRecordService flowTaskOperatorRecordService;
	@Autowired
	private FlowTaskCirculateService flowTaskCirculateService;
	@Autowired
	private FlowEngineService flowEngineService;
	@Autowired
	private FlowTaskService flowTaskService;
	@Autowired
	private FlowDataUtil flowDataUtil;
	@Autowired
	private SentMessageUtil sentMessageUtil;
	@Autowired
	private DataSourceService dblinkService;
	@Autowired
	private BillRuleService billRuleService;
	@Resource
	private RuntimeService runtimeService;
	@Resource
	private ActivitiUtils activitiUtils;
	@Resource
	private ActivitiDataBaseUtils activitiDataBaseUtils;
	@Resource
	private UserTaskNodeHelper userTaskNodeHelper;
	@Resource
	private RepositoryService repositoryService;
	@Resource
	private TaskService taskService;
	@Resource
	private ManagementService managementService;
	@Resource
	private HistoryService historyService;

	/**
	 * 节点id
	 **/
	private String taskNodeId = "taskNodeId";
	/**
	 * 状态
	 **/
	private String handleStatus = "handleStatus";
	/**
	 * 任务id
	 **/
	private String taskId = "taskId";
	/**
	 * 空节点默认审批人
	 **/
	private String user = "admin";

	@Override
	public ProcessInstance saveIsAdmin(FlowModel flowModel) throws WorkFlowException {
		return this.save(flowModel);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public ProcessInstance save(FlowModel flowModel) throws WorkFlowException {
		String flowId = flowModel.getFlowId();
		UserInfo userInfo = userProvider.get();
		flowModel.setStatus(StringUtil.isNotEmpty(flowModel.getStatus()) ? flowModel.getStatus()
				: FlowStatusEnum.save.getMessage());
		String userId = StringUtil.isNotEmpty(flowModel.getUserId()) ? flowModel.getUserId() : userInfo.getUserId();
		// 流程引擎
		FlowEngineEntity engine = flowEngineService.getInfo(flowId);
		String enCode = engine.getEnCode();
		String processDefinitionKey = BasicActivitiConstants.activitiPrefix + enCode;
		Map<String, Object> variablesMap = new HashMap<>();
		boolean flag = flowModel.getId() == null;
		// 第一次保存草稿 或者第一次提交审核
		if (flag) {
			variablesMap.put(BILL_CODE, flowModel.getBillNo());// 单据控件的编码
			variablesMap.put(FLOW_URGENT, flowModel.getFlowUrgent());// 流程实例紧急程度
			variablesMap.put(FLOW_ENGINE_ID, engine.getId());// 流程引擎表id
			//
			if (FlowStatusEnum.save.getMessage().equals(flowModel.getStatus())) {
				variablesMap.put(PROCESS_STATUS, FlowTaskStatusEnum.Draft.getCode());// 流程状态
			} else {
				variablesMap.put(PROCESS_STATUS, FlowTaskStatusEnum.Handle.getCode());// 流程状态
			}

			variablesMap.put(PROCESS_CATEGORY, engine.getCategory());// 流程分类
			variablesMap.put(BUSINESS_TITLE, flowModel.getFlowTitle());// 流程标题
			variablesMap.put(BUSINESS_KEY, flowModel.getProcessId());// 业务表的主键
			if (flowModel.getFormData() != null && !flowModel.getFormData().isEmpty()) {
				FormDataInfo formDataInfo = new FormDataInfo();
				// 表单内容也需要将 字段为空的值给放进去 否则破坏了表单的数据了
				formDataInfo.setFormDataJson(JsonUtilEx.getObjectToString(flowModel.getFormData()));
				variablesMap.put(FORM_INFO_JSON, formDataInfo);
				ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
						.processDefinitionKey(processDefinitionKey).latestVersion().singleResult();
				if (processDefinition.isSuspended()) {
					throw new WorkFlowException("流程已经禁用,无法启动流程,请开启流程之后再试!");
				}
				Process process = getBpmnModelMainProcess(processDefinition.getId());
				String property = getAttributeValueByTaskDefinitionKey(process, "", "global");
				GlobalExPropertyDTO activityExPropertyDTO = JSONObject.parseObject(property,
						new TypeReference<GlobalExPropertyDTO>() {
						});
				Set<String> fieldSet = activityExPropertyDTO.getFieldSet();
				// 先把这些元素都放到流程变量中 防止下面都没有,到时候报错
				for (String field : fieldSet) {
					variablesMap.put(field, null);
				}

				HashMap<String, Object> businessMap = JSONObject.parseObject(
						JSONObject.toJSONString(flowModel.getFormData()), new TypeReference<HashMap<String, Object>>() {
						});
				HashMap<String, Object> sequenceFlowConditionMap = new HashMap<>();
				if (fieldSet != null && !fieldSet.isEmpty()) {
					Set<String> set = businessMap.keySet();
					Collection<String> intersection = CollectionUtil.intersection(set, fieldSet);
					for (String s : set) {
						if (CollectionUtil.contains(intersection, s)) {
							sequenceFlowConditionMap.put(s, businessMap.get(s));
						}
					}
					// 需要进行条件判断的字段放入流程变量
					variablesMap.putAll(sequenceFlowConditionMap);
				}
				Authentication.setAuthenticatedUserId(userInfo.getUserId());
				variablesMap.put(APPLY_USER_NAME, userInfo.getUserName());
				ProcessInstance processInstance = null;
				try {
//                    processInstance = runtimeService.startProcessInstanceByKeyAndTenantId(
//                            processDefinitionKey,
//                            flowModel.getProcessId(),
//                            variablesMap,
//                            userInfo.getTenantId());
					ProcessInstanceBuilder processInstanceBuilder = runtimeService.createProcessInstanceBuilder()
							.processDefinitionKey(processDefinitionKey).businessKey(flowModel.getProcessId())
							.variables(variablesMap).name(flowModel.getFlowTitle()).tenantId(userInfo.getTenantId());
					processInstance = processInstanceBuilder.start();

				} catch (Exception e) {
					e.printStackTrace();
					throw new WorkFlowException("启动流程失败");
				} finally {
					// 此线程不安全 用完就需要在finally中释放
					Authentication.setAuthenticatedUserId(null);
				}
//                runtimeService.setProcessInstanceName(processInstance.getProcessInstanceId(),flowModel.getFlowTitle());

				return processInstance;

			}
		}
		// 后面多次保存草稿 或者是先保存草稿再提交审核
		else {
			ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
					.processInstanceBusinessKey(flowModel.getId()).singleResult();
			if (processInstance == null) {
				processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(flowModel.getId())
						.singleResult();
			}

			if (!activitiUtils.checkStatus(processInstance.getId())) {
				throw new WorkFlowException("当前流程正在运行不能重复保存");
			} else {
				runtimeService.setProcessInstanceName(processInstance.getId(), flowModel.getFlowTitle());
				variablesMap.put(FLOW_URGENT, flowModel.getFlowUrgent());
				if (flowModel.getFormData() != null && !flowModel.getFormData().isEmpty()) {
					FormDataInfo formDataInfo = new FormDataInfo();
					formDataInfo.setFormDataJson(JsonUtilEx.getObjectToString(flowModel.getFormData()));
//                    runtimeService.setVariable(flowModel.getId(), FORM_INFO_JSON,formDataInfo);
					variablesMap.put(FORM_INFO_JSON, formDataInfo);
					ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
							.processDefinitionKey(processDefinitionKey).latestVersion().singleResult();
					Process process = getBpmnModelMainProcess(processDefinition.getId());
					String property = getAttributeValueByTaskDefinitionKey(process, "", "global");
					GlobalExPropertyDTO activityExPropertyDTO = JSONObject.parseObject(property,
							new TypeReference<GlobalExPropertyDTO>() {
							});
					Set<String> fieldSet = activityExPropertyDTO.getFieldSet();
					HashMap<String, Object> businessMap = JSONObject.parseObject(
							JSONObject.toJSONString(flowModel.getFormData()),
							new TypeReference<HashMap<String, Object>>() {
							});
					HashMap<String, Object> sequenceFlowConditionMap = new HashMap<>();
					if (fieldSet != null && !fieldSet.isEmpty()) {
						Set<String> set = businessMap.keySet();
						Collection<String> intersection = CollectionUtil.intersection(set, fieldSet);
						for (String s : set) {
							if (CollectionUtil.contains(intersection, s)) {
								sequenceFlowConditionMap.put(s, businessMap.get(s));
							}
						}
						// 需要进行条件判断的字段放入流程变量
						variablesMap.putAll(sequenceFlowConditionMap);
					}

				}

				//
				if (FlowStatusEnum.submit.getMessage().equals(flowModel.getStatus())) {
					variablesMap.put(PROCESS_STATUS, FlowTaskStatusEnum.Handle.getCode());
				}
				runtimeService.setVariables(processInstance.getId(), variablesMap);
			}
			return processInstance;
		}
		return null;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void submit(FlowModel flowModel) throws WorkFlowException {
		UserInfo userInfo = userProvider.get();
		flowModel.setStatus(FlowStatusEnum.submit.getMessage());
		// 有id 和没id相关
		ProcessInstance processInstance = saveIsAdmin(flowModel);
		if (processInstance == null) {
			throw new WorkFlowException("提交流程失败");
		}
		try {
//            runtimeService.setVariable(processInstance.getProcessInstanceId(),PROCESS_STATUS,FlowTaskStatusEnum.Handle.getCode());
//            此时任务必定是一个 发起人的任务
			Task task = taskService.createTaskQuery().processInstanceId(processInstance.getProcessInstanceId())
					.singleResult();
			// 完成发起人的任务
			taskService.complete(task.getId());

			QueryWrapper<FlowTaskOperatorEntity> queryWrapper = new QueryWrapper<>();
			queryWrapper.lambda().eq(FlowTaskOperatorEntity::getTaskNodeId, task.getId())
					.eq(FlowTaskOperatorEntity::getTaskId, task.getProcessInstanceId())
					.eq(FlowTaskOperatorEntity::getHandleId, userInfo.getUserId())
					.orderByAsc(FlowTaskOperatorEntity::getCreatorTime);
			List<FlowTaskOperatorEntity> list = flowTaskOperatorService.list(queryWrapper);
			FlowTaskOperatorEntity flowTaskOperatorEntity = list.get(0);
			// 提交记录
			FlowTaskOperatorRecordEntity flowTaskOperatorRecordEntity = new FlowTaskOperatorRecordEntity();
			flowTaskOperatorRecordEntity.setHandleOpinion("自动通过");
			flowTaskOperatorRecordEntity.setHandleId(userInfo.getUserId());
			flowTaskOperatorRecordEntity.setHandleName(userInfo.getUserName());
			flowTaskOperatorRecordEntity.setHandleTime(new Date());
			flowTaskOperatorRecordEntity.setHandleStatus(FlowRecordEnum.submit.getCode());
			flowTaskOperatorRecordEntity.setOperatorId(userInfo.getUserId());
			flowTaskOperatorRecordEntity.setNodeCode(task.getTaskDefinitionKey());
			flowTaskOperatorRecordEntity.setNodeName("开始");
			flowTaskOperatorRecordEntity.setTaskOperatorId(flowTaskOperatorEntity.getId());
			flowTaskOperatorRecordEntity.setTaskNodeId(task.getId());
			flowTaskOperatorRecordEntity.setTaskId(task.getProcessInstanceId());
			BpmnModel bpmnModel = repositoryService.getBpmnModel(task.getProcessDefinitionId());
			Process mainProcess = bpmnModel.getMainProcess();
			String property = getAttributeValueByTaskDefinitionKey(mainProcess, task.getTaskDefinitionKey(),
					"userTask");
			UserTaskExPropertyDTO exPropertyDTO = JSONObject.parseObject(property,
					new TypeReference<UserTaskExPropertyDTO>() {
					});
			String assigneeType = exPropertyDTO.getUserTaskBasicPropDTO().getAssigneeType();
			flowTaskOperatorRecordEntity.setStatus(
					FlowTaskOperatorEnum.FreeApprover.getCode().equals(assigneeType) ? FlowNodeEnum.Futility.getCode()
							: FlowNodeEnum.Process.getCode());
			flowTaskOperatorRecordService.create(flowTaskOperatorRecordEntity);
			// 处理事件
			userTaskNodeHelper.event(flowTaskOperatorRecordEntity.getHandleStatus(), exPropertyDTO,
					task.getProcessInstanceId(), task.getId());

		} catch (WorkFlowException e) {
			throw new WorkFlowException(e.getMessage());
		}
	}

	@Override
	public void audit(String id, FlowModel flowModel) throws WorkFlowException {
//        FlowTaskOperatorEntity operator = flowTaskOperatorService.getInfo(id);
//        if (operator != null) {
//            FlowTaskEntity flowTaskEntity = flowTaskService.getInfo(operator.getTaskId());
//            if (operator.getCompletion() == 0) {
//                this.audit(flowTaskEntity, operator, flowModel);
//            }
//        }
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void audit(FlowTaskEntity flowTask, FlowTaskOperatorEntity operator, FlowModel flowModel, Task task)
			throws WorkFlowException {
		try {
			UserInfo userInfo = userProvider.get();
			// 同意记录
			FlowTaskOperatorRecordEntity operatorRecord = new FlowTaskOperatorRecordEntity();
			// 审批数据赋值
			FlowOperatordModel flowOperatordModel = new FlowOperatordModel();
			flowOperatordModel.setStatus(FlowRecordEnum.audit.getCode());
			flowOperatordModel.setFlowModel(flowModel);
			flowOperatordModel.setUserId(userInfo.getUserId());
			flowOperatordModel.setOperator(operator);
			this.operatorRecord(operatorRecord, flowOperatordModel);
			flowTaskOperatorRecordService.create(operatorRecord);

			// 节点事件
			userTaskNodeHelper.event(FlowRecordEnum.audit.getCode(), flowTask.getUserTaskExPropertyDTO(),
					task.getProcessInstanceId(), task.getId());

			operator.setCompletion(1);
			operator.setHandleStatus(FlowRecordEnum.audit.getCode());
			operator.setHandleTime(new Date());
			// 更新流当前程经办状态
			if (StringUtil.isNotEmpty(operator.getId())) {
				flowTaskOperatorService.update(operator);
			}

			// 更新数据
			FlowEngineEntity engine = flowEngineService.getInfo(flowTask.getFlowId());
			flowModel.setProcessId(task.getFormKey());
			flowModel.setId(task.getFormKey());
			Map<String, Object> dataAll = JsonUtil.stringToMap(flowTask.getFlowFormContentJson());
			if (FlowNature.CUSTOM.equals(engine.getFormType())) {
				Map<String, Object> formDataAll = flowModel.getFormData();
				flowModel.setFormData(dataAll);
				if (formDataAll.get("data") != null) {
					Map<String, Object> data = JsonUtil.stringToMap(String.valueOf(formDataAll.get("data")));
					flowModel.setFormData(data);
				}
			}

			flowTask.setProcessInstanceId(task.getProcessInstanceId());
			Map<String, Object> data = this.createData(engine, flowTask, flowModel);

			String copyIds = flowModel.getCopyIds();
			if (StringUtils.isNotBlank(copyIds)) {
				// 获取抄送人
				List<FlowTaskCirculateEntity> circulateList = new ArrayList<>();
				this.circulateList(circulateList, flowModel, task);
				flowTaskCirculateService.create(circulateList);
			}

			// 处理页面上的加签人
			String freeApproverUserId = flowModel.getFreeApproverUserId();
			// 目前页面上只能选择一个加签人, 如果设置为多个 那就可以 for循环就行
			// 普通节点的加签没有意义, 不在此系统中上实现前后加签的功能 只实现会签加减签
			if (StringUtils.isNotBlank(freeApproverUserId)) {
				//
				BpmnModel bpmnModel = repositoryService.getBpmnModel(task.getProcessDefinitionId());
				UserTask userTask = (UserTask) bpmnModel.getFlowElement(task.getTaskDefinitionKey());
				boolean b = userTask.hasMultiInstanceLoopCharacteristics();
				if (b) {
					Map<String, Object> variableMap = new HashMap<>();
					variableMap.put("assignee", freeApproverUserId);
					ExecutionEntity executionEntity = managementService
							.executeCommand(new GetRootExecutionEntityCmd(task.getExecutionId(), userTask.getId()));
					ExecutionEntity execution = (ExecutionEntity) runtimeService
							.addMultiInstanceExecution(userTask.getId(), executionEntity.getId(), variableMap);

					List<TaskEntity> tasks = execution.getTasks();
					if (tasks != null && !tasks.isEmpty()) {
						operator.setTaskNodeId(tasks.get(0).getId());
					}
					UserTaskExPropertyDTO userTaskExPropertyDTO = flowTask.getUserTaskExPropertyDTO();
					UserTaskBasicPropDTO userTaskBasicPropDTO = userTaskExPropertyDTO.getUserTaskBasicPropDTO();
					operator.setId(RandomUtil.uuId());
					operator.setHandleType(FlowTaskOperatorEnum.FreeApprover.getCode());
					operator.setHandleId(freeApproverUserId);
					operator.setTaskId(task.getProcessInstanceId());
					operator.setNodeCode(task.getTaskDefinitionKey());
					operator.setNodeName(task.getName());
					operator.setDescription(task.getDescription());
					operator.setCreatorTime(new Date());
					operator.setCompletion(Integer.valueOf(userTaskBasicPropDTO.getProgress()));
					operator.setType(FlowTaskOperatorEnum.FreeApprover.getCode());
					operator.setState(FlowNodeEnum.Process.getCode());
					flowTaskOperatorService.save(operator);
				}
				// 普通节点 加减签
				else {
					//
				}
			}
			taskService.setVariableLocal(task.getId(), TASK_STATE, TASK_STATE_AUDIT);// 设置任务状态
			taskService.complete(task.getId());
		} catch (WorkFlowException e) {
			// 手动回滚事务
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			throw new WorkFlowException(e.getMessage());
		}
	}

	@Override
	public void reject(String id, FlowModel flowModel) throws WorkFlowException {
//        FlowTaskOperatorEntity operator = flowTaskOperatorService.getInfo(id);
//        if (operator != null) {
//            FlowTaskEntity flowTaskEntity = flowTaskService.getInfo(operator.getTaskId());
//            if (operator.getCompletion() == 0) {
//                this.reject(flowTaskEntity, operator, flowModel);
//            }
//        }
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void reject(FlowTaskOperatorEntity operator, FlowModel flowModel, Task task) throws WorkFlowException {
		UserInfo userInfo = userProvider.get();
		BpmnModel bpmnModel = repositoryService.getBpmnModel(task.getProcessDefinitionId());
		String property = getAttributeValueByTaskDefinitionKey(bpmnModel.getMainProcess(), task.getTaskDefinitionKey(),
				"userTask");
		UserTaskExPropertyDTO exPropertyDTO = JSONObject.parseObject(property,
				new TypeReference<UserTaskExPropertyDTO>() {
				});

		// 驳回记录
		FlowTaskOperatorRecordEntity operatorRecord = new FlowTaskOperatorRecordEntity();
		// 审批数据赋值
		FlowOperatordModel flowOperatordModel = new FlowOperatordModel();
		flowOperatordModel.setStatus(FlowRecordEnum.reject.getCode());
		flowOperatordModel.setFlowModel(flowModel);
		flowOperatordModel.setUserId(userInfo.getUserId());
		flowOperatordModel.setOperator(operator);
		this.operatorRecord(operatorRecord, flowOperatordModel);
		flowTaskOperatorRecordService.create(operatorRecord);

		operator.setCompletion(1);
		operator.setHandleStatus(FlowRecordEnum.reject.getCode());
		operator.setHandleTime(new Date());
		// 更新流当前程经办状态
		flowTaskOperatorService.update(operator);

		taskService.setVariableLocal(task.getId(), TASK_STATE, TASK_STATE_REJECT);// 设置任务状态

		UserTaskBasicPropDTO userTaskBasicPropDTO = exPropertyDTO.getUserTaskBasicPropDTO();
		UserTaskAdvancedSettingDTO userTaskAdvancedSettingDTO = exPropertyDTO.getUserTaskAdvancedSettingDTO();
		// 驳回节点
		ArrayList<String> distinct = CollectionUtil
				.distinct(runtimeService.getActiveActivityIds(task.getProcessInstanceId()));
		// 如果没有驳回节点直接驳回到发起人节点
		UserTask userTask = getFirstNode(bpmnModel.getMainProcess());
		runtimeService.createChangeActivityStateBuilder().processInstanceId(task.getProcessInstanceId())
				.moveActivityIdsToSingleActivityId(distinct, userTask.getId())
				.localVariable(userTask.getId(), REJECT_NODE, userTask.getId()).changeState();

		Map<String, Object> variables = runtimeService.getVariables(task.getProcessInstanceId());
		String flowId = MapUtil.getStr(variables, FLOW_ENGINE_ID);
		FlowEngineEntity flowEngineServiceInfo = flowEngineService.getInfo(flowId);
		FormDataInfo formDataInfo = MapUtil.get(variables, FORM_INFO_JSON, FormDataInfo.class);

		FlowTaskEntity flowTaskEntity = new FlowTaskEntity();
		flowTaskEntity.setFlowId(flowId);
		flowTaskEntity.setFlowFormContentJson(formDataInfo.getFormDataJson());

		String gProperty = getAttributeValueByTaskDefinitionKey(bpmnModel.getMainProcess(), "", "global");
		GlobalExPropertyDTO globalExPropertyDTO = JSONObject.parseObject(gProperty,
				new TypeReference<GlobalExPropertyDTO>() {
				});

		flowTaskEntity.setFlowForm(globalExPropertyDTO.getFormData());
		flowTaskEntity.setId(task.getFormKey());
		flowTaskEntity.setProcessId(task.getFormKey());
		flowTaskEntity.setFieldSet(globalExPropertyDTO.getFieldSet());
		// 更改表单数据
		// 更新数据
		FlowEngineEntity engine = flowEngineService.getInfo(flowId);
		flowModel.setProcessId(task.getFormKey());
		flowModel.setId(task.getFormKey());
		flowTaskEntity.setProcessInstanceId(task.getProcessInstanceId());
		Map<String, Object> dataAll = JsonUtil.stringToMap(formDataInfo.getFormDataJson());
		if (FlowNature.CUSTOM.equals(engine.getFormType())) {
			Map<String, Object> formDataAll = flowModel.getFormData();
			flowModel.setFormData(dataAll);
			if (formDataAll.get("data") != null) {
				Map<String, Object> data = JsonUtil.stringToMap(String.valueOf(formDataAll.get("data")));
				flowModel.setFormData(data);
			}
		}
		Map<String, Object> data = this.createData(engine, flowTaskEntity, flowModel);

		// 获取抄送人
		if (StringUtils.isNotBlank(flowModel.getCopyIds())) {
			List<FlowTaskCirculateEntity> circulateList = new ArrayList<>();
			this.circulateList(circulateList, flowModel, task);
			flowTaskCirculateService.create(circulateList);
		}

		// 节点事件
//        userTaskNodeHelper.event(FlowRecordEnum.reject.getCode(),exPropertyDTO, (TaskEntity) task);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void recall(String id, FlowModel flowModel, HistoricTaskInstance historicTaskInstance)
			throws WorkFlowException {
		UserInfo userInfo = userProvider.get();
		// 判断流程是否结束
		ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
				.processInstanceId(historicTaskInstance.getProcessInstanceId()).singleResult();
		if (processInstance == null) {
			throw new WorkFlowException("流程已经结束,无法撤回");
		}

		List<String> activeActivityIds = runtimeService.getActiveActivityIds(processInstance.getProcessInstanceId());
		Process process = getBpmnModelMainProcess(processInstance.getProcessDefinitionId());
		UserTask userTask = getFirstNode(process);
		if (activeActivityIds.contains(userTask.getId())) {
			throw new WorkFlowException("当前已经处于此节点,不需要撤回");
		}

		ArrayList<String> distinct = CollectionUtil.distinct(activeActivityIds);
		String processInstanceId = processInstance.getProcessInstanceId();
		ProcessDefinitionEntity processDefinitionEntity = activitiUtils
				.getProcessDefinitionEntityById(processInstance.getProcessDefinitionId());
		String currentNodeId = "";

		if (activeActivityIds == null || activeActivityIds.isEmpty()) {
			throw new WorkFlowException("当前流程已经被挂起,无法撤回,请联系管理员重试");
		} else {
			currentNodeId = activeActivityIds.get(0);
			Task currentTask = activitiDataBaseUtils.getTaskByProcessInstanceIdAndTaskDefinitionKey(processInstanceId,
					currentNodeId);
			if (StringUtils.isNotBlank(currentTask.getAssignee())) {
				throw new WorkFlowException("任务已经被对应节点审批人签收,无法撤回!");
			} else {
				runtimeService.createChangeActivityStateBuilder().processInstanceId(processInstanceId)
						.moveActivityIdsToSingleActivityId(distinct, userTask.getId())
						.localVariable(userTask.getId(), REJECT_NODE, userTask.getId()).changeState();
			}
		}

		FlowTaskOperatorRecordEntity flowTaskOperatorRecordEntity = new FlowTaskOperatorRecordEntity();
		flowTaskOperatorRecordEntity.setHandleId(userInfo.getUserId());
		flowTaskOperatorRecordEntity.setHandleName(userInfo.getUserName());
		flowTaskOperatorRecordEntity.setHandleTime(new Date());
		flowTaskOperatorRecordEntity.setHandleStatus(FlowRecordEnum.revoke.getCode());
		flowTaskOperatorRecordEntity.setNodeName(processInstance.getName());
		flowTaskOperatorRecordEntity.setTaskId(processInstance.getProcessInstanceId());
		flowTaskOperatorRecordEntity.setTaskNodeId(historicTaskInstance.getId());
		flowTaskOperatorRecordEntity.setHandleOpinion(flowModel.getHandleOpinion());
		flowTaskOperatorRecordService.create(flowTaskOperatorRecordEntity);

		String taskProperty = getAttributeValueByTaskDefinitionKey(process, historicTaskInstance.getTaskDefinitionKey(),
				"userTask");
		UserTaskExPropertyDTO taskExPropertyDTO = JSONObject.parseObject(taskProperty,
				new TypeReference<UserTaskExPropertyDTO>() {
				});
		// 节点事件
		userTaskNodeHelper.event(FlowRecordEnum.recall.getCode(), taskExPropertyDTO,
				historicTaskInstance.getProcessInstanceId(), historicTaskInstance.getId());
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void revoke(ProcessInstance processInstance, FlowModel flowModel) {
		UserInfo userInfo = userProvider.get();
		String processInstanceId = processInstance.getProcessInstanceId();
		List<String> activeActivityIds = runtimeService.getActiveActivityIds(processInstance.getProcessInstanceId());
		Process process = getBpmnModelMainProcess(processInstance.getProcessDefinitionId());
		UserTask destination = getFirstNode(process);
		if (activeActivityIds.contains(destination.getId())) {
			throw new WorkFlowException("当前已经处于此节点,不需要撤回");
		}
		ArrayList<String> distinct = CollectionUtil.distinct(activeActivityIds);
		ProcessDefinitionEntity processDefinitionEntity = activitiUtils
				.getProcessDefinitionEntityById(processInstance.getProcessDefinitionId());
		String currentNodeId = "";

		if (activeActivityIds == null || activeActivityIds.isEmpty()) {
			throw new WorkFlowException("当前流程已经被挂起,无法撤回,请联系管理员重试");
		}
		currentNodeId = activeActivityIds.get(0);
		Task task = activitiDataBaseUtils.getTaskByProcessInstanceIdAndTaskDefinitionKey(processInstanceId,
				currentNodeId);
		if (StringUtils.isNotBlank(task.getAssignee())) {
			throw new WorkFlowException("任务已经被审批人签收,无法撤回!");
		} else {
			runtimeService.createChangeActivityStateBuilder().processInstanceId(processInstanceId)
					.moveActivityIdsToSingleActivityId(distinct, destination.getId())
					.localVariable(destination.getId(), REJECT_NODE, destination.getId()).changeState();
		}
		runtimeService.setVariable(processInstanceId, PROCESS_STATUS, FlowTaskStatusEnum.Revoke.getCode());
		FlowNode currentNode = BpmnModelUtils.getFlowNodeById(process, currentNodeId);
		/**
		 *    record.setHandleOpinion(flowModel.getHandleOpinion());
		 *         record.setHandleId(userId);
		 *         record.setHandleTime(new Date());
		 *         record.setHandleStatus(status);
		 *         record.setOperatorId(operatorId);
		 *         record.setNodeCode(operator.getNodeCode());
		 *         record.setNodeName(operator.getNodeName() != null ? operator.getNodeName() : "开始");
		 *         record.setTaskOperatorId(operator.getId());
		 *         record.setTaskNodeId(operator.getTaskNodeId());
		 *         record.setTaskId(operator.getTaskId());
		 *         record.setSignImg(flowModel.getSignImg());
		 *         record.setStatus(FlowTaskOperatorEnum.FreeApprover.getCode().equals(operator.getHandleType()) ? FlowNodeEnum.Futility.getCode() : FlowNodeEnum.Process.getCode());
		 */
		// 撤回记录
		FlowTaskOperatorRecordEntity operatorRecord = new FlowTaskOperatorRecordEntity();
		operatorRecord.setId(RandomUtil.uuId());
//        operatorRecord.setNodeCode(currentNode.getId());
		operatorRecord.setNodeName(currentNode.getName());
		operatorRecord.setHandleStatus(FlowRecordEnum.revoke.getCode());
		operatorRecord.setHandleId(userInfo.getUserId());
		operatorRecord.setHandleName(userInfo.getUserName());
		operatorRecord.setHandleTime(new Date());
		if (StringUtils.isNotBlank(flowModel.getHandleOpinion())) {
			operatorRecord.setHandleOpinion(flowModel.getHandleOpinion());
		}
//        operatorRecord.setOperatorId();
//        operatorRecord.setTaskOperatorId();
//        operatorRecord.setTaskNodeId();
		operatorRecord.setTaskId(processInstanceId);
		if (StringUtils.isNotBlank(flowModel.getSignImg())) {
			flowModel.setSignImg(flowModel.getSignImg());
		}
		operatorRecord.setStatus(FlowNodeEnum.Process.getCode());
		flowTaskOperatorRecordService.create(operatorRecord);

		String userTaskEx = getAttributeValueByTaskDefinitionKey(process, currentNode.getId(), "userTask");
		UserTaskExPropertyDTO exPropertyDTO = JSONObject.parseObject(userTaskEx,
				new TypeReference<UserTaskExPropertyDTO>() {
				});
		userTaskNodeHelper.event(FlowRecordEnum.recall.getCode(), exPropertyDTO, task.getProcessInstanceId(),
				task.getId());
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void cancel(String processInstanceId, FlowModel flowModel) {
		UserInfo userInfo = userProvider.get();
		ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
				.processInstanceId(processInstanceId).singleResult();
		runtimeService.setVariable(processInstanceId, PROCESS_STATUS, FlowTaskStatusEnum.Cancel.getCode());
		List<String> activeActivityIds = runtimeService.getActiveActivityIds(processInstanceId);
		ArrayList<String> distinct = CollectionUtil.distinct(activeActivityIds);
		String processDefinitionId = processInstance.getProcessDefinitionId();
		ProcessDefinitionEntity processDefinitionEntity = activitiUtils
				.getProcessDefinitionEntityById(processDefinitionId);
		Process process = getBpmnModelMainProcess(processDefinitionId);
		List<String> currentNodeNames = new ArrayList<>();
		for (String d : distinct) {
			String name = process.getFlowElement(d).getName();
			currentNodeNames.add(name);
		}
		runtimeService.deleteProcessInstance(processInstanceId, "流程监控页面点击终止按钮");
		// 作废记录
		FlowTaskOperatorRecordEntity flowTaskOperatorRecordEntity = new FlowTaskOperatorRecordEntity();
		flowTaskOperatorRecordEntity.setHandleOpinion(flowModel.getHandleOpinion());
		flowTaskOperatorRecordEntity.setHandleId(userInfo.getUserId());
		flowTaskOperatorRecordEntity.setHandleName(userInfo.getUserName());
		flowTaskOperatorRecordEntity.setHandleTime(new Date());
		flowTaskOperatorRecordEntity.setHandleStatus(FlowRecordEnum.cancel.getCode());
//        flowTaskOperatorRecordEntity.setNodeName(StringUtils.join(currentNodeNames,","));
		flowTaskOperatorRecordEntity.setTaskId(processInstanceId);
		flowTaskOperatorRecordService.create(flowTaskOperatorRecordEntity);
	}

	@Override

	public boolean assign(String id, FlowHandleModel flowHandleModel) {
//        List<FlowTaskOperatorEntity> list = flowTaskOperatorService.getList(id).stream().filter(t -> FlowNodeEnum.Process.getCode().equals(t.getState()) && flowHandleModel.getNodeCode().equals(t.getNodeCode())).collect(Collectors.toList());
//        boolean isOk = list.size() > 0;
//        if (list.size() > 0) {
//            FlowTaskOperatorEntity entity = list.get(0);
//            entity.setHandleStatus(null);
//            entity.setHandleTime(null);
//            entity.setCompletion(0);
//            entity.setCreatorTime(new Date());
//            entity.setHandleId(flowHandleModel.getFreeApproverUserId());
//            List<String> idAll = list.stream().map(t -> t.getId()).collect(Collectors.toList());
//            flowTaskOperatorService.deleteList(idAll);
//            List<FlowTaskOperatorEntity> addList = new ArrayList<>();
//            addList.add(entity);
//            flowTaskOperatorService.create(addList);
//            //指派记录
//            UserInfo userInfo = userProvider.get();
//            FlowModel flowModel = JsonUtil.getJsonToBean(flowHandleModel, FlowModel.class);
//            FlowTaskOperatorRecordEntity operatorRecord = new FlowTaskOperatorRecordEntity();
//            FlowTaskOperatorEntity operator = new FlowTaskOperatorEntity();
//            operator.setTaskId(entity.getTaskId());
//            operator.setNodeCode(entity.getNodeCode());
//            operator.setNodeName(entity.getNodeName());
//            //审批数据赋值
//            FlowOperatordModel flowOperatordModel = new FlowOperatordModel();
//            flowOperatordModel.setStatus(FlowRecordEnum.assign.getCode());
//            flowOperatordModel.setFlowModel(flowModel);
//            flowOperatordModel.setUserId(userInfo.getUserId());
//            flowOperatordModel.setOperator(operator);
//            flowOperatordModel.setOperatorId(entity.getHandleId());
//            this.operatorRecord(operatorRecord, flowOperatordModel);
//            flowTaskOperatorRecordService.create(operatorRecord);
//        }
		Boolean isOk = true;
		return isOk;
	}

	@Override
	public void transfer(FlowTaskOperatorEntity taskOperator) {
		flowTaskOperatorService.update(taskOperator);
		// 转办记录
		UserInfo userInfo = userProvider.get();
		FlowModel flowModel = new FlowModel();
		FlowTaskOperatorRecordEntity operatorRecord = new FlowTaskOperatorRecordEntity();
		FlowTaskOperatorEntity operator = new FlowTaskOperatorEntity();
		operator.setTaskId(taskOperator.getTaskId());
		operator.setNodeCode(taskOperator.getNodeCode());
		operator.setNodeName(taskOperator.getNodeName());
		// 审批数据赋值
		FlowOperatordModel flowOperatordModel = new FlowOperatordModel();
		flowOperatordModel.setStatus(FlowRecordEnum.transfer.getCode());
		flowOperatordModel.setFlowModel(flowModel);
		flowOperatordModel.setUserId(userInfo.getUserId());
		flowOperatordModel.setOperator(operator);
		flowOperatordModel.setOperatorId(taskOperator.getHandleId());
		this.operatorRecord(operatorRecord, flowOperatordModel);
		flowTaskOperatorRecordService.create(operatorRecord);
	}

	@Override
	public FlowBeforeInfoVO getBeforeInfo(String id, String taskNodeId) throws WorkFlowException {
//        return  null;
		FlowBeforeInfoVO vo = new FlowBeforeInfoVO();
		HistoricProcessInstance historicProcessInstance = activitiUtils
				.getHistoricProcessInstanceByIdOrBusinessKeyOrTaskId(id);
		List<FlowTaskOperatorEntity> taskOperatorList = flowTaskOperatorService.getList(historicProcessInstance.getId())
				.stream().filter(t -> FlowNodeEnum.Process.getCode().equals(t.getState())).collect(Collectors.toList());
		List<FlowTaskOperatorRecordEntity> operatorRecordList = flowTaskOperatorRecordService
				.getList(historicProcessInstance.getId());
		boolean colorFlag = true;
//        //已办人员
		List<FlowTaskOperatorRecordModel> recordList = new ArrayList<>();
		for (FlowTaskOperatorRecordEntity entity : operatorRecordList) {
			FlowTaskOperatorRecordModel infoModel = JsonUtil.getJsonToBean(entity, FlowTaskOperatorRecordModel.class);
			infoModel.setUserName(entity.getHandleName());
//            infoModel.setOperatorId(operatorName != null ? operatorName.getRealName() + "/" + operatorName.getAccount() : "");
			recordList.add(infoModel);
		}
		vo.setFlowTaskOperatorRecordList(recordList);
//        //流程节点
		List<String> tepIdAll = runtimeService.getActiveActivityIds(historicProcessInstance.getId());

		List<HistoricActivityInstance> list = historyService.createHistoricActivityInstanceQuery()
				.processInstanceId(historicProcessInstance.getId()).orderByHistoricActivityInstanceStartTime().asc()
				.list();
		List<UserAllModel> all = userService.getAll();
		List<FlowTaskNodeModel> flowTaskNodeModels = new ArrayList<>();
		Process process = getBpmnModelMainProcess(historicProcessInstance.getProcessDefinitionId());
		String globalProperty = getAttributeValueByTaskDefinitionKey(process, "", "global");
		GlobalExPropertyDTO globalExPropertyDTO = JSONObject.parseObject(globalProperty,
				new TypeReference<GlobalExPropertyDTO>() {
				});
		UserTask destination = getFirstNode(process);
		List<FlowElement> activities = getFlowElementsWithOutSequenceFlow(process);
		List<FlowTaskNodeEntity> flowTaskNodeEntityList = new ArrayList<>();

		Map<String, HistoricActivityInstance> activityInstanceMap = new HashMap<>();
		for (HistoricActivityInstance historicActivityInstance : list) {
			activityInstanceMap.put(historicActivityInstance.getActivityId(), historicActivityInstance);
		}

		String applyUserActivityNodePropertyJson = "";
		for (FlowElement activity : activities) {
			FlowNode flowNode = (FlowNode) activity;
			Object activityBehavior = flowNode.getBehavior();
			HistoricActivityInstance historicActivityInstance = activityInstanceMap.get(flowNode.getId());

			FlowTaskNodeEntity flowTaskNodeEntity = new FlowTaskNodeEntity();
			if (historicActivityInstance != null) {
				flowTaskNodeEntity.setCreatorTime(historicActivityInstance.getStartTime());
				if (historicActivityInstance.getEndTime() == null) {
					flowTaskNodeEntity.setCompletion(0);
					flowTaskNodeEntity.setType("1");
					flowTaskNodeEntity.setUserName(flowNode.getName());
				} else {
					flowTaskNodeEntity.setCompletion(1);
					flowTaskNodeEntity.setType("0");

					if (historicActivityInstance.getActivityType().equals("userTask")) {
						UserAllModel user = all.stream()
								.filter(t -> t.getId().equals(historicActivityInstance.getAssignee())).findFirst()
								.orElse(null);
						if (user != null) {
							flowTaskNodeEntity.setUserName(user.getRealName() + "/" + user.getAccount());
						} else {
							flowTaskNodeEntity.setUserName(flowNode.getName());
						}
					}
				}
			} else {
				flowTaskNodeEntity.setCompletion(0);
				flowTaskNodeEntity.setUserName(flowNode.getName());
			}

			if (activityBehavior instanceof UserTaskActivityBehavior) {
				flowTaskNodeEntity.setId(historicProcessInstance.getId() + activity.getId());
				flowTaskNodeEntity.setNodeCode(activity.getId());
				flowTaskNodeEntity.setNodeName(flowNode.getName());
				String property = getAttributeValueByTaskDefinitionKey(process, flowNode.getId(), "userTask");
				UserTaskExPropertyDTO activityExPropertyDTO = JSONObject.parseObject(property,
						new TypeReference<UserTaskExPropertyDTO>() {
						});
				String childNodeListJson = activityExPropertyDTO.getUserTaskBasicPropDTO().getChildNodeListJson();
				flowTaskNodeEntity.setNodePropertyJson(childNodeListJson);
				String rejectStep = activityExPropertyDTO.getUserTaskAdvancedSettingDTO().getRejectStep();
				applyUserActivityNodePropertyJson = childNodeListJson;
				flowTaskNodeEntity.setNodeUp(rejectStep);
				List<String> nextNode = activitiUtils.getNextNode(historicProcessInstance.getProcessDefinitionId(),
						activity.getId());
				flowTaskNodeEntity.setNodeNext(nextNode.isEmpty() ? null : StringUtils.join(nextNode, ","));

				flowTaskNodeEntity.setTaskId(historicProcessInstance.getId());
				flowTaskNodeEntity.setState("0");
				// 代表是start节点
				if (destination.getId().equals(activity.getId())) {
					flowTaskNodeEntity.setNodeType(FlowNodeTypeEnum.START.getType());
				} else {
					flowTaskNodeEntity.setNodeType(FlowNodeTypeEnum.APPROVER.getType());
				}
				flowTaskNodeEntityList.add(flowTaskNodeEntity);
			} else if (activityBehavior instanceof MultiInstanceActivityBehavior) {
				flowTaskNodeEntity.setId(historicProcessInstance.getId() + activity.getId());
				flowTaskNodeEntity.setNodeCode(activity.getId());
				flowTaskNodeEntity.setNodeName(flowNode.getName());
				String property = getAttributeValueByTaskDefinitionKey(process, flowNode.getId(), "userTask");
				UserTaskExPropertyDTO activityExPropertyDTO = JSONObject.parseObject(property,
						new TypeReference<UserTaskExPropertyDTO>() {
						});
				String childNodeListJson = activityExPropertyDTO.getUserTaskBasicPropDTO().getChildNodeListJson();
				flowTaskNodeEntity.setNodePropertyJson(childNodeListJson);
				String rejectStep = activityExPropertyDTO.getUserTaskAdvancedSettingDTO().getRejectStep();
				flowTaskNodeEntity.setNodeUp(rejectStep);
				List<String> nextNode = activitiUtils.getNextNode(historicProcessInstance.getProcessDefinitionId(),
						activity.getId());
				flowTaskNodeEntity.setNodeNext(nextNode.isEmpty() ? null : StringUtils.join(nextNode, ","));
				flowTaskNodeEntity.setTaskId(historicProcessInstance.getId());
				flowTaskNodeEntity.setState("0");
				flowTaskNodeEntity.setNodeType(FlowNodeTypeEnum.APPROVER.getType());
				flowTaskNodeEntityList.add(flowTaskNodeEntity);
			} else if (activityBehavior instanceof ReceiveTaskActivityBehavior) {
				// ActivityImpl activityImpl =
				// processDefinitionEntity.findActivity(activity.getId());
				// FlowTaskNodeEntity flowTaskNodeEntity = new FlowTaskNodeEntity();
				// flowTaskNodeEntity.setId(historicProcessInstance.getId()+activity.getId());
				// flowTaskNodeEntity.setNodeCode(activity.getId());
				// flowTaskNodeEntity.setNodeName(activityImpl.getProperty("name").toString());
				// Object property =
				// activity.getProperty(BasicActivitiConstants.extensionAttributeName);
				// ActivityExPropertyDTO activityExPropertyDTO =
				// JSONObject.parseObject(property.toString(), new
				// TypeReference<ActivityExPropertyDTO>() {
				// });
				// flowTaskNodeEntity.setNodePropertyJson(activityExPropertyDTO.getChildNodeListJson());
				// flowTaskNodeEntity.setNodeUp(activityExPropertyDTO.getRejectStep());
				// List<String> nextNode =
				// activitiUtils.getNextNode(processDefinitionEntity.getId(), activity.getId());
				// flowTaskNodeEntity.setNodeNext(nextNode.isEmpty()?null:
				// StringUtils.join(nextNode,","));
				// flowTaskNodeEntity.setCompletion(0);
				// flowTaskNodeEntity.setCreatorTime(new Date());
				// flowTaskNodeEntity.setTaskId(historicProcessInstance.getId());
				// flowTaskNodeEntity.setState("0");
				// flowTaskNodeEntity.setNodeType(FlowNodeTypeEnum.TIMER.getType());
				// flowTaskNodeEntityList.add(flowTaskNodeEntity);
			}

			else if (activityBehavior instanceof CustomCallActivityActivityBehavior) {
				flowTaskNodeEntity.setId(historicProcessInstance.getId() + activity.getId());
				flowTaskNodeEntity.setNodeCode(activity.getId());
				flowTaskNodeEntity.setNodeName(flowNode.getName());
				flowTaskNodeEntity.setUserName(flowNode.getName());

				String property = getAttributeValueByTaskDefinitionKey(process, flowNode.getId(), "callActivity");
				CallActivityExPropertyDTO activityExPropertyDTO = JSONObject.parseObject(property,
						new TypeReference<CallActivityExPropertyDTO>() {
						});

				String childNodeListJson = activityExPropertyDTO.getChildNodeListJson();
				flowTaskNodeEntity.setNodePropertyJson(childNodeListJson);
				applyUserActivityNodePropertyJson = childNodeListJson;
				flowTaskNodeEntity.setNodeUp(flowNode.getIncomingFlows().get(0).getSourceRef());
				List<String> nextNode = activitiUtils.getNextNode(historicProcessInstance.getProcessDefinitionId(),
						activity.getId());
				flowTaskNodeEntity.setNodeNext(nextNode.isEmpty() ? null : StringUtils.join(nextNode, ","));
				flowTaskNodeEntity.setTaskId(historicProcessInstance.getId());
				flowTaskNodeEntity.setState("0");
				flowTaskNodeEntity.setNodeType(FlowNodeTypeEnum.CALL_ACTIVITY.getType());
				if (historicActivityInstance != null) {
					if (historicActivityInstance.getEndTime() != null) {
						flowTaskNodeEntity.setUserName("子流程执行完成!");
					}
				}
				flowTaskNodeEntityList.add(flowTaskNodeEntity);
			}

			else if (activityBehavior instanceof CustomManualTaskActivityBehavior) {
				flowTaskNodeEntity.setId(historicProcessInstance.getId() + activity.getId());
				flowTaskNodeEntity.setNodeCode(activity.getId());
				flowTaskNodeEntity.setNodeName(flowNode.getName());
				flowTaskNodeEntity.setUserName(flowNode.getName());

				String property = getAttributeValueByTaskDefinitionKey(process, flowNode.getId(), "manualTask");
				ManualTaskExPropertyDTO activityExPropertyDTO = JSONObject.parseObject(property,
						new TypeReference<ManualTaskExPropertyDTO>() {
						});

				String childNodeListJson = activityExPropertyDTO.getChildNodeListJson();
				flowTaskNodeEntity.setNodePropertyJson(childNodeListJson);
				applyUserActivityNodePropertyJson = childNodeListJson;
				flowTaskNodeEntity.setNodeUp(flowNode.getIncomingFlows().get(0).getSourceRef());
				List<String> nextNode = activitiUtils.getNextNode(historicProcessInstance.getProcessDefinitionId(),
						activity.getId());
				flowTaskNodeEntity.setNodeNext(nextNode.isEmpty() ? null : StringUtils.join(nextNode, ","));
				flowTaskNodeEntity.setTaskId(historicProcessInstance.getId());
				flowTaskNodeEntity.setState("0");

				if (FlowNodeTypeEnum.COPY.getType().equals(activityExPropertyDTO.getType())) {
					flowTaskNodeEntity.setNodeType(FlowNodeTypeEnum.COPY.getType());
					if (historicActivityInstance != null) {
						if (historicActivityInstance.getEndTime() != null) {
							flowTaskNodeEntity.setUserName("已经成功抄送给相关人员!");
						}
					}
				} else if (FlowNodeTypeEnum.MAIL.getType().equals(activityExPropertyDTO.getType())) {
					flowTaskNodeEntity.setNodeType(FlowNodeTypeEnum.MAIL.getType());
					if (historicActivityInstance != null) {
						if (historicActivityInstance.getEndTime() != null) {
							flowTaskNodeEntity.setUserName("已经成功发邮件给相关人员!");
						}
					}

				}
				flowTaskNodeEntityList.add(flowTaskNodeEntity);
			}

			else if (activityBehavior instanceof NoneEndEventActivityBehavior) {
				flowTaskNodeEntity.setId(historicProcessInstance.getId() + activity.getId());
				flowTaskNodeEntity.setNodeCode(activity.getId());
				flowTaskNodeEntity.setNodeName("结束");
				flowTaskNodeEntity.setUserName("结束");
				flowTaskNodeEntity.setNodePropertyJson(applyUserActivityNodePropertyJson);
				flowTaskNodeEntity.setNodeUp("0");
				flowTaskNodeEntity.setNodeNext(null);
				flowTaskNodeEntity.setTaskId(historicProcessInstance.getId());
				flowTaskNodeEntity.setState("0");
				flowTaskNodeEntity.setNodeType("endround");
				flowTaskNodeEntityList.add(flowTaskNodeEntity);
			}
		}

		List<FlowTaskNodeModel> flowTaskNodeListAll = JsonUtil.getJsonToList(flowTaskNodeEntityList,
				FlowTaskNodeModel.class);
		vo.setFlowTaskNodeList(flowTaskNodeListAll);
//        //表单权限
		Properties approversProperties = new Properties();
		if (StringUtil.isNotEmpty(taskNodeId)) {
			vo.setFormOperates(new ArrayList<>());
			FlowElement flowElement = process.getFlowElement(taskNodeId);
			if (flowElement != null) {
				String property = getAttributeValueByTaskDefinitionKey(process, taskNodeId, "userTask");
				UserTaskExPropertyDTO activityExPropertyDTO = JSONObject.parseObject(property,
						new TypeReference<UserTaskExPropertyDTO>() {
						});
				String childNodeListJson = activityExPropertyDTO.getUserTaskBasicPropDTO().getChildNodeListJson();
				ChildNodeList childNode = JsonUtil.getJsonToBean(childNodeListJson, ChildNodeList.class);
				approversProperties = childNode.getProperties();
				List<FormOperates> operatesList = activityExPropertyDTO.getOperatesList();
				vo.setFormOperates(operatesList);
			}
		}
		FlowJsonUtil.assignment(approversProperties);
		vo.setApproversProperties(approversProperties);
//        //流程任务
		FlowTaskModel inof = new FlowTaskModel();

		Map<String, Object> processVariables = historicProcessInstance.getProcessVariables();
		inof.setId(historicProcessInstance.getBusinessKey());
		inof.setProcessId(historicProcessInstance.getId());
		inof.setEnCode(MapUtil.getStr(processVariables, GlobalProcessVariableConstants.BILL_CODE));
		inof.setFullName(historicProcessInstance.getName());
		inof.setFlowUrgent(MapUtil.getInt(processVariables, GlobalProcessVariableConstants.FLOW_URGENT));
		inof.setFlowId(MapUtil.getStr(processVariables, GlobalProcessVariableConstants.FLOW_ENGINE_ID));
		inof.setFlowCode(historicProcessInstance.getProcessDefinitionKey());
		inof.setFlowName(historicProcessInstance.getProcessDefinitionName());
		inof.setFlowType(globalExPropertyDTO.getFlowType());
		inof.setFlowCategory(MapUtil.getStr(processVariables, GlobalProcessVariableConstants.PROCESS_CATEGORY));
		inof.setFlowForm(globalExPropertyDTO.getFormData());
		FormDataInfo formDataInfo = MapUtil.get(processVariables, FORM_INFO_JSON, FormDataInfo.class);
		inof.setFlowFormContentJson(formDataInfo.getFormDataJson());
		inof.setFlowTemplateJson(globalExPropertyDTO.getFlowTemplateJson());
		inof.setFlowVersion(globalExPropertyDTO.getFlowVersion());
		inof.setStartTime(historicProcessInstance.getStartTime().getTime());
		Date endTime = historicProcessInstance.getEndTime();
		inof.setEndTime(endTime == null ? null : endTime.getTime());
		inof.setStatus(MapUtil.getInt(processVariables, GlobalProcessVariableConstants.PROCESS_STATUS));
		inof.setCompletion(50);
		inof.setEnabledMark(1);
		inof.setDescription(process.getDocumentation());
		inof.setGrade(MapUtil.getInt(processVariables, GlobalProcessVariableConstants.FLOW_URGENT) + "");
		if (historicProcessInstance.getEndTime() == null) {
			ArrayList<String> distinct = CollectionUtil.distinct(tepIdAll);
			inof.setThisStepId(StringUtils.joinWith(",", distinct));
			List<String> thisName = new ArrayList<>();
			for (String s : distinct) {
				String name = process.getFlowElement(s).getName();
				thisName.add(name);
			}
			inof.setThisStep(StringUtils.join(",", thisName));
		} else {
			inof.setThisStep("结束");
			inof.setThisStepId("end");
		}
		FlowEngineEntity engine = flowEngineService.getInfo(MapUtil.getStr(processVariables, FLOW_ENGINE_ID));
		inof.setAppFormUrl(engine.getAppFormUrl());
		inof.setFormUrl(engine.getFormUrl());
		inof.setType(engine.getType());
		vo.setFlowTaskInfo(inof);
//        //流程经办
		vo.setFlowTaskOperatorList(JsonUtil.getJsonToList(taskOperatorList, FlowTaskOperatorModel.class));
//        //流程引擎
		vo.setFlowFormInfo(globalExPropertyDTO.getFormData());
		return vo;
	}

	// -----------------------------------提交保存--------------------------------------------

	/**
	 * 流程任务赋值
	 *
	 * @param taskEntity 流程任务实例
	 * @param engine     流程引擎实例
	 * @param flowModel  提交数据
	 * @throws WorkFlowException 异常
	 */
	private void task(FlowTaskEntity taskEntity, FlowEngineEntity engine, FlowModel flowModel, String userId)
			throws WorkFlowException {
		if (flowModel.getId() != null && !checkStatus(taskEntity.getStatus())) {
			throw new WorkFlowException("当前流程正在运行不能重复提交");
		}
		// 创建实例
		taskEntity.setId(flowModel.getProcessId());
		taskEntity.setProcessId(flowModel.getProcessId());
		taskEntity.setEnCode(flowModel.getBillNo());
		taskEntity.setFullName(flowModel.getFlowTitle());
		taskEntity.setFlowUrgent(flowModel.getFlowUrgent() != null ? flowModel.getFlowUrgent() : 1);
		taskEntity.setFlowId(engine.getId());
		taskEntity.setFlowCode(engine.getEnCode() != null ? engine.getEnCode() : "单据规则不存在");
		taskEntity.setFlowName(engine.getFullName());
		taskEntity.setFlowType(engine.getType());
		taskEntity.setFlowCategory(engine.getCategory());
		taskEntity.setFlowForm(engine.getFormData());
		taskEntity.setFlowTemplateJson(engine.getFlowTemplateJson());
		taskEntity.setFlowVersion(engine.getVersion());
		taskEntity.setStatus(
				FlowStatusEnum.save.getMessage().equals(flowModel.getStatus()) ? FlowTaskStatusEnum.Draft.getCode()
						: FlowTaskStatusEnum.Handle.getCode());
		taskEntity.setCompletion(0);
		taskEntity.setStartTime(new Date());
		taskEntity.setCreatorTime(new Date());
		taskEntity.setCreatorUserId(userId);
		taskEntity.setFlowFormContentJson(
				flowModel.getFormData() != null ? JsonUtilEx.getObjectToString(flowModel.getFormData()) : "{}");
		taskEntity.setParentId(flowModel.getParentId() != null ? flowModel.getParentId() : "0");
	}

	/**
	 * 验证有效状态
	 *
	 * @param status 状态编码
	 * @return
	 */
	private boolean checkStatus(int status) {
		if (status == FlowTaskStatusEnum.Draft.getCode() || status == FlowTaskStatusEnum.Reject.getCode()
				|| status == FlowTaskStatusEnum.Revoke.getCode()) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 提交节点
	 *
	 * @param dataAll 所有流程节点
	 */
	private void nodeListAll(List<FlowTaskNodeEntity> dataAll) {
		FlowTaskNodeEntity startNodes = dataAll.stream().filter(t -> FlowNature.NodeStart.equals(t.getNodeType()))
				.findFirst().get();
		List<FlowTaskNodeEntity> treeList = new ArrayList<>();
		long num = 1L;
		this.nodeList(dataAll, startNodes.getNodeCode(), treeList, num);
		String nodeNext = FlowNature.NodeEnd;
		String type = "endround";
		long maxNum = 1L;
		for (FlowTaskNodeEntity entity : dataAll) {
			if (StringUtil.isEmpty(entity.getNodeNext())) {
				entity.setNodeNext(nodeNext);
			}
			if (entity.getSortCode() != null && entity.getSortCode() > maxNum) {
				maxNum = entity.getSortCode();
			}
			if (!"timer".equals(entity.getNodeType())) {
				flowTaskNodeService.save(entity);
			}
		}
		FlowTaskNodeEntity endround = new FlowTaskNodeEntity();
		endround.setId(RandomUtil.uuId());
		endround.setNodeCode(nodeNext);
		endround.setNodeName("结束");
		endround.setCompletion(0);
		endround.setCreatorTime(new Date());
		endround.setSortCode(++maxNum);
		endround.setTaskId(startNodes.getTaskId());
		ChildNodeList endNode = JsonUtil.getJsonToBean(startNodes.getNodePropertyJson(), ChildNodeList.class);
		endNode.getCustom().setNodeId(nodeNext);
		endNode.setTaskNodeId(endround.getId());
		endNode.getCustom().setType(type);
		endround.setNodePropertyJson(JsonUtil.getObjectToString(endNode));
		endround.setNodeType(type);
		endround.setState(FlowNodeEnum.Process.getCode());
		flowTaskNodeService.save(endround);
	}

	/**
	 * 递归遍历编码
	 *
	 * @param dataAll  所有节点
	 * @param node     当前节点
	 * @param treeList 保存走过的节点
	 * @param num      排序
	 */
	private void nodeList(List<FlowTaskNodeEntity> dataAll, String node, List<FlowTaskNodeEntity> treeList, long num) {
		List<String> nodeAll = Arrays.asList(node.split(","));
		List<FlowTaskNodeEntity> nodeList = dataAll.stream().filter(t -> nodeAll.contains(t.getNodeCode()))
				.collect(Collectors.toList());
		for (FlowTaskNodeEntity entity : nodeList) {
			entity.setSortCode(num);
			entity.setState(FlowNodeEnum.Process.getCode());
		}
		treeList.addAll(nodeList);
		List<String> nextNode = nodeList.stream().filter(t -> t.getNodeNext() != null).map(t -> t.getNodeNext())
				.collect(Collectors.toList());
		if (nextNode.size() > 0) {
			String nodes = String.join(",", nextNode);
			num++;
			nodeList(dataAll, nodes, treeList, num);
		}
	}

	/**
	 * 创建节点
	 *
	 * @param flowTask
	 * @param nodeListAll
	 * @param conditionListAll
	 * @param taskNodeList
	 */
	private void createNodeList(FlowTaskEntity flowTask, List<ChildNodeList> nodeListAll,
			List<ConditionList> conditionListAll, List<FlowTaskNodeEntity> taskNodeList) {
		List<FlowTaskNodeEntity> timerList = new ArrayList<>();
		List<FlowTaskNodeEntity> emptyList = new ArrayList<>();
		for (ChildNodeList childNode : nodeListAll) {
			FlowTaskNodeEntity taskNode = new FlowTaskNodeEntity();
			String nodeId = childNode.getCustom().getNodeId();
			Properties properties = childNode.getProperties();
			String dataJson = flowTask.getFlowFormContentJson();
			String type = childNode.getCustom().getType();
			taskNode.setId(RandomUtil.uuId());
			childNode.setTaskNodeId(taskNode.getId());
			childNode.setTaskId(flowTask.getId());
			taskNode.setCreatorTime(new Date());
			taskNode.setTaskId(flowTask.getId());
			taskNode.setNodeCode(nodeId);
			taskNode.setNodeType(type);
			taskNode.setState(FlowNodeEnum.Futility.getCode());
			taskNode.setSortCode(-2L);
			taskNode.setNodeUp(properties.getRejectStep());
			taskNode.setNodeNext(FlowJsonUtil.getNextNode(nodeId, dataJson, nodeListAll, conditionListAll));
			taskNode.setNodePropertyJson(JsonUtilEx.getObjectToString(childNode));
			boolean isSstart = FlowNature.NodeStart.equals(childNode.getCustom().getType());
			taskNode.setCompletion(isSstart ? 1 : 0);
			taskNode.setNodeName(isSstart ? "开始" : properties.getTitle());
			taskNodeList.add(taskNode);
			if ("empty".equals(type)) {
				emptyList.add(taskNode);
			}
			if ("timer".equals(type)) {
				timerList.add(taskNode);
			}
		}
		// 指向empty，继续指向下一个节点
		for (FlowTaskNodeEntity empty : emptyList) {
			List<FlowTaskNodeEntity> noxtEmptyList = taskNodeList.stream()
					.filter(t -> t.getNodeNext().contains(empty.getNodeCode())).collect(Collectors.toList());
			for (FlowTaskNodeEntity entity : noxtEmptyList) {
				entity.setNodeNext(empty.getNodeNext());
			}
		}
		// 指向timer，继续指向下一个节点
		for (FlowTaskNodeEntity timer : timerList) {
			// 获取到timer的上一节点
			ChildNodeList timerlList = JsonUtil.getJsonToBean(timer.getNodePropertyJson(), ChildNodeList.class);
			DateProperties timers = timerlList.getTimer();
			timers.setNodeId(timer.getNodeCode());
			timers.setTime(true);
			List<FlowTaskNodeEntity> upEmptyList = taskNodeList.stream()
					.filter(t -> t.getNodeNext().contains(timer.getNodeCode())).collect(Collectors.toList());
			for (FlowTaskNodeEntity entity : upEmptyList) {
				// 上一节点赋值timer的属性
				ChildNodeList modelList = JsonUtil.getJsonToBean(entity.getNodePropertyJson(), ChildNodeList.class);
				modelList.setTimer(timers);
				entity.setNodeNext(timer.getNodeNext());
				entity.setNodePropertyJson(JsonUtilEx.getObjectToString(modelList));
			}
		}
	}

	// -------------------------审批--------------------------------
	// ---------通过-------------

	/**
	 * 统计当前节点总人数
	 *
	 * @param nodeIdAll     子流程关联的id
	 * @param taskNodeList 所有节点
	 * @param operatorList 节点的审批人
	 */
	private void totalAll(Map<String, List<String>> nodeIdAll, List<FlowTaskOperatorEntity> operatorList,
			List<FlowTaskNodeEntity> taskNodeList) {
		// 更新关联子流程id
		for (String nodeId : nodeIdAll.keySet()) {
			FlowTaskNodeEntity entity = flowTaskNodeService.getInfo(nodeId);
			if (entity != null) {
				ChildNodeList childNodeList = JsonUtil.getJsonToBean(entity.getNodePropertyJson(), ChildNodeList.class);
				childNodeList.getCustom().setTaskId(nodeIdAll.get(nodeId));
				entity.setNodePropertyJson(JsonUtil.getObjectToString(childNodeList));
				flowTaskNodeService.update(entity);
			}
		}
		// 统计当前节点总人数
		Map<String, Long> countAll = operatorList.stream()
				.collect(Collectors.groupingBy(FlowTaskOperatorEntity::getTaskNodeId, Collectors.counting()));
		for (String key : countAll.keySet()) {
			FlowTaskNodeEntity entity = taskNodeList.stream().filter(t -> t.getId().equals(key)).findFirst()
					.orElse(null);
			if (entity != null) {
				ChildNodeList childNodeList = JsonUtil.getJsonToBean(entity.getNodePropertyJson(), ChildNodeList.class);
				childNodeList.setTotal((double) countAll.get(key));
				entity.setNodePropertyJson(JsonUtil.getObjectToString(childNodeList));
				flowTaskNodeService.update(entity);
			}
		}
	}

	/**
	 * 下一审批人
	 *
	 * @param operatorListAll 审批人数据
	 * @param nodeList        下一审批的数据
	 * @param taskEntity      引擎实例
	 * @param flowModel       提交数据
	 * @throws WorkFlowException 异常
	 */
	private Map<String, List<String>> nextOperator(List<FlowTaskOperatorEntity> operatorListAll,
			List<ChildNodeList> nodeList, FlowTaskEntity taskEntity, FlowModel flowModel) throws WorkFlowException {
		Map<String, List<String>> taskNode = new HashMap<>(16);
		try {
			List<UserEntity> userList = userService.getList();
			// 查询审批人
			for (ChildNodeList childNode : nodeList) {
				List<FlowTaskOperatorEntity> operatorList = new ArrayList<>();
				Custom custom = childNode.getCustom();
				Properties properties = childNode.getProperties();
				String type = custom.getType();
				String flowId = properties.getFlowId();
				List<FlowAssignModel> assignList = childNode.getProperties().getAssignList();
				// 判断是否超时
				TimeOutConfig config = properties.getTimeoutConfig();
				// 判断子流程
				boolean isChild = FlowNature.NodeSubFlow.equals(type);
				if (isChild) {
					// 判断当前流程引擎类型
					FlowEngineEntity parentEngine = flowEngineService.getInfo(taskEntity.getFlowId());
					boolean isCustom = FlowNature.CUSTOM.equals(parentEngine.getFormType());
					List<String> taskNodeList = new ArrayList<>();
					FlowEngineEntity engine = flowEngineService.getInfo(flowId);
					// 创建子流程
					Map<String, Object> data = this.childData(engine, flowModel, assignList, isCustom);
					data.put("flowId", flowId);
					// 子节点审批人
					List<String> list = this.childSaveList(childNode, taskEntity, userList);
					for (String id : list) {
						UserEntity userEntity = userList.stream().filter(t -> t.getId().equals(id)).findFirst()
								.orElse(null);
						String title = userEntity.getRealName() + "的" + engine.getFullName() + "(子流程)";
						FlowModel nextFlowModel = this.assignment(data, parentEngine, taskEntity.getId(), title);
						nextFlowModel.setUserId(id);
						nextFlowModel.setFlowTitle(title);
						nextFlowModel.setFormData(data);
						nextFlowModel.setFlowId(engine.getId());
//                        FlowTaskEntity childTaskEntity = this.save(nextFlowModel);
//                        this.createData(engine, childTaskEntity, nextFlowModel);
						taskNodeList.add(nextFlowModel.getProcessId());
					}
					taskNode.put(childNode.getTaskNodeId(), taskNodeList);
				} else {
					if (!FlowNature.NodeEnd.equals(childNode.getCustom().getNodeId())) {
						// 审批人
						this.operator(childNode, operatorList, taskEntity, flowModel, userList, true);
					}
				}
				operatorListAll.addAll(operatorList);
			}
		} catch (WorkFlowException e) {
			throw new WorkFlowException(e.getMessage());
		}
		return taskNode;
	}

	/**
	 * 审批人
	 *
	 * @param childNode    当前节点数据
	 * @param operatorList 审批人所有数据
	 * @param taskEntity   引擎实例
	 * @param flowModel    提交数据
	 * @param details      true记录 false不记录
	 * @throws WorkFlowException 异常
	 */
	private void operator(ChildNodeList childNode, List<FlowTaskOperatorEntity> operatorList, FlowTaskEntity taskEntity,
			FlowModel flowModel, List<UserEntity> userList, boolean details) {
		String createUserId = taskEntity.getCreatorUserId();
		Date date = new Date();
		List<FlowTaskOperatorEntity> nextList = new ArrayList<>();
		Properties properties = childNode.getProperties();
		String type = properties.getAssigneeType();
		String userId = "";
		String freeApproverUserId = flowModel.getFreeApproverUserId();
		// 【加签】
		if (StringUtil.isNotEmpty(freeApproverUserId)) {
			this.operatorUser(nextList, freeApproverUserId, date, childNode, true);
			// 加签记录
			if (details) {
				UserInfo userInfo = userProvider.get();
				Custom custom = childNode.getCustom();
				FlowTaskOperatorRecordEntity operatorRecord = new FlowTaskOperatorRecordEntity();
				FlowTaskOperatorEntity operator = new FlowTaskOperatorEntity();
				operator.setTaskId(childNode.getTaskId());
				operator.setNodeCode(custom.getNodeId());
				operator.setNodeName(properties.getTitle());
				// 审批数据赋值
				FlowOperatordModel flowOperatordModel = new FlowOperatordModel();
				flowOperatordModel.setStatus(FlowRecordEnum.copyId.getCode());
				flowOperatordModel.setFlowModel(flowModel);
				flowOperatordModel.setUserId(userInfo.getUserId());
				flowOperatordModel.setOperator(operator);
				flowOperatordModel.setOperatorId(freeApproverUserId);
				this.operatorRecord(operatorRecord, flowOperatordModel);
				flowTaskOperatorRecordService.create(operatorRecord);
			}
		} else {
			// 发起者【发起者主管】
			if (FlowTaskOperatorEnum.LaunchCharge.getCode().equals(type)) {
				// 时时查用户主管
				UserEntity info = userService.getInfo(createUserId);
				if (info != null) {
					userId = getManagerByLevel(info.getManagerId(), properties.getManagerLevel(), userList);
					this.operatorUser(nextList, userId, date, childNode);
				}
			}
			// 发起者【部门主管】
			if (FlowTaskOperatorEnum.DepartmentCharge.getCode().equals(type)) {
				UserEntity userEntity = userService.getInfo(createUserId);
				OrganizeEntity organizeEntity = organizeService
						.getInfo(userEntity != null ? userEntity.getOrganizeId() : "");
				if (organizeEntity != null) {
					userId = organizeEntity.getManager();
					this.operatorUser(nextList, userId, date, childNode);
				}
			}
			// 发起者【发起本人】
			if (FlowTaskOperatorEnum.InitiatorMe.getCode().equals(type)) {
				this.operatorUser(nextList, createUserId, date, childNode);
			}
			// 【环节】
			if (FlowTaskOperatorEnum.Tache.getCode().equals(type)) {
				List<FlowTaskOperatorRecordEntity> operatorUserList = flowTaskOperatorRecordService
						.getList(taskEntity.getId()).stream()
						.filter(t -> properties.getNodeId().equals(t.getNodeCode())
								&& FlowRecordEnum.audit.getCode().equals(t.getHandleStatus())
								&& FlowNodeEnum.Process.getCode().equals(t.getStatus()))
						.collect(Collectors.toList());
				if (operatorUserList.size() > 0) {
					for (FlowTaskOperatorRecordEntity entity : operatorUserList) {
						this.operatorUser(nextList, entity.getHandleId(), date, childNode);
					}
				}
			}
			// 【变量】
			if (FlowTaskOperatorEnum.Variate.getCode().equals(type)) {
				Map<String, Object> dataAll = JsonUtil.stringToMap(taskEntity.getFlowFormContentJson());
				Object data = dataAll.get(properties.getFormField());
				if (data != null) {
					List<String> handleId = Arrays.asList(String.valueOf(data).split(","));
					List<String> userAll = userList.stream().filter(t -> handleId.contains(t.getId()))
							.map(t -> t.getId()).collect(Collectors.toList());
					for (String user : userAll) {
						this.operatorUser(nextList, user, date, childNode);
					}
				}
			}
			// 【服务】
			if (FlowTaskOperatorEnum.Serve.getCode().equals(type)) {
				String url = properties.getGetUserUrl();
				String token = UserProvider.getToken();
				JSONObject object = HttpUtil.httpRequest(url, "GET", null, token);
				if (object != null) {
					if (object.get("data") != null) {
						JSONObject data = object.getJSONObject("data");
						List<String> handleId = StringUtil.isNotEmpty(data.getString("handleId"))
								? Arrays.asList(data.getString("handleId").split(","))
								: new ArrayList<>();
						List<String> userAll = userList.stream().filter(t -> handleId.contains(t.getId()))
								.map(t -> t.getId()).collect(Collectors.toList());
						for (String user : userAll) {
							this.operatorUser(nextList, user, date, childNode);
						}
					}
				}
			}
			// 发起者【指定用户】
			for (String userIdAll : properties.getApprovers()) {
				this.operatorUser(nextList, userIdAll, date, childNode);
			}
			// 发起者【指定岗位】
			List<String> positionList = properties.getApproverPos();
			// 发起者【指定角色】
			List<String> roleList = properties.getApproverRole();
			List<String> list = new ArrayList<>();
			list.addAll(positionList);
			list.addAll(roleList);
			List<UserRelationEntity> listByObjectIdAll = userRelationService.getListByObjectIdAll(list);
			List<String> userPosition = listByObjectIdAll.stream().map(t -> t.getUserId()).collect(Collectors.toList());
			this.getApproverUser(userPosition, nextList, childNode);
		}
		if (nextList.size() == 0) {
			this.operatorUser(nextList, user, date, childNode);
		}
		operatorList.addAll(nextList);
	}

	/**
	 * 递归主管
	 *
	 * @param managerId 主管id
	 * @param level     第几级
	 * @return
	 */
	private static String getManagerByLevel(String managerId, long level, List<UserEntity> userList) {
		--level;
		if (level == 0) {
			return managerId;
		} else {
			UserEntity userEntity = userList.stream().filter(t -> t.getId().equals(managerId)).findFirst().orElse(null);
			return userEntity != null ? getManagerByLevel(userEntity.getManagerId(), level, userList) : "";
		}
	}

	/**
	 * 封装审批人
	 *
	 * @param nextList  所有审批人数据
	 * @param handLeId  审批人id
	 * @param date      审批日期
	 * @param childNode 当前节点数据
	 */
	private void operatorUser(List<FlowTaskOperatorEntity> nextList, String handLeId, Date date,
			ChildNodeList childNode) {
		this.operatorUser(nextList, handLeId, date, childNode, false);
	}

	/**
	 * 封装审批人
	 *
	 * @param nextList  所有审批人数据
	 * @param handLeId  审批人id
	 * @param date      审批日期
	 * @param childNode 当前节点数据
	 * @param isStatus  是否加签人
	 */
	private void operatorUser(List<FlowTaskOperatorEntity> nextList, String handLeId, Date date,
			ChildNodeList childNode, boolean isStatus) {
		Properties properties = childNode.getProperties();
		Custom custom = childNode.getCustom();
		String type = properties.getAssigneeType();
		FlowTaskOperatorEntity operator = new FlowTaskOperatorEntity();
		operator.setId(RandomUtil.uuId());
		operator.setHandleType(isStatus ? FlowTaskOperatorEnum.FreeApprover.getCode() : type);
		operator.setHandleId(StringUtil.isEmpty(handLeId) ? user : handLeId);
		operator.setTaskNodeId(childNode.getTaskNodeId());
		operator.setTaskId(childNode.getTaskId());
		operator.setNodeCode(custom.getNodeId());
		operator.setNodeName(properties.getTitle());
		operator.setDescription(JsonUtil.getObjectToString(new ArrayList<>()));
		operator.setCreatorTime(date);
		operator.setCompletion(0);
		operator.setType(type);
		operator.setState(FlowNodeEnum.Process.getCode());
		nextList.add(operator);
	}

	/**
	 * 用户是否重复
	 *
	 * @param userPosition 审批人
	 * @param operatorList 经办的数据
	 * @param childNode    节点数据
	 */
	private void getApproverUser(List<String> userPosition, List<FlowTaskOperatorEntity> operatorList,
			ChildNodeList childNode) {
		Date date = new Date();
		for (String user : userPosition) {
			// 判断是否有添加这个人
			if (operatorList.stream().filter(t -> t.getHandleId().equals(user)).count() == 0) {
				this.operatorUser(operatorList, user, date, childNode);
			}
		}
	}

	/**
	 * 更新经办数据
	 *
	 * @param status       审批类型（0：拒绝，1：同意）
	 * @param nodeModel    当前节点属性
	 * @param operator     当前经办
	 * @param userInfo     用户
	 * @param taskNodeList 节点list
	 */
	private void handleIdStatus(int status, ChildNodeList nodeModel, FlowTaskOperatorEntity operator, UserInfo userInfo,
			List<FlowTaskNodeEntity> taskNodeList) {
		Properties properties = nodeModel.getProperties();
		Integer counterSign = properties.getCounterSign();
		operator.setHandleTime(new Date());
		operator.setHandleStatus(status);
		String type = properties.getAssigneeType();
		boolean isApprover = FlowNature.FixedJointlyApprover.equals(counterSign);
		// 更新委托的id
		List<String> userIdListAll = new ArrayList<>();
		// 审核自己的话，更新委托人，不是审核自己的话，不更新自己
		if (userInfo.getUserId().equals(operator.getHandleId())) {
			List<String> userList = flowDelegateService.getUser(userInfo.getUserId()).stream()
					.map(t -> t.getCreatorUserId()).collect(Collectors.toList());
			userIdListAll.addAll(userList);
		}
		if (status == 1) {
			if (isApprover) {
				// 更新会签都改成完成
				flowTaskOperatorService.update(operator.getTaskNodeId(), userIdListAll, "1");
			} else {
				// 更新或签都改成完成
				flowTaskOperatorService.update(operator.getTaskNodeId(), type);
			}
			operator.setCompletion(1);
			// 修改当前审批的定时器
			List<Date> list = JsonUtil.getJsonToList(operator.getDescription(), Date.class);
			DateProperties timer = nodeModel.getTimer();
			if (timer.getTime()) {
				Date date = new Date();
				date = DateUtil.dateAddDays(date, timer.getDay());
				date = DateUtil.dateAddHours(date, timer.getHour());
				date = DateUtil.dateAddMinutes(date, timer.getMinute());
				date = DateUtil.dateAddSeconds(date, timer.getSecond());
				list.add(date);
				operator.setDescription(JsonUtil.getObjectToString(list));
			}
		} else {
			if (isApprover) {
				// 更新会签都改成完成
				flowTaskOperatorService.update(operator.getTaskNodeId(), userIdListAll, "-1");
			} else {
				// 更新或签都改成完成
				flowTaskOperatorService.update(operator.getTaskNodeId(), type);
			}
			operator.setCompletion(-1);
			operator.setState(FlowNodeEnum.Futility.getCode());
		}
	}

	/**
	 * 判断是否进行下一步
	 *
	 * @param nodeListAll    所有节点
	 * @param nextNodeEntity 下一节点
	 * @param taskNode       当前节点
	 * @param flowModel      提交数据
	 * @return
	 */
	private List<FlowTaskNodeEntity> isNextAll(List<FlowTaskNodeEntity> nodeListAll,
			List<FlowTaskNodeEntity> nextNodeEntity, FlowTaskNodeEntity taskNode, FlowModel flowModel) {
		// 1.先看是否加签人，有都不要进行，无进行下一步
		// 2.判断会签是否比例通过
		// 3.判断分流是否都结束
		// 4.判断审批人是否都通过
		List<FlowTaskNodeEntity> result = new ArrayList<>();
		boolean hasFreeApprover = StringUtil.isNotEmpty(flowModel.getFreeApproverUserId());
		if (hasFreeApprover) {
			result.add(taskNode);
			// 加签记录
		} else {
			ChildNodeList nodeModel = JsonUtil.getJsonToBean(taskNode.getNodePropertyJson(), ChildNodeList.class);
			Properties properties = nodeModel.getProperties();
			// 会签通过
			boolean isCountersign = true;
			boolean fixed = FlowNature.FixedJointlyApprover.equals(properties.getCounterSign());
			long pass = properties.getCountersignRatio();
			String type = properties.getAssigneeType();
			// 判断是否是会签
			if (fixed) {
				List<FlowTaskOperatorEntity> operatorList = flowTaskOperatorService.getList(taskNode.getTaskId())
						.stream().filter(t -> t.getTaskNodeId().equals(taskNode.getId())
								&& FlowNodeEnum.Process.getCode().equals(t.getState()))
						.collect(Collectors.toList());
				double total = operatorList.size();
				double passNum = operatorList.stream().filter(t -> t.getCompletion() == 1).count();
				isCountersign = this.isCountersign(pass, total, passNum);
			}
			// 流程通过
			if (isCountersign) {
				// 会签通过更新未审批用户
				if (fixed) {
					flowTaskOperatorService.update(nodeModel.getTaskNodeId(), type);
				}
				taskNode.setCompletion(1);
				// 跟新审批状态
				flowTaskNodeService.update(taskNode);
				// 分流通过
				boolean isShunt = this.isShunt(nodeListAll, nextNodeEntity, taskNode);
				if (isShunt) {
					result.addAll(nextNodeEntity);
				}
			}
		}
		return result;
	}

	/**
	 * 会签比例
	 *
	 * @param pass    比例
	 * @param total   总数
	 * @param passNum 数量
	 * @return
	 */
	private boolean isCountersign(long pass, double total, double passNum) {
		int scale = (int) (passNum / total * 100);
		return scale >= pass;
	}

	/**
	 * 判断分流是否结束
	 *
	 * @param nodeListAll    所有节点
	 * @param nextNodeEntity 下一节点
	 * @param taskNode       单前节点
	 * @return
	 */
	private boolean isShunt(List<FlowTaskNodeEntity> nodeListAll, List<FlowTaskNodeEntity> nextNodeEntity,
			FlowTaskNodeEntity taskNode) {
		boolean isNext = true;
		for (FlowTaskNodeEntity nodeEntity : nextNodeEntity) {
			String nextNode = nodeEntity.getNodeCode();
			List<FlowTaskNodeEntity> interflowAll = nodeListAll.stream()
					.filter(t -> String.valueOf(t.getNodeNext()).contains(nextNode)
							&& FlowNodeEnum.Process.getCode().equals(t.getState()))
					.collect(Collectors.toList());
			List<FlowTaskNodeEntity> flowAll = interflowAll.stream().filter(t -> t.getCompletion() != 1)
					.collect(Collectors.toList());
			if (flowAll.size() > 0) {
				isNext = false;
				break;
			}
		}
		return isNext;
	}

	/**
	 * 判断传阅用户是否存在指定用户
	 *
	 * @param userPosition  获取岗位岗位下的人
	 * @param circulateList 经办的数据
	 * @param nodeModel     节点数据
	 */
	private void getCirculateUser(List<String> userPosition, List<FlowTaskCirculateEntity> circulateList,
			ChildNodeList nodeModel) {
		for (String user : userPosition) {
			// 判断是否有添加这个人
			if (circulateList.stream().filter(t -> t.getObjectId().equals(user)).count() == 0) {
				FlowTaskCirculateEntity flowTask = new FlowTaskCirculateEntity();
				flowTask.setId(RandomUtil.uuId());
				flowTask.setObjectId(user);
				flowTask.setNodeCode(nodeModel.getCustom().getNodeId());
				flowTask.setNodeName(nodeModel.getProperties().getTitle());
				flowTask.setTaskNodeId(nodeModel.getTaskNodeId());
				flowTask.setTaskId(nodeModel.getTaskId());
				flowTask.setCreatorTime(new Date());
				circulateList.add(flowTask);
			}
		}
	}

	/**
	 * 抄送人
	 *
	 * @param nodeModel     当前json对象
	 * @param circulateList 抄送list
	 * @param flowModel     提交数据
	 */
	private void circulateList(List<FlowTaskCirculateEntity> circulateList, FlowModel flowModel, Task task) {
		List<String> userIds = new ArrayList<>();
		// 指定传阅人
		String[] copyIds = StringUtil.isNotEmpty(flowModel.getCopyIds()) ? flowModel.getCopyIds().split(",")
				: new String[] {};
		List<String> id = Arrays.asList(copyIds);
		userIds.addAll(id);
		for (String userId : userIds) {
			FlowTaskCirculateEntity flowTask = new FlowTaskCirculateEntity();
			flowTask.setId(RandomUtil.uuId());
			flowTask.setObjectId(userId);
			flowTask.setNodeCode(task.getTaskDefinitionKey());
			flowTask.setNodeName(task.getName());
			flowTask.setTaskNodeId(task.getId());
			flowTask.setTaskId(task.getProcessInstanceId());
			flowTask.setCreatorTime(new Date());
			Map<String, Object> variables = task.getProcessVariables();
			flowTask.setEnCode(MapUtil.getStr(variables, BILL_CODE));
			flowTask.setFullName(MapUtil.getStr(variables, BUSINESS_TITLE));
			flowTask.setFlowId(MapUtil.getStr(variables, FLOW_ENGINE_ID));
			flowTask.setFlowCategory(MapUtil.getStr(variables, PROCESS_CATEGORY));
			flowTask.setUpdateTime(new Date());
			flowTask.setCreateUserId(MapUtil.getStr(variables, APPLY_USER_ID));
			circulateList.add(flowTask);
		}
	}

	/**
	 * 流程任务结束
	 *
	 * @param flowTask 流程任务
	 */
	private boolean endround(FlowTaskEntity flowTask, ChildNodeList childNode) throws WorkFlowException {
		flowTask.setStatus(FlowTaskStatusEnum.Adopt.getCode());
		flowTask.setCompletion(100);
		flowTask.setEndTime(DateUtil.getNowDate());
		flowTask.setThisStepId(FlowNature.NodeEnd);
		flowTask.setThisStep("结束");
		// 结束事件
		FlowTaskOperatorRecordEntity operatorRecord = new FlowTaskOperatorRecordEntity();
		operatorRecord.setTaskId(flowTask.getId());
		operatorRecord.setHandleStatus(flowTask.getStatus());
		this.event(FlowRecordEnum.end.getCode(), childNode, operatorRecord);
		// 子流程结束，触发主流程
		boolean isEnd = this.isNext(flowTask);
		return isEnd;
	}

	// ---------------拒绝-------------------

	/**
	 * 审批驳回节点
	 *
	 * @param nodeListAll 所有节点
	 * @param taskNode    审批节点
	 * @return
	 */
	private List<FlowTaskNodeEntity> isUpAll(List<FlowTaskNodeEntity> nodeListAll, FlowTaskNodeEntity taskNode,
			boolean isUp) throws WorkFlowException {
		List<FlowTaskNodeEntity> result = new ArrayList<>();
		if (isUp) {
			if (FlowNature.START.equals(taskNode.getNodeUp())) {
				List<FlowTaskNodeEntity> startNode = nodeListAll.stream()
						.filter(t -> FlowNature.NodeStart.equals(t.getNodeType())).collect(Collectors.toList());
				result.addAll(startNode);
			} else {
				List<FlowTaskNodeEntity> taskNodeList = nodeListAll.stream()
						.filter(t -> t.getNodeCode().equals(taskNode.getNodeUp())).collect(Collectors.toList());
				if (taskNodeList.size() == 0) {
					taskNodeList = nodeListAll
							.stream().filter(t -> t.getNodeNext() != null
									&& t.getNodeNext().contains(taskNode.getNodeCode()) && "0".equals(t.getState()))
							.collect(Collectors.toList());
				}
				result.addAll(taskNodeList);
			}
			boolean isChild = result.stream().filter(t -> FlowNature.NodeSubFlow.equals(t.getNodeType())).count() > 0;
			if (isChild) {
				throw new WorkFlowException("驳回节点不能是子流程");
			}
		}
		return result;
	}

	/**
	 * 拒绝比例
	 *
	 * @param taskNode 节点实体
	 * @return
	 */
	private boolean isReject(FlowTaskNodeEntity taskNode) {
		List<FlowTaskOperatorEntity> operatorList = flowTaskOperatorService.getList(taskNode.getTaskId()).stream()
				.filter(t -> t.getTaskNodeId().equals(taskNode.getId())).collect(Collectors.toList());
		ChildNodeList nodeModel = JsonUtil.getJsonToBean(taskNode.getNodePropertyJson(), ChildNodeList.class);
		Properties properties = nodeModel.getProperties();
		long pass = 100 - properties.getCountersignRatio();
		double total = operatorList.size();
		double passNum = operatorList.stream().filter(t -> t.getCompletion() == -1).count();
		boolean isCountersign = this.isCountersign(pass, total, passNum);
		return isCountersign;
	}

	// -----------------------子节点---------------------------------

	/**
	 * 插入数据
	 *
	 * @param engine    引擎
	 * @param flowModel 提交数据
	 */
	private Map<String, Object> createData(FlowEngineEntity engine, FlowTaskEntity taskEntity, FlowModel flowModel)
			throws WorkFlowException {
		Map<String, Object> resultData = new HashMap<>(16);
		try {
			Map<String, Object> data = flowModel.getFormData();
			if (FlowNature.CUSTOM.equals(engine.getFormType())) {
				List<FlowTableModel> tableList = JsonUtil.getJsonToList(engine.getTables(), FlowTableModel.class);
				// 获取属性
				DbLinkEntity dbLink = null;
				if (StringUtil.isNotEmpty(engine.getDbLinkId())) {
					dbLink = dblinkService.getInfo(engine.getDbLinkId());
				}
				FormDataModel formData = JsonUtil.getJsonToBean(taskEntity.getFlowForm(), FormDataModel.class);
				List<FieldsModel> list = JsonUtil.getJsonToList(formData.getFields(), FieldsModel.class);
				if (StringUtil.isNotEmpty(flowModel.getId())) {
					// 更新
					resultData = flowDataUtil.update(data, list, tableList, taskEntity.getProcessId(), dbLink);
				} else {
					// 新增
					resultData = flowDataUtil.create(data, list, tableList, taskEntity.getProcessId(),
							new HashMap<>(16), dbLink);
				}

				FormDataInfo formDataInfo = new FormDataInfo();
				formDataInfo.setFormDataJson(JsonUtil.getObjectToString(resultData));

				Map<String, Object> variablesMap = new HashMap<>();
				HashMap<String, Object> sequenceFlowConditionMap = new HashMap<>();
				variablesMap.put(FORM_INFO_JSON, formDataInfo);
				Set<String> fieldSet = taskEntity.getFieldSet();
				if (fieldSet != null && !fieldSet.isEmpty()) {
					Set<String> set = resultData.keySet();
					Collection<String> intersection = CollectionUtil.intersection(set, fieldSet);
					for (String s : set) {
						if (CollectionUtil.contains(intersection, s)) {
							sequenceFlowConditionMap.put(s, resultData.get(s));
						}
					}
					// 需要进行条件判断的字段放入流程变量
					variablesMap.putAll(sequenceFlowConditionMap);
				}

				runtimeService.setVariables(taskEntity.getProcessInstanceId(), variablesMap);

			} else {
				// 系统表单
				String dataAll = JsonUtil.getObjectToString(data);
				if (engine.getType() != 1) {
					String coed = engine.getEnCode();
					this.formData(coed, flowModel.getProcessId(), dataAll);

					Map<String, Object> variablesMap = new HashMap<>();
					FormDataInfo formDataInfo = new FormDataInfo();
					formDataInfo.setFormDataJson(dataAll);
					variablesMap.put(FORM_INFO_JSON, formDataInfo);
					HashMap<String, Object> sequenceFlowConditionMap = new HashMap<>();
					Set<String> fieldSet = taskEntity.getFieldSet();
					if (fieldSet != null && !fieldSet.isEmpty()) {
						Set<String> set = data.keySet();
						Collection<String> intersection = CollectionUtil.intersection(set, fieldSet);
						for (String s : set) {
							if (CollectionUtil.contains(intersection, s)) {
								sequenceFlowConditionMap.put(s, data.get(s));
							}
						}
						// 需要进行条件判断的字段放入流程变量
						variablesMap.putAll(sequenceFlowConditionMap);
					}
					runtimeService.setVariables(taskEntity.getProcessInstanceId(), variablesMap);

				}
			}
		} catch (Exception e) {
			throw new WorkFlowException("新增数据失败");
		}
		return resultData;
	}

	/**
	 * 判断子流程是否全部走完，进行主流程任务
	 *
	 * @param flowTask 子流程任务
	 * @throws WorkFlowException
	 */
	private boolean isNext(FlowTaskEntity flowTask) throws WorkFlowException {
		boolean isEnd = true;
		// 子流程结束，触发主流程
		if (!FlowNature.ParentId.equals(flowTask.getParentId()) && StringUtil.isNotEmpty(flowTask.getParentId())) {
			isEnd = false;
			List<FlowTaskEntity> parentList = flowTaskService.getChildList(flowTask.getParentId());
			// 判断子流程排除自己，判断其他子流程是否都完成
			boolean isNext = parentList.stream().filter(t -> !t.getId().equals(flowTask.getId())
					&& !FlowTaskStatusEnum.Adopt.getCode().equals(flowTask.getStatus())).count() == 0;
			if (isNext) {
				FlowTaskEntity parent = flowTaskService.getInfo(flowTask.getParentId());
				List<FlowTaskNodeEntity> parentNodeAll = flowTaskNodeService.getList(parent.getId());
				FlowTaskOperatorEntity parentOperator = new FlowTaskOperatorEntity();
				boolean isNode = true;
				for (FlowTaskNodeEntity nodeEntity : parentNodeAll) {
					ChildNodeList parentNode = JsonUtil.getJsonToBean(nodeEntity.getNodePropertyJson(),
							ChildNodeList.class);
					isNode = parentNode.getCustom().getTaskId().stream().filter(t -> flowTask.getId().equals(t))
							.count() > 0;
					if (isNode) {
						parentOperator.setTaskNodeId(nodeEntity.getId());
						parentOperator.setDescription(JsonUtil.getObjectToString(new ArrayList<>()));
						parentOperator.setNodeCode(nodeEntity.getNodeCode());
						parentOperator.setNodeName(nodeEntity.getNodeName());
						parentOperator.setTaskId(nodeEntity.getTaskId());
						parentOperator.setCompletion(0);
						break;
					}
				}
				FlowModel parentModel = new FlowModel();
				parentModel.setUserId("");
				Map<String, Object> data = new HashMap<>(16);
				parentModel.setFormData(data);
				if (isNode) {
//                    this.audit(parent, parentOperator, parentModel);
				}
			}
		}
		return isEnd;
	}

	/**
	 * 子节点审批人
	 *
	 * @param childNode
	 * @param taskEntity
	 * @return
	 */
	private List<String> childSaveList(ChildNodeList childNode, FlowTaskEntity taskEntity, List<UserEntity> userList) {
		String createUserId = taskEntity.getCreatorUserId();
		Properties properties = childNode.getProperties();
		String type = properties.getInitiateType();
		List<FlowTaskOperatorEntity> nextList = new ArrayList<>();
		String userId = "";
		Date date = new Date();
		// 子节点部门主管
		if (FlowTaskOperatorEnum.ChildDepartmentCharge.getCode().equals(type)) {
			UserEntity userEntity = userService.getInfo(createUserId);
			OrganizeEntity organizeEntity = organizeService
					.getInfo(userEntity != null ? userEntity.getOrganizeId() : "");
			if (organizeEntity != null) {
				userId = organizeEntity.getManager();
				this.operatorUser(nextList, userId, date, childNode);
			}
		}
		// 子节点发起者主管
		if (FlowTaskOperatorEnum.ChildLaunchCharge.getCode().equals(type)) {
			// 时时查用户主管
			UserEntity info = userService.getInfo(createUserId);
			if (info != null) {
				userId = getManagerByLevel(info.getManagerId(), properties.getManagerLevel(), userList);
				this.operatorUser(nextList, userId, date, childNode);
			}
		}
		// 子节点发起者本人
		if (FlowTaskOperatorEnum.ChildInitiatorMe.getCode().equals(type)) {
			this.operatorUser(nextList, createUserId, date, childNode);
		}
		// 发起者【指定用户】
		for (String userIdAll : properties.getInitiator()) {
			this.operatorUser(nextList, userIdAll, date, childNode);
		}
		// 发起者【指定岗位】
		List<String> positionList = properties.getInitiatePos();
		// 发起者【指定角色】
		List<String> roleList = properties.getInitiateRole();
		List<String> list = new ArrayList<>();
		list.addAll(positionList);
		list.addAll(roleList);
		List<UserRelationEntity> listByObjectIdAll = userRelationService.getListByObjectIdAll(list);
		List<String> userPosition = listByObjectIdAll.stream().map(t -> t.getUserId()).collect(Collectors.toList());
		this.getApproverUser(userPosition, nextList, childNode);
		List<String> result = nextList.stream().map(t -> t.getHandleId()).collect(Collectors.toList());
		if (result.size() == 0) {
			result.add(user);
		}
		return result;
	}

	/**
	 * 赋值
	 *
	 * @param data     数据
	 * @param engine   引擎
	 * @param parentId 上一节点
	 * @return
	 */
	private FlowModel assignment(Map<String, Object> data, FlowEngineEntity engine, String parentId, String title) {
		FlowModel flowModel = new FlowModel();
		String billNo = "单据规则不存在";
		if (FlowNature.CUSTOM.equals(engine.getFormType())) {
			FormDataModel formData = JsonUtil.getJsonToBean(engine.getFormData(), FormDataModel.class);
			List<FieldsModel> list = JsonUtil.getJsonToList(formData.getFields(), FieldsModel.class);
			List<FormAllModel> formAllModel = new ArrayList<>();
			FormCloumnUtil.recursionForm(list, formAllModel);
			List<FormAllModel> mastForm = formAllModel.stream()
					.filter(t -> FormEnum.mast.getMessage().equals(t.getJnpfKey())).collect(Collectors.toList());
			FormAllModel formModel = mastForm.stream()
					.filter(t -> JnpfKeyConsts.BILLRULE
							.equals(t.getFormColumnModel().getFieLdsModel().getConfig().getJnpfKey()))
					.findFirst().orElse(null);
			try {
				if (flowModel != null) {
					FieldsModel fieLdsModel = formModel.getFormColumnModel().getFieLdsModel();
					String ruleKey = fieLdsModel.getConfig().getRule();
					billNo = billRuleService.getBillNumber(ruleKey, false);
				}
			} catch (Exception e) {

			}
		}
		flowModel.setFormData(data);
		flowModel.setParentId(parentId);
		flowModel.setProcessId(RandomUtil.uuId());
		flowModel.setBillNo(billNo);
		flowModel.setFlowTitle(title);
		return flowModel;
	}

	/**
	 * 子表表单赋值
	 *
	 * @param engine     子表引擎
	 * @param flowModel  提交数据
	 * @param assignList 数据传递
	 * @param isCustom   true自定义表单 false系统表单
	 * @return
	 */
	private Map<String, Object> childData(FlowEngineEntity engine, FlowModel flowModel,
			List<FlowAssignModel> assignList, boolean isCustom) {
		Map<String, Object> result = new HashMap<>(16);
		if (engine != null) {
			Map<String, Object> formData = flowModel.getFormData();
			for (FlowAssignModel assignMode : assignList) {
				String childField = assignMode.getChildField();
				String parentField = assignMode.getParentField();
				result.put(childField, formData.get(parentField));
			}
		}
		return result;
	}

	/**
	 * 递归删除子流程任务
	 *
	 * @param task 父节点流程任务
	 */
	private void delChild(FlowTaskEntity task) {
		List<FlowTaskEntity> childTaskList = flowTaskService.getChildList(task.getId());
		for (FlowTaskEntity flowTask : childTaskList) {
			// 删除子流程
			flowTaskService.deleteChild(flowTask);
			this.delChild(flowTask);
		}
	}

	// ---------------------公共方法--------------------------

	/**
	 * 事件处理
	 *
	 * @param status    事件状态
	 * @param childNode 节点数据
	 * @param record    审批数据
	 */
	private void event(Integer status, ChildNodeList childNode, FlowTaskOperatorRecordEntity record) {
		boolean flag = false;
		String faceUrl = "";
		// 属性
		if (childNode != null) {
			Properties properties = childNode.getProperties();
			if (FlowRecordEnum.audit.getCode().equals(status) || FlowRecordEnum.reject.getCode().equals(status)) {
				flag = properties.getHasApproverfunc() != null ? properties.getHasApproverfunc() : false;
				faceUrl = properties.getApproverInterfaceUrl() + "?" + taskNodeId + "=" + record.getTaskNodeId() + "&"
						+ handleStatus + "=" + record.getHandleStatus() + "&" + taskId + "=" + record.getTaskId();
				System.out.println("进入节点事件:" + faceUrl);
			} else if (FlowRecordEnum.submit.getCode().equals(status)) {
				flag = properties.getHasInitfunc() != null ? properties.getHasInitfunc() : false;
				faceUrl = properties.getInitInterfaceUrl() + "?" + taskNodeId + "=" + record.getTaskNodeId() + "&"
						+ taskId + "=" + record.getTaskId();
				System.out.println("进入开始事件:" + faceUrl);
			} else if (FlowRecordEnum.revoke.getCode().equals(status)) {
				flag = properties.getHasFlowRecallFunc() != null ? properties.getHasFlowRecallFunc() : false;
				faceUrl = properties.getFlowRecallInterfaceUrl() + "?" + handleStatus + "=" + record.getHandleStatus()
						+ "&" + taskId + "=" + record.getTaskId();
				System.out.println("开始撤回事件:" + faceUrl);
			} else if (FlowRecordEnum.end.getCode().equals(status)) {
				flag = properties.getHasEndfunc() != null ? properties.getHasEndfunc() : false;
				faceUrl = properties.getEndInterfaceUrl() + "?" + taskNodeId + "=" + record.getTaskNodeId() + "&"
						+ handleStatus + "=" + record.getHandleStatus() + "&" + taskId + "=" + record.getTaskId();
				System.out.println("进入结束事件:" + faceUrl);
			} else if (FlowRecordEnum.recall.getCode().equals(status)) {
				flag = properties.getHasRecallFunc() != null ? properties.getHasRecallFunc() : false;
				faceUrl = properties.getRecallInterfaceUrl() + "?" + taskNodeId + "=" + record.getTaskNodeId() + "&"
						+ handleStatus + "=" + record.getHandleStatus() + "&" + taskId + "=" + record.getTaskId();
				System.out.println("进入撤回事件:" + faceUrl);
			}
		}
		if (flag) {
			String token = UserProvider.getToken();
			HttpUtil.httpRequest(faceUrl, "GET", null, token);
		}
	}

	/**
	 * 发送消息
	 *
	 * @param flowMsgModel
	 */
	private void message(FlowMsgModel flowMsgModel) {
		List<SentMessageForm> messageList = new ArrayList<>();
		List<FlowTaskNodeEntity> nodeList = flowMsgModel.getNodeList();
		List<FlowTaskOperatorEntity> operatorList = flowMsgModel.getOperatorList();
		List<FlowTaskCirculateEntity> circulateList = flowMsgModel.getCirculateList();
		FlowTaskEntity taskEntity = flowMsgModel.getTaskEntity();
		String msgTitle = flowMsgModel.getMsgTitel();
		// 审批人
		for (FlowTaskOperatorEntity operator : operatorList) {
			FlowTaskNodeEntity node = nodeList.stream().filter(t -> t.getId().equals(operator.getTaskNodeId()))
					.findFirst().orElse(null);
			if (node != null) {
				List<String> userList = operatorList.stream().map(t -> t.getHandleId()).collect(Collectors.toList());
				ChildNodeList childNode = JsonUtil.getJsonToBean(node.getNodePropertyJson(), ChildNodeList.class);
				Properties properties = childNode.getProperties();
				List<String> messageType = properties.getMessageType() != null ? properties.getMessageType()
						: Arrays.asList(new String[] {});
				SentMessageForm sentMessageForm = this.message("【审核】", FlowMessageEnum.wait.getCode(), messageType,
						taskEntity, userList);
				messageList.add(sentMessageForm);
			}
		}
		// 抄送人
		for (FlowTaskCirculateEntity circulate : circulateList) {
			FlowTaskNodeEntity node = nodeList.stream().filter(t -> t.getId().equals(circulate.getTaskNodeId()))
					.findFirst().orElse(null);
			if (node != null) {
				List<String> userList = circulateList.stream().map(t -> t.getObjectId()).collect(Collectors.toList());
				ChildNodeList childNode = JsonUtil.getJsonToBean(node.getNodePropertyJson(), ChildNodeList.class);
				Properties properties = childNode.getProperties();
				List<String> messageType = properties.getMessageType() != null ? properties.getMessageType()
						: Arrays.asList(new String[] {});
				SentMessageForm sentMessageForm = this.message("【抄送】", FlowMessageEnum.circulate.getCode(), messageType,
						taskEntity, userList);
				messageList.add(sentMessageForm);
			}
		}
		// 发给创建人
		if (StringUtil.isNotEmpty(msgTitle)) {
			List<String> userList = new ArrayList<>();
			userList.add(taskEntity.getCreatorUserId());
			List<String> messageType = new ArrayList<>();
			messageType.add(MessageTypeEnum.SysMessage.getCode());
			SentMessageForm sentMessageForm = this.message(msgTitle, FlowMessageEnum.me.getCode(), messageType,
					taskEntity, userList);
			messageList.add(sentMessageForm);
		}
		for (SentMessageForm messageForm : messageList) {
			sentMessageUtil.sendMessage(messageForm);
		}
	}

	/**
	 * 发送消息封装
	 *
	 * @param title       名称
	 * @param type        类型
	 * @param messageType 发送消息类型
	 * @param taskEntity  所有节点
	 * @param userList    发送用户
	 * @return
	 */
	private SentMessageForm message(String title, int type, List<String> messageType, FlowTaskEntity taskEntity,
			List<String> userList) {
		SentMessageForm sentMessageForm = new SentMessageForm();
		sentMessageForm.setSendType(messageType);
		Map<String, Object> message = new HashMap<>(16);
		message.put("type", type);
		message.put("id", taskEntity.getId());
		sentMessageForm.setContent(JsonUtilEx.getObjectToString(message));
		sentMessageForm.setTitle(taskEntity.getFullName() + title);
		sentMessageForm.setToUserIds(userList);
		Map<String, String> smsContent = new HashMap<>(16);
		this.message(taskEntity.getFullName(), title, smsContent);
		sentMessageForm.setSmsContent(smsContent);
		return sentMessageForm;
	}

	/**
	 * 更新当前节点
	 *
	 * @param nextOperatorList 下一审批节点
	 * @param flowTaskNodeList 所有节点
	 * @param flowTask         流程任务
	 */
	private boolean getNextStepId(List<ChildNodeList> nextOperatorList, List<FlowTaskNodeEntity> flowTaskNodeList,
			FlowTaskEntity flowTask) throws WorkFlowException {
		boolean isEnd = false;
		Set<String> delNodeList = new HashSet<>();
		List<String> progressList = new ArrayList<>();
		List<String> nextOperator = new ArrayList<>();
		ChildNodeList end = nextOperatorList.stream()
				.filter(t -> t.getCustom().getNodeId().contains(FlowNature.NodeEnd)).findFirst().orElse(null);
		for (ChildNodeList childNode : nextOperatorList) {
			Properties properties = childNode.getProperties();
			String id = childNode.getCustom().getNodeId();
			String progress = properties.getProgress();
			List<FlowTaskNodeEntity> taskNodeList = flowTaskNodeList.stream().filter(t -> t.getNodeNext() != null)
					.filter(t -> t.getNodeNext().contains(id)).collect(Collectors.toList());
			List<String> nodeList = taskNodeList.stream().map(t -> t.getNodeCode()).collect(Collectors.toList());
			nextOperatorList.stream().filter(t -> t.getProperties().getProgress() != null)
					.map(t -> t.getProperties().getProgress()).collect(Collectors.toList());
			delNodeList.addAll(nodeList);
			nextOperator.add(id);
			if (StringUtil.isNotEmpty(progress)) {
				progressList.add(progress);
			}
		}
		String[] thisNode = flowTask.getThisStepId() != null ? flowTask.getThisStepId().split(",") : new String[] {};
		Set<String> thisStepId = new HashSet<>();
		for (String id : thisNode) {
			boolean isStepId = flowTaskNodeList.stream()
					.filter(t -> t.getNodeCode().equals(id) && t.getCompletion() == 0).count() > 0;
			if (isStepId) {
				thisStepId.add(id);
			}
		}
		thisStepId.removeAll(delNodeList);
		thisStepId.addAll(nextOperator);
		List<String> thisNodeName = new ArrayList<>();
		for (String id : thisStepId) {
			List<String> nodeList = flowTaskNodeList.stream().filter(t -> t.getNodeCode().equals(id))
					.map(t -> t.getNodeName()).collect(Collectors.toList());
			thisNodeName.addAll(nodeList);
		}
		flowTask.setThisStepId(String.join(",", thisStepId));
		flowTask.setThisStep(String.join(",", thisNodeName));
		Collections.sort(progressList);
		flowTask.setCompletion(progressList.size() > 0 ? Integer.valueOf(progressList.get(0)) : null);
		if (end != null) {
			isEnd = this.endround(flowTask, end);
		}
		return isEnd;
	}

	/**
	 * 审核记录
	 *
	 * @param record         审批实例
	 * @param operatordModel 对象数据
	 */
	private void operatorRecord(FlowTaskOperatorRecordEntity record, FlowOperatordModel operatordModel) {
		UserInfo userInfo = userProvider.get();
		int status = operatordModel.getStatus();
		FlowModel flowModel = operatordModel.getFlowModel();
		String userId = operatordModel.getUserId();
		FlowTaskOperatorEntity operator = operatordModel.getOperator();
		String operatorId = operatordModel.getOperatorId();
		record.setHandleOpinion(flowModel.getHandleOpinion());
		record.setHandleId(userId);
		record.setHandleName(userInfo.getUserName());
		record.setHandleTime(new Date());
		record.setHandleStatus(status);
		record.setOperatorId(operatorId);
		record.setNodeCode(operator.getNodeCode());
		record.setNodeName(operator.getNodeName() != null ? operator.getNodeName() : "开始");
		record.setTaskOperatorId(operator.getId());
		record.setTaskNodeId(operator.getTaskNodeId());
		record.setTaskId(operator.getTaskId());
		record.setSignImg(flowModel.getSignImg());
		record.setStatus(FlowTaskOperatorEnum.FreeApprover.getCode().equals(operator.getHandleType())
				? FlowNodeEnum.Futility.getCode()
				: FlowNodeEnum.Process.getCode());
	}

	/**
	 * 修改系统表单数据
	 *
	 * @param code 编码
	 * @param id   主键id
	 * @param data 数据
	 * @throws WorkFlowException
	 */
	private void formData(String code, String id, String data) throws WorkFlowException {
		Map<String, Object> objectData = JsonUtil.stringToMap(data);
		if (objectData.size() > 0) {
			try {
				Class[] types = new Class[] { String.class, String.class };
				Object[] datas = new Object[] { id, data };
				Object service = SpringContext.getBean(code + "ServiceImpl");
				ReflectionUtil.invokeMethod(service, "data", types, datas);
			} catch (Exception e) {
				throw new WorkFlowException("系统表单反射失败");
			}
		}
	}

	/**
	 * 定时器
	 *
	 * @param taskOperator 流程经办
	 * @param taskNodeList 所有流程节点
	 * @param operatorList 下一流程经办
	 * @return
	 */
	private List<FlowTaskOperatorEntity> timer(FlowTaskOperatorEntity taskOperator,
			List<FlowTaskNodeEntity> taskNodeList, List<FlowTaskOperatorEntity> operatorList) {
		List<FlowTaskOperatorEntity> operatorListAll = new ArrayList<>();
		FlowTaskNodeEntity taskNode = taskNodeList.stream().filter(t -> t.getId().equals(taskOperator.getTaskNodeId()))
				.findFirst().orElse(null);
		if (taskNode != null) {
			// 获取其他分流的定时器
			List<String> nodeList = taskNodeList.stream().filter(t -> t.getSortCode().equals(taskNode.getSortCode()))
					.map(t -> t.getId()).collect(Collectors.toList());
			List<FlowTaskOperatorEntity> operatorAll = flowTaskOperatorService.getList(taskOperator.getTaskId());
			Set<Date> dateListAll = new HashSet<>();
			List<FlowTaskOperatorEntity> list = operatorAll.stream().filter(t -> nodeList.contains(t.getTaskNodeId()))
					.collect(Collectors.toList());
			for (FlowTaskOperatorEntity operator : list) {
				List<Date> dateList = JsonUtil.getJsonToList(operator.getDescription(), Date.class);
				dateListAll.addAll(dateList);
			}
			// 获取单前审批定时器
			List<Date> date = JsonUtil.getJsonToList(taskOperator.getDescription(), Date.class);
			dateListAll.addAll(date);
			for (FlowTaskOperatorEntity operator : operatorList) {
				operator.setDescription(JsonUtil.getObjectToString(dateListAll));
				operatorListAll.add(operator);
			}
		}
		return operatorListAll;
	}

	/**
	 * 短信模板
	 *
	 * @param title  标题
	 * @param status 状态
	 * @return
	 */
	private void message(String title, String status, Map<String, String> msg) {
		Map<String, String> aliyun = new HashMap<>(16);
		aliyun.put("title", title);
		aliyun.put("status", status);
		msg.put("1", JsonUtil.getObjectToString(aliyun));
		msg.put("2", "2");
	}

}
