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

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.el.ExpressionFactory;
import javax.el.ValueExpression;
import javax.inject.Inject;
import javax.inject.Named;

import org.activiti.bpmn.model.BpmnModel;
import org.activiti.bpmn.model.ExclusiveGateway;
import org.activiti.bpmn.model.FlowElement;
import org.activiti.bpmn.model.FlowNode;
import org.activiti.bpmn.model.MultiInstanceLoopCharacteristics;
import org.activiti.bpmn.model.SequenceFlow;
import org.activiti.bpmn.model.UserTask;
import org.activiti.engine.ActivitiException;
import org.activiti.engine.ActivitiObjectNotFoundException;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricProcessInstanceQuery;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.history.HistoricTaskInstanceQuery;
import org.activiti.engine.history.HistoricVariableInstance;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.DeploymentBuilder;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.Execution;
import org.activiti.engine.runtime.ExecutionQuery;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Attachment;
import org.activiti.engine.task.Comment;
import org.activiti.engine.task.Task;
import org.activiti.engine.task.TaskQuery;
import org.apache.el.ExpressionFactoryImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.leanwo.activiti.dto.BaseObjectResponse;
import com.leanwo.activiti.dto.BaseRangeResponse;
import com.leanwo.activiti.dto.BaseResponse;
import com.leanwo.activiti.dto.approver.ChildNode;
import com.leanwo.activiti.dto.approver.ConditionNode;
import com.leanwo.activiti.dto.approver.FormOperate;
import com.leanwo.activiti.dto.approver.ProcessData;
import com.leanwo.activiti.dto.approver.Propertie;
import com.leanwo.activiti.dto.base.ChooseTask;
import com.leanwo.activiti.dto.base.CommentDto;
import com.leanwo.activiti.dto.base.DeploymentDto;
import com.leanwo.activiti.dto.base.DisplayType;
import com.leanwo.activiti.dto.base.Form;
import com.leanwo.activiti.dto.base.FormField;
import com.leanwo.activiti.dto.base.FormRequest;
import com.leanwo.activiti.dto.base.HistoricProcessInstanceInfo;
import com.leanwo.activiti.dto.base.HistoricProcessInstanceInfos;
import com.leanwo.activiti.dto.base.HistoricTaskInfo;
import com.leanwo.activiti.dto.base.HistoricTaskInfos;
import com.leanwo.activiti.dto.base.KeyValueObject;
import com.leanwo.activiti.dto.base.ModelData;
import com.leanwo.activiti.dto.base.NeedReceiveCountQueryParam;
import com.leanwo.activiti.dto.base.PreviousUserSelectCalculateRequest;
import com.leanwo.activiti.dto.base.PreviousUserSelectCalculateResponse;
import com.leanwo.activiti.dto.base.ProcessInstanceDescription;
import com.leanwo.activiti.dto.base.ProcessStatusQuery;
import com.leanwo.activiti.dto.base.Range;
import com.leanwo.activiti.dto.base.TaskCommand;
import com.leanwo.activiti.dto.base.TaskComment;
import com.leanwo.activiti.dto.base.TaskCountResponse;
import com.leanwo.activiti.dto.base.TaskDescription;
import com.leanwo.activiti.dto.base.TaskDto;
import com.leanwo.activiti.dto.base.TaskInfo;
import com.leanwo.activiti.dto.base.TaskInfos;
import com.leanwo.activiti.dto.base.TaskQueryParam;
import com.leanwo.activiti.dto.base.TaskQueryParam.TaskQueryOrderBy;
import com.leanwo.activiti.dto.base.TransferTaskDto;
import com.leanwo.activiti.dto.base.UserSelectCalculateRequest;
import com.leanwo.activiti.dto.base.UserSelectDefine;
import com.leanwo.activiti.dto.base.UserSelectDto;
import com.leanwo.activiti.dto.base.UserTaskDto;
import com.leanwo.activiti.dto.base.WorkflowInfo;
import com.leanwo.activiti.dto.base.WorkflowParam;
import com.leanwo.activiti.exception.ServerException;
import com.leanwo.activiti.exception.WorkflowException;
import com.leanwo.activiti.service.base.DeploymentVariableService;
import com.leanwo.activiti.service.base.PreviousUserSelectCondition;
import com.leanwo.activiti.service.base.PreviousUserSelectService;
import com.leanwo.activiti.service.base.WorkflowService;
import com.leanwo.activiti.util.FormatUtil;
import com.leanwo.activiti.util.LoginContextUtil;
import com.leanwo.activiti.util.StringUtil;

import de.odysseus.el.util.SimpleContext;

@Named
public class WorkflowServiceImpl implements WorkflowService {
	private static Logger logger = LoggerFactory.getLogger(WorkflowServiceImpl.class);

	// 启动工作流
	@Inject
	private RepositoryService repositoryService;

	@Inject
	private RuntimeService runtimeService;

	@Inject
	private TaskService taskService;

	@Inject
	private HistoryService historyService;
	
	@Inject
	private ObjectMapper mapper;

	@Inject 
	private DeploymentVariableService deploymentVariableService ;
	

	@Override
	public String startWorkflow(WorkflowInfo workflowInfo) {

		String deploymentId = workflowInfo.getDeploymentId();

		// 查询流程定义
		ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
				.deploymentId(deploymentId).singleResult();
		if (processDefinition == null) {
			throw new WorkflowException("找不到工作流文件。");
		}
		
		ProcessInstance processInstance = null;

		WorkflowParam parameters = workflowInfo.getParameters();
		Map<String, Object> vars = null;
	
		if (parameters != null) {
			vars = parameters.findHashMap();
			if(workflowInfo.getModelData() != null) {
				vars.put("modelData", workflowInfo.getModelData());
			}
		}

		// 启用跳过表达式模式
		if(vars != null) {
			vars.put("_ACTIVITI_SKIP_EXPRESSION_ENABLED", true);
		}
		
		if(vars == null) {
			vars = new HashMap<String, Object>();
		}
		vars.put(UserPreference.ACCOUNT_ID, LoginContextUtil.getLoginContext().getAccountId());
		
		// 启动流程
		try {
			processInstance = runtimeService.startProcessInstanceById(processDefinition.getId(), vars);
		} catch (Exception ex) {
			logger.error("工作流启动失败", ex);
			throw new WorkflowException(ex.getMessage());
		}

		return processInstance.getId();
	}

	@Override
	public void deleteAllDeployment() {

		// 得到流程存储服务
		// 得到所有的资源部署
		List<Deployment> deployments = repositoryService.createDeploymentQuery().list();
		if (deployments != null) {
			for (int i = 0; i < deployments.size(); i++) {
				Deployment deployment = deployments.get(i);
				repositoryService.deleteDeployment(deployment.getId(), true);
				logger.debug("delete deployment " + deployment.getId());
			}
		}
	}

	@Override
	public String deploy(String fileName) {
		File bpmnFile = new File(fileName);
		if (!bpmnFile.exists()) {
			throw new ServerException("部署文件" + fileName + "不存在。");
		}
		try {
			FileInputStream bpmnFileInputStream = new FileInputStream(bpmnFile);
			Deployment deployment = repositoryService.createDeployment()
					.addInputStream(bpmnFile.getName(), bpmnFileInputStream).deploy();
			if (deployment != null) {
				// 查询流程定义实体
				ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
						.deploymentId(deployment.getId()).singleResult();
				if (processDefinition == null) {
					throw new ServerException("流程部署失败");
				} else {
					logger.debug("部署流程(" + processDefinition.getDiagramResourceName() + ")成功。");
				}
			}
			return deployment.getId();
		} catch (FileNotFoundException e) {
			logger.error("找不到部署文件。", e);
			throw new ServerException("找不到部署文件。");
		} catch (Exception e) {
			logger.error("流程部署失败。", e);
			throw new ServerException("流程部署失败。");
		}
	}


	@Override
	public String deploy(BpmnModel bpmnModel, Map<String, String> extraStringDatas) {
		String resourceName = FormatUtil.formatDateTimeFormat(new Date());
		resourceName = resourceName.replace(" ", "_").replace(":", "_").replace("-", "_") + ".bpmn";

		DeploymentBuilder deploymentBuilder = repositoryService.createDeployment().addBpmnModel(resourceName, bpmnModel);
		
		
		Deployment deployment = deploymentBuilder.deploy();
		if (deployment != null) {
			// 查询流程定义实体
			ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
					.deploymentId(deployment.getId()).singleResult();
			if (processDefinition == null) {
				throw new ServerException("流程部署失败");
			} else {
				logger.debug("部署流程(" + processDefinition.getDiagramResourceName() + ")成功。");
			}
		}

		// 增加字符串变量的存储
		// add by jack 2021-12-23
		if(extraStringDatas != null) {
			deploymentVariableService.addDeploymentVariables(deployment.getId(), extraStringDatas);
		}
		return deployment.getId();
	}
	
	/**
	 * @author YangZhiJie 20171115
	 */
	@Override
	public void deleteDeployment(String deploymentId) {
		if (deploymentId != null && deploymentId.length() > 0) {
			try {
				repositoryService.deleteDeployment(deploymentId, true);
			} catch (ActivitiObjectNotFoundException ex) {
				logger.info("工作流已被删除:" + deploymentId);
			} catch (Exception ex) {
				logger.error("工作流删除异常:" + deploymentId, ex);
				throw new WorkflowException("工作流删除异常");
			}
		}
	}

	@Override
	public Integer getProcessInstanceCount(String deploymentId) {
		return (int) runtimeService.createProcessInstanceQuery().deploymentId(deploymentId).count();
	}

