package com.leanwo.activiti.service.base.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import org.activiti.bpmn.model.ActivitiListener;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.bpmn.model.EndEvent;
import org.activiti.bpmn.model.FieldExtension;
import org.activiti.bpmn.model.FlowNode;
import org.activiti.bpmn.model.ImplementationType;
import org.activiti.bpmn.model.InclusiveGateway;
import org.activiti.bpmn.model.IntermediateCatchEvent;
import org.activiti.bpmn.model.Message;
import org.activiti.bpmn.model.MessageEventDefinition;
import org.activiti.bpmn.model.ParallelGateway;
import org.activiti.bpmn.model.Process;
import org.activiti.bpmn.model.SequenceFlow;
import org.activiti.bpmn.model.ServiceTask;
import org.activiti.bpmn.model.StartEvent;
import org.activiti.bpmn.model.UserTask;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.leanwo.activiti.delegate.base.AddCopyUserDelegate;
import com.leanwo.activiti.delegate.base.EmptyDelegate;
import com.leanwo.activiti.dto.approver.Approver;
import com.leanwo.activiti.dto.approver.ApproverUser;
import com.leanwo.activiti.dto.approver.ChildNode;
import com.leanwo.activiti.dto.approver.Condition;
import com.leanwo.activiti.dto.approver.ConditionNode;
import com.leanwo.activiti.dto.approver.OptionalGroup;
import com.leanwo.activiti.dto.approver.OptionalUser;
import com.leanwo.activiti.dto.approver.ProcessData;
import com.leanwo.activiti.dto.approver.Propertie;
import com.leanwo.activiti.dto.base.UserSelectDefine;
import com.leanwo.activiti.exception.BpmnModelDefineException;
import com.leanwo.activiti.listener.base.DingDingUserTaskAssignmentListener;
import com.leanwo.activiti.listener.base.DingDingUserTaskCompleteListener;
import com.leanwo.activiti.listener.base.DocumentStatusExecutionListener;
import com.leanwo.activiti.listener.base.EmailMessageAssignmentListener;
import com.leanwo.activiti.listener.base.MultiInstanceUserTaskByDirectorExecutionListener;
import com.leanwo.activiti.listener.base.MultiInstanceUserTaskByGroupIdsExecutionListener;
import com.leanwo.activiti.listener.base.MultiInstanceUserTaskByOrganizationExecutionListener;
import com.leanwo.activiti.listener.base.MultiInstanceUserTaskByUserIdsExecutionListener;
import com.leanwo.activiti.listener.base.MultiInstanceUserTaskByUserProgramExecutionListener;
import com.leanwo.activiti.listener.base.MultiInstanceUserTaskByUserProgramTaskAssignmentListener;
import com.leanwo.activiti.listener.base.ProcessStartUserTaskListener;
import com.leanwo.activiti.listener.base.UserTaskContinueListener;
import com.leanwo.activiti.listener.base.UserTaskStopListener;
import com.leanwo.activiti.service.base.BpmnElementService;
import com.leanwo.activiti.service.base.BpmnGeneratorService;
import com.leanwo.activiti.util.FormatUtil;
import com.leanwo.activiti.util.StringUtil;

public class BpmnGeneratorServiceImpl implements BpmnGeneratorService {

	private static Logger logger = LoggerFactory.getLogger(BpmnGeneratorServiceImpl.class);

	private BpmnElementService bpmnElementService;

	/** 是否集成钉钉 */
	private boolean integrateDingDing;
	private boolean triggerAfterNodeApproved;

	private int userTaskIndex = 0;
	private int exclusiveGatewayIndex = 0;
	private int endEventIndex = 0;
	private int parallelGatewayIndex = 0;
	private int inclusiveGatewayIndex = 0;

	private StartEvent startEvent = null;

	private List<UserSelectDefine> userSelectDefineList = null;
	private List<UserSelectDefine> previousAssigneeSelectDefineList = null;

	public BpmnGeneratorServiceImpl(boolean integrateDingDing, boolean triggerAfterNodeApproved, BpmnElementService bpmnElementService) {
		this.integrateDingDing = integrateDingDing;
		this.triggerAfterNodeApproved = triggerAfterNodeApproved;
		this.bpmnElementService = bpmnElementService;
		this.userTaskIndex = 0;
		this.exclusiveGatewayIndex = 0;
		this.endEventIndex = 0;
		this.parallelGatewayIndex = 0;
		this.inclusiveGatewayIndex = 0;
		this.userSelectDefineList = new ArrayList<UserSelectDefine>();
		this.previousAssigneeSelectDefineList = new ArrayList<UserSelectDefine>();
	}

	@Override
	public BpmnModel generateBpmnModel(String name, ProcessData processData) {
		BpmnModel bpmnModel = bpmnElementService.createBpmnModel("http://www.leanwo.com/workflow");

		Process process = bpmnElementService.createProcess(newUuid(), name);
		bpmnModel.addProcess(process);

		Message message = bpmnElementService.createMessage(UserPreference.STOP_MESSAGE_ID, UserPreference.STOP_MESSAGE);
		bpmnModel.addMessage(message);

		parseProcessData(processData, process);

		if (userSelectDefineList != null) {
			for (UserSelectDefine userSelectDefine : userSelectDefineList) {
				logger.debug("发起人自选的条件: " + userSelectDefine.toString());
			}
		}

		if (previousAssigneeSelectDefineList != null) {
			for (UserSelectDefine userSelectDefine : previousAssigneeSelectDefineList) {
				logger.debug("上一个审批人选择的条件: " + userSelectDefine.toString());
			}
		}

		return bpmnModel;
	}

	@Override
	public List<UserSelectDefine> getUserSelectDefineList() {
		return userSelectDefineList;
	}

	@Override
	public List<UserSelectDefine> getPreviousAssigneeSelectDefineList() {
		return previousAssigneeSelectDefineList;
	}

	/**
	 * 生成UUID字符串
	 * 
	 * @return
	 */
	private String newUuid() {
		return "id_" + UUID.randomUUID().toString().replace("-", "");
	}

	/**
	 * 新建排他网关Id
	 * 
	 * @return
	 */
	private String newExclusiveGatewayId() {
		exclusiveGatewayIndex++;
		return "ExclusiveGateway" + exclusiveGatewayIndex;
	}

	/**
	 * 新建并行网关Id
	 * 
	 * @return
	 */
	private String newParallelGatewayId() {
		parallelGatewayIndex++;
		return "ParallelGateway" + parallelGatewayIndex;
	}

	private String newInclusiveGatewayId() {
		inclusiveGatewayIndex++;
		return "InclusiveGateway" + inclusiveGatewayIndex;
	}

	/**
	 * 新建结束事件Id
	 * 
	 * @return
	 */
	private String newEndEventId() {
		endEventIndex++;
		return "EndEvent" + endEventIndex;
	}

