Activiti 常用操作方法大全

时间:2022-05-11 15:10:57
package com.test;


import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;


import org.activiti.engine.HistoryService;
import org.activiti.engine.ProcessEngineConfiguration;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.impl.RepositoryServiceImpl;
import org.activiti.engine.impl.bpmn.behavior.UserTaskActivityBehavior;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.impl.pvm.PvmActivity;
import org.activiti.engine.impl.pvm.PvmTransition;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.impl.pvm.process.ProcessDefinitionImpl;
import org.activiti.engine.impl.pvm.process.TransitionImpl;
import org.activiti.engine.impl.task.TaskDefinition;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.Execution;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.spring.ProcessEngineFactoryBean;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;


@Controller
@RequestMapping(value = "/HandlerPeocess")
public class HandlerPeocessAction {
@Autowired
    RepositoryService repositoryService;
    @Autowired
    protected RuntimeService runtimeService;
    @Autowired
    ProcessEngineConfiguration processEngineConfiguration;
    @Autowired
    ProcessEngineFactoryBean processEngine;
    @Autowired
    HistoryService historyService;
    @Autowired
    TaskService taskService;
    
    
/**
* 方法说明 : 根据流程定义Id查询最新流程定义.

* @param processDefinitionId
*            流程定义Id
*/
public ProcessDefinition findProcessDefinitionByPrcDefId(String processDefinitionId) {
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(processDefinitionId).orderByProcessDefinitionVersion().desc().singleResult();
return processDefinition;
}


/**
* 方法说明 : 根据流程定义Id查询流程定义.

* @param processDefinitionId
*            流程定义Id
*/
public ProcessDefinitionEntity findProcessDefinitionEntityByProcDefId(String processDefinitionId) {
ProcessDefinitionEntity processDefinitionEntity = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService).getDeployedProcessDefinition(processDefinitionId);
return processDefinitionEntity;
}


/**

* 方法说明 : 根据流程实例Id查询流程实例.

* @param processInstanceId
*            流程实例Id
*/
public ProcessInstance findProcessInstanceByProcInst(String processInstanceId) {
return runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
}


/**
* 根据流程实例Id查询流程实例.

* @param processInstanceId
*/
public Execution findExecutionByProcInst(String processInstanceId) {
return runtimeService.createExecutionQuery().processInstanceId(processInstanceId).singleResult();
}

/**
* 方法说明 : 根据实例Id查询任务. 返回多个任务

* @param executionId
*            实例Id
*/
public List<Task> findTaskByProcInstIds(String processInstanceId) {
return taskService.createTaskQuery().processInstanceId(processInstanceId).orderByTaskDefinitionKey().asc().list();
}