	@Override
	public TaskInfos queryNeedApproveTaskInfo(TaskQueryParam taskQueryParam) {
		// 根据用户查询任务
		TaskQuery taskQuery = taskService.createTaskQuery().active().taskAssignee(taskQueryParam.getAssigneeId());

		String condition = taskQueryParam.getCondition();
		Long createUserId = taskQueryParam.getStartUserId();
		Date startAfter = taskQueryParam.getStartAfter();
		Date startBefore = taskQueryParam.getStartBefore();
		String deploymentId = taskQueryParam.getDeploymentId();
		boolean advancedQuery = taskQueryParam.isAdvancedQuery();
		Range range = taskQueryParam.getRange();
		TaskQueryOrderBy taskQueryOrderBy = taskQueryParam.getTaskQueryOrderBy();
		boolean orderByAsc = taskQueryParam.isOrderByAsc();

		// 审批标题、编号、正文内容、审批意见
		if (condition != null && condition.length() > 0) {
			condition = ("%" + condition + "%");
			taskQuery = taskQuery.or().processVariableValueLike(UserPreference.DOCUMENT_NO, condition)
					.processVariableValueLike(UserPreference.APPROVE_TITLE, condition)
					.processVariableValueLike(UserPreference.APPROVE_CONTENT, condition)
					.processVariableValueLike(UserPreference.COMMENT, condition).endOr();
		}

		// 审批类型
		if (deploymentId != null && deploymentId.length() > 0) {
			taskQuery = taskQuery.deploymentId(deploymentId);
		}

		if (advancedQuery) {
			// 发起日期（提交审批日期）
			if (startAfter != null) {
				taskQuery = taskQuery.processVariableValueGreaterThanOrEqual(UserPreference.PROCESS_INSTANCE_BEGIN_DATE,
						startAfter);
			}

			if (startBefore != null) {
				taskQuery = taskQuery.processVariableValueLessThanOrEqual(UserPreference.PROCESS_INSTANCE_BEGIN_DATE,
						startBefore);
			}

			// 审批单发起人
			if (createUserId != null) {
				taskQuery = taskQuery.processVariableValueEquals(UserPreference.CREATE_USER_ID, createUserId);
			}
		}

		if (orderByAsc) {
			taskQuery = taskQuery.orderByTaskCreateTime().asc();
		} else {
			taskQuery = taskQuery.orderByTaskCreateTime().desc();
		}

		List<Task> tasks = taskQuery.listPage(range.getStart(), range.getLength());
		List<TaskInfo> taskInfoList = new ArrayList<>();
		if (tasks != null) {
			for (Task task : tasks) {
				taskInfoList.add(getTaskInfo(task));
			}
		}
		long count = taskQuery.count();
		TaskInfos taskInfos = new TaskInfos();
		taskInfos.setTaskInfo(taskInfoList);
		taskInfos.setRange(range);
		taskInfos.setTotalCount(count);

		return taskInfos;
	}

	@Override
	public TaskInfos queryAllNeedApproveTaskInfo(TaskQueryParam taskQueryParam) {

		// 根据用户查询任务
		TaskQuery taskQuery = taskService.createTaskQuery().active();

		Long createUserId = taskQueryParam.getStartUserId();
		Date startAfter = taskQueryParam.getStartAfter();
		Date startBefore = taskQueryParam.getStartBefore();
		boolean advancedQuery = taskQueryParam.isAdvancedQuery();
		Range range = taskQueryParam.getRange();

		if (advancedQuery) {
			// 发起日期（提交审批日期）
			if (startAfter != null) {
				taskQuery = taskQuery.processVariableValueGreaterThanOrEqual(UserPreference.PROCESS_INSTANCE_BEGIN_DATE,
						startAfter);
			}

			if (startBefore != null) {
				taskQuery = taskQuery.processVariableValueLessThanOrEqual(UserPreference.PROCESS_INSTANCE_BEGIN_DATE,
						startBefore);
			}

			// 审批单发起人
			if (createUserId != null) {
				taskQuery = taskQuery.processVariableValueEquals(UserPreference.CREATE_USER_ID, createUserId);
			}
		}

		List<Task> tasks = taskQuery.orderByTaskCreateTime().asc().list();
		List<TaskInfo> taskInfoList = new ArrayList<>();
		long count = 0;
		if (tasks != null) {
			for (Task task : tasks) {
				Date date1 = task.getCreateTime();
				Date date2 = new Date();
				Long day = daysBetween(date1, date2);
				// 审批时间超过三天的将数据填充进去
				if (day > 3) {
					count++;
					TaskInfo taskInfo = getTaskInfo(task);
					taskInfo.setOverdueDays(day);
					taskInfoList.add(taskInfo);
				}
			}
		}

		TaskInfos taskInfos = new TaskInfos();
		taskInfos.setTaskInfo(taskInfoList);
		taskInfos.setRange(range);
		taskInfos.setTotalCount(count);

		return taskInfos;
	}