	/**
	 * 生成流程数据
	 * 
	 * @param processData
	 * @param process
	 */
	private void parseProcessData(ProcessData processData, Process process) {
		String content = processData.getContent();
		String nodeId = processData.getNodeId();

		// 添加开始节点
		startEvent = bpmnElementService.createStartEvent(nodeId, content);
		process.addFlowElement(startEvent);

		// 新建发起人审批节点-发起人自己
		UserTask processStartUserTask = createUserTaskOfMyself(nodeId + "_userTask", "发起人", true);
		process.addFlowElement(processStartUserTask);
		
		ActivitiListener activitiListener = bpmnElementService.createActivitiListener("create",
				ProcessStartUserTaskListener.class.getName(), ImplementationType.IMPLEMENTATION_TYPE_CLASS);
		processStartUserTask.getTaskListeners().add(activitiListener);
		// 我们设置Skip expression ${1 == 1}来实现 当A发出申请，需要A审核时跳过审核环节。
		processStartUserTask.setSkipExpression("${1==1}");
		
		
		SequenceFlow sequenceFlow = bpmnElementService.createSequenceFlow(newUuid(), null, startEvent,
				processStartUserTask, null);
		process.addFlowElement(sequenceFlow);
		
		// 添加并行网关(开始节点-并行网关-中间信号捕获事件-终结任务)
		ParallelGateway parallelGateway0 = bpmnElementService.createParallelGateway(newUuid(), newParallelGatewayId());
		process.addFlowElement(parallelGateway0);

		SequenceFlow sequenceFlow0 = bpmnElementService.createSequenceFlow(newUuid(), null, processStartUserTask,
				parallelGateway0, null);
		process.addFlowElement(sequenceFlow0);

		// 添加中间信号捕获事件(开始节点-并行网关-中间信号捕获事件-终结任务)
		IntermediateCatchEvent intermediateCatchEvent0 = bpmnElementService.createIntermediateCatchEvent(newUuid(),
				"Catch Stop Message");
		process.addFlowElement(intermediateCatchEvent0);
		MessageEventDefinition messageEventDefinition = bpmnElementService.createMessageEventDefinition(newUuid(),
				UserPreference.STOP_MESSAGE_ID);
		intermediateCatchEvent0.addEventDefinition(messageEventDefinition);

		SequenceFlow sequenceFlow1 = bpmnElementService.createSequenceFlow(newUuid(), null, parallelGateway0,
				intermediateCatchEvent0, null);
		process.addFlowElement(sequenceFlow1);

		// 添加终结任务(开始节点-并行网关-中间信号捕获事件-终结任务)
		EndEvent endEvent = createEndEvent();
		process.addFlowElement(endEvent);

		SequenceFlow sequenceFlow2 = bpmnElementService.createSequenceFlow(newUuid(), null, intermediateCatchEvent0,
				endEvent, null);
		process.addFlowElement(sequenceFlow2);

		// 分支条件
		List<ConditionNode> conditionNodes = processData.getConditionNodes();
		// 处理分支条件
		InclusiveGateway inclusiveGatewaySub = null;
		if (conditionNodes != null) {
			inclusiveGatewaySub = parseConditionNode(conditionNodes, process, parallelGateway0, null, null, null);
		}

		ChildNode childNode = processData.getChildNode();
		FlowNode flowNode = null;
		FlowNode flowNodeSub = null;
		if (childNode != null) {
			if (inclusiveGatewaySub != null) {
				flowNodeSub = parseChildNode(childNode, process, inclusiveGatewaySub, null, null, null);
			} else {
				flowNodeSub = parseChildNode(childNode, process, parallelGateway0, null, null, null);
			}
			flowNode = flowNodeSub;
		} else {
			if (inclusiveGatewaySub != null) {
				flowNode = inclusiveGatewaySub;
			} else {
				flowNode = parallelGateway0;
			}
		}

		// 添加终结任务
		EndEvent endEvent1 = createEndEvent();
		process.addFlowElement(endEvent1);
		SequenceFlow sequenceFlowEnd1 = bpmnElementService.createSequenceFlow(newUuid(), null, flowNode, endEvent1,
				null);
		process.addFlowElement(sequenceFlowEnd1);
	}

	/**
	 * 转换子节点
	 * 
	 * @param childNode
	 * @param process
	 * @param conditionExpression
	 * @param parentFlowNode
	 * @return 结束节点
	 */
	private FlowNode parseChildNode(ChildNode childNode, Process process, FlowNode parentFlowNode, String conditionName,
			String conditionExpression, String parentConditionExpression) {
		String content = childNode.getContent();
		String type = childNode.getType();
		String nodeId = childNode.getNodeId();

		FlowNode flowNode = null;
		FlowNode flowNodeCurrent = null;
		UserTask userTask = null;
		String title = childNode.getProperties().getTitle();
		title = ((title == null) ? "" : title);
		if (type.equals("approver") && childNode.getProperties().getAssigneeType() != null) {
			// 1: 会签（须所有审批人同意）
			// 2: 或签（一名审批人同意或拒绝即可）
			// 3: 顺序审批
			Integer counterSign = childNode.getProperties().getCounterSign();
			
			// 节点：审批人
			if (childNode.getProperties().getAssigneeType().equals("user")) {
				List<String> approverUserIds = new ArrayList<String>();
				// 指定成员
				List<Approver> approvers = childNode.getProperties().getApprovers();
				if (approvers != null && approvers.size() > 0) {
					for (Approver approver : approvers) {
						if (approver.getUserId() != null) {
							approverUserIds.add(approver.getUserId().toString());
						}
					}
				}
				// 会签，或签
				userTask = createUserTaskOfUserIds(nodeId, title, approverUserIds, counterSign);
			} else if (childNode.getProperties().getAssigneeType().equals("userGroup")) {
				List<String> approverUserGroupIds = new ArrayList<String>();
				// 用户组
				List<Approver> approvers = childNode.getProperties().getApprovers();
				if (approvers != null && approvers.size() > 0) {
					for (Approver approver : approvers) {
						if (approver.getGroupId() != null) {
							approverUserGroupIds.add(approver.getGroupId().toString());
						}
					}
				}
				userTask = createUserTaskOfGroupIds(nodeId, title, approverUserGroupIds,
						counterSign);
			} else if (childNode.getProperties().getAssigneeType().equals("director")) {
				// 主管
				Propertie propertie = childNode.getProperties();

				// 1:直接主管, 2: 第2级主管, 3: 第3级主管, 4: 第4级主管, 5: 第5级主管.
				Integer directorLevel = propertie.getDirectorLevel();

				// 找不到主管时，由上级主管代审批
				Boolean useDirectorProxy = propertie.getUseDirectorProxy();

				userTask = createUserTaskOfDirect(nodeId, title, directorLevel, useDirectorProxy,
						counterSign);

			} else if (childNode.getProperties().getAssigneeType().equals("position")) {
				// 部门主管
				List<String> approverOrganizationIds = new ArrayList<String>();
				List<Approver> approvers = childNode.getProperties().getApprovers();
				if (approvers != null && approvers.size() > 0) {
					for (Approver approver : approvers) {
						if (approver.getDeptId() != null) {
							approverOrganizationIds.add(approver.getDeptId().toString());
						}
					}
				}
				userTask = createUserTaskOfOrganization(nodeId, title, approverOrganizationIds,
						counterSign);
			} else if (childNode.getProperties().getAssigneeType().equals("myself")) {
				// 发起人自己
				userTask = createUserTaskOfMyself(nodeId, title, false);
			} else if (childNode.getProperties().getAssigneeType().equals("optional")) {
				// 发起人自选
				boolean multiSelect = childNode.getProperties().getOptionalMultiUser();
				String optionlRange = childNode.getProperties().getOptionalRange();
				List<OptionalUser> optionalUsers = childNode.getProperties().getOptionalUsers();
				List<OptionalGroup> optionalGroups = childNode.getProperties().getOptionalUserGroups();
				if (optionlRange.equals("USER")) {
					optionalGroups = null;
				} else if (optionlRange.equals("USER_GROUP")) {
					optionalUsers = null;
				} else {
					optionalGroups = null;
					optionalUsers = null;
				}
				userTask = createUserTaskOfOption(nodeId, title, counterSign, multiSelect,
						optionlRange, parentConditionExpression, optionalUsers, optionalGroups);
			} else if (childNode.getProperties().getAssigneeType().equals("previousAssigneeSelect")) {
				// 上一个审批人选择
				boolean multiSelect = childNode.getProperties().getOptionalMultiUser();
				String optionlRange = childNode.getProperties().getOptionalRange();
				String previousAssigneeSelectNodeId = childNode.getProperties().getPreviousAssigneeSelectNodeId();
				String[] previousAssigneeSelectNodeIds = childNode.getProperties().getPreviousAssigneeSelectNodeIds();

				if (StringUtil.isEmpty(previousAssigneeSelectNodeId)
						&& (previousAssigneeSelectNodeIds == null || previousAssigneeSelectNodeIds.length == 0)) {
					String message = String.format("节点(%s)(%s)未选择上一个审批节点。", title, content);
					throw new BpmnModelDefineException(message);
				}

				List<OptionalUser> optionalUsers = childNode.getProperties().getOptionalUsers();
				List<OptionalGroup> optionalGroups = childNode.getProperties().getOptionalUserGroups();
				if (optionlRange.equals("USER")) {
					optionalGroups = null;
				} else if (optionlRange.equals("USER_GROUP")) {
					optionalUsers = null;
				} else {
					optionalGroups = null;
					optionalUsers = null;
				}
				userTask = createUserTaskOfPreviousAssigneeSelect(nodeId, title, counterSign,
						multiSelect, optionlRange, parentConditionExpression, optionalUsers, optionalGroups,
						previousAssigneeSelectNodeId, previousAssigneeSelectNodeIds);
			} else if (childNode.getProperties().getAssigneeType().equals("programSelect")) {
				// 开发人员自定义的SQL语句，用于审批人的查询
				String assignSql = childNode.getProperties().getAssignSql();
				userTask = createUserTaskOfProgramSelect(nodeId, title, assignSql, counterSign);
			}

			List<ActivitiListener> taskListeners = userTask.getTaskListeners();
			if (taskListeners == null) {
				taskListeners = new ArrayList<ActivitiListener>();
				userTask.setTaskListeners(taskListeners);
			}

			if (integrateDingDing == true) {
				ActivitiListener assignmentActivitiListener = bpmnElementService.createActivitiListener("assignment",
						DingDingUserTaskAssignmentListener.class.getName(),
						ImplementationType.IMPLEMENTATION_TYPE_CLASS);
				taskListeners.add(assignmentActivitiListener);

				ActivitiListener completeActivitiListener = bpmnElementService.createActivitiListener("complete",
						DingDingUserTaskCompleteListener.class.getName(), ImplementationType.IMPLEMENTATION_TYPE_CLASS);
				taskListeners.add(completeActivitiListener);
			}

			process.addFlowElement(userTask);
			flowNodeCurrent = userTask;
		} else if (type.equals("copy")) {
			// 抄送节点
			List<ApproverUser> copyUsers = childNode.getProperties().getMenbers().getUser();
			if (copyUsers != null && copyUsers.size() > 0) {
				List<Long> copyUserIds = new ArrayList<Long>();
				for (ApproverUser approverUser : copyUsers) {
					copyUserIds.add(approverUser.getUserId());
				}
				ServiceTask serviceTask = createServiceTaskOfCopy(nodeId, title, copyUserIds);
				process.addFlowElement(serviceTask);
				flowNodeCurrent = serviceTask;
			} else {
				String message = String.format("节点(%s)(%s)未选择抄送人。", title, content);
				throw new BpmnModelDefineException(message);
			}
		} else if (type.equals("condition")) {
			String message = String.format("节点(%s)(%s)的节点类型%s，程序应该不会执行到此处。", title, content, type);
			throw new BpmnModelDefineException(message);
		} else if (type.equals("empty")) {
			ServiceTask serviceTask = createServiceTaskOfEmpty(nodeId, "空节点");
			process.addFlowElement(serviceTask);
			flowNodeCurrent = serviceTask;
		} else {
			String message = String.format("节点(%s)(%s)的节点类型%s不识别。", title, content, type);
			throw new BpmnModelDefineException(message);
		}

		SequenceFlow sequenceFlow = bpmnElementService.createSequenceFlow(newUuid(), conditionName, parentFlowNode,
				flowNodeCurrent, generateJuelExpression(conditionExpression));
		process.addFlowElement(sequenceFlow);

		List<ConditionNode> conditionNodesSub = childNode.getConditionNodes();
		// 处理分支条件
		InclusiveGateway inclusiveGatewaySub = null;
		if (conditionNodesSub != null && conditionNodesSub.size() > 0) {
			inclusiveGatewaySub = parseConditionNode(conditionNodesSub, process, flowNodeCurrent, null, null,
					parentConditionExpression);
		}

		ChildNode childNodeSub = childNode.getChildNode();
		FlowNode flowNodeSub = null;
		if (childNodeSub != null) {
			if (inclusiveGatewaySub != null) {
				flowNodeSub = parseChildNode(childNodeSub, process, inclusiveGatewaySub, null, null,
						parentConditionExpression);
			} else {
				flowNodeSub = parseChildNode(childNodeSub, process, flowNodeCurrent, null, null,
						parentConditionExpression);
			}
			flowNode = flowNodeSub;
		} else {
			if (inclusiveGatewaySub != null) {
				flowNode = inclusiveGatewaySub;
			} else {
				flowNode = flowNodeCurrent;
			}
		}

		return flowNode;
	}

