package com.blueland.bpm.engine.core.service.impl;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.activiti.bpmn.model.BpmnModel;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.delegate.Expression;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.impl.ProcessEngineImpl;
import org.activiti.engine.impl.bpmn.behavior.UserTaskActivityBehavior;
import org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.activiti.engine.impl.context.Context;
import org.activiti.engine.impl.interceptor.Command;
import org.activiti.engine.impl.persistence.entity.HistoricActivityInstanceEntity;
import org.activiti.engine.impl.persistence.entity.HistoricTaskInstanceEntity;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.impl.persistence.entity.SuspensionState;
import org.activiti.engine.impl.pvm.delegate.ActivityBehavior;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.impl.task.TaskDefinition;
import org.activiti.engine.runtime.Execution;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Comment;
import org.activiti.engine.task.Task;
import org.activiti.image.ProcessDiagramGenerator;
import org.activiti.image.impl.DefaultProcessDiagramGenerator;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.blueland.bpm.common.util.DateUtil;
import com.blueland.bpm.engine.config.model.ActivityInfoConfig;
import com.blueland.bpm.engine.config.service.ActivityInfoConfigManager;
import com.blueland.bpm.engine.core.cmd.GetHistoryProcessDivCmd;
import com.blueland.bpm.engine.core.cmd.GetProcessDefinitionDivCmd;
import com.blueland.bpm.engine.core.cmd.GetProcessDiagramSize;
import com.blueland.bpm.engine.core.cmd.GetProcessHistoryDivCmd;
import com.blueland.bpm.engine.core.cmd.GetProcessTraceCmd;
import com.blueland.bpm.engine.core.cmd.HistoryProcessInstanceDiagramCmd;
import com.blueland.bpm.engine.core.model.ProcessLogModel;
import com.blueland.bpm.engine.core.service.AbstractServiceHelper;
import com.blueland.bpm.engine.core.service.ProcessTraceService;
import com.blueland.bpm.engine.util.ProcessDefinitionUtils;
import com.blueland.bpm.engine.util.WorkFlowException;
import com.blueland.bpm.identity.OrgService;
import com.blueland.bpm.identity.UserService;
import com.blueland.bpm.identity.model.Org;
import com.blueland.bpm.identity.model.User;

/**
 * 流程监控Service
 * 
 * @version: 1.0
 * @author lw
 */