/**
* 获取当前流程实例 当前节点的历史任务信息
* @param processInstanceId 流程实例id
* @param taskDefinitionKey 任务环节id (key)
* @return 返回历史任务实例信息
* @throws Exception
*/
public List<HistoricTaskInstance> getHistoricTaskInstance(String processInstanceId,String taskDefinitionKey){
List<HistoricTaskInstance> historicTaskInstances = new ArrayList<HistoricTaskInstance>();
List<HistoricTaskInstance> instances = historyService.createHistoricTaskInstanceQuery().processInstanceId(processInstanceId).taskDefinitionKey(taskDefinitionKey).orderByHistoricTaskInstanceEndTime().desc().list();
if(instances!=null){
HistoricTaskInstance instance = instances.get(0);//只取最新的
historicTaskInstances.add(instance);
List<HistoricTaskInstance> taskInstances = historyService.createHistoricTaskInstanceQuery().taskParentTaskId(instance.getId()).list();//查询子历史任务 并添加到历史任务信息中
if(taskInstances!=null){
for(HistoricTaskInstance historicTaskInstance : taskInstances){
historicTaskInstances.add(historicTaskInstance);
}
}
}
return historicTaskInstances;
}

    
@RequestMapping("/returnTask.do")
public void returnTask(@RequestParam("processDefinitionId") String processDefinitionId
,@RequestParam("processInstanceId") String processInstanceId) {

Map<String, Object> variables = new HashMap<String, Object>();
ProcessDefinitionEntity processDefinitionEntity =(ProcessDefinitionEntity)((RepositoryServiceImpl)repositoryService)
.getDeployedProcessDefinition(processDefinitionId);
ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
ActivityImpl currActivity = processDefinitionEntity.findActivity(processInstance.getActivityId());
if (currActivity != null) {
//获取当前活动的所有入口
List<PvmTransition> nextTransitionList = currActivity.getIncomingTransitions();
// 新建一个节点连线关系集合(用于保存出口连线信息)
List<PvmTransition> oriPvmTransitionList = new ArrayList<PvmTransition>();
//获取当前环节的所有出口
List<PvmTransition> pvmTransitionList = currActivity.getOutgoingTransitions();
for (PvmTransition pvmTransition : pvmTransitionList) {
oriPvmTransitionList.add(pvmTransition);
}
//建立临时新的出口集合
List<TransitionImpl> newTransitions = new ArrayList<TransitionImpl>();
List<String> lsTasks = new ArrayList<String>();
for (PvmTransition nextTransition : nextTransitionList) {// 建立临时出口连线
PvmActivity nextActivity = nextTransition.getSource();// 目标节点
ActivityImpl nextActivityImpl = ((ProcessDefinitionImpl) processDefinitionEntity).findActivity(nextActivity.getId());
// 清除当前活动的出口
pvmTransitionList.clear();
TransitionImpl newTransition = currActivity.createOutgoingTransition();
if ("userTask".equals(nextActivity.getProperty("type"))) {// 判断上一节点是否为任务节点 其它节点无法退回
newTransition.setDestination(nextActivityImpl);// 建立当前节点到目标节点的连线
newTransitions.add(newTransition);
} else if ("parallelGateway".equals(nextActivity.getProperty("type"))) {// 判断上一节点是否为并发节点
List<PvmTransition> outTransitionsTemp = nextActivity.getIncomingTransitions();// 查找parallelGateway环节的所有进入连线
for (PvmTransition tr1 : outTransitionsTemp) {
ActivityImpl activityImpl = (ActivityImpl) tr1.getSource();
TaskDefinition taskDefinition = ((UserTaskActivityBehavior) activityImpl.getActivityBehavior()).getTaskDefinition();
String taskAssignee = taskDefinition.getAssigneeExpression().getExpressionText();
newTransition.setDestination(activityImpl);// 建立当前节点到目标节点的连线
newTransitions.add(newTransition);
}
} else if ("exclusiveGateway".equals(nextActivity.getProperty("type"))) {
List<PvmTransition> outTransitionsTemp = nextActivity.getIncomingTransitions();// 查找exclusiveGateway环节的所有进入连线
for (PvmTransition tr1 : outTransitionsTemp) {
ActivityImpl activityImpl = (ActivityImpl) tr1.getSource();
newTransition.setDestination(activityImpl);// 建立当前节点到目标节点的连线
newTransitions.add(newTransition);
}
}
}
if (newTransitions !=null) {
List<Task> taskList = taskService.createTaskQuery().processInstanceId(processInstance.getId()).taskDefinitionKey(processInstance.getActivityId()).list();
for (Task task : taskList) {
taskService.complete(task.getId(), variables);
   historyService.deleteHistoricTaskInstance(task.getId());
}
for (TransitionImpl transitionImpl : newTransitions) {
currActivity.getOutgoingTransitions().remove(transitionImpl);
}
for (PvmTransition pvmTransition : oriPvmTransitionList) {
pvmTransitionList.add(pvmTransition);
}
}
}
}