	private String generateJuelExpression(String conditionExpression) {
		if (StringUtil.isEmpty(conditionExpression)) {
			return null;
		}
		return "${" + conditionExpression + "}";
	}

	/**
	 * 转换条件节点 <br>
	 * |---用户任务---| <br>
	 * | | <br>
	 * - 排他网关 --|---用户任务---|-- 并行网关--用户任务 <br>
	 * | | <br>
	 * |---用户任务---| <br>
	 * 
	 * @param conditionNodes
	 * @param process
	 * @param parentFlowNode
	 * @param conditionExpression
	 * @return 返回最后的节点
	 */
	private InclusiveGateway parseConditionNode(List<ConditionNode> conditionNodes, Process process,
			FlowNode parentFlowNode, String conditionName, String conditionExpression,
			String parentConditionExpression) {
		FlowNode flowNode = null;
		// 添加排他网关
		InclusiveGateway inclusiveGatewayStart = bpmnElementService.createInclusiveGateway(newUuid(),
				newInclusiveGatewayId(), false, true);
		process.addFlowElement(inclusiveGatewayStart);
		SequenceFlow sequenceFlow1 = bpmnElementService.createSequenceFlow(newUuid(), conditionName, parentFlowNode,
				inclusiveGatewayStart, generateJuelExpression(conditionExpression));
		process.addFlowElement(sequenceFlow1);

		// 添加并行网关
		InclusiveGateway inclusiveGatewayEnd = bpmnElementService.createInclusiveGateway(newUuid(),
				newInclusiveGatewayId(), false, true);
		process.addFlowElement(inclusiveGatewayEnd);

		for (ConditionNode conditionNode : conditionNodes) {
			String content = conditionNode.getContent();
			String type = conditionNode.getType();
			String nodeId = conditionNode.getNodeId();

			if (type == null || !type.equals("condition")) {
				String message = String.format("节点(%s)应该是条件类型的节点(%s)", content, type);
				throw new BpmnModelDefineException(message);
			}

			String condition = getConditionExpression(conditionNode.getProperties().getConditions());
			String approveCondition =  getApproveConditionExpression(conditionNode.getProperties().getApproveConditions());
			
			// add by jack 20210723
			if(StringUtil.isNotEmpty(approveCondition)) {
				if(StringUtil.isEmpty(condition)) {
					condition = approveCondition;
				}else {
					condition += (" && " + approveCondition);
				}
			}
			
			
			String newCondition = null;
			if (StringUtil.isEmpty(parentConditionExpression)) {
				newCondition = condition;
			} else {
				newCondition = parentConditionExpression + " && " + condition;
			}
			

			List<ConditionNode> conditionNodesSub = conditionNode.getConditionNodes();
			// 处理分支条件
			InclusiveGateway inclusiveGatewaySub = null;
			if (conditionNodesSub != null && conditionNodesSub.size() > 0) {
				inclusiveGatewaySub = parseConditionNode(conditionNodesSub, process, inclusiveGatewayStart, content,
						condition, newCondition);
			}

			ChildNode childNodeSub = conditionNode.getChildNode();
			FlowNode flowNodeSub = null;
			if (childNodeSub != null) {
				if (inclusiveGatewaySub != null) {
					flowNodeSub = parseChildNode(childNodeSub, process, inclusiveGatewaySub, null, null, newCondition);
				} else {
					flowNodeSub = parseChildNode(childNodeSub, process, inclusiveGatewayStart, content, condition,
							newCondition);
				}
				flowNode = flowNodeSub;
			} else {
				if (inclusiveGatewaySub != null) {
					flowNode = inclusiveGatewaySub;
				} else {
					flowNode = null;
				}
			}

			if (flowNode != null) {
				SequenceFlow sequenceFlow2 = bpmnElementService.createSequenceFlow(newUuid(), null, flowNode,
						inclusiveGatewayEnd, null);
				process.addFlowElement(sequenceFlow2);
			} else {
				SequenceFlow sequenceFlow2 = bpmnElementService.createSequenceFlow(newUuid(), conditionName,
						inclusiveGatewayStart, inclusiveGatewayEnd, generateJuelExpression(condition));
				process.addFlowElement(sequenceFlow2);
			}
		}

		return inclusiveGatewayEnd;
	}