	// 时间间隔天数
	public Long daysBetween(Date date1, Date date2) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date1);
		long time1 = cal.getTimeInMillis();
		cal.setTime(date2);
		long time2 = cal.getTimeInMillis();
		long between_days = (time2 - time1) / (1000 * 3600 * 24);
		return Long.valueOf(String.valueOf(between_days));
	}

	/**
	 * 根据Task获取TaskInfo
	 * 
	 * @param task
	 * @return
	 */
	private TaskInfo getTaskInfo(Task task) {

		TaskInfo taskInfo = new TaskInfo();
		if (task.getAssignee() != null) {
			taskInfo.setAssigneeId(Long.valueOf(task.getAssignee()));
		}
		taskInfo.setId(task.getId());
		taskInfo.setProcessInstanceId(task.getProcessInstanceId());
		taskInfo.setTaskDefinitionKey(task.getTaskDefinitionKey());
		ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
				.processDefinitionId(task.getProcessDefinitionId()).singleResult();
		taskInfo.setType(processDefinition.getName());
		taskInfo.setTitle((String) taskService.getVariable(task.getId(), UserPreference.APPROVE_TITLE));
		taskInfo.setNo((String) taskService.getVariable(task.getId(), UserPreference.DOCUMENT_NO));
		taskInfo.setContent((String) taskService.getVariable(task.getId(), UserPreference.APPROVE_CONTENT));
		taskInfo.setStartDate(task.getCreateTime());
		taskInfo.setStartUserId((Long) taskService.getVariable(task.getId(), UserPreference.CREATE_USER_ID));
		taskInfo.setStartUserName((String) taskService.getVariable(task.getId(), UserPreference.CREATE_USER_NAME));
		taskInfo.setDocumentStatus(task.isSuspended() ? "已完成" : "进行中");
		taskInfo.setWindowNo((String) taskService.getVariable(task.getId(), UserPreference.WINDOW_NO));
		taskInfo.setRecordId((Long) taskService.getVariable(task.getId(), UserPreference.RECORD_ID));
		taskInfo.setTabIndex((Integer) taskService.getVariable(task.getId(), UserPreference.TAB_INDEX));
		taskInfo.setFormKey(task.getFormKey());
		taskInfo.setName(task.getName());
		taskInfo.setDescription(task.getDescription());
		return taskInfo;
	}

	@Override
	public HistoricTaskInfos queryApprovedTask(TaskQueryParam taskQueryParam) {

		// 根据用户查询任务
		HistoricTaskInstanceQuery historicTaskInstanceQuery = historyService.createHistoricTaskInstanceQuery()
//				 .finished()
				.taskAssignee(taskQueryParam.getAssigneeId());

		String condition = taskQueryParam.getCondition();
		String deploymentId = taskQueryParam.getDeploymentId();
		ProcessStatusQuery processStatusQuery = taskQueryParam.getProcessStatusQuery();
		Range range = taskQueryParam.getRange();

		boolean advancedQuery = taskQueryParam.isAdvancedQuery();
		Date startAfter = taskQueryParam.getStartAfter();
		Date startBefore = taskQueryParam.getStartBefore();
		Date finishAfter = taskQueryParam.getFinishAfter();
		Date finishBefore = taskQueryParam.getFinishBefore();
		Long createUserId = taskQueryParam.getStartUserId();
		TaskQueryOrderBy taskQueryOrderBy = taskQueryParam.getTaskQueryOrderBy();
		boolean orderByAsc = taskQueryParam.isOrderByAsc();

		// 审批标题、编号、正文内容、审批意见
		if (condition != null && condition.length() > 0) {
			condition = ("%" + condition + "%");
			historicTaskInstanceQuery = historicTaskInstanceQuery.or()
					.processVariableValueLike(UserPreference.DOCUMENT_NO, condition)
					.processVariableValueLike(UserPreference.APPROVE_TITLE, condition)
					.processVariableValueLike(UserPreference.APPROVE_CONTENT, condition)
					.processVariableValueLike(UserPreference.COMMENT, condition).endOr();
		}

		// 审批类型
		if (deploymentId != null && deploymentId.length() > 0) {
			historicTaskInstanceQuery = historicTaskInstanceQuery.deploymentId(deploymentId);
		}

		// 审批状态
		if (processStatusQuery != null) {
			if (processStatusQuery.equals(ProcessStatusQuery.FINISH)) {
				historicTaskInstanceQuery = historicTaskInstanceQuery.processFinished();
			} else if (processStatusQuery.equals(ProcessStatusQuery.RUNNING)) {
				historicTaskInstanceQuery = historicTaskInstanceQuery.processUnfinished();
			}
		}

		// 高级搜索
		if (advancedQuery) {
			// 发起日期（提交审批日期）
			if (startAfter != null) {
				historicTaskInstanceQuery = historicTaskInstanceQuery
						.processVariableValueGreaterThanOrEqual(UserPreference.PROCESS_INSTANCE_BEGIN_DATE, startAfter);
			}

			if (startBefore != null) {
				historicTaskInstanceQuery = historicTaskInstanceQuery
						.processVariableValueLessThanOrEqual(UserPreference.PROCESS_INSTANCE_BEGIN_DATE, startBefore);
			}

			// 完成日期（最终审批日期）
			if (finishAfter != null) {
				historicTaskInstanceQuery = historicTaskInstanceQuery.processVariableValueGreaterThanOrEqual(
						UserPreference.PROCESS_INSTANCE_BEGIN_DATE, finishAfter);
			}

			if (finishBefore != null) {
				historicTaskInstanceQuery = historicTaskInstanceQuery
						.processVariableValueLessThanOrEqual(UserPreference.PROCESS_INSTANCE_BEGIN_DATE, finishBefore);
			}

			// 审批单发起人
			if (createUserId != null) {
				historicTaskInstanceQuery = historicTaskInstanceQuery
						.processVariableValueEquals(UserPreference.CREATE_USER_ID, createUserId);
			}
		}

		if (taskQueryOrderBy == null) {
			historicTaskInstanceQuery = historicTaskInstanceQuery.orderByTaskCreateTime();
		} else {
			switch (taskQueryOrderBy) {
			case StartTime:
				historicTaskInstanceQuery = historicTaskInstanceQuery.orderByTaskCreateTime();
				break;
			case EndTime:
				historicTaskInstanceQuery = historicTaskInstanceQuery.orderByHistoricTaskInstanceEndTime();
				break;
			}
		}

		if (orderByAsc) {
			historicTaskInstanceQuery = historicTaskInstanceQuery.asc();
		} else {
			historicTaskInstanceQuery = historicTaskInstanceQuery.desc();
		}

		List<HistoricTaskInstance> historicTaskInstances = historicTaskInstanceQuery.listPage(range.getStart(),
				range.getLength());

		List<HistoricTaskInfo> historicTaskInfoList = new ArrayList<>();
		if (historicTaskInstances != null) {
			for (HistoricTaskInstance historicTaskInstance : historicTaskInstances) {
				HistoricTaskInfo historicTaskInfo = getHistoricTaskInfo(historicTaskInstance);
				historicTaskInfoList.add(historicTaskInfo);
			}
		}

		long totalCount = historicTaskInstanceQuery.count();

		HistoricTaskInfos historicTaskInfos = new HistoricTaskInfos();
		historicTaskInfos.setHistoricTaskInfos(historicTaskInfoList);
		historicTaskInfos.setRange(range);
		historicTaskInfos.setTotalCount(totalCount);

		return historicTaskInfos;
	}

	@Override
	public HistoricTaskInfos queryNotApprovedTask(TaskQueryParam taskQueryParam) {

		// 根据用户查询任务
		HistoricTaskInstanceQuery historicTaskInstanceQuery = historyService.createHistoricTaskInstanceQuery()
				// .finished()
				.taskAssignee(taskQueryParam.getAssigneeId())
				.processVariableValueLike(UserPreference.COMMAND, TaskCommand.REJECT.toString());

		String condition = taskQueryParam.getCondition();
		String deploymentId = taskQueryParam.getDeploymentId();
		ProcessStatusQuery processStatusQuery = taskQueryParam.getProcessStatusQuery();
		Range range = taskQueryParam.getRange();

		boolean advancedQuery = taskQueryParam.isAdvancedQuery();
		Date startAfter = taskQueryParam.getStartAfter();
		Date startBefore = taskQueryParam.getStartBefore();
		Date finishAfter = taskQueryParam.getFinishAfter();
		Date finishBefore = taskQueryParam.getFinishBefore();
		Long createUserId = taskQueryParam.getStartUserId();
		TaskQueryOrderBy taskQueryOrderBy = taskQueryParam.getTaskQueryOrderBy();
		boolean orderByAsc = taskQueryParam.isOrderByAsc();

		// 审批标题、编号、正文内容、审批意见
		if (condition != null && condition.length() > 0) {
			condition = ("%" + condition + "%");
			historicTaskInstanceQuery = historicTaskInstanceQuery.or()
					.processVariableValueLike(UserPreference.DOCUMENT_NO, condition)
					.processVariableValueLike(UserPreference.APPROVE_TITLE, condition)
					.processVariableValueLike(UserPreference.APPROVE_CONTENT, condition)
					.processVariableValueLike(UserPreference.COMMENT, condition).endOr();
		}

		// 审批类型
		if (deploymentId != null && deploymentId.length() > 0) {
			historicTaskInstanceQuery = historicTaskInstanceQuery.deploymentId(deploymentId);
		}

		// 审批状态
		if (processStatusQuery != null) {
			if (processStatusQuery.equals(ProcessStatusQuery.FINISH)) {
				historicTaskInstanceQuery = historicTaskInstanceQuery.processFinished();
			} else if (processStatusQuery.equals(ProcessStatusQuery.RUNNING)) {
				historicTaskInstanceQuery = historicTaskInstanceQuery.processUnfinished();
			}
		}

		// 高级搜索
		if (advancedQuery) {
			// 发起日期（提交审批日期）
			if (startAfter != null) {
				historicTaskInstanceQuery = historicTaskInstanceQuery
						.processVariableValueGreaterThanOrEqual(UserPreference.PROCESS_INSTANCE_BEGIN_DATE, startAfter);
			}

			if (startBefore != null) {
				historicTaskInstanceQuery = historicTaskInstanceQuery
						.processVariableValueLessThanOrEqual(UserPreference.PROCESS_INSTANCE_BEGIN_DATE, startBefore);
			}

			// 完成日期（最终审批日期）
			if (finishAfter != null) {
				historicTaskInstanceQuery = historicTaskInstanceQuery.processVariableValueGreaterThanOrEqual(
						UserPreference.PROCESS_INSTANCE_BEGIN_DATE, finishAfter);
			}

			if (finishBefore != null) {
				historicTaskInstanceQuery = historicTaskInstanceQuery
						.processVariableValueLessThanOrEqual(UserPreference.PROCESS_INSTANCE_BEGIN_DATE, finishBefore);
			}

			// 审批单发起人
			if (createUserId != null) {
				historicTaskInstanceQuery = historicTaskInstanceQuery
						.processVariableValueEquals(UserPreference.CREATE_USER_ID, createUserId);
			}
		}

		if (taskQueryOrderBy == null) {
			historicTaskInstanceQuery = historicTaskInstanceQuery.orderByTaskCreateTime();
		} else {
			switch (taskQueryOrderBy) {
			case StartTime:
				historicTaskInstanceQuery = historicTaskInstanceQuery.orderByTaskCreateTime();
				break;
			case EndTime:
				historicTaskInstanceQuery = historicTaskInstanceQuery.orderByHistoricTaskInstanceEndTime();
				break;
			}
		}

		if (orderByAsc) {
			historicTaskInstanceQuery = historicTaskInstanceQuery.asc();
		} else {
			historicTaskInstanceQuery = historicTaskInstanceQuery.desc();
		}

		List<HistoricTaskInstance> historicTaskInstances = historicTaskInstanceQuery.listPage(range.getStart(),
				range.getLength());

		List<HistoricTaskInfo> historicTaskInfoList = new ArrayList<>();
		if (historicTaskInstances != null) {
			for (HistoricTaskInstance historicTaskInstance : historicTaskInstances) {
				HistoricTaskInfo historicTaskInfo = getHistoricTaskInfo(historicTaskInstance);
				historicTaskInfoList.add(historicTaskInfo);
			}
		}

		long totalCount = historicTaskInstanceQuery.count();

		HistoricTaskInfos historicTaskInfos = new HistoricTaskInfos();
		historicTaskInfos.setHistoricTaskInfos(historicTaskInfoList);
		historicTaskInfos.setRange(range);
		historicTaskInfos.setTotalCount(totalCount);

		return historicTaskInfos;
	}

	/**
	 * 获取历史任务消息
	 * 
	 * @param historicTaskInstance
	 * @return
	 */
	private HistoricTaskInfo getHistoricTaskInfo(HistoricTaskInstance historicTaskInstance) {

		HistoricTaskInfo historyTaskInfo = new HistoricTaskInfo();
		historyTaskInfo.setId(historicTaskInstance.getId());
		String processInstanceId = historicTaskInstance.getProcessInstanceId();

		ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
				.processDefinitionId(historicTaskInstance.getProcessDefinitionId()).singleResult();

		historyTaskInfo.setType(processDefinition.getName());
		historyTaskInfo.setTitle((String) getHistoryProcessInstanceVariableValue(historyService, processInstanceId,
				UserPreference.APPROVE_TITLE));
		historyTaskInfo.setNo((String) getHistoryProcessInstanceVariableValue(historyService, processInstanceId,
				UserPreference.DOCUMENT_NO));
		historyTaskInfo.setContent((String) getHistoryProcessInstanceVariableValue(historyService, processInstanceId,
				UserPreference.APPROVE_CONTENT));
		historyTaskInfo.setStartDate(historicTaskInstance.getCreateTime());
		historyTaskInfo.setStartUserId(getHistoryTaskVariableValue(historyService, historicTaskInstance.getId(),
				UserPreference.CREATE_USER_ID) != null
						? getHistoryTaskVariableValue(historyService, historicTaskInstance.getId(),
								UserPreference.CREATE_USER_ID).toString()
						: null);
		historyTaskInfo.setStartUserName((String) getHistoryTaskVariableValue(historyService,
				historicTaskInstance.getId(), UserPreference.CREATE_USER_NAME));
		historyTaskInfo.setEndDate(historicTaskInstance.getEndTime());
		historyTaskInfo.setDocumentStatus((historicTaskInstance.getEndTime() != null) ? "已完成" : "进行中");
		String windowNo = (String) getHistoryProcessInstanceVariableValue(historyService, processInstanceId,
				UserPreference.WINDOW_NO);
		if(windowNo != null) {
			historyTaskInfo.setWindowNo(windowNo.toString());
		}
		
		Integer tabIndex = (Integer) getHistoryProcessInstanceVariableValue(historyService, processInstanceId, UserPreference.TAB_INDEX);
		historyTaskInfo.setTabIndex(tabIndex);
		
		Long recordId = (Long) getHistoryProcessInstanceVariableValue(historyService, processInstanceId, UserPreference.RECORD_ID);
		if(recordId != null) {
			historyTaskInfo.setRecordId(recordId.toString());
		}

		return historyTaskInfo;
	}

	/**
	 * 获取历史任务的变量值
	 * 
	 * @param historyService        Activiti 历史服务
	 * @param historyTaskInstanceId 历史任务Id
	 * @param variableName          变量值
	 * @return
	 */
	private Object getHistoryTaskVariableValue(HistoryService historyService, String historyTaskInstanceId,
			String variableName) {
		HistoricVariableInstance historicVariableInstance = historyService.createHistoricVariableInstanceQuery()
				.taskId(historyTaskInstanceId).variableName(variableName).singleResult();
		if (historicVariableInstance == null) {
			return null;
		}
		return historicVariableInstance.getValue();
	}

	private Object getHistoryProcessInstanceVariableValue(HistoryService historyService,
			String historyProcessInstanceId, String variableName) {

		List<HistoricVariableInstance> list = historyService.createHistoricVariableInstanceQuery()
				.processInstanceId(historyProcessInstanceId).list();
		if (list != null && list.size() > 0) {
			for (HistoricVariableInstance h : list) {
				logger.debug(
						h.getId() + "; " + h.getVariableName() + "; " + h.getValue() + "; " + h.getVariableTypeName());
			}
		}

		HistoricVariableInstance historicVariableInstance = historyService.createHistoricVariableInstanceQuery()
				.processInstanceId(historyProcessInstanceId).variableName(variableName).singleResult();
		if (historicVariableInstance == null) {
			return null;
		}
		return historicVariableInstance.getValue();
	}

	@Override
	public HistoricProcessInstanceInfos queryMyApplyProcessInfo(TaskQueryParam taskQueryParam) {

		HistoricProcessInstanceQuery historicProcessInstanceQuery = historyService.createHistoricProcessInstanceQuery();

		String condition = taskQueryParam.getCondition();
		String deploymentId = taskQueryParam.getDeploymentId();
		ProcessStatusQuery processStatusQuery = taskQueryParam.getProcessStatusQuery();
		Range range = taskQueryParam.getRange();

		boolean advancedQuery = taskQueryParam.isAdvancedQuery();
		Date startAfter = taskQueryParam.getStartAfter();
		Date startBefore = taskQueryParam.getStartBefore();
		Date finishAfter = taskQueryParam.getFinishAfter();
		Date finishBefore = taskQueryParam.getFinishBefore();
		Long createUserId = taskQueryParam.getCreateUserId();
		TaskQueryOrderBy taskQueryOrderBy = taskQueryParam.getTaskQueryOrderBy();
		boolean orderByAsc = taskQueryParam.isOrderByAsc();

		// 审批标题、编号、正文内容、审批意见
		if (condition != null && condition.length() > 0) {
			condition = ("%" + condition + "%");
			historicProcessInstanceQuery = historicProcessInstanceQuery.or()
					.variableValueLike(UserPreference.DOCUMENT_NO, condition)
					.variableValueLike(UserPreference.APPROVE_TITLE, condition)
					.variableValueLike(UserPreference.APPROVE_CONTENT, condition)
					.variableValueLike(UserPreference.COMMENT, condition).endOr();
		}

		// 审批类型
		if (deploymentId != null && deploymentId.length() > 0) {
			historicProcessInstanceQuery = historicProcessInstanceQuery.deploymentId(deploymentId);
		}

		// 审批状态
		if (processStatusQuery != null) {
			if (processStatusQuery.equals(ProcessStatusQuery.FINISH)) {
				historicProcessInstanceQuery = historicProcessInstanceQuery.finished();
			} else if (processStatusQuery.equals(ProcessStatusQuery.RUNNING)) {
				historicProcessInstanceQuery = historicProcessInstanceQuery.unfinished();
			}
		}

		// add by jack
		historicProcessInstanceQuery = historicProcessInstanceQuery
				.variableValueGreaterThan(UserPreference.CREATE_USER_ID, 0L);

		// 审批单发起人
		if (createUserId != null) {
			historicProcessInstanceQuery = historicProcessInstanceQuery
					.variableValueEquals(UserPreference.CREATE_USER_ID, createUserId);
		}

		// 高级搜索
		if (advancedQuery) {
			// 发起日期（提交审批日期）
			if (startAfter != null) {
				historicProcessInstanceQuery = historicProcessInstanceQuery.startedAfter(startAfter);
			}

			if (startBefore != null) {
				historicProcessInstanceQuery = historicProcessInstanceQuery.startedBefore(startBefore);
			}

			// 完成日期（最终审批日期）
			if (finishAfter != null) {
				historicProcessInstanceQuery = historicProcessInstanceQuery.finishedAfter(finishAfter);
			}

			if (finishBefore != null) {
				historicProcessInstanceQuery = historicProcessInstanceQuery.finishedBefore(finishBefore);
			}
		}

		if (taskQueryOrderBy == null) {
			historicProcessInstanceQuery = historicProcessInstanceQuery.orderByProcessInstanceStartTime();
		} else {
			switch (taskQueryOrderBy) {
			case StartTime:
				historicProcessInstanceQuery = historicProcessInstanceQuery.orderByProcessInstanceStartTime();
				break;
			case EndTime:
				historicProcessInstanceQuery = historicProcessInstanceQuery.orderByProcessInstanceEndTime();
				break;
			}
		}

		if (orderByAsc) {
			historicProcessInstanceQuery = historicProcessInstanceQuery.asc();
		} else {
			historicProcessInstanceQuery = historicProcessInstanceQuery.desc();
		}

		List<HistoricProcessInstance> historicProcessInstances = historicProcessInstanceQuery.listPage(range.getStart(),
				range.getLength());

		List<HistoricProcessInstanceInfo> historicProcessInstanceInfoList = new ArrayList<>();
		if (historicProcessInstances != null) {
			for (HistoricProcessInstance historicProcessInstance : historicProcessInstances) {
				historicProcessInstanceInfoList.add(getHistoricProcessInstanceInfos(historicProcessInstance));
			}
		}

		long totalCount = historicProcessInstanceQuery.count();

		HistoricProcessInstanceInfos historicProcessInstanceInfos = new HistoricProcessInstanceInfos();
		historicProcessInstanceInfos.setHistoricProcessInstanceInfos(historicProcessInstanceInfoList);
		historicProcessInstanceInfos.setRange(range);
		historicProcessInstanceInfos.setTotalCount(totalCount);

		return historicProcessInstanceInfos;
	}

	/**
	 * 获取历史工作流实例信息
	 * 
	 * @param historicProcessInstanceInfo
	 * @return
	 */
	private HistoricProcessInstanceInfo getHistoricProcessInstanceInfos(
			HistoricProcessInstance historicProcessInstance) {

		HistoricProcessInstanceInfo historicProcessInstanceInfo = new HistoricProcessInstanceInfo();
		historicProcessInstanceInfo.setId(historicProcessInstance.getId());
		Map<String, Object> data = historicProcessInstance.getProcessVariables();

		historicProcessInstanceInfo.setType(historicProcessInstance.getProcessDefinitionName());
		historicProcessInstanceInfo.setTitle((String) getHistoryProcessInstanceVariableValue(historyService,
				historicProcessInstance.getId(), UserPreference.APPROVE_TITLE));
		historicProcessInstanceInfo.setNo((String) getHistoryProcessInstanceVariableValue(historyService,
				historicProcessInstance.getId(), UserPreference.DOCUMENT_NO));
		historicProcessInstanceInfo.setContent((String) getHistoryProcessInstanceVariableValue(historyService,
				historicProcessInstance.getId(), UserPreference.APPROVE_CONTENT));
		historicProcessInstanceInfo.setStartDate(historicProcessInstance.getStartTime());
		historicProcessInstanceInfo.setStartUserId(getHistoryProcessInstanceVariableValue(historyService,
				historicProcessInstance.getId(), UserPreference.CREATE_USER_ID) != null
						? getHistoryProcessInstanceVariableValue(historyService, historicProcessInstance.getId(),
								UserPreference.CREATE_USER_ID).toString()
						: null);
		historicProcessInstanceInfo.setStartUserName((String) getHistoryProcessInstanceVariableValue(historyService,
				historicProcessInstance.getId(), UserPreference.CREATE_USER_NAME));
		historicProcessInstanceInfo.setEndDate(historicProcessInstance.getEndTime());
		historicProcessInstanceInfo.setDocumentStatus((historicProcessInstance.getEndTime() != null) ? "已完成" : "进行中");
		String windowNo = (String) getHistoryProcessInstanceVariableValue(historyService,
				historicProcessInstance.getId(), UserPreference.WINDOW_NO);
		historicProcessInstanceInfo.setWindowNo(windowNo.toString());
		historicProcessInstanceInfo.setTabIndex(getHistoryProcessInstanceVariableValue(historyService,
				historicProcessInstance.getId(), UserPreference.TAB_INDEX).toString());
		historicProcessInstanceInfo.setRecordId(getHistoryProcessInstanceVariableValue(historyService,
				historicProcessInstance.getId(), UserPreference.RECORD_ID).toString());

		return historicProcessInstanceInfo;
	}

	@Override
	public List<Long> countActiveByProcessInstanceId(List<String> processInstanceIds) {
		List<Long> results = new ArrayList<Long>();
		for (String processInstanceId : processInstanceIds) {
			Long count = 0L;
			if (processInstanceId != null && processInstanceId.length() > 0) {
				count = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).active()
						.count();
			}
			results.add(count);
		}
		return results;
	}

	@Override
	public Long getTaskInfoNeedReceiveCount(NeedReceiveCountQueryParam param) {
		List<String> groupIds = param.getGroupIds();
		// 根据用户查询任务
		Long count = 0L;
		if (groupIds != null) {
			count = taskService.createTaskQuery().active().taskCandidateGroupIn(groupIds).count();
		} else {
			count = taskService.createTaskQuery().active().taskCandidateUser(param.getCandidateUserId()).count();
		}
		return count;
	}

	@Override
	public Long getTaskInfoNeedApproveCount(Long userId) {
		return taskService.createTaskQuery().active().taskAssignee(String.valueOf(userId)).count();
	}


	@Override
	public ProcessInstanceDescription getProcessInstanceDescription(String processInstanceId) {

		ProcessInstanceDescription processDescription = new ProcessInstanceDescription();
		List<TaskComment> taskComments = new ArrayList<>();

		List<HistoricTaskInstance> historicTaskInstances = historyService.createHistoricTaskInstanceQuery()
				.processInstanceId(processInstanceId).orderByTaskCreateTime().asc().list();
		if (historicTaskInstances != null && historicTaskInstances.size() > 0) {
			for (HistoricTaskInstance historicTaskInstance : historicTaskInstances) {
				String assigneeIdString = historicTaskInstance.getAssignee();

				if (assigneeIdString == null) {
					continue;
				}

				TaskComment taskComment = new TaskComment();

				taskComment.setId(historicTaskInstance.getId());
				taskComment.setTaskName(historicTaskInstance.getName());
				taskComment.setUserId(assigneeIdString);

				// 查询评论信息
				List<Comment> comments = taskService.getTaskComments(historicTaskInstance.getId());
				if (comments != null && comments.size() > 0) {
					List<CommentDto> comments1 = new ArrayList<CommentDto>();
					for (Comment comment : comments) {
						CommentDto commentTemp = new CommentDto();
						commentTemp.setComment(comment.getFullMessage());
						commentTemp.setCommentDate(comment.getTime());
						comments1.add(commentTemp);
					}
					taskComment.setComments(comments1);
				} else {
					continue;
				}

				// 查询附件信息
				List<Attachment> attachments = taskService.getTaskAttachments(historicTaskInstance.getId());
				if (attachments != null && attachments.size() > 0) {
					List<String> fileAttachments = new ArrayList<String>();
					List<String> imageAttachments = new ArrayList<String>();

					for (int i = 0, len = attachments.size(); i < len; i++) {
						Attachment attachment = attachments.get(i);
						String attachmentType = attachment.getType();
						String url = attachment.getUrl();
						if (attachmentType.equals("FileAttachment")) {
							fileAttachments.add(url);
						} else if (attachmentType.equals("ImageAttachment")) {
							imageAttachments.add(url);
						} else {
							logger.error("不识别的附件类型," + attachmentType);
						}
					}

					// 附件信息
					if (fileAttachments.size() > 0) {
						taskComment.setAttachmentNames(fileAttachments);
					}

					// 图片信息
					if (imageAttachments.size() > 0) {
						taskComment.setImageNames(imageAttachments);
					}
				}
				taskComments.add(taskComment);
			}
		}

		processDescription.setTaskComments(taskComments);

		HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery()
				.processInstanceId(processInstanceId).singleResult();
		if (historicProcessInstance != null) {
			Date startTime = historicProcessInstance.getStartTime();
			Date endTime = historicProcessInstance.getEndTime();

			boolean isActive = false;

			// 查询流程实例的执行数
			List<Execution> executions = runtimeService.createExecutionQuery().processInstanceId(processInstanceId)
					.list();
			if (executions != null && executions.size() > 0) {
				isActive = true;
				List<Task> activeTasks = taskService.createTaskQuery().processInstanceId(processInstanceId).list();
				List<TaskDescription> activeTaskDescriptions = new ArrayList<TaskDescription>();

				for (Task activeTask : activeTasks) {
					TaskDescription activeTaskDescription = new TaskDescription();
					activeTaskDescription.setId(activeTask.getId());
					activeTaskDescription.setName(activeTask.getName());
					if (activeTask.getAssignee() != null) {
						activeTaskDescription.setAssigneeId(activeTask.getAssignee());
					}
					activeTaskDescription.setStartTime(activeTask.getCreateTime());
					activeTaskDescriptions.add(activeTaskDescription);
				}
				processDescription.setActiveTaskDescriptions(activeTaskDescriptions);
			}
			processDescription.setStartTime(startTime);
			processDescription.setEndTime(endTime);
			processDescription.setActive(isActive);

			/** 审批单发起人姓名 */
			String createUserName = (String) getHistoryProcessInstanceVariableValue(historyService, processInstanceId,
					UserPreference.CREATE_USER_NAME);
			/** 审批单发起人Id */
			Long createUserId = (Long) getHistoryProcessInstanceVariableValue(historyService, processInstanceId,
					UserPreference.CREATE_USER_ID);

			if (createUserName != null) {
				processDescription.setStartUserName(createUserName);
			}

			if (createUserId != null) {
				processDescription.setStartUserId(createUserId);
			}
		}
		return processDescription;
	}

	@Override
	public void suspendProcessInstance(String processInstanceId) {
		try {
			long count = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).count();
			if (count > 0) {
				runtimeService.suspendProcessInstanceById(processInstanceId);
			}
		} catch (ActivitiException e) {
			logger.error("挂起流程实例异常", e);
			throw new WorkflowException("挂起流程实例异常");
		}
	}

	@Override
	public void activateProcessInstance(String processInstanceId) {
		try {
			runtimeService.activateProcessInstanceById(processInstanceId);
		} catch (ActivitiException e) {
			logger.error("激活流程实例异常", e);
			throw new WorkflowException("激活流程实例异常");
		}
	}

	@Override
	public void setChoice(ChooseTask chooseTask) {
		Long userId = LoginContextUtil.getLoginContext().getUserId();


		if (chooseTask == null) {
			throw new WorkflowException("任务已完成或已删除。");
		}

		if (chooseTask.getCommand() == null) {
			throw new WorkflowException("无操作指令。");
		}
		
		Task task = taskService.createTaskQuery().taskId(chooseTask.getTaskId()).singleResult();

		if (task == null) {
			throw new WorkflowException("任务已完成或已删除。");
		}

		if (!task.getAssignee().equals(String.valueOf(userId))) {
			throw new WorkflowException("您没有权限操作进行该操作。");
		}

		if (task.isSuspended()) {
			throw new WorkflowException("任务已经被挂起。");
		}
		
		TaskCommand command = chooseTask.getCommand();
		
		String comment = null;
		if (command.equals(TaskCommand.APPROVE)) {
			comment = "审批通过";
		} else if (command.equals(TaskCommand.REJECT)) {
			comment = "审批不通过";
		} else if (command.equals(TaskCommand.WITHDRAW)) {
			comment = "审批撤销";
		}

		comment = (comment + ",意见:" + (chooseTask.getComment() == null ? "无" : chooseTask.getComment()));
		taskService.addComment(task.getId(), task.getProcessInstanceId(), comment);
		runtimeService.setVariableLocal(task.getExecutionId(), UserPreference.COMMENT, chooseTask.getComment());
//		if (taskInfo.getWorkflowType() != null && taskInfo.getWorkflowType().equals("SingleElection")
//				&& taskInfo.getUserId() != null) {
//			runtimeService.setVariable(task.getExecutionId(), "USER_ID", taskInfo.getUserId().toString());
//		}

		taskService.setVariable(task.getId(), UserPreference.COMMAND, chooseTask.getCommand().toString());
		
		if(chooseTask.getModelData() != null) {
			taskService.setVariable(task.getId(), UserPreference.MODEL_DATA, chooseTask.getModelData());
		}
		
		if (chooseTask.getAttachmentNames() != null && chooseTask.getAttachmentNames().length > 0) {
			for (String attachmentName : chooseTask.getAttachmentNames()) {
				taskService.createAttachment("FileAttachment", task.getId(), task.getProcessInstanceId(),
						attachmentName, "", attachmentName);
			}
		}

		if (chooseTask.getImageNames() != null && chooseTask.getImageNames().length > 0) {
			for (String imageName : chooseTask.getImageNames()) {
				taskService.createAttachment("ImageAttachment", task.getId(), task.getProcessInstanceId(), imageName,
						"", imageName);
			}
		}


		Map<String, Object> properties = new HashMap<String, Object>();
		if(chooseTask.getUserSelectDtos() != null) {
		    for(UserSelectDto userSelectDto : chooseTask.getUserSelectDtos()) {
		        String variableName = userSelectDto.getVariableName();
		        List<Long> userIds = userSelectDto.getUserIds();
		        if(userIds != null && userIds.size() > 0) {
		            List<String> userIdsString = new ArrayList<String>();
		            userIds.forEach(item -> {
		                userIdsString.add(item.toString());
		            });
		            properties.put(variableName, userIds);
		        }
		    }
		}
		
		
		if (chooseTask.getKeyValueObjects() != null) {
			for (KeyValueObject keyValue : chooseTask.getKeyValueObjects()) {
				if(keyValue.getValueString() != null && keyValue.getValueString().length() > 0) {
					properties.put(keyValue.getKey(), keyValue.getValueString());
				} else if(keyValue.getValueBoolean() != null) {
					properties.put(keyValue.getKey(), keyValue.getValueBoolean());
				} else if(keyValue.getValueDouble() != null) {
					properties.put(keyValue.getKey(), keyValue.getValueDouble());
				}
			}
		}
		taskService.complete(chooseTask.getTaskId(), properties);
//		HistoricTaskInstance historicTaskInstance = historyService.createHistoricTaskInstanceQuery().taskId(chooseTask.getTaskId()).singleResult();
//		Task taskTwo=taskService.createTaskQuery().processInstanceId(historicTaskInstance.getProcessInstanceId()).singleResult();
//		if(taskTwo != null && (taskTwo.getAssignee().equals("0") || taskTwo.getAssignee() == null)) {
//			throw new ServerException("未找到下一个审批人信息，无法进行审批。");
//		}
	}

	@Override
	public void addComment(ChooseTask chooseTask) {
		Long userId = LoginContextUtil.getLoginContext().getUserId();
		
		String taskId = chooseTask.getTaskId();

		Task task = taskService.createTaskQuery().taskId(taskId).singleResult();

		if (taskId == null) {
			throw new WorkflowException("任务已完成或已删除。");
		}

		if (!task.getAssignee().equals(String.valueOf(userId))) {
			throw new WorkflowException("您没有权限操作进行该操作。");
		}

		if (task.isSuspended()) {
			throw new WorkflowException("任务已经被挂起。");
		}

		String comment = "发表评论：" + chooseTask.getComment();

		taskService.addComment(task.getId(), task.getProcessInstanceId(), comment);

		if (chooseTask.getAttachmentNames() != null && chooseTask.getAttachmentNames().length > 0) {
			for (String attachmentName : chooseTask.getAttachmentNames()) {
				taskService.createAttachment("FileAttachment", task.getId(), task.getProcessInstanceId(),
						attachmentName, "", attachmentName);
			}
		}

		if (chooseTask.getImageNames() != null && chooseTask.getImageNames().length > 0) {
			for (String imageName : chooseTask.getImageNames()) {
				taskService.createAttachment("ImageAttachment", task.getId(), task.getProcessInstanceId(), imageName,
						"", imageName);
			}
		}
	}

	@Override
	public List<UserTaskDto> listUserTask(String deploymentId) {
		if (deploymentId == null || deploymentId.length() == 0) {
			return null;
		}

		ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
				.deploymentId(deploymentId).singleResult();
		if (processDefinition == null) {
			logger.info("找不到工作流的定义(部署id=" + deploymentId + ")");
//			throw new WorkflowException();
			return null;
		}

		BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinition.getId());
		List<org.activiti.bpmn.model.Process> processList = bpmnModel.getProcesses();

		List<UserTaskDto> userTaskDtos = new ArrayList<UserTaskDto>();

		if (processList != null && processList.size() > 0) {
			for (org.activiti.bpmn.model.Process process : processList) {
				if (process != null) {
					Collection<FlowElement> flowElementCollection = process.getFlowElements();
					if (flowElementCollection != null && flowElementCollection.size() > 0) {
						for (FlowElement flowElement : flowElementCollection) {
							if (flowElement instanceof UserTask) {
								UserTask userTask = (UserTask) flowElement;

								// 如果已有审批用户则跳过
								if (userTask.getAssignee() != null && userTask.getAssignee().length() > 0) {
									continue;
								}

								List<String> candidateUsers = userTask.getCandidateUsers();
								List<String> candidateGroups = userTask.getCandidateGroups();

								UserTaskDto userTaskDto = new UserTaskDto();
								userTaskDto.setId(userTask.getId());
								userTaskDto.setDeploymentId(deploymentId);
								userTaskDto.setName(userTask.getName());
								userTaskDto.setDocumentation(userTask.getDocumentation());

								MultiInstanceLoopCharacteristics loopCharacteristics = userTask
										.getLoopCharacteristics();
								if (loopCharacteristics != null) {
									userTaskDto.setMultipleInstance(true);
								} else {
									userTaskDto.setMultipleInstance(false);
								}

								if (candidateUsers != null && candidateUsers.size() > 0) {
									userTaskDto.setCandidateUserIds(candidateUsers.toArray(new String[0]));
								}

								if (candidateGroups != null && candidateGroups.size() > 0) {
									userTaskDto.setCandidateGroupIds(candidateGroups.toArray(new String[0]));
								}

								userTaskDtos.add(userTaskDto);
							}
						}
					}
				}
			}
		}

		// AddByHaoYanbing 20180119 排序 取ID的第二位、第三位转化为数字排序
		Collections.sort(userTaskDtos, new Comparator<UserTaskDto>() {
			@Override
			public int compare(UserTaskDto o1, UserTaskDto o2) {
				if (o1.getId() != null && o1.getId().length() > 3 && o2.getId() != null && o2.getId().length() > 3) {
					String id1 = o1.getId().substring(1, 3);
					String id2 = o2.getId().substring(1, 3);
					if (StringUtil.isNumeric(id1) && StringUtil.isNumeric(id2)) {
						return (Integer.parseInt(id1) - Integer.parseInt(id2));
					}
				}
				return 0;
			}
		});
		return userTaskDtos;
	}

	@Override
	public Long countTaskInfoApproved(Long userId) {
		// 根据用户查询任务
		HistoricTaskInstanceQuery historicTaskInstanceQuery = historyService.createHistoricTaskInstanceQuery()
				.taskAssignee(userId.toString());
		return historicTaskInstanceQuery.count();
	}

	@Override
	public Long countTaskInfoMyApply(Long userId) {

		HistoricProcessInstanceQuery historicProcessInstanceQuery = historyService.createHistoricProcessInstanceQuery();
		return historicProcessInstanceQuery.variableValueEquals(UserPreference.CREATE_USER_ID, userId).count();
	}

	@Override
	public Long countTaskInfoRefuse(Long userId) {
		HistoricTaskInstanceQuery historicProcessInstanceQuery = historyService.createHistoricTaskInstanceQuery()
				.taskAssignee(userId.toString())
				.processVariableValueLike(UserPreference.COMMAND, TaskCommand.REJECT.toString());
		return historicProcessInstanceQuery.count();
	}

	@Override
	public TaskInfo getTaskInfoByProcessInstanceId(String processInstanceId, String userId) {

		// 根据用户查询任务
		TaskQuery taskQuery = taskService.createTaskQuery().active().processInstanceId(processInstanceId)
				.taskAssignee(userId);
		List<Task> tasks = taskQuery.list();
		if (tasks != null && tasks.size() > 0) {
			return getTaskInfo(tasks.get(0));
		} else {
			return null;
		}
	}

	@Override
	public TaskInfo queryTaskInfo(String taskId) {
		// 根据用户查询任务
		TaskQuery taskQuery = taskService.createTaskQuery().active().taskId(taskId);
		Task task = taskQuery.singleResult();
		if (task != null) {
			return getTaskInfo(task);
		}
		return null;
	}

	@Override
	public TaskInfo getProcessInstanceIdTaskInfo(String processInstanceId) {

		// 根据processInstanceId查询任务
		TaskQuery taskQuery = taskService.createTaskQuery().active().processInstanceId(processInstanceId);
		List<Task> tasks = taskQuery.list();
		if (tasks != null && tasks.size() > 0) {
			return getTaskInfo(tasks.get(0));
		} else {
			return null;
		}
	}

	@Override
	public UserTaskDto getUserTask(ChooseTask chooseTask) throws Exception {
		UserTaskDto userTaskDto = null;
		UserTask userTask = getNextUserFlowElement(chooseTask);
		//当用户活动是空的时候说明已经是最后一了，不需要再选择审批人了
		if(userTask != null) {
			userTaskDto	= new UserTaskDto();
			userTaskDto.setId(userTask.getId());
	        userTaskDto.setDeploymentId(chooseTask.getDeploymentId());
        	userTaskDto.setDocumentation(userTask.getDocumentation());
	        userTaskDto.setName(userTask.getName());
	        userTaskDto.setCandidateGroupIds(userTask.getCandidateGroups().toArray(new String[0]));
		}
		return userTaskDto;
	}

	public  UserTask getNextUserFlowElement(ChooseTask chooseTask){
        Task task = taskService.createTaskQuery().taskId(chooseTask.getTaskId()).singleResult();
        Map<String, Object> formData = new HashMap<>();
        formData.put("COMMAND", "APPROVE");
        if(chooseTask.getModelData() != null) {
        	formData.put("modelData", chooseTask.getModelData());
        }
        if (task == null){
            throw new ServerException("任务已执行完成或者已经删除。");
        }
        // 取得已提交的任务
        HistoricTaskInstance historicTaskInstance = historyService.createHistoricTaskInstanceQuery()
                .taskId(task.getId()).singleResult();
        // 取得正在流转的流程实例,若已完成则为null
        //getRuntimeProcessInstance是自己封装的获取流程实例的方法
        //每个流程实例只有一个executionId
        //获得流程定义
        ProcessDefinition processDefinition = repositoryService.getProcessDefinition(historicTaskInstance.getProcessDefinitionId());
 
        //获得当前流程的活动ID
        ExecutionQuery executionQuery = runtimeService.createExecutionQuery();
        Execution execution =executionQuery.executionId(historicTaskInstance.getExecutionId()).singleResult();
        String activityId = execution.getActivityId();
        UserTask userTask =null;
        while (true){
        	Boolean isflag = true;
            //根据活动节点获取当前的组件信息
            FlowNode flowNode = getFlowNode(processDefinition.getId(),activityId);
            //获取该流程组件的之后/之前的组件信息
            List<SequenceFlow> sequenceFlowListOutGoing = flowNode.getOutgoingFlows();
            if(flowNode == null || sequenceFlowListOutGoing == null || sequenceFlowListOutGoing.size() <= 0) {
            	break;
            }
            //获取的下个节点不一定是userTask的任务节点，所以要判断是否是任务节点
            for(SequenceFlow sequenceFlow :sequenceFlowListOutGoing) {
                FlowElement flowElement = sequenceFlow.getTargetFlowElement();
            	if (flowElement instanceof UserTask){
            		String expression = sequenceFlow.getConditionExpression();
            		isflag = true;
                    if(checkFormDataByRuleEl(expression, formData)) {
                    	userTask = (UserTask)flowElement;
                    	break;
                    }else {
                    	continue;
                    }
                }else if(flowElement instanceof ExclusiveGateway){
                    //下一节点不是任务userTask的任务节点,所以要获取再下一个节点的信息,直到获取到userTask任务节点信息
                    activityId = flowElement.getId();
                    isflag = false;
                    break;
                }
                
            }
            if(userTask != null) {
            	break;
            }else {
            	if(isflag == false) {
            		continue;
            	}
            }
        }
		return userTask;
    }
	

	/**
	  * 计算boolean表达式的值
	  * @param expression 表达式
	  * @param varsMap 参数
	  * @return boolean值
	  **/
	public static Boolean checkFormDataByRuleEl(String el, Map<String, Object> formData){
		if(el == null || el.equals("")) {
			return false;
		}
        ExpressionFactory factory = new ExpressionFactoryImpl();
        SimpleContext context = new SimpleContext();
        for (Object k : formData.keySet()) {
            if (formData.get(k) != null) {
                context.setVariable(k.toString(), factory.createValueExpression(formData.get(k), formData.get(k).getClass()));
            }
        }

        ValueExpression e = factory.createValueExpression(context, el, Boolean.class);
        return (Boolean) e.getValue(context);
    }
	
    //根据活动节点和流程定义ID获取该活动节点的组件信息
    public FlowNode getFlowNode(String processDefinitionId,String activityId){
        BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
        FlowNode flowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(activityId);
        return flowNode;
    }

	/**
	 * 查询流程启动时设置排他网关判断条件信息
	 * 
	 * @param String gatewayId 排他网关Id信息, 流程启动时设置网关路线判断条件key为网关Id信息
	 * @param String processInstanceId 流程实例Id信息
	 * @return
	 */
	public String getGatewayCondition(String gatewayId, String processInstanceId) {
		Execution execution = runtimeService.createExecutionQuery().processInstanceId(processInstanceId).singleResult();
		Object object = runtimeService.getVariable(execution.getId(), gatewayId);
		return object == null ? "" : object.toString();
	}

	/**
	 * 根据key和value判断el表达式是否通过信息
	 * 
	 * @param String key el表达式key信息
	 * @param String el el表达式信息
	 * @param String value el表达式传入值信息
	 * @return
	 */