/**
* 方法说明 : 查询上一个节点.

* @param activityImpl
*            活动节点
* @param activityId
*            当前活动节点ID
* @param elString
*/
public TaskDefinition beforeTaskDefinition(ActivityImpl activityImpl, String activityId, String elString) {
if ("userTask".equals(activityImpl.getProperty("type")) && !activityId.equals(activityImpl.getId())) {
TaskDefinition taskDefinition = null;
if (activityImpl != null) {
taskDefinition = ((UserTaskActivityBehavior) activityImpl.getActivityBehavior()).getTaskDefinition();
}
return taskDefinition;
} else {
List<PvmTransition> inTransitions = activityImpl.getIncomingTransitions(); // 通过活动节点查询所有线路
if (inTransitions != null && inTransitions.size() > 0) {
List<PvmTransition> inTransitionsTemp = null;
for (PvmTransition tr : inTransitions) {
PvmActivity ac = tr.getSource(); // 获取线路的前节点
if ("exclusiveGateway".equals(ac.getProperty("type"))) {
inTransitionsTemp = ac.getIncomingTransitions();
if (inTransitionsTemp.size() == 1) {
return beforeTaskDefinition((ActivityImpl) inTransitionsTemp.get(0).getSource(), activityId, elString);
} else if (inTransitionsTemp.size() > 1) {
for (PvmTransition tr1 : inTransitionsTemp) {
Object s = tr1.getProperty("conditionText");
if (elString.equals(StringUtils.replacePattern(StringUtils.trim(s.toString()), " ", ""))) {
return beforeTaskDefinition((ActivityImpl) tr1.getSource(), activityId, elString);
}
}
}
}
}
}
return null;
}
}

/**
* 方法说明 : 查询下一个节点.

* @param activityImpl
*            活动节点
* @param activityId
*            当前活动节点ID
* @param elString
*/
public TaskDefinition nextTaskDefinition(ActivityImpl activityImpl, String activityId, String elString) {
if ("userTask".equals(activityImpl.getProperty("type")) && !activityId.equals(activityImpl.getId())) {
TaskDefinition taskDefinition = null;
if (activityImpl != null) {
taskDefinition = ((UserTaskActivityBehavior) activityImpl.getActivityBehavior()).getTaskDefinition();
}
return taskDefinition;
} else {
List<PvmTransition> outTransitions = activityImpl.getOutgoingTransitions(); // 通过活动节点查询所有线路
if (outTransitions != null && outTransitions.size() > 0) {
List<PvmTransition> outTransitionsTemp = null;
for (PvmTransition tr : outTransitions) {
PvmActivity ac = tr.getDestination(); // 获取线路的终点节点
if ("exclusiveGateway".equals(ac.getProperty("type"))) {
outTransitionsTemp = ac.getOutgoingTransitions();
if (outTransitionsTemp.size() == 1) {
return nextTaskDefinition((ActivityImpl) outTransitionsTemp.get(0).getDestination(), activityId, elString);
} else if (outTransitionsTemp.size() > 1) {
for (PvmTransition tr1 : outTransitionsTemp) {
Object s = tr1.getProperty("conditionText");
if (s != null && elString.equals(StringUtils.replacePattern(StringUtils.trim(s.toString()), " ", ""))) {
return nextTaskDefinition((ActivityImpl) tr1.getDestination(), activityId, elString);
}
}
}
} else if ("userTask".equals(ac.getProperty("type"))) {
return findTaskDefinitionByActivityImpl((ActivityImpl) ac);
} else if ("startEvent".equals(ac.getProperty("type"))) {
return findTaskDefinitionByActivityImpl((ActivityImpl) ac);
} else {
//logger.info(ac.getProperty("type").toString());
}
}
}
return null;
}


}

/**
* 方法说明 : 根据活动节点查询任务定义.

* @param activityImpl
*            活动节点
*/
public TaskDefinition findTaskDefinitionByActivityImpl(ActivityImpl activityImpl) {
return ((UserTaskActivityBehavior) activityImpl.getActivityBehavior()).getTaskDefinition();
}