	/**
	 * 新建指定成员类型的用户任务
	 * 
	 * @param id           节点id
	 * @param name         节点名称
	 * @param assigneeList 任务指派人
	 * @param counterSign  1: 会签（须所有审批人同意）2: 或签（一名审批人同意或拒绝即可）
	 * @return 用户任务
	 */
	private UserTask createUserTaskOfUserIds(String id, String name, List<String> assigneeList, Integer counterSign) {
		if (assigneeList == null || assigneeList.size() == 0) {
			String errorMessage = String.format("审批人-指定成员节点(%s)未指定成员", name);
			throw new BpmnModelDefineException(errorMessage);
		}

		userTaskIndex++;

		UserTask userTask = null;

		if (assigneeList.size() == 1) {
			String assignee = assigneeList.get(0);
			userTask = bpmnElementService.createUserTask(id, name, assignee);
		} else {

			String assignee = String.format("${assignee%d}", userTaskIndex);
			String multiInstanceCollection = String.format("assigneeList%d", userTaskIndex);
			String multiInstanceVariable = String.format("assignee%d", userTaskIndex);

			if (counterSign != null && counterSign == 1) {
				// 1: 会签（须所有审批人同意）
				String multiInstanceCompleteCondition = "${nrOfInstances == nrOfCompletedInstances}";
				userTask = bpmnElementService.createUserTask(id, name, assignee, true, false, multiInstanceCollection,
						multiInstanceVariable, multiInstanceCompleteCondition);
			} else if (counterSign != null && counterSign == 2) {
				// 2: 或签（一名审批人同意或拒绝即可）
				String multiInstanceCompleteCondition = "${nrOfCompletedInstances >= 1}";
				userTask = bpmnElementService.createUserTask(id, name, assignee, true, false, multiInstanceCollection,
						multiInstanceVariable, multiInstanceCompleteCondition);
			} else if (counterSign != null && counterSign == 3) {
				// 3: 依次审批
				String multiInstanceCompleteCondition = "${nrOfInstances == nrOfCompletedInstances}";
				userTask = bpmnElementService.createUserTask(id, name, assignee, true, true, multiInstanceCollection,
						multiInstanceVariable, multiInstanceCompleteCondition);
			} else {
				String errorMessage = String.format("审批人-指定成员节点(%s)未选择多人审批时采用的审批方式", name);
				throw new BpmnModelDefineException(errorMessage);
			}

			if (counterSign != null && (counterSign == 1 || counterSign == 2 || counterSign == 3)) {
				ActivitiListener activitiListener = bpmnElementService.createActivitiListener("start",
						MultiInstanceUserTaskByUserIdsExecutionListener.class.getName(),
						ImplementationType.IMPLEMENTATION_TYPE_CLASS);

				FieldExtension fieldExtension1 = bpmnElementService.createFieldExtension("assignListVariableName",
						multiInstanceCollection);
				FieldExtension fieldExtension2 = bpmnElementService.createFieldExtension("assigneeList",
						FormatUtil.getGson().toJson(assigneeList));
				FieldExtension fieldExtension3 = bpmnElementService.createFieldExtension("nodeName", name);
				List<FieldExtension> fieldExtensions = bpmnElementService.createFieldExtensions(fieldExtension1,
						fieldExtension2, fieldExtension3);
				activitiListener.setFieldExtensions(fieldExtensions);

				List<ActivitiListener> activitiListeners = startEvent.getExecutionListeners();
				if (activitiListeners == null) {
					activitiListeners = bpmnElementService.createActivitiListeners(activitiListener);
					startEvent.setExecutionListeners(activitiListeners);
				} else {
					activitiListeners.add(activitiListener);
				}
			}
		}

		ActivitiListener activitiListener1 = bpmnElementService.createActivitiListener("complete",
				UserTaskStopListener.class.getName(), ImplementationType.IMPLEMENTATION_TYPE_CLASS);
		

		
		if (userTask.getTaskListeners() == null) {
			List<ActivitiListener> activitiListeners = bpmnElementService.createActivitiListeners(activitiListener1);
			userTask.setTaskListeners(activitiListeners);
		} else {
			userTask.getTaskListeners().add(activitiListener1);
		}
		
		userTaskAddEmailMessageAssignmentListener(userTask);
		createUserTaskContinueListener(userTask);

		return userTask;
	}

	/**
	 * 增加邮件发送监听器
	 * @param userTask
	 */
	private void userTaskAddEmailMessageAssignmentListener(UserTask userTask){
		ActivitiListener activitiListener2 = bpmnElementService.createActivitiListener("assignment",
				EmailMessageAssignmentListener.class.getName(), ImplementationType.IMPLEMENTATION_TYPE_CLASS);		
		if (userTask.getTaskListeners() == null) {
			List<ActivitiListener> activitiListeners = bpmnElementService.createActivitiListeners(activitiListener2);
			userTask.setTaskListeners(activitiListeners);
		} else {
			userTask.getTaskListeners().add(activitiListener2);
		}
	}
	
	/**
	 * 新建指定开发人员定义SQL审批人的用户任务
	 * 
	 * @param id           节点id
	 * @param name         节点名称
	 * @param sqlData 	查询任务指派人的SQL语句
	 * @param counterSign  1: 会签（须所有审批人同意）2: 或签（一名审批人同意或拒绝即可）
	 * @return 用户任务
	 */
	private UserTask createUserTaskOfProgramSelect(String id, String name, String sqlData, Integer counterSign) {
		if (sqlData == null || sqlData.length() == 0) {
			String errorMessage = String.format("开发人员自定义审批人员节点(%s)未指定SQL语句", name);
			throw new BpmnModelDefineException(errorMessage);
		}

		userTaskIndex++;

		UserTask userTask = null;

		String assignee = String.format("${assignee%d}", userTaskIndex);
		String multiInstanceCollection = String.format("assigneeList%d", userTaskIndex);
		String multiInstanceVariable = String.format("assignee%d", userTaskIndex);

		if (counterSign != null && counterSign == 1) {
			// 1: 会签（须所有审批人同意）
			String multiInstanceCompleteCondition = "${nrOfInstances == nrOfCompletedInstances}";
			userTask = bpmnElementService.createUserTask(id, name, assignee, true, false, multiInstanceCollection,
					multiInstanceVariable, multiInstanceCompleteCondition);
		} else if (counterSign != null && counterSign == 2) {
			// 2: 或签（一名审批人同意或拒绝即可）
			String multiInstanceCompleteCondition = "${nrOfCompletedInstances >= 1}";
			userTask = bpmnElementService.createUserTask(id, name, assignee, true, false, multiInstanceCollection,
					multiInstanceVariable, multiInstanceCompleteCondition);
		} else if (counterSign != null && counterSign == 3) {
			// 3: 依次审批
			String multiInstanceCompleteCondition = "${nrOfInstances == nrOfCompletedInstances}";
			userTask = bpmnElementService.createUserTask(id, name, assignee, true, true, multiInstanceCollection,
					multiInstanceVariable, multiInstanceCompleteCondition);
		} else {
			String errorMessage = String.format("开发人员自定义审批人员节点(%s)未选择多人审批时采用的审批方式", name);
			throw new BpmnModelDefineException(errorMessage);
		}

		if (counterSign != null && (counterSign == 1 || counterSign == 2 || counterSign == 3)) {
			ActivitiListener activitiListener = bpmnElementService.createActivitiListener("start",
					MultiInstanceUserTaskByUserProgramExecutionListener.class.getName(),
					ImplementationType.IMPLEMENTATION_TYPE_CLASS);

			FieldExtension fieldExtension1 = bpmnElementService.createFieldExtension("assignListVariableName",
					multiInstanceCollection);
			FieldExtension fieldExtension2 = bpmnElementService.createFieldExtension("sqlDataExpression", sqlData);
			FieldExtension fieldExtension3 = bpmnElementService.createFieldExtension("nodeName", name);
			List<FieldExtension> fieldExtensions = bpmnElementService.createFieldExtensions(fieldExtension1,
					fieldExtension2, fieldExtension3);
			activitiListener.setFieldExtensions(fieldExtensions);

			List<ActivitiListener> activitiListeners = startEvent.getExecutionListeners();
			if (activitiListeners == null) {
				activitiListeners = bpmnElementService.createActivitiListeners(activitiListener);
				startEvent.setExecutionListeners(activitiListeners);
			} else {
				activitiListeners.add(activitiListener);
			}
		}

		ActivitiListener activitiListener1 = bpmnElementService.createActivitiListener("complete",
				UserTaskStopListener.class.getName(), ImplementationType.IMPLEMENTATION_TYPE_CLASS);
		if (userTask.getTaskListeners() == null) {
			List<ActivitiListener> activitiListeners = bpmnElementService.createActivitiListeners(activitiListener1);
			userTask.setTaskListeners(activitiListeners);
		} else {
			userTask.getTaskListeners().add(activitiListener1);
		}

		
		// add by jack 20220718
		// 审批过程中重新对SQL审批人赋值
		if (counterSign != null && (counterSign == 1 || counterSign == 2 || counterSign == 3)) {
		    //create: 任务被创建，并且所有的属性都被设置好后。
		    //assignment: 任务被委派给某人后.。注意: 当流程执行到达一个userTask时，会先触发一个assignment事件，再触发create事件。
		    //complete:在任务完成后，且被从运行时数据（runtime data）中删除前触发。
		    //delete: 在任务将要被删除之前发生。注意，当任务通过completeTask完成任务时，它也会被执行
		    ActivitiListener assignmentActivitiListener = bpmnElementService.createActivitiListener("assignment",
		        MultiInstanceUserTaskByUserProgramTaskAssignmentListener.class.getName(),
                ImplementationType.IMPLEMENTATION_TYPE_CLASS);

            FieldExtension fieldExtension1 = bpmnElementService.createFieldExtension("assignListVariableName",
                    multiInstanceCollection);
            FieldExtension fieldExtension2 = bpmnElementService.createFieldExtension("sqlDataExpression", sqlData);
            FieldExtension fieldExtension3 = bpmnElementService.createFieldExtension("nodeName", name);
            List<FieldExtension> fieldExtensions = bpmnElementService.createFieldExtensions(fieldExtension1,
                    fieldExtension2, fieldExtension3);
            assignmentActivitiListener.setFieldExtensions(fieldExtensions);
            
            if (userTask.getTaskListeners() == null) {
                List<ActivitiListener> activitiListeners = bpmnElementService.createActivitiListeners(assignmentActivitiListener);
                userTask.setTaskListeners(activitiListeners);
            } else {
                userTask.getTaskListeners().add(assignmentActivitiListener);
            }
        }
		
		
		userTaskAddEmailMessageAssignmentListener(userTask);
		createUserTaskContinueListener(userTask);

		return userTask;
	}
	
	
	