@Service
public class ProcessTraceServiceImpl extends AbstractServiceHelper implements
		ProcessTraceService {
	protected Logger logger = LoggerFactory.getLogger(getClass());
	@Autowired
	private UserService userService;
	@Autowired
	private OrgService orgService;
	@Autowired
	ActivityInfoConfigManager activityInfoConfigManager;

	/**
	 * 流程跟踪图
	 * 
	 * @param processInstanceId
	 *            流程实例ID
	 * @return 封装了各种节点信息
	 */
	public List<Map<String, Object>> traceProcess(String processInstanceId) {

		List<Map<String, Object>> activityInfos = new ArrayList<Map<String, Object>>();

		try {
			Execution execution = runtimeService.createExecutionQuery()
					.executionId(processInstanceId).singleResult();// 执行实例
			Object property = PropertyUtils
					.getProperty(execution, "activityId");
			String activityId = "";
			if (property != null) {
				activityId = property.toString();
			}
			ProcessInstance processInstance = runtimeService
					.createProcessInstanceQuery()
					.processInstanceId(processInstanceId).singleResult();
			ProcessDefinitionEntity processDefinition = (ProcessDefinitionEntity) this
					.getDeployedProcessDefinition(processInstance
							.getProcessDefinitionId());
			List<ActivityImpl> activitiList = processDefinition.getActivities();// 获得当前任务的所有节点

			for (ActivityImpl activity : activitiList) {
				boolean currentActiviti = false;
				String id = activity.getId();
				// 判断是否当前节点
				if (id.equals(activityId)) {
					currentActiviti = true;
				}

				Map<String, Object> activityImageInfo = getSingleActivitiInfo(
						activity, processInstance, currentActiviti);

				activityInfos.add(activityImageInfo);
			}
		} catch (Exception e) {
			logger.error("", e);
		}

		return activityInfos;
	}

	/**
	 * 加载流程定义静态图片,并老亮显示当前活动 通过引擎内置提供的API来实现
	 * 
	 * @param processInstanceId
	 * @return InputStream
	 */
	public InputStream loadInternalProcessImage(String processInstanceId) {
		InputStream resourceAsStream = null;
		try {
			List<String> activeActivityIds = new ArrayList<String>();
			String processDefinitionId = null;

			ProcessInstance processInstance = runtimeService
					.createProcessInstanceQuery()
					.processInstanceId(processInstanceId).singleResult();
			// 办结ProcessInstance为空,需要查询HistoricProcessInstance
			if (processInstance == null) {
				HistoricProcessInstance historicProcessInstances = historyService
						.createHistoricProcessInstanceQuery()
						.processInstanceId(processInstanceId).singleResult();
				activeActivityIds.add(historicProcessInstances
						.getEndActivityId());
				processDefinitionId = historicProcessInstances
						.getProcessDefinitionId();
			} else {
				processDefinitionId = processInstance.getProcessDefinitionId();
				// 获取当前活动集合
				activeActivityIds.addAll(runtimeService
						.getActiveActivityIds(processInstanceId));
			}
			BpmnModel bpmnModel = repositoryService
					.getBpmnModel(processDefinitionId);
			// 重置引擎配置,不然生成图片有乱码问题
			ProcessEngineImpl defaultProcessEngine = (ProcessEngineImpl) ProcessEngines
					.getDefaultProcessEngine();
			Context.setProcessEngineConfiguration(defaultProcessEngine
					.getProcessEngineConfiguration());
			Context.setProcessEngineConfiguration((ProcessEngineConfigurationImpl) processEngineConfiguration);
			// 输出图片流
			ProcessDiagramGenerator processDiagramGenerator = new DefaultProcessDiagramGenerator();
			resourceAsStream = processDiagramGenerator.generateDiagram(
					bpmnModel, "png", activeActivityIds);
		} catch (Exception e) {
			logger.error("", e);
		}
		return resourceAsStream;
	}

	/**
	 * 获取流程流转轨迹列表-含意见
	 * 
	 * @param procInstId
	 * @return 返回历史任务、意见等数据
	 */
	public Map<String, Object> getHisTaskLog(String procInstId) {
		Map<String, Object> hisTaskLog = new HashMap<String, Object>();
		HistoricProcessInstance curProcessInstance = historyService
				.createHistoricProcessInstanceQuery()
				.processInstanceId(procInstId).singleResult();
		if (curProcessInstance == null) {
			return hisTaskLog;
		}
		List<HistoricTaskInstance> historicTaskInstances = historyService
				.createHistoricTaskInstanceQuery()
				.processInstanceId(curProcessInstance.getId()).orderByTaskCreateTime().asc().list();
		//Map<String,HistoricActivityInstance> actsMap=convertActivityInstance(curProcessInstance.getId());
		if (historicTaskInstances == null || historicTaskInstances.isEmpty()) {
			return hisTaskLog;
		}
		// 获取当前流程所有意见
		Map<String, List<Comment>> commentMaps = allComments(procInstId);
		//如有办结，增加办结环节逻辑
		addEndTask(curProcessInstance,historicTaskInstances,commentMaps);
		List<ProcessLogModel> processDetailLogs = new ArrayList<ProcessLogModel>();
		for (HistoricTaskInstance historicTask : historicTaskInstances) {
			HistoricTaskInstanceEntity historicTaskInstance = (HistoricTaskInstanceEntity) historicTask;
			// 过滤掉前一任务定义ID为空的数据,一般为第一个环节
			if (historicTaskInstances.size()>1&&StringUtils.isEmpty(historicTaskInstance.getPreTaskDefKey())) {
				continue;

			}
			/*HistoricActivityInstance actInst=actsMap.get(historicTaskInstance.getPreTaskId());
			if(actInst!=null&&actInst.getActivityType().equals("inclusiveGateway")) {
				historicTaskInstance.setPreTaskDefKey(actInst.getPreActId());
				historicTaskInstance.setPreTaskDefName(actInst.getPreActName());
				historicTaskInstance.setPreTaskId(actInst.getPreActInstId());
			}*/
			// 处理第一个用户任务的意见逻辑，只有子流程中有次逻辑
			if (StringUtils.isNotEmpty(historicTaskInstance
					.getProcessDefinitionId())
					&& StringUtils.isNotEmpty(historicTaskInstance
							.getPreTaskDefKey())
					&& curProcessInstance.getSuperProcessInstanceId() != null
					&& !commentMaps.containsKey(historicTaskInstance
							.getPreTaskId())) {
				if (ProcessDefinitionUtils
						.isStartUserTask(historicTaskInstance)) {
					List<Comment> tempComments = taskService
							.getTaskComments(historicTaskInstance
									.getPreTaskId());
					if (tempComments != null && !tempComments.isEmpty()) {
						commentMaps.put(historicTaskInstance.getPreTaskId(),
								taskService
										.getTaskComments(historicTaskInstance
												.getPreTaskId()));
					}
				}
			}

			List<Comment> comments = commentMaps.get(historicTaskInstance
					.getPreTaskId());
			//处理接受人、发送人
			String assigneeUserName = historicTaskInstance
					.getAssigneeUserName();
			String assigneeOrgName = historicTaskInstance.getAssigneeOrgName();
			String sendUserName = historicTaskInstance.getSendUserName();
			String senderOrgName = historicTaskInstance.getSenderOrgName();
			//补全接收人数据
			if ((StringUtils
					.isEmpty(historicTaskInstance.getAssigneeUserName()) || StringUtils
					.isEmpty(historicTaskInstance.getAssigneeOrgName()))
					&& StringUtils.isNotEmpty(historicTaskInstance
							.getAssignee())&&historicTaskInstance.getAssignee().indexOf(",")==-1) {
				//historicTaskInstance.getAssignee().indexOf(",")可能是子流程的发起节点
				User assigneeUser = userService
						.getUserById(historicTaskInstance.getAssignee());
				assigneeUserName = assigneeUser.getUserName();
				assigneeOrgName = assigneeUser.getOrgName();

			}
			//补全发送人数据
			if (StringUtils.isEmpty(historicTaskInstance.getSendUserName())
					|| StringUtils.isEmpty(historicTaskInstance
							.getSenderOrgName())
					&& StringUtils.isNotEmpty(historicTaskInstance.getSender())) {
				User sendUser = userService.getUserById(historicTaskInstance
						.getSender());
				sendUserName = sendUser.getUserName();
				senderOrgName = sendUser.getOrgName();
			}
			//包装ProcessLogModel
			ProcessLogModel processDetailLog = new ProcessLogModel();
			processDetailLog.setHistoricTaskInstance(historicTaskInstance);
			processDetailLog
					.setComment(comments != null && !comments.isEmpty() ? comments
							.get(0) : null);
			processDetailLog.setSendUserName(sendUserName);
			processDetailLog
					.setSendUserId(historicTaskInstance.getSendUserId());
			processDetailLog
					.setSendOrgId(historicTaskInstance.getSenderOrgId());
			processDetailLog.setSendOrgName(senderOrgName);
			processDetailLog.setReiceiveUserName(assigneeUserName);
			processDetailLog.setReiceiveUserId(historicTaskInstance.getAssigneeUserId());
			processDetailLog.setReceiveOrgId(historicTaskInstance
					.getAssigneeOrgId());
			processDetailLog.setReceiveOrgName(assigneeOrgName);
			try{
				if (StringUtils.isNotBlank(historicTaskInstance.getOwner())) {
					processDetailLog.setOwnerName(userService.getUserById(historicTaskInstance.getOwner())
							.getUserName());
				}}catch(Exception e){
					logger.error(String.format(
							"获取委托人owner的userName出现异常,procInstId[%s],userId[%s]",
							procInstId, historicTaskInstance.getOwner()), e);
				}
			processDetailLogs.add(processDetailLog);
		}
		hisTaskLog.put("curProcessInstance", curProcessInstance);
		hisTaskLog.put("processDetailLogs", processDetailLogs);
		return hisTaskLog;
	}
	
	
	private ProcessLogModel buildProcessLogModel(HistoricTaskInstanceEntity historicTaskInstance,List<Comment>  prevcomment,List<Comment> curReceiverTransferComments){
		//处理接受人、发送人
		String assigneeUserName = historicTaskInstance
				.getAssigneeUserName();
		String assigneeOrgName = historicTaskInstance.getAssigneeOrgName();
		String sendUserName = historicTaskInstance.getSendUserName();
		String senderOrgName = historicTaskInstance.getSenderOrgName();

		if ((StringUtils
				.isEmpty(historicTaskInstance.getAssigneeUserName()) || StringUtils
				.isEmpty(historicTaskInstance.getAssigneeOrgName()))
				&& StringUtils.isNotEmpty(historicTaskInstance
						.getAssignee())&&historicTaskInstance.getAssignee().indexOf(",")==-1) {
			//historicTaskInstance.getAssignee().indexOf(",")可能是子流程的发起节点
			User assigneeUser = userService
					.getUserById(historicTaskInstance.getAssignee());
			assigneeUserName = assigneeUser.getUserName();
			assigneeOrgName = assigneeUser.getOrgName();

		}
		if (StringUtils.isEmpty(historicTaskInstance.getSendUserName())
				|| StringUtils.isEmpty(historicTaskInstance
						.getSenderOrgName())
				&& StringUtils.isNotEmpty(historicTaskInstance.getSender())) {
			User sendUser = userService.getUserById(historicTaskInstance
					.getSender());
			sendUserName = sendUser.getUserName();
			senderOrgName = sendUser.getOrgName();
		}
		//包装ProcessLogModel
		ProcessLogModel processDetailLog = new ProcessLogModel();
		processDetailLog.setHistoricTaskInstance(historicTaskInstance);
		if(prevcomment!=null&&!prevcomment.isEmpty()){
			processDetailLog.setComment(prevcomment.get(0));
		}
		try{
		//转派会有条意见，将所有意思组装起来展现
		if(curReceiverTransferComments!=null){
			String multiCommentMsg="";
			for (Comment comment : curReceiverTransferComments) {
				//转派意见特殊标示
				if(StringUtils.isEmpty(comment.getType())||!"transfer_comment".equals(comment.getType())){
					continue;
				}
				User commentUser = userService
						.getUserById(comment.getUserId());
				multiCommentMsg+=commentUser.getUserName()+"于"+DateUtil.convertDateToString("yyyy-MM-dd HH:mm:ss",
						comment.getTime())+"签署了意见("+comment.getFullMessage()+")<br/>";
			}
			processDetailLog.setMultiCommentMsg(multiCommentMsg);
		}}catch(Exception e){
			this.logger.error("处理转办意见出现异常,procInstId:"+historicTaskInstance.getProcessInstanceId(),e);
		}
		processDetailLog.setSendUserName(sendUserName);
		processDetailLog
				.setSendUserId(historicTaskInstance.getSendUserId());
		processDetailLog
				.setSendOrgId(historicTaskInstance.getSenderOrgId());
		processDetailLog.setSendOrgName(senderOrgName);
		processDetailLog.setReiceiveUserName(assigneeUserName);
		processDetailLog.setReiceiveUserId(historicTaskInstance.getAssigneeUserId());
		processDetailLog.setReceiveOrgId(historicTaskInstance
				.getAssigneeOrgId());
		processDetailLog.setReceiveOrgName(assigneeOrgName);
		try{
			if (StringUtils.isNotBlank(historicTaskInstance.getOwner())) {
				processDetailLog.setOwnerName(userService.getUserById(historicTaskInstance.getOwner())
						.getUserName());
			}}catch(Exception e){
				logger.error(String.format(
						"获取委托人owner的userName出现异常,procInstId[%s],userId[%s]",
						historicTaskInstance.getProcessInstanceId(), historicTaskInstance.getOwner()), e);
			}
		return processDetailLog;
	}
	
	@Override
	public Map<String, Object> getHisTaskComments(String topProcInstId)
			throws WorkFlowException {
		Map<String, Object> hisTaskLog = new HashMap<String, Object>();
		HistoricProcessInstance curProcessInstance = historyService
				.createHistoricProcessInstanceQuery()
				.processInstanceId(topProcInstId).singleResult();
		if (curProcessInstance == null) {
			return hisTaskLog;
		}
		// 获取当前流程所有意见
		Map<String, List<Comment>> commentMaps = this.allCommentsByTopProcessInstanceId(topProcInstId);
		List<ProcessLogModel> processDetailLogs = new ArrayList<ProcessLogModel>();
		for (Map.Entry<String, List<Comment>> commentMap : commentMaps.entrySet()) {
			List<Comment> prevComments = commentMap.getValue();
			if(prevComments==null||prevComments.isEmpty()){
				continue;
			}
			for (Comment comment : prevComments) {
				//暂时不返回转派意见
				if(comment.getType()!=null&&comment.getType().equals("transfer_comment")) {
					continue;
				}
				//包装ProcessLogModel
				ProcessLogModel processDetailLog = new ProcessLogModel();
				HistoricTaskInstance historicTaskInstance=this.getHistoryService().createHistoricTaskInstanceQuery().taskId(comment.getTaskId()).singleResult();
				if(historicTaskInstance==null){
					continue;
				}
				processDetailLog.setComment(comment);
				if (StringUtils.isEmpty(historicTaskInstance.getAssigneeUserName())
						|| StringUtils.isEmpty(historicTaskInstance
								.getAssigneeOrgName())
						&& StringUtils.isNotEmpty(historicTaskInstance.getAssignee())) {
					User sendUser = userService.getUserById(historicTaskInstance.getAssignee());
					processDetailLog.setSendCompanyId(sendUser.getCompanyId());
					processDetailLog.setSendCompanyName(sendUser.getCompanyName());
					processDetailLog.setSendUserName(sendUser.getUserName());
					processDetailLog
							.setSendUserId(sendUser.getUserId());
					processDetailLog
							.setSendOrgId(sendUser.getOrgId());
					processDetailLog.setSendOrgName(sendUser.getOrgName());
				}else{
					try {
					Org org=orgService.getOrgById(historicTaskInstance.getAssigneeOrgId());
					if(org!=null) {
						processDetailLog.setSendCompanyId(org.getCompanyId());
						processDetailLog.setSendCompanyName(org.getCompanyName());
					}}catch(Exception e) {
						this.logger.error("",e);
					}
					processDetailLog.setSendUserName(historicTaskInstance.getAssigneeUserName());
					processDetailLog
							.setSendUserId(historicTaskInstance.getAssigneeUserId());
					processDetailLog
							.setSendOrgId(historicTaskInstance.getAssigneeOrgId());
					processDetailLog.setSendOrgName(historicTaskInstance.getAssigneeOrgName());
				}
				processDetailLog.setHistoricTaskInstance(historicTaskInstance);
				processDetailLogs.add(processDetailLog);
			}
		}
		hisTaskLog.put("curProcessInstance", curProcessInstance);
		hisTaskLog.put("processDetailLogs", processDetailLogs);
		return hisTaskLog;
	}

	/**
	 * 获取当前任务日志
	 * 
	 * @param procInstId
	 * @return 返回相同的历史任务、意见等数据
	 */
	public Map<String, Object> getCurTaskLog(String procInstId) {
		Map<String, Object> hisTaskLog = new HashMap<String, Object>();
		HistoricProcessInstance curProcessInstance = historyService
				.createHistoricProcessInstanceQuery()
				.processInstanceId(procInstId).singleResult();
		if (curProcessInstance == null) {
			return hisTaskLog;
		}
		List<HistoricTaskInstance> historicTaskInstances = historyService
				.createHistoricTaskInstanceQuery()
				.processInstanceId(curProcessInstance.getId()).orderByTaskCreateTime().desc().list();
		if (historicTaskInstances == null || historicTaskInstances.isEmpty()) {
			return hisTaskLog;
		}
		// 获取当前流程所有意见
		Map<String, List<Comment>> commentMaps = allComments(procInstId);
		
		List<ProcessLogModel> processDetailLogs = new ArrayList<ProcessLogModel>();
		//存储当前流程已运行的环节列表
		Map<String, HistoricTaskInstance> allActivitys = new HashMap<String, HistoricTaskInstance>();
		for (HistoricTaskInstance historicTask : historicTaskInstances) {
			HistoricTaskInstanceEntity historicTaskInstance = (HistoricTaskInstanceEntity) historicTask;
			if (historicTaskInstance.getDeleteReason() != null
					&& "custom-completed".equals(historicTaskInstance
							.getDeleteReason())) {
				continue;
			}
			if (!allActivitys.containsKey(historicTask.getTaskDefinitionKey())) {
				allActivitys.put(historicTask.getTaskDefinitionKey(),
						historicTask);
			}
			
			List<Comment> comments = commentMaps.get(historicTaskInstance
					.getId());
			//处理接收人、发送人逻辑
			String assigneeUserName = historicTaskInstance
					.getAssigneeUserName();
			String assigneeOrgName = historicTaskInstance.getAssigneeOrgName();
			String sendUserName = historicTaskInstance.getSendUserName();
			String senderOrgName = historicTaskInstance.getSenderOrgName();
			String appendAssigneeInfo = "";
			String appendSenderInfo="";
			if ((StringUtils
					.isEmpty(historicTaskInstance.getAssigneeUserName()) || StringUtils
					.isEmpty(historicTaskInstance.getAssigneeOrgName()))
					&& StringUtils.isNotEmpty(historicTaskInstance
							.getAssignee())&&historicTaskInstance.getAssignee().indexOf(",")==-1) {
				User assigneeUser = userService
						.getUserById(historicTaskInstance.getAssignee());
				assigneeUserName = assigneeUser.getUserName();
				assigneeOrgName = assigneeUser.getOrgName();

			}
			if (StringUtils.isEmpty(historicTaskInstance.getSendUserName())
					&& StringUtils.isEmpty(historicTaskInstance
							.getSenderOrgName())
					&& StringUtils.isNotEmpty(historicTaskInstance.getSender())) {
				User sendUser = userService.getUserById(historicTaskInstance
						.getSender());
				sendUserName = sendUser.getUserName();
				senderOrgName = sendUser.getOrgName();
			}
			//包装ProcessLogModel
			ProcessLogModel processDetailLog = new ProcessLogModel();
			processDetailLog.setHistoricTaskInstance(historicTaskInstance);
			processDetailLog
					.setComment(comments != null && !comments.isEmpty() ? comments
							.get(0) : null);
			processDetailLog.setSendUserName(sendUserName);
			processDetailLog
					.setSendUserId(historicTaskInstance.getSendUserId());
			processDetailLog
					.setSendOrgId(historicTaskInstance.getSenderOrgId());
			processDetailLog.setSendOrgName(senderOrgName);
			processDetailLog.setReiceiveUserName(assigneeUserName);
			processDetailLog.setReiceiveUserId(historicTaskInstance.getAssigneeUserId());
			processDetailLog.setReceiveOrgId(historicTaskInstance
					.getAssigneeOrgId());
			processDetailLog.setReceiveOrgName(assigneeOrgName);
			processDetailLog.setSendInfo(appendSenderInfo);
			processDetailLog.setAssigneeInfo(appendAssigneeInfo);
			try{
				if (StringUtils.isNotBlank(historicTaskInstance.getOwner())) {
					processDetailLog.setOwnerName(userService.getUserById(historicTaskInstance.getOwner())
							.getUserName());
				}}catch(Exception e){
					logger.error(String.format(
							"获取委托人owner的userName出现异常,procInstId[%s],userId[%s]",
							procInstId, historicTaskInstance.getOwner()), e);
				}
			processDetailLogs.add(processDetailLog);
		}
		//获取已运行的节点对应的ActivityInfoConfig
		Map<String, ActivityInfoConfig> allActivityInfoConfigs = new HashMap<String, ActivityInfoConfig>();
		for (Map.Entry<String, HistoricTaskInstance> activity : allActivitys
				.entrySet()) {
			ActivityInfoConfig activityInfoConfig = activityInfoConfigManager
					.getActivityInfoConfig(
							curProcessInstance.getProcessDefinitionId(),
							activity.getKey());
			if (activityInfoConfig == null) {
				continue;
			}
			allActivityInfoConfigs.put(activity.getKey(), activityInfoConfig);
		}
		hisTaskLog.put("allActivityInfoConfigs", allActivityInfoConfigs);
		hisTaskLog.put("curProcessInstance", curProcessInstance);
		hisTaskLog.put("processDetailLogs", processDetailLogs);
		return hisTaskLog;
	}

	@Override
	public InputStream getProcessInstanceDiagram(String processInstanceId) {
		InputStream is = null;
		Command<InputStream> cmd = new HistoryProcessInstanceDiagramCmd(
				processInstanceId);
		try {
			is = getManagementService().executeCommand(cmd);
		} catch (Exception e) {
			logger.error("", e);
		}
		return is;
	}

	@Override
	public String getProcessInstanceDiv(String processInstanceId) {
		Command<String> cmd = new GetHistoryProcessDivCmd(processInstanceId);
		String processInstanceDiv = "";
		try {
			processInstanceDiv = getManagementService().executeCommand(cmd);
		} catch (Exception e) {
			logger.error("", e);
		}
		return processInstanceDiv;
	}

	/**
	 * 获取输出信息，包括：当前节点的X、Y坐标、变量信息、任务类型、任务描述
	 * 
	 * @param activity
	 * @param processInstance
	 * @param currentActiviti
	 * @return
	 */
	private Map<String, Object> getSingleActivitiInfo(ActivityImpl activity,
			ProcessInstance processInstance, boolean currentActiviti)
			throws Exception {
		Map<String, Object> vars = new HashMap<String, Object>();
		Map<String, Object> activityInfo = new HashMap<String, Object>();
		activityInfo.put("currentActiviti", currentActiviti);
		setPosition(activity, activityInfo);
		setWidthAndHeight(activity, activityInfo);

		Map<String, Object> properties = activity.getProperties();
		vars.put("任务类型", ProcessDefinitionUtils.parseToZhType(properties.get(
				"type").toString()));

		ActivityBehavior activityBehavior = activity.getActivityBehavior();
		logger.debug("activityBehavior={}", activityBehavior);
		if (activityBehavior instanceof UserTaskActivityBehavior) {

			Task currentTask = null;

			/*
			 * 当前节点的task
			 */
			if (currentActiviti) {
				currentTask = getCurrentTaskInfo(processInstance);
			}

			/*
			 * 当前任务的分配角色
			 */
			UserTaskActivityBehavior userTaskActivityBehavior = (UserTaskActivityBehavior) activityBehavior;
			TaskDefinition taskDefinition = userTaskActivityBehavior
					.getTaskDefinition();
			Set<Expression> candidateGroupIdExpressions = taskDefinition
					.getCandidateGroupIdExpressions();
			if (!candidateGroupIdExpressions.isEmpty()) {

				// 任务的处理角色
				setTaskGroup(vars, candidateGroupIdExpressions);

				// 当前处理人
				if (currentTask != null) {
					setCurrentTaskAssignee(vars, currentTask);
				}
			}
		}

		vars.put("节点说明", properties.get("documentation"));

		String description = activity.getProcessDefinition().getDescription();
		vars.put("描述", description);

		logger.debug("trace variables: {}", vars);
		activityInfo.put("vars", vars);
		return activityInfo;
	}

	/**
	 * 设置任务资源
	 * 
	 * @param vars
	 * @param candidateGroupIdExpressions
	 */
	private void setTaskGroup(Map<String, Object> vars,
			Set<Expression> candidateGroupIdExpressions) {
		String roles = "";
		try {
			for (Expression expression : candidateGroupIdExpressions) {
				String expressionText = expression.getExpressionText();
				if (StringUtils.isEmpty(expressionText))
					continue;
				String roleName = identityService.createGroupQuery()
						.groupId(expressionText).singleResult().getName();
				roles += roleName;
			}
		} catch (Exception e) {
			logger.error("查询流程定义中绑定的角色组出现异常,角色组在数据库中不存在", e);

		}
		vars.put("任务所属角色", roles);
	}

	/**
	 * 设置当前处理人信息
	 * 
	 * @param vars
	 * @param currentTask
	 */
	private void setCurrentTaskAssignee(Map<String, Object> vars,
			Task currentTask) {
		String assignee = currentTask.getAssignee();
		String userInfo = "";
		try {
			if (StringUtils.isEmpty(assignee))
				return;
			org.activiti.engine.identity.User assigneeUser = identityService
					.createUserQuery().userId(assignee).singleResult();
			userInfo = assigneeUser.getFirstName() + " "
					+ assigneeUser.getLastName();
		} catch (Exception e) {
			logger.error("查询流程定义中绑定的处理人出现异常,处理人{}在数据库中不存在",
					currentTask.getAssignee(), e);

		}
		vars.put("当前处理人", userInfo);

	}

	/**
	 * 获取当前节点信息
	 * 
	 * @param processInstance
	 * @return
	 */
	private Task getCurrentTaskInfo(ProcessInstance processInstance) {
		Task currentTask = null;
		try {
			String activitiId = (String) PropertyUtils.getProperty(
					processInstance, "activityId");
			logger.debug("current activity id: {}", activitiId);

			currentTask = taskService.createTaskQuery()
					.processInstanceId(processInstance.getId())
					.taskDefinitionKey(activitiId).singleResult();
			logger.debug("current task for processInstance: {}",
					ToStringBuilder.reflectionToString(currentTask));

		} catch (Exception e) {
			logger.error(
					"can not get property activityId from processInstance: {}",
					processInstance);
		}
		return currentTask;
	}

	/**
	 * 设置宽度、高度属性
	 * 
	 * @param activity
	 * @param activityInfo
	 */
	private void setWidthAndHeight(ActivityImpl activity,
			Map<String, Object> activityInfo) {
		activityInfo.put("width", activity.getWidth());
		activityInfo.put("height", activity.getHeight());
	}

	/**
	 * 设置坐标位置
	 * 
	 * @param activity
	 * @param activityInfo
	 */
	private void setPosition(ActivityImpl activity,
			Map<String, Object> activityInfo) {
		activityInfo.put("x", activity.getX());
		activityInfo.put("y", activity.getY());
	}

	@Override
	public String[] getProcessDiagramSize(String processDefinitionId) {
		Command<String[]> cmd = new GetProcessDiagramSize(processDefinitionId);
		String[] size = null;
		try {
			size = getManagementService().executeCommand(cmd);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return size;

	}
	
	
	@Override
	public List<Map<String, Object>> getProcessTrace(String proceInstaceId) {
		Command<List<Map<String, Object>>> cmd = new GetProcessTraceCmd(
				proceInstaceId);
		List<Map<String, Object>> result = null;
		try {
			result = getManagementService().executeCommand(cmd);
		} catch (Exception e) {
			logger.error("", e);
		}
		return result;
	}

	@Override
	public String getProcessDefinitionDiv(String processDefinitionId) {
		Command<String> cmd = new GetProcessDefinitionDivCmd(
				processDefinitionId);
		String processDefinitionDiv = null;
		try {
			processDefinitionDiv = getManagementService().executeCommand(cmd);
		} catch (Exception e) {
			logger.error("", e);
		}
		return processDefinitionDiv;
	}

	/**
	 * 根据流程ID获取意见
	 * @param curProcessInstanceId
	 * @return
	 */
	private Map<String, List<Comment>> allComments(String curProcessInstanceId) {
		LinkedHashMap<String, List<Comment>> commentMaps = new LinkedHashMap<String, List<Comment>>();
		try {
			List<Comment> allComments = taskService
					.getProcessInstanceComments(curProcessInstanceId);
			for (Comment comment : allComments) {
				if (commentMaps.containsKey(comment.getTaskId())) {
					((List) commentMaps.get(comment.getTaskId())).add(comment);
				} else {
					List tempComments = new ArrayList();
					tempComments.add(comment);
					commentMaps.put(comment.getTaskId(), tempComments);
				}
			}
		} catch (Exception e) {
			logger.error("", e);
		}
		return commentMaps;
	}

	/**
	 * 根据顶级流程ID获取意见
	 * @param topProcessInstanceId
	 * @return
	 */
	private Map<String, List<Comment>> allCommentsByTopProcessInstanceId(String topProcessInstanceId) {
		LinkedHashMap<String, List<Comment>> commentMaps = new LinkedHashMap<String, List<Comment>>();
		try {
			List<Comment> allComments = taskService.getTopProcessInstanceComments(topProcessInstanceId);
			for(int i=allComments.size()-1;i>=0;i--){
				Comment comment=allComments.get(i);
				if (commentMaps.containsKey(comment.getTaskId())) {
					((List) commentMaps.get(comment.getTaskId())).add(comment);
				} else {
					List tempComments = new ArrayList();
					tempComments.add(comment);
					commentMaps.put(comment.getTaskId(), tempComments);
				}
			}
		} catch (Exception e) {
			logger.error("", e);
		}
		return commentMaps;
	}

	@Override
	public Map<String, Object> getHistoryProcess(String processInstanceId) {
		Command<Map<String,Object>> cmd = new GetProcessHistoryDivCmd(
				processInstanceId);
		Map<String,Object> processDiv = new HashMap<String, Object>();
		try {
			processDiv = getManagementService().executeCommand(cmd);
		} catch (Exception e) {
			logger.error("", e);
		}
		return processDiv;
	}
	private void addEndTask(HistoricProcessInstance curProcessInstance,List<HistoricTaskInstance> historicTaskInstances,Map<String, List<Comment>> commentMaps) {
		if (curProcessInstance.getProcState() == SuspensionState.FINISH
				.getStateCode()
				&& curProcessInstance.getEndTime() != null
				&& curProcessInstance.getEndActivityId() != null) {
			// 将办结节点加入historicTaskInstances中
			List<HistoricActivityInstance> hisActInsts = historyService
					.createHistoricActivityInstanceQuery()
					.processInstanceId(curProcessInstance.getId())
					.activityId(curProcessInstance.getEndActivityId())
					.orderByHistoricActivityInstanceStartTime().desc().list();
			if (hisActInsts != null && !hisActInsts.isEmpty()) {
				HistoricActivityInstanceEntity hisActInst = (HistoricActivityInstanceEntity) hisActInsts
						.get(0);

				HistoricTaskInstanceEntity task = new HistoricTaskInstanceEntity();
				task.setSender(hisActInst != null ? hisActInst.getSender() : "");
				task.setSenderOrgId(hisActInst != null ? hisActInst.getSenderOrgId() : "");
				task.setSendUserId(hisActInst != null ? hisActInst.getSendUserId() : "");
				task.setSendUserName(hisActInst != null ? hisActInst.getSendUserName() : "");
				task.setSenderOrgName(hisActInst != null ? hisActInst.getSenderOrgName() : "");
				task.setId(hisActInst.getTaskId());
				task.setProcessInstanceId(hisActInst.getProcessInstanceId());
				task.setExecutionId(hisActInst.getExecutionId());
				task.setTaskDefinitionKey(hisActInst.getActivityId());
				String activityName = hisActInst.getActivityName();
				if ("endEvent".equals(hisActInst.getActivityType())
						&& StringUtils.isEmpty(activityName)) {
					activityName = "结束";
				}
				task.setName(activityName);
				task.setActionType(hisActInst.getActivityType());
				task.setPreTaskDefKey(hisActInst != null ? hisActInst
						.getPreActId() : "");
				task.setPreTaskDefName(hisActInst != null ? hisActInst
						.getPreActName() : "");
				task.setPreTaskId(hisActInst != null ? hisActInst
						.getPreActInstId() : "");
				task.setStartTime(hisActInst.getStartTime());
				task.setEndTime(hisActInst.getEndTime());
				historicTaskInstances.add((HistoricTaskInstance) task);
				// 处理办结节点意见逻辑,只有子流程中有次逻辑
				if (StringUtils.isNotEmpty(task.getPreTaskDefKey())
						&& curProcessInstance.getSuperProcessInstanceId() != null
						&& !commentMaps.containsKey(task.getPreTaskId())) {
					List<Comment> tempComments = taskService
							.getTaskComments(task.getPreTaskId());
					if (tempComments != null && !tempComments.isEmpty()) {
						commentMaps.put(task.getPreTaskId(), taskService
								.getTaskComments(task.getPreTaskId()));
					}

				}
			}
		}
	}
	private Map<String,HistoricActivityInstance> convertActivityInstance(String processId) {
		List<HistoricActivityInstance> historicActInstances=historyService.createHistoricActivityInstanceQuery().processInstanceId(processId).list();		
		Map<String,HistoricActivityInstance> actsMap=new HashMap<String,HistoricActivityInstance>();
		for (HistoricActivityInstance historicActivityInstance : historicActInstances) {
			if(historicActivityInstance.getTaskId()==null) {
				continue;
			}
			if(!actsMap.containsKey(historicActivityInstance.getActivityId())) {
				actsMap.put(historicActivityInstance.getTaskId(),historicActivityInstance);
			}
		}
		return actsMap;
	}
}