//    public boolean isCondition(String key, String el, String value) {
//        ExpressionFactory factory = new ExpressionFactoryImpl();
//        SimpleContext context = new SimpleContext();
//        context.setVariable(key, factory.createValueExpression(value, String.class));
//        ValueExpression e = factory.createValueExpression(context, el, boolean.class);
//        if(value.equals("")) {
//        	if(el.equals("${COMMAND=='REJECT'}") || el.equals("${COMMAND=='WITHDRAW'}") ||
//        			el.equals("${COMMAND=='APPROVE'&&\ncontinue==true}") || el.equals("${COMMAND=='APPROVE'&&PASS==1}")
//        			|| el.equals("${COMMAND=='APPROVE'&&PASS==2}")) {
//            	return false;
//            }else {
//            	return true;
//            }
//        }else {
//        	return (Boolean) e.getValue(context);
//        }
//    }

	@Override
	public void setBooleanVariable(String processInstanceId, String variableName, Boolean variableValue) {
		Execution execution = runtimeService.createExecutionQuery().processInstanceId(processInstanceId).singleResult();
		runtimeService.setVariable(execution.getId(), variableName, variableValue);
	}


	@Override
	public Boolean deleteProcessInstanceByProcessInstanceId(String processInstanceId) {
		if (processInstanceId != null) {
			// 获取父工作流实例Id
			// 删除流程的equipmentTask
			Long count0 = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).count();
			if (count0 != null && count0 > 0) {
				runtimeService.deleteProcessInstance(processInstanceId, "人工删除");// 删除流程
			}
			Long count1 = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId)
					.count();
			if (count1 != null && count1 > 0) {
				historyService.deleteHistoricProcessInstance(processInstanceId);
			}
			return (count0 != null && count0 > 0) && (count1 != null && count1 > 0);
		} else {
			return false;
		}
	}

	@Override
	public List<DeploymentDto> queryDeploymentIds() {
		List<DeploymentDto> deploymentDtos = new ArrayList<>();
		List<ProcessDefinition> lists = repositoryService.createProcessDefinitionQuery().list();
		if(lists != null) {
			for(ProcessDefinition processDefinition : lists) {
				DeploymentDto deploymentDto = new DeploymentDto();
				deploymentDto.setDeploymentId(processDefinition.getDeploymentId());
				deploymentDto.setName(processDefinition.getName());
				deploymentDto.setDescription(processDefinition.getDescription());
				deploymentDto.setShowName((processDefinition.getDeploymentId() == null ? "" : processDefinition.getDeploymentId()) + "," + (processDefinition.getName() == null ? "":processDefinition.getName()) + "," + (processDefinition.getDescription() == null ? "" : processDefinition.getDescription()));
				deploymentDtos.add(deploymentDto);
			}
		}
		return deploymentDtos;
	}

	@Override
	public void transfer(TransferTaskDto transferTaskDto) {
		Long userId = LoginContextUtil.getLoginContext().getUserId();

		Task task = taskService.createTaskQuery().taskId(transferTaskDto.getTaskId()).singleResult();

		if (!task.getAssignee().equals(String.valueOf(userId))) {
			throw new WorkflowException("您没有权限操作进行该操作。");
		}

		if (task.isSuspended()) {
			throw new WorkflowException("任务已经被挂起。");
		}
		
		taskService.setAssignee(task.getId(), transferTaskDto.getTransferUserId().toString());
		
		String comment = transferTaskDto.getUserName() + "转交给了" + transferTaskDto.getTransferUserName() + "，转交意见：" + transferTaskDto.getComment();
		
		taskService.addComment(task.getId(), task.getProcessInstanceId(), comment);
	}

	@Override
	public void setVariableModelData(WorkflowInfo workflowInfo) {
		//获取当前办理人的任务ID
		Task task = taskService.createTaskQuery()
				.processInstanceId(workflowInfo.getDeploymentId())
				.singleResult();
		taskService.setVariable(task.getId(), "modelData", workflowInfo.getModelData());
	}

	@Override
	public List<UserSelectDefine> calculateUserSelect(UserSelectCalculateRequest userSelectCalculateRequest) {
		ModelData modelData = userSelectCalculateRequest.getModelData();
		List<UserSelectDefine> userSelectDefines = userSelectCalculateRequest.getUserSelectDefines();
		List<UserSelectDefine> userSelectDefinesCanExecute = new ArrayList<UserSelectDefine>();
		
		ExpressionFactory factory = new ExpressionFactoryImpl();  
		SimpleContext context = new SimpleContext();
		
		context.setVariable("modelData", factory.createValueExpression(modelData, ModelData.class));


		if (userSelectCalculateRequest.getKeyValueObjects() != null) {
			for (KeyValueObject keyValue : userSelectCalculateRequest.getKeyValueObjects()) {
				if(keyValue.getValueString() != null && keyValue.getValueString().length() > 0) {
					context.setVariable(keyValue.getKey(), factory.createValueExpression(keyValue.getValueString(), String.class));
				} else if(keyValue.getValueBoolean() != null) {
					context.setVariable(keyValue.getKey(), factory.createValueExpression(keyValue.getValueBoolean(), Boolean.class));
				} else if(keyValue.getValueDouble() != null) {
					context.setVariable(keyValue.getKey(), factory.createValueExpression(keyValue.getValueDouble(), Double.class));
				}
			}
		}
		
		if(userSelectDefines != null) {
			for(UserSelectDefine userSelectDefine : userSelectDefines) {
				if(StringUtil.isEmpty(userSelectDefine.getCondition())){
					userSelectDefinesCanExecute.add(userSelectDefine);
				}else {
					try {
						ValueExpression valueExpression = factory.createValueExpression(context, userSelectDefine.getCondition(), Boolean.class);  
						Boolean value = (Boolean) valueExpression.getValue(context);
						if(value != null && value == true) {
							userSelectDefinesCanExecute.add(userSelectDefine);
						}else {
							String data = String.format("表达式(%s)解析以后等于false", userSelectDefine.getCondition());
							logger.debug(data);
						}
					}catch(Exception ex) {
						logger.error("表达式(" + userSelectDefine.getCondition() + ")解析异常。", ex);
					}
				}
			}
		}
		
		return userSelectDefinesCanExecute;
	}

	@Override
	public List<UserSelectDefine> calculatePreviousUserSelect(
			PreviousUserSelectCalculateRequest previousUserSelectCalculateRequest) {
		String taskId = previousUserSelectCalculateRequest.getTaskId();
		Execution execution = this.getExecution(taskId);
		if(execution == null) {
			return null;
		}
		
        String activityId = execution.getActivityId();
        
        List<UserSelectDefine> userSelectDefines = previousUserSelectCalculateRequest.getUserSelectDefines();
        List<UserSelectDefine> targetUserSelectDefines = new ArrayList<UserSelectDefine>();
        if(userSelectDefines != null && userSelectDefines.size() > 0) {
        	for(UserSelectDefine userSelectDefine : userSelectDefines) {
        		if(userSelectDefine != null 
        				&& (
        						(userSelectDefine.getPreviousNodeId() != null && userSelectDefine.getPreviousNodeId().equals(activityId))
        						||
        						(StringUtil.arrayEquals(userSelectDefine.getPreviousNodeIds(), activityId))
        				)) {
        			targetUserSelectDefines.add(userSelectDefine);
        		}
        	}
        }
        
        UserSelectCalculateRequest userSelectCalculateRequest = new UserSelectCalculateRequest();
        userSelectCalculateRequest.setModelData(previousUserSelectCalculateRequest.getModelData());
        userSelectCalculateRequest.setUserSelectDefines(targetUserSelectDefines);
        userSelectCalculateRequest.setKeyValueObjects(previousUserSelectCalculateRequest.getKeyValueObjects());
        
		// return calculateUserSelect(userSelectCalculateRequest);
		return targetUserSelectDefines;
	}

	@Override
	public Execution getExecution(String taskId) {
		Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        if (task == null){
            // throw new ServiceException("任务已执行完成或者已经删除。");
        	return null;
        }
        String executionId = task.getExecutionId();
        ExecutionQuery executionQuery = runtimeService.createExecutionQuery();
        Execution execution =executionQuery.executionId(executionId).singleResult();
        return execution;
	}

	@Override
	public TaskInfo uniqueTaskInfoByTaskIdUserId(String taskId, String userId) {
		// 根据用户查询任务
		TaskQuery taskQuery = taskService.createTaskQuery().active().taskId(taskId).taskAssignee(userId);
		Task task = taskQuery.singleResult();
		if (task != null) {
			return getTaskInfo(task);
		}else {
			return null;
		}
	}

	@Override
	public Form findForm(FormRequest formRequest) {
		String taskId = formRequest.getTaskId();
		Execution execution = this.getExecution(taskId);
        String activityId = execution.getActivityId();
        
		if(activityId == null) {
			return null;
		}
		
		String processDataStr = formRequest.getProcessData();
		String fromDataStr = formRequest.getFormData();
		if(StringUtil.isEmpty(processDataStr) || StringUtil.isEmpty(fromDataStr)) {
			logger.debug("没有流程数据，或者是没有表单定义。");
			return null;
		}
		
		// 解析ProcessData
		ProcessData processData = null;
		try {
			processData = mapper.readValue(processDataStr, ProcessData.class);
		} catch (JsonProcessingException e) {
			throw new ServerException("读取流程数据异常。" + e.getMessage());
		}
		
		Propertie propertie = findByActivityId(processData, activityId);
		if(propertie == null) {
			return null;
		}
		
		List<FormOperate> formOperates = propertie.getFormOperates();
		if(formOperates == null || formOperates.size() == 0) {
			return null;
		}
		
		String formData = formRequest.getFormData();
		
		// 1. 找到Form的定义
		Form form = null;
		if(StringUtil.isNotEmpty(formData)) {
			form = new Form();
			List<FormField> formFields = new ArrayList<FormField>();
			form.setFields(formFields);
            JsonObject formDataJsonObject = new JsonParser().parse(formData).getAsJsonObject();
            JsonArray fieldsJsonArray = formDataJsonObject.get("fields").getAsJsonArray();
            fieldsJsonArray.forEach(fieldJsonElement -> {
            	JsonObject fieldJsonObject = fieldJsonElement.getAsJsonObject();
            	FormField formField = new FormField();
            	formField.setFieldName(fieldJsonObject.get("vModel").getAsString());
            	formField.setDisplayName(fieldJsonObject.get("label").getAsString());
            	String tag = fieldJsonObject.get("tag").getAsString();
            	if(tag.equals("el-input-number")) {
            		formField.setDisplayType(DisplayType.IntegerBoxEditor);
            	} else if(tag.equals("el-input")) {
            		formField.setDisplayType(DisplayType.TextBoxEditor);
            	} else if(tag.equals("el-switch")) {
            		formField.setDisplayType(DisplayType.CheckBoxEditor);
            	} else {
            		formField.setDisplayType(DisplayType.TextBoxEditor);
            	}
            	if(fieldJsonObject.get("placeholder") != null) {
            		formField.setPlaceholder(fieldJsonObject.get("placeholder").getAsString());
            	}

            	if(fieldJsonObject.get("formId") != null) {
            		formField.setFormId(fieldJsonObject.get("formId").getAsInt());
            	}
            	
            	if(fieldJsonObject.get("readonly") != null) {
            		formField.setReadonly(fieldJsonObject.get("readonly").getAsBoolean());
            	}
            	
            	if(fieldJsonObject.get("disabled") != null) {
            		formField.setDisabled(fieldJsonObject.get("disabled").getAsBoolean());
            	}
            	
            	if(fieldJsonObject.get("required") != null) {
            		formField.setRequired(fieldJsonObject.get("required").getAsBoolean());
            	}
            	
            	for(int i = 0; i < formOperates.size(); i ++) {
            		FormOperate formOperate = formOperates.get(i);
            		if(formOperate.getFormId().equals(formField.getFormId())) {
            			Integer operate = formOperate.getFormOperate();
            			operate = (operate == null) ? 0 : operate;
            			switch(operate) {
	            			case 0:
	            				break;
	            			case 1:
	            				formField.setReadonly(true);
	            				formField.setDisabled(false);
	            				formFields.add(formField);
	            				break;
	            			case 2:
	            				formField.setReadonly(false);
	            				formField.setDisabled(false);
	            				formFields.add(formField);
	            				break;
            			}
            			break;
            		}
            	}
            });
        }		
		return form;
	}
	
	/**
	 * 根据activityId获取节点属性
	 * @param processData 流程数据
	 * @param activityId 工作流节点Id
	 * @return 节点属性
	 */
	private Propertie findByActivityId(ProcessData processData, String activityId){
		// 分支条件
		List<ConditionNode> conditionNodes = processData.getConditionNodes();

		Propertie propertie = null;
		if (conditionNodes != null) {
			propertie = parseConditionNode(conditionNodes, activityId);
			if(propertie != null) {
				return propertie;
			}
		}

		ChildNode childNode = processData.getChildNode();
		if (childNode != null) {
			propertie = parseChildNode(childNode, activityId);
			if(propertie != null) {
				return propertie;
			}
		}
		
		return null;
	}
	
	/**
	 * 根据activityId获取节点属性
	 * @param conditionNodes 节点数据
	 * @param activityId 工作流节点Id
	 * @return 节点属性
	 */
	private Propertie parseConditionNode(List<ConditionNode> conditionNodes, String activityId) {
		for (ConditionNode conditionNode : conditionNodes) {
			String nodeId = conditionNode.getNodeId();
			Propertie propertie = null;

			if(nodeId != null && nodeId.equals(activityId)) {
				propertie = conditionNode.getProperties();
				return propertie;
			}

			List<ConditionNode> conditionNodesSub = conditionNode.getConditionNodes();
			if (conditionNodesSub != null && conditionNodesSub.size() > 0) {
				propertie = parseConditionNode(conditionNodesSub, activityId);
				if(propertie != null) {
					return propertie;
				}
			}

			ChildNode childNodeSub = conditionNode.getChildNode();
			if (childNodeSub != null) {
				propertie = parseChildNode(childNodeSub, activityId);
				if(propertie != null) {
					return propertie;
				}
			}
		}

		return null;
	}


	/**
	 * 根据activityId获取节点属性
	 * @param childNode 节点数据
	 * @param activityId 工作流节点Id
	 * @return 节点属性
	 */
	private Propertie parseChildNode(ChildNode childNode, String activityId) {
		String nodeId = childNode.getNodeId();
		Propertie propertie = null;
		
		if(nodeId != null && nodeId.equals(activityId)) {
			propertie = childNode.getProperties();
			return propertie;
		}
		
		List<ConditionNode> conditionNodesSub = childNode.getConditionNodes();
		if (conditionNodesSub != null && conditionNodesSub.size() > 0) {
			propertie = parseConditionNode(conditionNodesSub, activityId);
			if(propertie != null) {
				return propertie;
			}
		}

		ChildNode childNodeSub = childNode.getChildNode();
		if (childNodeSub != null) {
			propertie = parseChildNode(childNodeSub, activityId);
			if(propertie != null) {
				return propertie;
			}
		}
		return null;
	}

	@Override
	public List<PreviousUserSelectCalculateResponse> reCalculatePreviousUserSelect(
			PreviousUserSelectCalculateRequest previousUserSelectCalculateRequest) {
		List<PreviousUserSelectCalculateResponse> previousUserSelectCalculateResponseList = null;
		
		List<UserSelectDefine> userSelectDefineList = calculatePreviousUserSelect(previousUserSelectCalculateRequest);
		
		ModelData modelData = previousUserSelectCalculateRequest.getModelData();
		String taskId = previousUserSelectCalculateRequest.getTaskId();
		
        Execution execution = this.getExecution(taskId);
        String activityId = execution.getActivityId();
        
		String processInstanceId = execution.getProcessInstanceId();
		ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();

        BpmnModel bpmnModel = repositoryService.getBpmnModel(processInstance.getProcessDefinitionId());
        
		PreviousUserSelectService previousUserSelectService = new PreviousUserSelectServiceImpl(bpmnModel);
		
		ExpressionFactory factory = new ExpressionFactoryImpl();  
		SimpleContext context = new SimpleContext();
		
		context.setVariable("modelData", factory.createValueExpression(modelData, ModelData.class));

		if (previousUserSelectCalculateRequest.getKeyValueObjects() != null) {
			for (KeyValueObject keyValue : previousUserSelectCalculateRequest.getKeyValueObjects()) {
				if(keyValue.getValueString() != null && keyValue.getValueString().length() > 0) {
					context.setVariable(keyValue.getKey(), factory.createValueExpression(keyValue.getValueString(), String.class));
				} else if(keyValue.getValueBoolean() != null) {
					context.setVariable(keyValue.getKey(), factory.createValueExpression(keyValue.getValueBoolean(), Boolean.class));
				} else if(keyValue.getValueDouble() != null) {
					context.setVariable(keyValue.getKey(), factory.createValueExpression(keyValue.getValueDouble(), Double.class));
				}
			}
		}
		
		if(bpmnModel !=null && userSelectDefineList != null) {
			previousUserSelectCalculateResponseList = new ArrayList<PreviousUserSelectCalculateResponse>();
			for(UserSelectDefine userSelectDefine : userSelectDefineList) {
				PreviousUserSelectCalculateResponse previousUserSelectCalculateResponse = new PreviousUserSelectCalculateResponse();
				BeanUtils.copyProperties(userSelectDefine, previousUserSelectCalculateResponse);
				previousUserSelectCalculateResponseList.add(previousUserSelectCalculateResponse);

				boolean editable = false;
				List<PreviousUserSelectCondition> previousUserSelectConditions = previousUserSelectService.getConditions(activityId, userSelectDefine.getNodeId());
				if(previousUserSelectConditions != null && previousUserSelectConditions.size() > 0) {
					
					for(PreviousUserSelectCondition previousUserSelectCondition : previousUserSelectConditions) {
						boolean editableItem = true;
						List<String> previousConditions = previousUserSelectCondition.getPreviousConditions();
						if(previousConditions != null && previousConditions.size() > 0) {
							for(String previousCondition : previousConditions) {
								if(StringUtil.isEmpty(previousCondition)){
									continue;
								}else {
									try {
										ValueExpression valueExpression = factory.createValueExpression(context, previousCondition, Boolean.class);  
										Boolean value = (Boolean) valueExpression.getValue(context);
										if(value != null && value == true) {
											//editable = true;
										}else {
											String data = String.format("表达式(%s)解析以后等于false", userSelectDefine.getCondition());
											logger.debug(data);
											editableItem = false;
										}
									}catch(Exception ex) {
										logger.error("表达式(" + userSelectDefine.getCondition() + ")解析异常。", ex);
									}
								}
							}
						}
						
						if(editableItem == true) {
							editable = true;
						}
					}
				}
				previousUserSelectCalculateResponse.setEditable(editable);
			}
		}
		
		return previousUserSelectCalculateResponseList;
	}

	@Override
	public String getDeploymentId(String processInstanceId) {
		ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
		if(processInstance != null) {
			return processInstance.getDeploymentId();
		}
		
		HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
		if(historicProcessInstance != null) {
			return historicProcessInstance.getDeploymentId();
		}
		
		return null;
	}

    /* (non-Javadoc)
     * @see com.leanwo.activiti.service.base.WorkflowService#countTaskByUserIdRecordId(java.lang.Long, java.lang.Long)
     */
    @Override
    public BaseObjectResponse<TaskCountResponse> countTaskByUserIdRecordId(Long userId, Long recordId) {
        // 查询任务的数量
        TaskQuery taskQuery = taskService.createTaskQuery().taskAssignee(String.valueOf(userId))
            .processVariableValueEquals(UserPreference.RECORD_ID,recordId);
        
        Long taskCount = taskQuery.count();
        
        HistoricTaskInstanceQuery  historicTaskInstanceQuery  = historyService.createHistoricTaskInstanceQuery().taskAssignee(String.valueOf(userId))
            .processVariableValueEquals(UserPreference.RECORD_ID,recordId);
        
        Long historicTaskInstanceCount = historicTaskInstanceQuery.count();
        
        TaskCountResponse taskCountResponse = new TaskCountResponse();
        taskCountResponse.setTaskCount(taskCount);
        taskCountResponse.setHistoricTaskInstanceCount(historicTaskInstanceCount);
        
        BaseObjectResponse<TaskCountResponse> baseObjectResponse = new BaseObjectResponse<TaskCountResponse>();
        baseObjectResponse.setErrorCode(0);
        baseObjectResponse.setData(taskCountResponse);
        return baseObjectResponse;
    }

}