	/**
	 * UserTask 创建 UserTaskContinueListener 节点
	 * @param userTask
	 */
	public void createUserTaskContinueListener(UserTask userTask) {
		if(triggerAfterNodeApproved == true) {
			ActivitiListener activitiListener2 = bpmnElementService.createActivitiListener("complete",
					UserTaskContinueListener.class.getName(), ImplementationType.IMPLEMENTATION_TYPE_CLASS);
			if (userTask.getTaskListeners() == null) {
				List<ActivitiListener> activitiListeners = bpmnElementService.createActivitiListeners(activitiListener2);
				userTask.setTaskListeners(activitiListeners);
			} else {
				userTask.getTaskListeners().add(activitiListener2);
			}
		}
	}
	/**
	 * 新建用户组类型的用户任务
	 * 
	 * @param id          节点id
	 * @param name        节点名称
	 * @param groupIdList 用户组id集合
	 * @param counterSign 1: 会签（须所有审批人同意）2: 或签（一名审批人同意或拒绝即可）
	 * @return 用户任务
	 */
	private UserTask createUserTaskOfGroupIds(String id, String name, List<String> groupIdList, Integer counterSign) {
		if (groupIdList == null || groupIdList.size() == 0) {
			String errorMessage = String.format("审批人-选择用户组节点(%s)未指定用户组", name);
			throw new BpmnModelDefineException(errorMessage);
		}

		userTaskIndex++;

		UserTask userTask = null;

		String assignee = String.format("${assignee%d}", userTaskIndex);
		String multiInstanceCollection = String.format("assigneeList%d", userTaskIndex);
		String multiInstanceVariable = String.format("assignee%d", userTaskIndex);

		if (counterSign != null && counterSign == 1) {
			// 1: 会签（须所有审批人同意）
			String multiInstanceCompleteCondition = "${nrOfInstances == nrOfCompletedInstances}";
			userTask = bpmnElementService.createUserTask(id, name, assignee, true, false, multiInstanceCollection,
					multiInstanceVariable, multiInstanceCompleteCondition);
		} else if (counterSign != null && counterSign == 2) {
			// 2: 或签（一名审批人同意或拒绝即可）
			String multiInstanceCompleteCondition = "${nrOfCompletedInstances >= 1}";
			userTask = bpmnElementService.createUserTask(id, name, assignee, true, false, multiInstanceCollection,
					multiInstanceVariable, multiInstanceCompleteCondition);
		} else if (counterSign != null && counterSign == 3) {
			// 3: 依次审批
			String multiInstanceCompleteCondition = "${nrOfInstances == nrOfCompletedInstances}";
			userTask = bpmnElementService.createUserTask(id, name, assignee, true, true, multiInstanceCollection,
					multiInstanceVariable, multiInstanceCompleteCondition);
		} else {
			String errorMessage = String.format("审批人-选择用户组节点(%s)未选择多人审批时采用的审批方式", name);
			throw new BpmnModelDefineException(errorMessage);
		}

		if (counterSign != null && (counterSign == 1 || counterSign == 2 || counterSign == 3)) {
			ActivitiListener activitiListener = bpmnElementService.createActivitiListener("start",
					MultiInstanceUserTaskByGroupIdsExecutionListener.class.getName(),
					ImplementationType.IMPLEMENTATION_TYPE_CLASS);

			FieldExtension fieldExtension1 = bpmnElementService.createFieldExtension("assignListVariableName",
					multiInstanceCollection);
			FieldExtension fieldExtension2 = bpmnElementService.createFieldExtension("groupIdList",
					FormatUtil.getGson().toJson(groupIdList));
			FieldExtension fieldExtension3 = bpmnElementService.createFieldExtension("nodeName", name);
			List<FieldExtension> fieldExtensions = bpmnElementService.createFieldExtensions(fieldExtension1,
					fieldExtension2, fieldExtension3);
			activitiListener.setFieldExtensions(fieldExtensions);

			List<ActivitiListener> activitiListeners = startEvent.getExecutionListeners();
			if (activitiListeners == null) {
				activitiListeners = bpmnElementService.createActivitiListeners(activitiListener);
				startEvent.setExecutionListeners(activitiListeners);
			} else {
				activitiListeners.add(activitiListener);
			}
		}

		ActivitiListener activitiListener1 = bpmnElementService.createActivitiListener("complete",
				UserTaskStopListener.class.getName(), ImplementationType.IMPLEMENTATION_TYPE_CLASS);
		if (userTask.getTaskListeners() == null) {
			List<ActivitiListener> activitiListeners = bpmnElementService.createActivitiListeners(activitiListener1);
			userTask.setTaskListeners(activitiListeners);
		} else {
			userTask.getTaskListeners().add(activitiListener1);
		}

		userTaskAddEmailMessageAssignmentListener(userTask);
		createUserTaskContinueListener(userTask);

		return userTask;
	}