/**
* 方法说明: 根据活动节点、活动线路查询线路的连接线.
*/
@SuppressWarnings("rawtypes")
public PvmActivity findPvmActivity(ActivityImpl activityImpl, String transitions) {
PvmActivity activity = null;
List<PvmTransition> pvmTransitions = activityImpl.getOutgoingTransitions(); // 获取所有线路
for (Iterator iterator = pvmTransitions.iterator(); iterator.hasNext();) {
PvmTransition pvmTransition = (PvmTransition) iterator.next();
PvmActivity pvmActivity = pvmTransition.getDestination(); // 获取下一个任务节点
String transitionsVal = (String) pvmActivity.getProperty("name");
if (transitions.equals(transitionsVal)) {
activity = pvmActivity;
break;
}
}
return activity;
}


/**
* 收回任务
* @param processDefinitionId 流程定义id
* @param processInstanceId 流出实例id
* @return
*/
public String rollBackTask(String assignee, String processDefinitionId, String processInstanceId) {
boolean isSuccess = false;
Map<String, Object> variables = new HashMap<String, Object>();
// 获取流程部署定义
ProcessDefinitionEntity processDefinitionEntity = this.findProcessDefinitionEntityByProcDefId(processDefinitionId);
// 获取流程实例
ProcessInstance processInstance = this.findProcessInstanceByProcInst(processInstanceId);
List<Task> currTasks = taskService.createTaskQuery().processInstanceId(processInstanceId).list();// 根据流程实例id查询
String taskKey = "";
String taskName = "";
String handleResult = "";//处理结果
if(currTasks !=null){
for (Task currTask : currTasks) {
// 根据当前活动节点key 取得当前活动节点
ActivityImpl currActivity = processDefinitionEntity.findActivity(currTask.getTaskDefinitionKey());
if (currActivity != null) {
// 本节点跟上一环节的连接线(入口线)
List<PvmTransition> nextTransitionList = currActivity.getIncomingTransitions();
// 新建一个节点连线关系集合 用于临时存储出口线
List<PvmTransition> oriPvmTransitionList = new ArrayList<PvmTransition>();
// 获取当前活动的出口
List<PvmTransition> pvmTransitionList = currActivity.getOutgoingTransitions();
for (PvmTransition pvmTransition : pvmTransitionList) {
oriPvmTransitionList.add(pvmTransition);
}
// 建立新出口
List<TransitionImpl> newTransitions = new ArrayList<TransitionImpl>();
List<String> lsTasks = new ArrayList<String>();
for (PvmTransition nextTransition : nextTransitionList) {// 建立临时出口连线
PvmActivity nextActivity = nextTransition.getSource();// 目标节点 实际上一环节
ActivityImpl nextActivityImpl = processDefinitionEntity.findActivity(nextActivity.getId());
ActivityImpl activityImpl = null;//最终上一环节(并发、排它节点时的上一环节)
if("userTask".equals(nextActivity.getProperty("type"))){// 判断上一节点是否为任务节点 其它节点无法退回
activityImpl = nextActivityImpl;
}else if ("parallelGateway".equals(nextActivity.getProperty("type"))) {// 判断上一节点是否为并发节点
List<PvmTransition> outTransitionsTemp = nextActivity.getIncomingTransitions();// 查找parallelGateway环节的所有进入连线
for (PvmTransition tr1 : outTransitionsTemp) {//获取并发节点的上一环节
activityImpl = (ActivityImpl) tr1.getSource();
}
}else if ("exclusiveGateway".equals(nextActivity.getProperty("type"))) {// 判断上一节点是否为排它关口
List<PvmTransition> outTransitionsTemp = nextActivity.getIncomingTransitions();// 查找exclusiveGateway环节的所有进入连线
for (PvmTransition tr1 : outTransitionsTemp) {//获取排它关口的上一环节
activityImpl = (ActivityImpl) tr1.getSource();
}
}
List<HistoricTaskInstance> historicTaskInstances = getHistoricTaskInstance(processInstanceId,activityImpl.getId());
for(HistoricTaskInstance taskInstance : historicTaskInstances){
if(assignee.equals(taskInstance.getAssignee())){//判断当前用户是否是上一环节中的审批人 如果是则允许收回
taskKey += currTask.getTaskDefinitionKey() +",";
taskName += currTask.getName() +",";
// 清除当前活动的出口
pvmTransitionList.clear();
TransitionImpl newTransition = currActivity.createOutgoingTransition();//建立新的出口连接线
if ("userTask".equals(nextActivity.getProperty("type"))) {// 判断上一节点是否为任务节点 其它节点无法退回
newTransition.setDestination(activityImpl);// 建立当前节点到目标节点的连线
newTransitions.add(newTransition);
} else if ("parallelGateway".equals(nextActivity.getProperty("type"))) {// 判断上一节点是否为并发节点
TaskDefinition taskDefinition = findTaskDefinitionByActivityImpl(activityImpl);
String taskAssignee = taskDefinition.getAssigneeExpression().getExpressionText();
if (!assignee.equals(taskAssignee)) {// 并发流程时 只收回到自己环节 后面再处理时有异常,此处放到临时集合中,在后面将这些不属于自己的环节处理掉
lsTasks.add(taskDefinition.getKey());//如果是收回  退回不做此处理
}
newTransition.setDestination(activityImpl);// 建立当前节点到目标节点的连线
newTransitions.add(newTransition);
} else if ("exclusiveGateway".equals(nextActivity.getProperty("type"))) {
newTransition.setDestination(activityImpl);// 建立当前节点到目标节点的连线
newTransitions.add(newTransition);
}
}
}
}
ActivityImpl currActivity1 = processDefinitionEntity.findActivity(currTask.getTaskDefinitionKey());
if (newTransitions!=null) {// 判断出口是否已建立
// 完成任务
List<Task> taskList = taskService.createTaskQuery().processInstanceId(processInstance.getId()).taskDefinitionKey(currTask.getTaskDefinitionKey()).list();
for (Task task : taskList) {
taskService.complete(task.getId(), variables);// 完成当前任务
historyService.deleteHistoricTaskInstance(task.getId());// 删除当前操作历史记录
}
// 恢复方向
for (TransitionImpl transitionImpl : newTransitions) {
isSuccess = currActivity.getOutgoingTransitions().remove(transitionImpl);// 删除新建立的临时连线
}
for (PvmTransition pvmTransition : oriPvmTransitionList) {
pvmTransitionList.add(pvmTransition);// 恢复清除的出口线
}
if (isSuccess && lsTasks!=null) {// 处理上一步环节为并发环节时,将其它不属于自己的环节 任务 自动完成。解决收回了其它环节的问题
List<Task> tasks = this.findTaskByProcInstIds(processInstanceId);
for (Task task : tasks) {
for (String key : lsTasks) {
if (key.equals(task.getTaskDefinitionKey())) {
taskService.complete(task.getId(), variables);// 完成当前任务
}
}
}
}
}
}
}
handleResult = taskName;
if(handleResult.length() > 0){//设置处理结果
handleResult = handleResult.indexOf(",") > -1 ? handleResult.substring(0, handleResult.length() -1) : handleResult;
handleResult = "从<font color='green'>" + handleResult + "</font><font color='red'>收回</font>";
}
}
return "{\"IsSuccess\":" + isSuccess + ",\"handleResult\":\"" + handleResult + "\"}";

}

            /**
    * 读取带跟踪的图片
    */
   @RequestMapping("/view.do")
   public void test(HttpServletResponse response,@RequestParam("processInstanceId") String processInstanceId) throws Exception {
       //获取历史流程实例
       HistoricProcessInstance processInstance =  historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
       //获取流程图
       BpmnModel bpmnModel = repositoryService.getBpmnModel(processInstance.getProcessDefinitionId());
       processEngineConfiguration = processEngine.getProcessEngineConfiguration();
       Context.setProcessEngineConfiguration((ProcessEngineConfigurationImpl) processEngineConfiguration);


       ProcessDiagramGenerator diagramGenerator = processEngineConfiguration.getProcessDiagramGenerator();
       ProcessDefinitionEntity definitionEntity = (ProcessDefinitionEntity)repositoryService.getProcessDefinition(processInstance.getProcessDefinitionId());


       List<HistoricActivityInstance> highLightedActivitList =  historyService.createHistoricActivityInstanceQuery().processInstanceId(processInstanceId).list();
       //高亮环节id集合
       List<String> highLightedActivitis = new ArrayList<String>();
       //高亮线路id集合
       List<String> highLightedFlows = getHighLightedFlows(definitionEntity,highLightedActivitList);


       for(HistoricActivityInstance tempActivity : highLightedActivitList){
           String activityId = tempActivity.getActivityId();
           highLightedActivitis.add(activityId);
       }


       //中文显示的是口口口,设置字体就好了
       InputStream imageStream = diagramGenerator.generateDiagram(bpmnModel, "png", highLightedActivitis,highLightedFlows,"宋体","宋体",null,1.0);
       //单独返回流程图,不高亮显示
//        InputStream imageStream = diagramGenerator.generatePngDiagram(bpmnModel);
       // 输出资源内容到相应对象
       byte[] b = new byte[1024];
       int len;
       while ((len = imageStream.read(b, 0, 1024)) != -1) {
           response.getOutputStream().write(b, 0, len);
       }
   }


   /**
    * 获取需要高亮的线
    * @param processDefinitionEntity
    * @param historicActivityInstances
    * @return
    */
   private List<String> getHighLightedFlows(
           ProcessDefinitionEntity processDefinitionEntity,
           List<HistoricActivityInstance> historicActivityInstances) {
       List<String> highFlows = new ArrayList<String>();// 用以保存高亮的线flowId
       for (int i = 0; i < historicActivityInstances.size() - 1; i++) {// 对历史流程节点进行遍历
           ActivityImpl activityImpl = processDefinitionEntity
                   .findActivity(historicActivityInstances.get(i)
                           .getActivityId());// 得到节点定义的详细信息
           List<ActivityImpl> sameStartTimeNodes = new ArrayList<ActivityImpl>();// 用以保存后需开始时间相同的节点
           ActivityImpl sameActivityImpl1 = processDefinitionEntity
                   .findActivity(historicActivityInstances.get(i + 1)
                           .getActivityId());
           // 将后面第一个节点放在时间相同节点的集合里
           sameStartTimeNodes.add(sameActivityImpl1);
           for (int j = i + 1; j < historicActivityInstances.size() - 1; j++) {
               HistoricActivityInstance activityImpl1 = historicActivityInstances
                       .get(j);// 后续第一个节点
               HistoricActivityInstance activityImpl2 = historicActivityInstances
                       .get(j + 1);// 后续第二个节点
               if (activityImpl1.getStartTime().equals(
                       activityImpl2.getStartTime())) {
                   // 如果第一个节点和第二个节点开始时间相同保存
                   ActivityImpl sameActivityImpl2 = processDefinitionEntity
                           .findActivity(activityImpl2.getActivityId());
                   sameStartTimeNodes.add(sameActivityImpl2);
               } else {
                   // 有不相同跳出循环
                   break;
               }
           }
           List<PvmTransition> pvmTransitions = activityImpl
                   .getOutgoingTransitions();// 取出节点的所有出去的线
           for (PvmTransition pvmTransition : pvmTransitions) {
               // 对所有的线进行遍历
               ActivityImpl pvmActivityImpl = (ActivityImpl) pvmTransition
                       .getDestination();
               // 如果取出的线的目标节点存在时间相同的节点里,保存该线的id,进行高亮显示
               if (sameStartTimeNodes.contains(pvmActivityImpl)) {
                   highFlows.add(pvmTransition.getId());
               }
           }
       }
       return highFlows;
   }



}