	/**
	 * 新建主管类型的用户任务
	 * 
	 * @param id               节点id
	 * @param name             节点名称
	 * @param directorLevel    1:直接主管, 2: 第2级主管, 3: 第3级主管, 4: 第4级主管, 5: 第5级主管.
	 * @param useDirectorProxy 找不到主管时，由上级主管代审批.
	 * @param counterSign      1: 会签（须所有审批人同意）2: 或签（一名审批人同意或拒绝即可）
	 * @return 用户任务
	 */
	private UserTask createUserTaskOfDirect(String id, String name, Integer directorLevel, Boolean useDirectorProxy,
			Integer counterSign) {
		if (directorLevel == null || useDirectorProxy == null) {
			String errorMessage = String.format("审批人-主管节点(%s)未指定主管", name);
			throw new BpmnModelDefineException(errorMessage);
		}

		userTaskIndex++;

		UserTask userTask = null;

		String assignee = String.format("${assignee%d}", userTaskIndex);
		String multiInstanceCollection = String.format("assigneeList%d", userTaskIndex);
		String multiInstanceVariable = String.format("assignee%d", userTaskIndex);

		if (counterSign != null && counterSign == 1) {
			// 1: 会签（须所有审批人同意）
			String multiInstanceCompleteCondition = "${nrOfInstances == nrOfCompletedInstances}";
			userTask = bpmnElementService.createUserTask(id, name, assignee, true, false, multiInstanceCollection,
					multiInstanceVariable, multiInstanceCompleteCondition);
		} else if (counterSign != null && counterSign == 2) {
			// 2: 或签（一名审批人同意或拒绝即可）
			String multiInstanceCompleteCondition = "${nrOfCompletedInstances >= 1}";
			userTask = bpmnElementService.createUserTask(id, name, assignee, true, false, multiInstanceCollection,
					multiInstanceVariable, multiInstanceCompleteCondition);
		} else if (counterSign != null && counterSign == 3) {
			// 3: 依次审批
			String multiInstanceCompleteCondition = "${nrOfInstances == nrOfCompletedInstances}";
			userTask = bpmnElementService.createUserTask(id, name, assignee, true, true, multiInstanceCollection,
					multiInstanceVariable, multiInstanceCompleteCondition);
		} else {
			String errorMessage = String.format("审批人-主管节点(%s)未选择多人审批时采用的审批方式", name);
			throw new BpmnModelDefineException(errorMessage);
		}

		if (counterSign != null && (counterSign == 1 || counterSign == 2 || counterSign == 3)) {
			ActivitiListener activitiListener = bpmnElementService.createActivitiListener("start",
					MultiInstanceUserTaskByDirectorExecutionListener.class.getName(),
					ImplementationType.IMPLEMENTATION_TYPE_CLASS);

			FieldExtension fieldExtension1 = bpmnElementService.createFieldExtension("assignListVariableName",
					multiInstanceCollection);
			FieldExtension fieldExtension2 = bpmnElementService.createFieldExtension("leaderLevel",
					directorLevel.toString());
			FieldExtension fieldExtension3 = bpmnElementService.createFieldExtension("useDirectorProxy",
					useDirectorProxy.toString());
			FieldExtension fieldExtension4 = bpmnElementService.createFieldExtension("nodeName", name);
			List<FieldExtension> fieldExtensions = bpmnElementService.createFieldExtensions(fieldExtension1,
					fieldExtension2, fieldExtension3, fieldExtension4);
			activitiListener.setFieldExtensions(fieldExtensions);

			List<ActivitiListener> activitiListeners = startEvent.getExecutionListeners();
			if (activitiListeners == null) {
				activitiListeners = bpmnElementService.createActivitiListeners(activitiListener);
				startEvent.setExecutionListeners(activitiListeners);
			} else {
				activitiListeners.add(activitiListener);
			}
		}

		ActivitiListener activitiListener1 = bpmnElementService.createActivitiListener("complete",
				UserTaskStopListener.class.getName(), ImplementationType.IMPLEMENTATION_TYPE_CLASS);
		if (userTask.getTaskListeners() == null) {
			List<ActivitiListener> activitiListeners = bpmnElementService.createActivitiListeners(activitiListener1);
			userTask.setTaskListeners(activitiListeners);
		} else {
			userTask.getTaskListeners().add(activitiListener1);
		}

		userTaskAddEmailMessageAssignmentListener(userTask);
		createUserTaskContinueListener(userTask);

		return userTask;
	}

	/**
	 * 新建部门主管类型的用户任务
	 * 
	 * @param id                 节点id
	 * @param name               节点名称
	 * @param organizationIdList 部门集合
	 * @param counterSign        1: 会签（须所有审批人同意）2: 或签（一名审批人同意或拒绝即可）
	 * @return 用户任务
	 */
	private UserTask createUserTaskOfOrganization(String id, String name, List<String> organizationIdList,
			Integer counterSign) {
		if (organizationIdList == null || organizationIdList.size() == 0) {
			String errorMessage = String.format("审批人-部门主管节点(%s)未指定部门", name);
			throw new BpmnModelDefineException(errorMessage);
		}

		userTaskIndex++;

		UserTask userTask = null;

		String assignee = String.format("${assignee%d}", userTaskIndex);
		String multiInstanceCollection = String.format("assigneeList%d", userTaskIndex);
		String multiInstanceVariable = String.format("assignee%d", userTaskIndex);

		if (counterSign != null && counterSign == 1) {
			// 1: 会签（须所有审批人同意）
			String multiInstanceCompleteCondition = "${nrOfInstances == nrOfCompletedInstances}";
			userTask = bpmnElementService.createUserTask(id, name, assignee, true, false, multiInstanceCollection,
					multiInstanceVariable, multiInstanceCompleteCondition);
		} else if (counterSign != null && counterSign == 2) {
			// 2: 或签（一名审批人同意或拒绝即可）
			String multiInstanceCompleteCondition = "${nrOfCompletedInstances >= 1}";
			userTask = bpmnElementService.createUserTask(id, name, assignee, true, false, multiInstanceCollection,
					multiInstanceVariable, multiInstanceCompleteCondition);
		} else if (counterSign != null && counterSign == 3) {
			// 3: 依次审批
			String multiInstanceCompleteCondition = "${nrOfInstances == nrOfCompletedInstances}";
			userTask = bpmnElementService.createUserTask(id, name, assignee, true, true, multiInstanceCollection,
					multiInstanceVariable, multiInstanceCompleteCondition);
		} else {
			String errorMessage = String.format("审批人-选择用户组节点(%s)未选择多人审批时采用的审批方式", name);
			throw new BpmnModelDefineException(errorMessage);
		}

		if (counterSign != null && (counterSign == 1 || counterSign == 2 || counterSign == 3)) {
			ActivitiListener activitiListener = bpmnElementService.createActivitiListener("start",
					MultiInstanceUserTaskByOrganizationExecutionListener.class.getName(),
					ImplementationType.IMPLEMENTATION_TYPE_CLASS);

			FieldExtension fieldExtension1 = bpmnElementService.createFieldExtension("assignListVariableName",
					multiInstanceCollection);
			FieldExtension fieldExtension2 = bpmnElementService.createFieldExtension("organizationIdList",
					FormatUtil.getGson().toJson(organizationIdList));
			FieldExtension fieldExtension3 = bpmnElementService.createFieldExtension("nodeName", name);
			List<FieldExtension> fieldExtensions = bpmnElementService.createFieldExtensions(fieldExtension1,
					fieldExtension2, fieldExtension3);
			activitiListener.setFieldExtensions(fieldExtensions);

			List<ActivitiListener> activitiListeners = startEvent.getExecutionListeners();
			if (activitiListeners == null) {
				activitiListeners = bpmnElementService.createActivitiListeners(activitiListener);
				startEvent.setExecutionListeners(activitiListeners);
			} else {
				activitiListeners.add(activitiListener);
			}
		}

		ActivitiListener activitiListener1 = bpmnElementService.createActivitiListener("complete",
				UserTaskStopListener.class.getName(), ImplementationType.IMPLEMENTATION_TYPE_CLASS);
		if (userTask.getTaskListeners() == null) {
			List<ActivitiListener> activitiListeners = bpmnElementService.createActivitiListeners(activitiListener1);
			userTask.setTaskListeners(activitiListeners);
		} else {
			userTask.getTaskListeners().add(activitiListener1);
		}

		userTaskAddEmailMessageAssignmentListener(userTask);
		createUserTaskContinueListener(userTask);

		return userTask;
	}

	/**
	 * 新建发起人自己类型的用户任务
	 * 
	 * @param id   节点id
	 * @param name 节点名称
	 * @param firstApproveNode 是否是第一个审批节点
	 * @return 用户任务
	 */
	private UserTask createUserTaskOfMyself(String id, String name, boolean firstApproveNode) {
		userTaskIndex++;
		UserTask userTask = null;
		String assignee = String.format("${%s}", UserPreference.CREATE_USER_ID);
		userTask = bpmnElementService.createUserTask(id, name, assignee);
		ActivitiListener activitiListener1 = bpmnElementService.createActivitiListener("complete",
				UserTaskStopListener.class.getName(), ImplementationType.IMPLEMENTATION_TYPE_CLASS);
		if (userTask.getTaskListeners() == null) {
			List<ActivitiListener> activitiListeners = bpmnElementService.createActivitiListeners(activitiListener1);
			userTask.setTaskListeners(activitiListeners);
		} else {
			userTask.getTaskListeners().add(activitiListener1);
		}
		
		if(!firstApproveNode) {
			userTaskAddEmailMessageAssignmentListener(userTask);
		}
		
		createUserTaskContinueListener(userTask);
		
		return userTask;
	}

	/**
	 * 新建发起人自选类型的用户任务
	 * 
	 * @param id   节点id
	 * @param name 节点名称
	 * @return 用户任务
	 */
	private UserTask createUserTaskOfOption(String id, String name, Integer counterSign, boolean multiSelect,
			String optionalRange, String condition, List<OptionalUser> optionalUsers,
			List<OptionalGroup> optionalGroups) {
		userTaskIndex++;

		UserTask userTask = null;

		String assignee = String.format("${assignee%d}", userTaskIndex);
		String multiInstanceCollection = String.format("assigneeList%d", userTaskIndex);
		String multiInstanceVariable = String.format("assignee%d", userTaskIndex);

		UserSelectDefine userSelectDefine = new UserSelectDefine();
		userSelectDefine.setNodeId(id);
		userSelectDefine.setNodeName(name);
		userSelectDefine.setMultiSelect(multiSelect);
		userSelectDefine.setOptionalRange(optionalRange);
		userSelectDefine.setCondition(generateJuelExpression(condition));
		userSelectDefine.setVariableName(multiInstanceCollection);
		userSelectDefine.setOptionalUserGroups(optionalGroups);
		userSelectDefine.setOptionalUsers(optionalUsers);

		userSelectDefineList.add(userSelectDefine);

		if (counterSign != null && counterSign == 1) {
			// 1: 会签（须所有审批人同意）
			String multiInstanceCompleteCondition = "${nrOfInstances == nrOfCompletedInstances}";
			userTask = bpmnElementService.createUserTask(id, name, assignee, true, false, multiInstanceCollection,
					multiInstanceVariable, multiInstanceCompleteCondition);
		} else if (counterSign != null && counterSign == 2) {
			// 2: 或签（一名审批人同意或拒绝即可）
			String multiInstanceCompleteCondition = "${nrOfCompletedInstances >= 1}";
			userTask = bpmnElementService.createUserTask(id, name, assignee, true, false, multiInstanceCollection,
					multiInstanceVariable, multiInstanceCompleteCondition);
		} else if (counterSign != null && counterSign == 3) {
			// 3: 依次审批
			String multiInstanceCompleteCondition = "${nrOfInstances == nrOfCompletedInstances}";
			userTask = bpmnElementService.createUserTask(id, name, assignee, true, true, multiInstanceCollection,
					multiInstanceVariable, multiInstanceCompleteCondition);
		} else {
			String errorMessage = String.format("审批人-指定成员节点(%s)未选择多人审批时采用的审批方式", name);
			throw new BpmnModelDefineException(errorMessage);
		}

		ActivitiListener activitiListener1 = bpmnElementService.createActivitiListener("complete",
				UserTaskStopListener.class.getName(), ImplementationType.IMPLEMENTATION_TYPE_CLASS);
		if (userTask.getTaskListeners() == null) {
			List<ActivitiListener> activitiListeners = bpmnElementService.createActivitiListeners(activitiListener1);
			userTask.setTaskListeners(activitiListeners);
		} else {
			userTask.getTaskListeners().add(activitiListener1);
		}

		userTaskAddEmailMessageAssignmentListener(userTask);
		createUserTaskContinueListener(userTask);

		return userTask;
	}

	/**
	 * 新建上一个审批人选择类型的用户任务
	 * 
	 * @param id   节点id
	 * @param name 节点名称
	 * @return 用户任务
	 */
	private UserTask createUserTaskOfPreviousAssigneeSelect(String id, String name, Integer counterSign,
			boolean multiSelect, String optionalRange, String condition, List<OptionalUser> optionalUsers,
			List<OptionalGroup> optionalGroups, String previousNodeId, String[] previousNodeIds) {
		userTaskIndex++;

		UserTask userTask = null;

		String assignee = String.format("${assignee%d}", userTaskIndex);
		String multiInstanceCollection = String.format("assigneeList%d", userTaskIndex);
		String multiInstanceVariable = String.format("assignee%d", userTaskIndex);

		UserSelectDefine userSelectDefine = new UserSelectDefine();
		userSelectDefine.setNodeId(id);
		userSelectDefine.setNodeName(name);
		userSelectDefine.setMultiSelect(multiSelect);
		userSelectDefine.setOptionalRange(optionalRange);
		userSelectDefine.setCondition(generateJuelExpression(condition));
		userSelectDefine.setVariableName(multiInstanceCollection);
		userSelectDefine.setOptionalUserGroups(optionalGroups);
		userSelectDefine.setOptionalUsers(optionalUsers);
		userSelectDefine.setPreviousNodeId(previousNodeId);
		userSelectDefine.setPreviousNodeIds(previousNodeIds);

		previousAssigneeSelectDefineList.add(userSelectDefine);

		if (counterSign != null && counterSign == 1) {
			// 1: 会签（须所有审批人同意）
			String multiInstanceCompleteCondition = "${nrOfInstances == nrOfCompletedInstances}";
			userTask = bpmnElementService.createUserTask(id, name, assignee, true, false, multiInstanceCollection,
					multiInstanceVariable, multiInstanceCompleteCondition);
		} else if (counterSign != null && counterSign == 2) {
			// 2: 或签（一名审批人同意或拒绝即可）
			String multiInstanceCompleteCondition = "${nrOfCompletedInstances >= 1}";
			userTask = bpmnElementService.createUserTask(id, name, assignee, true, false, multiInstanceCollection,
					multiInstanceVariable, multiInstanceCompleteCondition);
		} else if (counterSign != null && counterSign == 3) {
			// 3: 依次审批
			String multiInstanceCompleteCondition = "${nrOfInstances == nrOfCompletedInstances}";
			userTask = bpmnElementService.createUserTask(id, name, assignee, true, true, multiInstanceCollection,
					multiInstanceVariable, multiInstanceCompleteCondition);
		} else {
			String errorMessage = String.format("审批人-指定成员节点(%s)未选择多人审批时采用的审批方式", name);
			throw new BpmnModelDefineException(errorMessage);
		}

		ActivitiListener activitiListener1 = bpmnElementService.createActivitiListener("complete",
				UserTaskStopListener.class.getName(), ImplementationType.IMPLEMENTATION_TYPE_CLASS);
		if (userTask.getTaskListeners() == null) {
			List<ActivitiListener> activitiListeners = bpmnElementService.createActivitiListeners(activitiListener1);
			userTask.setTaskListeners(activitiListeners);
		} else {
			userTask.getTaskListeners().add(activitiListener1);
		}

		userTaskAddEmailMessageAssignmentListener(userTask);
		createUserTaskContinueListener(userTask);

		return userTask;
	}

	/**
	 * 新建抄送任务节点(Service Task)
	 * 
	 * @param id
	 * @param name
	 * @param userIds
	 * @return
	 */
	private ServiceTask createServiceTaskOfCopy(String id, String name, List<Long> copyUserIds) {
		ServiceTask serviceTask = bpmnElementService.createServiceTask(id, name, AddCopyUserDelegate.class);
		String userIds = FormatUtil.getGson().toJson(copyUserIds);
		FieldExtension fieldExtension = bpmnElementService.createFieldExtension("userIds", userIds);
		List<FieldExtension> fieldExtensions = bpmnElementService.createFieldExtensions(fieldExtension);
		serviceTask.setFieldExtensions(fieldExtensions);
		return serviceTask;
	}


	/**
	 * 新建空任务节点(Service Task)
	 * 
	 * @param id
	 * @param name
	 * @param userIds
	 * @return
	 */
	private ServiceTask createServiceTaskOfEmpty(String id, String name) {
		ServiceTask serviceTask = bpmnElementService.createServiceTask(id, name, EmptyDelegate.class);
		return serviceTask;
	}
	
	/**
	 * 生成流转的条件
	 * 
	 * @param conditions 条件
	 * @return
	 * @author ShenChong
	 * @author YangZhiJie 2021-01-21
	 */
	private String getConditionExpression(List<Condition> conditions) {
		StringBuilder conditionExpression = new StringBuilder();
		String codition = null;
		if (conditions != null && conditions.size() > 0) {
			for (int i = 0; i < conditions.size(); i++) {
				Condition condition = conditions.get(i);

				String fieldName = condition.getFieldName();
				String displayType = condition.getDisplayType();
				String fieldCondition = condition.getCondition();

				if (i == 0) {
					// conditionExpression.append("${");
				} else {
					conditionExpression.append(condition.getType());
				}

				if (displayType.equals("IntegerBoxEditor") || displayType.equals("LongBoxEditor")) {
					if (StringUtil.isEmpty(condition.getValueText())) {
						throw new BpmnModelDefineException(String.format("%s字段定义错误。", condition.getDisplayName()));
					}
					codition = String.format("modelData.getFieldDisplayValue0(\"%s\") %s %s", fieldName, fieldCondition,
							condition.getValueText());
					conditionExpression.append(codition);
				} else if (displayType.equals("DoubleBoxEditor") || displayType.equals("FloatBoxEditor")
						|| displayType.equals("BigDecimalEditor")) {
					if (StringUtil.isEmpty(condition.getValueText())) {
						throw new BpmnModelDefineException(String.format("%s字段定义错误。", condition.getDisplayName()));
					}
					codition = String.format("modelData.getFieldDisplayValue0Double(\"%s\") %s %f", fieldName,
							fieldCondition, Double.parseDouble(condition.getValueText()));
					conditionExpression.append(codition);
				} else if (displayType.equals("TextBoxEditor") || displayType.equals("TextAreaEditor")
						|| displayType.equals("CheckBoxEditor")) {
					if (StringUtil.isEmpty(condition.getValueText())) {
						throw new BpmnModelDefineException(String.format("%s字段定义错误。", condition.getDisplayName()));
					}
					if (fieldCondition.equals("contains")) {
						codition = String.format("modelData.getFieldDisplayValue0(\"%s\").contains(\"%s\")", fieldName,
								condition.getValueText());
						conditionExpression.append(codition);
					} else {
						codition = String.format("modelData.getFieldDisplayValue0(\"%s\") %s \"%s\"", fieldName,
								fieldCondition, condition.getValueText());
						conditionExpression.append(codition);
					}
				} else if (displayType.equals("SearchBoxEditor")) {
					throw new BpmnModelDefineException("目前不支持搜索框类型作为判断的条件。");
				} else if (displayType.equals("DateBoxEditor") || displayType.equals("TimeBoxEditor")
						|| displayType.equals("DateTimeBoxEditor")) {
					throw new BpmnModelDefineException("目前不支持日期类型作为判断的条件。");
				} else if (displayType.equals("ListBoxEditor")) {
					Long[] valueIds = condition.getValueIds();
					if (valueIds == null || valueIds.length == 0) {
						throw new BpmnModelDefineException(String.format("%s字段定义错误。", condition.getDisplayName()));
					}
					String valueStr = "";
					for (int index = 0; index < valueIds.length; index++) {
						if (index == 0) {
							valueStr = String.valueOf(valueIds[index]);
						} else {
							valueStr += (", " + String.valueOf(valueIds[index]));
						}
					}

					if (fieldCondition.equals("include")) {
						codition = String.format("modelData.getData().get(\"%s\").idBelongTo(%s)", fieldName, valueStr);
						conditionExpression.append(codition);

					} else if (fieldCondition.equals("exclude")) {
						codition = String.format("modelData.getData().get(\"%s\").idNotBelongTo(%s)", fieldName,
								valueStr);
						conditionExpression.append(codition);
					}
				} else if (displayType.equals("ListBoxEnumEditor")) {
					String[] valueTexts = condition.getValueTexts();
					if (valueTexts == null || valueTexts.length == 0) {
						throw new BpmnModelDefineException(String.format("%s字段定义错误。", condition.getDisplayName()));
					}
					String valueStr = "";
					for (int index = 0; index < valueTexts.length; index++) {
						if (index == 0) {
							valueStr = ("\"" + String.valueOf(valueTexts[index]) + "\"");
						} else {
							valueStr += (", \"" + String.valueOf(valueTexts[index]) + "\"");
						}
					}

					if (fieldCondition.equals("include")) {
						codition = String.format("modelData.getData().get(\"%s\").displayValueBelongTo(0, %s)",
								fieldName, valueStr);
						conditionExpression.append(codition);
					} else if (fieldCondition.equals("exclude")) {
						codition = String.format("modelData.getData().get(\"%s\").displayNotValueBelongTo(0, %s)",
								fieldName, valueStr);
						conditionExpression.append(codition);
					}
				}
			}
			// conditionExpression.append("}");
		}
		return conditionExpression.toString();
	}

	/**
	 * 生成审批流转的条件
	 * 
	 * @param conditions 条件
	 * @return
	 * @author YangZhiJie
	 * @author YangZhiJie 2021-07-23
	 */
	private String getApproveConditionExpression(List<Condition> conditions) {
		StringBuilder conditionExpression = new StringBuilder();
		String codition = null;
		if (conditions != null && conditions.size() > 0) {
			for (int i = 0; i < conditions.size(); i++) {
				Condition condition = conditions.get(i);

				String fieldName = condition.getFieldName();
				String displayType = condition.getDisplayType();
				String fieldCondition = condition.getCondition();

				if (i == 0) {
					// conditionExpression.append("${");
				} else {
					conditionExpression.append(condition.getType());
				}

				if (displayType.equals("IntegerBoxEditor")) {
					if (StringUtil.isEmpty(condition.getValueText())) {
						throw new BpmnModelDefineException(String.format("%s字段定义错误。", condition.getDisplayName()));
					}
					if (fieldCondition.equals("between")) {
						if (StringUtil.isEmpty(condition.getValueText1())) {
							throw new BpmnModelDefineException(String.format("%s字段定义错误。", condition.getDisplayName()));
						}
						codition = String.format("%s >=%s && %s <= %s", fieldName, condition.getValueText(), fieldName,
								condition.getValueText1());
					} else {
						codition = String.format("%s %s %s", fieldName, fieldCondition, condition.getValueText());
					}
					conditionExpression.append(codition);
				} else if (displayType.equals("TextBoxEditor")) {
					if (StringUtil.isEmpty(condition.getValueText())) {
						throw new BpmnModelDefineException(String.format("%s字段定义错误。", condition.getDisplayName()));
					}
//					if (fieldCondition.equals("contains")) {
//						codition = String.format("modelData.getFieldDisplayValue0(\"%s\").contains(\"%s\")", fieldName,
//								condition.getValueText());
//						conditionExpression.append(codition);
//					} else 
					{
						codition = String.format("%s %s \"'%s\"", fieldName, fieldCondition, condition.getValueText());
						conditionExpression.append(codition);
					}
				} else if (displayType.equals("CheckBoxEditor")) {
					codition = String.format("%s == %s", fieldName, condition.getValueText());
					conditionExpression.append(codition);
				} else if (displayType.equals("SearchBoxEditor")) {
					throw new BpmnModelDefineException("目前不支持搜索框类型作为判断的条件。");
				} else if (displayType.equals("DateBoxEditor") || displayType.equals("TimeBoxEditor")
						|| displayType.equals("DateTimeBoxEditor")) {
					throw new BpmnModelDefineException("目前不支持日期类型作为判断的条件。");
				} else if (displayType.equals("ListBoxEditor")) {
					Long[] valueIds = condition.getValueIds();
					if (valueIds == null || valueIds.length == 0) {
						throw new BpmnModelDefineException(String.format("%s字段定义错误。", condition.getDisplayName()));
					}
					String valueStr = "";
					for (int index = 0; index < valueIds.length; index++) {
						if (index == 0) {
							valueStr = String.valueOf(valueIds[index]);
						} else {
							valueStr += (", " + String.valueOf(valueIds[index]));
						}
					}

					if (fieldCondition.equals("include")) {
						codition = String.format("modelData.getData().get(\"%s\").idBelongTo(%s)", fieldName, valueStr);
						conditionExpression.append(codition);

					} else if (fieldCondition.equals("exclude")) {
						codition = String.format("modelData.getData().get(\"%s\").idNotBelongTo(%s)", fieldName,
								valueStr);
						conditionExpression.append(codition);
					}
				} else if (displayType.equals("ListBoxEnumEditor")) {
					String[] valueTexts = condition.getValueTexts();
					if (valueTexts == null || valueTexts.length == 0) {
						throw new BpmnModelDefineException(String.format("%s字段定义错误。", condition.getDisplayName()));
					}
					String valueStr = "";
					for (int index = 0; index < valueTexts.length; index++) {
						if (index == 0) {
							valueStr = ("\"" + String.valueOf(valueTexts[index]) + "\"");
						} else {
							valueStr += (", \"" + String.valueOf(valueTexts[index]) + "\"");
						}
					}

					if (fieldCondition.equals("include")) {
						codition = String.format("modelData.getData().get(\"%s\").displayValueBelongTo(0, %s)",
								fieldName, valueStr);
						conditionExpression.append(codition);
					} else if (fieldCondition.equals("exclude")) {
						codition = String.format("modelData.getData().get(\"%s\").displayNotValueBelongTo(0, %s)",
								fieldName, valueStr);
						conditionExpression.append(codition);
					}
				}
			}
			// conditionExpression.append("}");
		}
		return conditionExpression.toString();
	}

	/**
	 * 创建结束节点
	 * 
	 * @return
	 */
	private EndEvent createEndEvent() {
		EndEvent endEvent = bpmnElementService.createEndEvent(newUuid(), newEndEventId(), true);
		ActivitiListener activitiListener = bpmnElementService.createActivitiListener("start",
				DocumentStatusExecutionListener.class.getName(), ImplementationType.IMPLEMENTATION_TYPE_CLASS);
		List<ActivitiListener> activitiListeners = bpmnElementService.createActivitiListeners(activitiListener);
		endEvent.setExecutionListeners(activitiListeners);
		return endEvent;
	}
	
	

}
