activiti util (2)

package com.famousPro.process.service.impl;

 

import java.util.ArrayList;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

 

import org.activiti.engine.FormService;

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.HistoricActivityInstance;

import org.activiti.engine.impl.RepositoryServiceImpl;

import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;

import org.activiti.engine.impl.persistence.entity.TaskEntity;

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.runtime.ProcessInstance;

import org.activiti.engine.task.Task;

 

import com.famousPro.common.service.impl.BaseServiceImp;

import com.famousPro.common.util.IDGenerator;

import com.famousPro.common.util.StringUtil;

import com.famousPro.process.service.ProcessCoreService;

import com.famousPro.process.service.ProcessOtherService;

 

/**

 * 流程操作核心类<br>

 * 此核心类主要处理:流程通过、驳回、会签、转办、中止、挂起等核心操作<br>

 * 

 * @author wangfuwei

 * 

 */

public class ProcessCoreServiceImpl extends BaseServiceImp implements

ProcessCoreService {

protected RepositoryService repositoryService;

 

protected RuntimeService runtimeService;

 

protected TaskService taskService;

 

protected FormService formService;

 

protected HistoryService historyService;

 

protected ProcessOtherService processOtherService;

 

/**

* 根据当前任务ID,查询可以驳回的任务节点

* @param taskId

*            当前任务ID

*/

public List<ActivityImpl> findBackAvtivity(String taskId) throws Exception {

List<ActivityImpl> rtnList = null;

if (processOtherService.isJointTask(taskId)) {// 会签任务节点,不允许驳回

rtnList = new ArrayList<ActivityImpl>();

} else {

rtnList = iteratorBackActivity(taskId, findActivitiImpl(taskId,

null), new ArrayList<ActivityImpl>(),

new ArrayList<ActivityImpl>());

}

return reverList(rtnList);

}

 

/**

* 审批通过(驳回直接跳回功能需后续扩展)

* @param taskId

*            当前任务ID

* @param variables

*            流程存储参数

* @throws Exception

*/

public void passProcess(String taskId, Map<String, Object> variables)

throws Exception {

List<Task> tasks = taskService.createTaskQuery().parentTaskId(taskId)

.taskDescription("jointProcess").list();

for (Task task : tasks) {// 级联结束本节点发起的会签任务

commitProcess(task.getId(), null, null);

}

commitProcess(taskId, variables, null);

}

 

/**

* 驳回流程

* @param taskId

*            当前任务ID

* @param activityId

*            驳回节点ID

* @param variables

*            流程存储参数

* @throws Exception

*/

public void backProcess(String taskId, String activityId,

Map<String, Object> variables) throws Exception {

if (StringUtil.isNull(activityId)) {

throw new Exception("驳回目标节点ID为空!");

}

 

// 查询本节点发起的会签任务,并结束

List<Task> tasks = taskService.createTaskQuery().parentTaskId(taskId)

.taskDescription("jointProcess").list();

for (Task task : tasks) {

commitProcess(task.getId(), null, null);

}

 

// 查找所有并行任务节点,同时驳回

List<Task> taskList = findTaskListByKey(findProcessInstanceByTaskId(

taskId).getId(), findTaskById(taskId).getTaskDefinitionKey());

for (Task task : taskList) {

commitProcess(task.getId(), variables, activityId);

}

}

 

/**

* 取回流程

* @param taskId

*            当前任务ID

* @param activityId

*            取回节点ID

* @throws Exception

*/

public void callBackProcess(String taskId, String activityId)

throws Exception {

if (StringUtil.isNull(activityId)) {

throw new Exception("目标节点ID为空!");

}

 

// 查找所有并行任务节点,同时取回

List<Task> taskList = findTaskListByKey(findProcessInstanceByTaskId(

taskId).getId(), findTaskById(taskId).getTaskDefinitionKey());

for (Task task : taskList) {

commitProcess(task.getId(), null, activityId);

}

}

 

/**

* 中止流程(特权人直接审批通过等)

* @param taskId

*/

public void endProcess(String taskId) throws Exception {

ActivityImpl endActivity = findActivitiImpl(taskId, "end");

commitProcess(taskId, null, endActivity.getId());

}

 

/**

* 会签操作

* @param taskId

*            当前任务ID

* @param userCodes

*            会签人账号集合

* @throws Exception

*/

public void jointProcess(String taskId, List<String> userCodes)

throws Exception {

for (String userCode : userCodes) {

TaskEntity task = (TaskEntity) taskService.newTask(IDGenerator

.generateID());

task.setAssignee(userCode);

task.setName(findTaskById(taskId).getName() + "-会签");

task.setProcessDefinitionId(findProcessDefinitionEntityByTaskId(

taskId).getId());

task.setProcessInstanceId(findProcessInstanceByTaskId(taskId)

.getId());

task.setParentTaskId(taskId);

task.setDescription("jointProcess");

taskService.saveTask(task);

}

}

 

/**

* 转办流程

* @param taskId

*            当前任务节点ID

* @param userCode

*            被转办人Code

*/

public void transferAssignee(String taskId, String userCode) {

taskService.setAssignee(taskId, userCode);

}

 

/**

* ***************************************************************************************************************************************************<br>

* ************************************************以下为流程会签操作核心逻辑******************************************************************************<br>

* ***************************************************************************************************************************************************<br>

*/

 

/**

* ***************************************************************************************************************************************************<br>

* ************************************************以上为流程会签操作核心逻辑******************************************************************************<br>

* ***************************************************************************************************************************************************<br>

*/

 

/**

* ***************************************************************************************************************************************************<br>

* ************************************************以下为流程转向操作核心逻辑******************************************************************************<br>

* ***************************************************************************************************************************************************<br>

*/

 

/**

* @param taskId

*            当前任务ID

* @param variables

*            流程变量

* @param activityId

*            流程转向执行任务节点ID<br>

*            此参数为空,默认为提交操作

* @throws Exception

*/

private void commitProcess(String taskId, Map<String, Object> variables,

String activityId) throws Exception {

if (variables == null) {

variables = new HashMap<String, Object>();

}

// 跳转节点为空,默认提交操作

if (StringUtil.isNull(activityId)) {

taskService.complete(taskId, variables);

} else {// 流程转向操作

turnTransition(taskId, activityId, variables);

}

}

 

/**

* 清空指定活动节点流向

* @param activityImpl

*            活动节点

* @return 节点流向集合

*/

private List<PvmTransition> clearTransition(ActivityImpl activityImpl) {

// 存储当前节点所有流向临时变量

List<PvmTransition> oriPvmTransitionList = new ArrayList<PvmTransition>();

// 获取当前节点所有流向,存储到临时变量,然后清空

List<PvmTransition> pvmTransitionList = activityImpl

.getOutgoingTransitions();

for (PvmTransition pvmTransition : pvmTransitionList) {

oriPvmTransitionList.add(pvmTransition);

}

pvmTransitionList.clear();

 

return oriPvmTransitionList;

}

 

/**

* 还原指定活动节点流向

* @param activityImpl

*            活动节点

* @param oriPvmTransitionList

*            原有节点流向集合

*/

private void restoreTransition(ActivityImpl activityImpl,

List<PvmTransition> oriPvmTransitionList) {

// 清空现有流向

List<PvmTransition> pvmTransitionList = activityImpl

.getOutgoingTransitions();

pvmTransitionList.clear();

// 还原以前流向

for (PvmTransition pvmTransition : oriPvmTransitionList) {

pvmTransitionList.add(pvmTransition);

}

}

 

/**

* 流程转向操作

* @param taskId

*            当前任务ID

* @param activityId

*            目标节点任务ID

* @param variables

*            流程变量

* @throws Exception

*/

private void turnTransition(String taskId, String activityId,

Map<String, Object> variables) throws Exception {

// 当前节点

ActivityImpl currActivity = findActivitiImpl(taskId, null);

// 清空当前流向

List<PvmTransition> oriPvmTransitionList = clearTransition(currActivity);

 

// 创建新流向

TransitionImpl newTransition = currActivity.createOutgoingTransition();

// 目标节点

ActivityImpl pointActivity = findActivitiImpl(taskId, activityId);

// 设置新流向的目标节点

newTransition.setDestination(pointActivity);

 

// 执行转向任务

taskService.complete(taskId, variables);

// 删除目标节点新流入

pointActivity.getIncomingTransitions().remove(newTransition);

 

// 还原以前流向

restoreTransition(currActivity, oriPvmTransitionList);

}

 

/**

* ***************************************************************************************************************************************************<br>

* ************************************************以上为流程转向操作核心逻辑******************************************************************************<br>

* ***************************************************************************************************************************************************<br>

*/

 

/**

* ***************************************************************************************************************************************************<br>

* ************************************************以下为查询流程驳回节点核心逻辑***************************************************************************<br>

* ***************************************************************************************************************************************************<br>

*/

 

/**

* 迭代循环流程树结构,查询当前节点可驳回的任务节点

* @param taskId

*            当前任务ID

* @param currActivity

*            当前活动节点

* @param rtnList

*            存储回退节点集合

* @param tempList

*            临时存储节点集合(存储一次迭代过程中的同级userTask节点)

* @return 回退节点集合

*/

private List<ActivityImpl> iteratorBackActivity(String taskId,

ActivityImpl currActivity, List<ActivityImpl> rtnList,

List<ActivityImpl> tempList) throws Exception {

// 查询流程定义,生成流程树结构

ProcessInstance processInstance = findProcessInstanceByTaskId(taskId);

 

// 当前节点的流入来源

List<PvmTransition> incomingTransitions = currActivity

.getIncomingTransitions();

// 条件分支节点集合,userTask节点遍历完毕,迭代遍历此集合,查询条件分支对应的userTask节点

List<ActivityImpl> exclusiveGateways = new ArrayList<ActivityImpl>();

// 并行节点集合,userTask节点遍历完毕,迭代遍历此集合,查询并行节点对应的userTask节点

List<ActivityImpl> parallelGateways = new ArrayList<ActivityImpl>();

// 遍历当前节点所有流入路径

for (PvmTransition pvmTransition : incomingTransitions) {

TransitionImpl transitionImpl = (TransitionImpl) pvmTransition;

ActivityImpl activityImpl = transitionImpl.getSource();

String type = (String) activityImpl.getProperty("type");

/**

* 并行节点配置要求:<br>

* 必须成对出现,且要求分别配置节点ID为:XXX_start(开始),XXX_end(结束)

*/

if ("parallelGateway".equals(type)) {// 并行路线

String gatewayId = activityImpl.getId();

String gatewayType = gatewayId.substring(gatewayId

.lastIndexOf("_") + 1);

if ("START".equals(gatewayType.toUpperCase())) {// 并行起点,停止递归

return rtnList;

} else {// 并行终点,临时存储此节点,本次循环结束,迭代集合,查询对应的userTask节点

parallelGateways.add(activityImpl);

}

} else if ("startEvent".equals(type)) {// 开始节点,停止递归

return rtnList;

} else if ("userTask".equals(type)) {// 用户任务

tempList.add(activityImpl);

} else if ("exclusiveGateway".equals(type)) {// 分支路线,临时存储此节点,本次循环结束,迭代集合,查询对应的userTask节点

currActivity = transitionImpl.getSource();

exclusiveGateways.add(currActivity);

}

}

 

/**

* 迭代条件分支集合,查询对应的userTask节点

*/

for (ActivityImpl activityImpl : exclusiveGateways) {

iteratorBackActivity(taskId, activityImpl, rtnList, tempList);

}

 

/**

* 迭代并行集合,查询对应的userTask节点

*/

for (ActivityImpl activityImpl : parallelGateways) {

iteratorBackActivity(taskId, activityImpl, rtnList, tempList);

}

 

/**

* 根据同级userTask集合,过滤最近发生的节点

*/

currActivity = filterNewestActivity(processInstance, tempList);

if (currActivity != null) {

// 查询当前节点的流向是否为并行终点,并获取并行起点ID

String id = findParallelGatewayId(currActivity);

if (StringUtil.isNull(id)) {// 并行起点ID为空,此节点流向不是并行终点,符合驳回条件,存储此节点

rtnList.add(currActivity);

} else {// 根据并行起点ID查询当前节点,然后迭代查询其对应的userTask任务节点

currActivity = findActivitiImpl(taskId, id);

}

 

// 清空本次迭代临时集合

tempList.clear();

// 执行下次迭代

iteratorBackActivity(taskId, currActivity, rtnList, tempList);

}

return rtnList;

}

 

/**

* 反向排序list集合,便于驳回节点按顺序显示

* @param list

* @return

*/

private List<ActivityImpl> reverList(List<ActivityImpl> list) {

List<ActivityImpl> rtnList = new ArrayList<ActivityImpl>();

// 由于迭代出现重复数据,排除重复

for (int i = list.size(); i > 0; i--) {

if (!rtnList.contains(list.get(i - 1)))

rtnList.add(list.get(i - 1));

}

return rtnList;

}

 

/**

* 根据当前节点,查询输出流向是否为并行终点,如果为并行终点,则拼装对应的并行起点ID

* @param activityImpl

*            当前节点

* @return

*/

private String findParallelGatewayId(ActivityImpl activityImpl) {

List<PvmTransition> incomingTransitions = activityImpl

.getOutgoingTransitions();

for (PvmTransition pvmTransition : incomingTransitions) {

TransitionImpl transitionImpl = (TransitionImpl) pvmTransition;

activityImpl = transitionImpl.getDestination();

String type = (String) activityImpl.getProperty("type");

if ("parallelGateway".equals(type)) {// 并行路线

String gatewayId = activityImpl.getId();

String gatewayType = gatewayId.substring(gatewayId

.lastIndexOf("_") + 1);

if ("END".equals(gatewayType.toUpperCase())) {

return gatewayId.substring(0, gatewayId.lastIndexOf("_"))

+ "_start";

}

}

}

return null;

}

 

/**

* 根据流入任务集合,查询最近一次的流入任务节点

* @param processInstance

*            流程实例

* @param tempList

*            流入任务集合

* @return

*/

private ActivityImpl filterNewestActivity(ProcessInstance processInstance,

List<ActivityImpl> tempList) {

while (tempList.size() > 0) {

ActivityImpl activity_1 = tempList.get(0);

HistoricActivityInstance activityInstance_1 = findHistoricUserTask(

processInstance, activity_1.getId());

if (activityInstance_1 == null) {

tempList.remove(activity_1);

continue;

}

 

if (tempList.size() > 1) {

ActivityImpl activity_2 = tempList.get(1);

HistoricActivityInstance activityInstance_2 = findHistoricUserTask(

processInstance, activity_2.getId());

if (activityInstance_2 == null) {

tempList.remove(activity_2);

continue;

}

 

if (activityInstance_1.getEndTime().before(

activityInstance_2.getEndTime())) {

tempList.remove(activity_1);

} else {

tempList.remove(activity_2);

}

} else {

break;

}

}

if (tempList.size() > 0) {

return tempList.get(0);

}

return null;

}

 

/**

* 查询指定任务节点的最新记录

* @param processInstance

*            流程实例

* @param activityId

* @return

*/

private HistoricActivityInstance findHistoricUserTask(

ProcessInstance processInstance, String activityId) {

HistoricActivityInstance rtnVal = null;

// 查询当前流程实例审批结束的历史节点

List<HistoricActivityInstance> historicActivityInstances = historyService

.createHistoricActivityInstanceQuery().activityType("userTask")

.processInstanceId(processInstance.getId()).activityId(

activityId).finished()

.orderByHistoricActivityInstanceEndTime().desc().list();

if (historicActivityInstances.size() > 0) {

rtnVal = historicActivityInstances.get(0);

}

 

return rtnVal;

}

 

/**

* *******************************************************************************************************<br>

* ********************************以上为查询流程驳回节点核心逻辑***********************************************<br>

* ********************************************************************************************************<br>

*/

 

/**

* ********************************************************************************<br>

* **********************以下为activiti 核心service

* set方法***************************<br>

* *********************************************************************************<br>

*/

public void setFormService(FormService formService) {

this.formService = formService;

}

 

public void setHistoryService(HistoryService historyService) {

this.historyService = historyService;

}

 

public void setRepositoryService(RepositoryService repositoryService) {

this.repositoryService = repositoryService;

}

 

public void setRuntimeService(RuntimeService runtimeService) {

this.runtimeService = runtimeService;

}

 

public void setTaskService(TaskService taskService) {

this.taskService = taskService;

}

 

/**

* ********************************************************************************<br>

* **********************以上为activiti 核心service

* set方法***************************<br>

* *********************************************************************************<br>

*/

 

/**

* ********************************************************************************<br>

* **********************以下为根据 任务节点ID 获取流程各对象查询方法**********************<br>

* *********************************************************************************<br>

*/

 

public void setProcessOtherService(ProcessOtherService processOtherService) {

this.processOtherService = processOtherService;

}

 

/**

* 根据任务ID获得任务实例

* @param taskId

*            任务ID

* @return

* @throws Exception

*/

private TaskEntity findTaskById(String taskId) throws Exception {

TaskEntity task = (TaskEntity) taskService.createTaskQuery().taskId(

taskId).singleResult();

if (task == null) {

throw new Exception("任务实例未找到!");

}

return task;

}

 

/**

* 根据流程实例ID和任务key值查询所有同级任务集合

* @param processInstanceId

* @param key

* @return

*/

private List<Task> findTaskListByKey(String processInstanceId, String key) {

return taskService.createTaskQuery().processInstanceId(

processInstanceId).taskDefinitionKey(key).list();

}

 

/**

* 根据任务ID获取对应的流程实例

* @param taskId

*            任务ID

* @return

* @throws Exception

*/

private ProcessInstance findProcessInstanceByTaskId(String taskId)

throws Exception {

// 找到流程实例

ProcessInstance processInstance = runtimeService

.createProcessInstanceQuery().processInstanceId(

findTaskById(taskId).getProcessInstanceId())

.singleResult();

if (processInstance == null) {

throw new Exception("流程实例未找到!");

}

return processInstance;

}

 

/**

* 根据任务ID获取流程定义

* @param taskId

*            任务ID

* @return

* @throws Exception

*/

private ProcessDefinitionEntity findProcessDefinitionEntityByTaskId(

String taskId) throws Exception {

// 取得流程定义

ProcessDefinitionEntity processDefinition = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService)

.getDeployedProcessDefinition(findTaskById(taskId)

.getProcessDefinitionId());

 

if (processDefinition == null) {

throw new Exception("流程定义未找到!");

}

 

return processDefinition;

}

 

/**

* 根据任务ID和节点ID获取活动节点 <br>

* @param taskId

*            任务ID

* @param activityId

*            活动节点ID <br>

*            如果为null或"",则默认查询当前活动节点 <br>

*            如果为"end",则查询结束节点 <br>

* @return

* @throws Exception

*/

private ActivityImpl findActivitiImpl(String taskId, String activityId)

throws Exception {

// 取得流程定义

ProcessDefinitionEntity processDefinition = findProcessDefinitionEntityByTaskId(taskId);

 

// 获取当前活动节点ID

if (StringUtil.isNull(activityId)) {

activityId = findTaskById(taskId).getTaskDefinitionKey();

}

 

// 根据流程定义,获取该流程实例的结束节点

if (activityId.toUpperCase().equals("END")) {

for (ActivityImpl activityImpl : processDefinition.getActivities()) {

List<PvmTransition> pvmTransitionList = activityImpl

.getOutgoingTransitions();

if (pvmTransitionList.isEmpty()) {

return activityImpl;

}

}

}

 

// 根据节点ID,获取对应的活动节点

ActivityImpl activityImpl = ((ProcessDefinitionImpl) processDefinition)

.findActivity(activityId);

 

return activityImpl;

}

 

/**

* ********************************************************************************<br>

* **********************以上为根据 任务节点ID 获取流程各对象查询方法**********************<br>

* *********************************************************************************<br>

*/

}

 

  1. package com.famousPro.process.service.impl;
  2.  
     
  3.  
    import java.util.ArrayList;
  4.  
    import java.util.HashMap;
  5.  
    import java.util.List;
  6.  
    import java.util.Map;
  7.  
     
  8.  
    import org.activiti.engine.FormService;
  9.  
    import org.activiti.engine.HistoryService;
  10.  
    import org.activiti.engine.RepositoryService;
  11.  
    import org.activiti.engine.RuntimeService;
  12.  
    import org.activiti.engine.TaskService;
  13.  
    import org.activiti.engine.history.HistoricActivityInstance;
  14.  
    import org.activiti.engine.impl.RepositoryServiceImpl;
  15.  
    import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
  16.  
    import org.activiti.engine.impl.persistence.entity.TaskEntity;
  17.  
    import org.activiti.engine.impl.pvm.PvmTransition;
  18.  
    import org.activiti.engine.impl.pvm.process.ActivityImpl;
  19.  
    import org.activiti.engine.impl.pvm.process.ProcessDefinitionImpl;
  20.  
    import org.activiti.engine.impl.pvm.process.TransitionImpl;
  21.  
    import org.activiti.engine.runtime.ProcessInstance;
  22.  
    import org.activiti.engine.task.Task;
  23.  
     
  24.  
    import com.famousPro.common.service.impl.BaseServiceImp;
  25.  
    import com.famousPro.common.util.IDGenerator;
  26.  
    import com.famousPro.common.util.StringUtil;
  27.  
    import com.famousPro.process.service.ProcessCoreService;
  28.  
    import com.famousPro.process.service.ProcessOtherService;
  29.  
     
  30.  
    /**
  31.  
    * 流程操作核心类<br>
  32.  
    * 此核心类主要处理:流程通过、驳回、会签、转办、中止、挂起等核心操作<br>
  33.  
    *
  34.  
    * @author wangfuwei
  35.  
    *
  36.  
    */
  37.  
    public class ProcessCoreServiceImpl extends BaseServiceImp implements
  38.  
    ProcessCoreService {
  39.  
    protected RepositoryService repositoryService;
  40.  
     
  41.  
    protected RuntimeService runtimeService;
  42.  
     
  43.  
    protected TaskService taskService;
  44.  
     
  45.  
    protected FormService formService;
  46.  
     
  47.  
    protected HistoryService historyService;
  48.  
     
  49.  
    protected ProcessOtherService processOtherService;
  50.  
     
  51.  
    /**
  52.  
    * 根据当前任务ID,查询可以驳回的任务节点
  53.  
    *
  54.  
    * @param taskId
  55.  
    * 当前任务ID
  56.  
    */
  57.  
    public List<ActivityImpl> findBackAvtivity(String taskId) throws Exception {
  58.  
    List<ActivityImpl> rtnList = null;
  59.  
    if (processOtherService.isJointTask(taskId)) {// 会签任务节点,不允许驳回
  60.  
    rtnList = new ArrayList<ActivityImpl>();
  61.  
    } else {
  62.  
    rtnList = iteratorBackActivity(taskId, findActivitiImpl(taskId,
  63.  
    null), new ArrayList<ActivityImpl>(),
  64.  
    new ArrayList<ActivityImpl>());
  65.  
    }
  66.  
    return reverList(rtnList);
  67.  
    }
  68.  
     
  69.  
    /**
  70.  
    * 审批通过(驳回直接跳回功能需后续扩展)
  71.  
    *
  72.  
    * @param taskId
  73.  
    * 当前任务ID
  74.  
    * @param variables
  75.  
    * 流程存储参数
  76.  
    * @throws Exception
  77.  
    */
  78.  
    public void passProcess(String taskId, Map<String, Object> variables)
  79.  
    throws Exception {
  80.  
    List<Task> tasks = taskService.createTaskQuery().parentTaskId(taskId)
  81.  
    .taskDescription("jointProcess").list();
  82.  
    for (Task task : tasks) {// 级联结束本节点发起的会签任务
  83.  
    commitProcess(task.getId(), null, null);
  84.  
    }
  85.  
    commitProcess(taskId, variables, null);
  86.  
    }
  87.  
     
  88.  
    /**
  89.  
    * 驳回流程
  90.  
    *
  91.  
    * @param taskId
  92.  
    * 当前任务ID
  93.  
    * @param activityId
  94.  
    * 驳回节点ID
  95.  
    * @param variables
  96.  
    * 流程存储参数
  97.  
    * @throws Exception
  98.  
    */
  99.  
    public void backProcess(String taskId, String activityId,
  100.  
    Map<String, Object> variables) throws Exception {
  101.  
    if (StringUtil.isNull(activityId)) {
  102.  
    throw new Exception("驳回目标节点ID为空!");
  103.  
    }
  104.  
     
  105.  
    // 查询本节点发起的会签任务,并结束
  106.  
    List<Task> tasks = taskService.createTaskQuery().parentTaskId(taskId)
  107.  
    .taskDescription("jointProcess").list();
  108.  
    for (Task task : tasks) {
  109.  
    commitProcess(task.getId(), null, null);
  110.  
    }
  111.  
     
  112.  
    // 查找所有并行任务节点,同时驳回
  113.  
    List<Task> taskList = findTaskListByKey(findProcessInstanceByTaskId(
  114.  
    taskId).getId(), findTaskById(taskId).getTaskDefinitionKey());
  115.  
    for (Task task : taskList) {
  116.  
    commitProcess(task.getId(), variables, activityId);
  117.  
    }
  118.  
    }
  119.  
     
  120.  
    /**
  121.  
    * 取回流程
  122.  
    *
  123.  
    * @param taskId
  124.  
    * 当前任务ID
  125.  
    * @param activityId
  126.  
    * 取回节点ID
  127.  
    * @throws Exception
  128.  
    */
  129.  
    public void callBackProcess(String taskId, String activityId)
  130.  
    throws Exception {
  131.  
    if (StringUtil.isNull(activityId)) {
  132.  
    throw new Exception("目标节点ID为空!");
  133.  
    }
  134.  
     
  135.  
    // 查找所有并行任务节点,同时取回
  136.  
    List<Task> taskList = findTaskListByKey(findProcessInstanceByTaskId(
  137.  
    taskId).getId(), findTaskById(taskId).getTaskDefinitionKey());
  138.  
    for (Task task : taskList) {
  139.  
    commitProcess(task.getId(), null, activityId);
  140.  
    }
  141.  
    }
  142.  
     
  143.  
    /**
  144.  
    * 中止流程(特权人直接审批通过等)
  145.  
    *
  146.  
    * @param taskId
  147.  
    */
  148.  
    public void endProcess(String taskId) throws Exception {
  149.  
    ActivityImpl endActivity = findActivitiImpl(taskId, "end");
  150.  
    commitProcess(taskId, null, endActivity.getId());
  151.  
    }
  152.  
     
  153.  
    /**
  154.  
    * 会签操作
  155.  
    *
  156.  
    * @param taskId
  157.  
    * 当前任务ID
  158.  
    * @param userCodes
  159.  
    * 会签人账号集合
  160.  
    * @throws Exception
  161.  
    */
  162.  
    public void jointProcess(String taskId, List<String> userCodes)
  163.  
    throws Exception {
  164.  
    for (String userCode : userCodes) {
  165.  
    TaskEntity task = (TaskEntity) taskService.newTask(IDGenerator
  166.  
    .generateID());
  167.  
    task.setAssignee(userCode);
  168.  
    task.setName(findTaskById(taskId).getName() + "-会签");
  169.  
    task.setProcessDefinitionId(findProcessDefinitionEntityByTaskId(
  170.  
    taskId).getId());
  171.  
    task.setProcessInstanceId(findProcessInstanceByTaskId(taskId)
  172.  
    .getId());
  173.  
    task.setParentTaskId(taskId);
  174.  
    task.setDescription("jointProcess");
  175.  
    taskService.saveTask(task);
  176.  
    }
  177.  
    }
  178.  
     
  179.  
    /**
  180.  
    * 转办流程
  181.  
    *
  182.  
    * @param taskId
  183.  
    * 当前任务节点ID
  184.  
    * @param userCode
  185.  
    * 被转办人Code
  186.  
    */
  187.  
    public void transferAssignee(String taskId, String userCode) {
  188.  
    taskService.setAssignee(taskId, userCode);
  189.  
    }
  190.  
     
  191.  
    /**
  192.  
    * ***************************************************************************************************************************************************<br>
  193.  
    * ************************************************以下为流程会签操作核心逻辑******************************************************************************<br>
  194.  
    * ***************************************************************************************************************************************************<br>
  195.  
    */
  196.  
     
  197.  
    /**
  198.  
    * ***************************************************************************************************************************************************<br>
  199.  
    * ************************************************以上为流程会签操作核心逻辑******************************************************************************<br>
  200.  
    * ***************************************************************************************************************************************************<br>
  201.  
    */
  202.  
     
  203.  
    /**
  204.  
    * ***************************************************************************************************************************************************<br>
  205.  
    * ************************************************以下为流程转向操作核心逻辑******************************************************************************<br>
  206.  
    * ***************************************************************************************************************************************************<br>
  207.  
    */
  208.  
     
  209.  
    /**
  210.  
    * @param taskId
  211.  
    * 当前任务ID
  212.  
    * @param variables
  213.  
    * 流程变量
  214.  
    * @param activityId
  215.  
    * 流程转向执行任务节点ID<br>
  216.  
    * 此参数为空,默认为提交操作
  217.  
    * @throws Exception
  218.  
    */
  219.  
    private void commitProcess(String taskId, Map<String, Object> variables,
  220.  
    String activityId) throws Exception {
  221.  
    if (variables == null) {
  222.  
    variables = new HashMap<String, Object>();
  223.  
    }
  224.  
    // 跳转节点为空,默认提交操作
  225.  
    if (StringUtil.isNull(activityId)) {
  226.  
    taskService.complete(taskId, variables);
  227.  
    } else {// 流程转向操作
  228.  
    turnTransition(taskId, activityId, variables);
  229.  
    }
  230.  
    }
  231.  
     
  232.  
    /**
  233.  
    * 清空指定活动节点流向
  234.  
    *
  235.  
    * @param activityImpl
  236.  
    * 活动节点
  237.  
    * @return 节点流向集合
  238.  
    */
  239.  
    private List<PvmTransition> clearTransition(ActivityImpl activityImpl) {
  240.  
    // 存储当前节点所有流向临时变量
  241.  
    List<PvmTransition> oriPvmTransitionList = new ArrayList<PvmTransition>();
  242.  
    // 获取当前节点所有流向,存储到临时变量,然后清空
  243.  
    List<PvmTransition> pvmTransitionList = activityImpl
  244.  
    .getOutgoingTransitions();
  245.  
    for (PvmTransition pvmTransition : pvmTransitionList) {
  246.  
    oriPvmTransitionList.add(pvmTransition);
  247.  
    }
  248.  
    pvmTransitionList.clear();
  249.  
     
  250.  
    return oriPvmTransitionList;
  251.  
    }
  252.  
     
  253.  
    /**
  254.  
    * 还原指定活动节点流向
  255.  
    *
  256.  
    * @param activityImpl
  257.  
    * 活动节点
  258.  
    * @param oriPvmTransitionList
  259.  
    * 原有节点流向集合
  260.  
    */
  261.  
    private void restoreTransition(ActivityImpl activityImpl,
  262.  
    List<PvmTransition> oriPvmTransitionList) {
  263.  
    // 清空现有流向
  264.  
    List<PvmTransition> pvmTransitionList = activityImpl
  265.  
    .getOutgoingTransitions();
  266.  
    pvmTransitionList.clear();
  267.  
    // 还原以前流向
  268.  
    for (PvmTransition pvmTransition : oriPvmTransitionList) {
  269.  
    pvmTransitionList.add(pvmTransition);
  270.  
    }
  271.  
    }
  272.  
     
  273.  
    /**
  274.  
    * 流程转向操作
  275.  
    *
  276.  
    * @param taskId
  277.  
    * 当前任务ID
  278.  
    * @param activityId
  279.  
    * 目标节点任务ID
  280.  
    * @param variables
  281.  
    * 流程变量
  282.  
    * @throws Exception
  283.  
    */
  284.  
    private void turnTransition(String taskId, String activityId,
  285.  
    Map<String, Object> variables) throws Exception {
  286.  
    // 当前节点
  287.  
    ActivityImpl currActivity = findActivitiImpl(taskId, null);
  288.  
    // 清空当前流向
  289.  
    List<PvmTransition> oriPvmTransitionList = clearTransition(currActivity);
  290.  
     
  291.  
    // 创建新流向
  292.  
    TransitionImpl newTransition = currActivity.createOutgoingTransition();
  293.  
    // 目标节点
  294.  
    ActivityImpl pointActivity = findActivitiImpl(taskId, activityId);
  295.  
    // 设置新流向的目标节点
  296.  
    newTransition.setDestination(pointActivity);
  297.  
     
  298.  
    // 执行转向任务
  299.  
    taskService.complete(taskId, variables);
  300.  
    // 删除目标节点新流入
  301.  
    pointActivity.getIncomingTransitions().remove(newTransition);
  302.  
     
  303.  
    // 还原以前流向
  304.  
    restoreTransition(currActivity, oriPvmTransitionList);
  305.  
    }
  306.  
     
  307.  
    /**
  308.  
    * ***************************************************************************************************************************************************<br>
  309.  
    * ************************************************以上为流程转向操作核心逻辑******************************************************************************<br>
  310.  
    * ***************************************************************************************************************************************************<br>
  311.  
    */
  312.  
     
  313.  
    /**
  314.  
    * ***************************************************************************************************************************************************<br>
  315.  
    * ************************************************以下为查询流程驳回节点核心逻辑***************************************************************************<br>
  316.  
    * ***************************************************************************************************************************************************<br>
  317.  
    */
  318.  
     
  319.  
    /**
  320.  
    * 迭代循环流程树结构,查询当前节点可驳回的任务节点
  321.  
    *
  322.  
    * @param taskId
  323.  
    * 当前任务ID
  324.  
    * @param currActivity
  325.  
    * 当前活动节点
  326.  
    * @param rtnList
  327.  
    * 存储回退节点集合
  328.  
    * @param tempList
  329.  
    * 临时存储节点集合(存储一次迭代过程中的同级userTask节点)
  330.  
    * @return 回退节点集合
  331.  
    */
  332.  
    private List<ActivityImpl> iteratorBackActivity(String taskId,
  333.  
    ActivityImpl currActivity, List<ActivityImpl> rtnList,
  334.  
    List<ActivityImpl> tempList) throws Exception {
  335.  
    // 查询流程定义,生成流程树结构
  336.  
    ProcessInstance processInstance = findProcessInstanceByTaskId(taskId);
  337.  
     
  338.  
    // 当前节点的流入来源
  339.  
    List<PvmTransition> incomingTransitions = currActivity
  340.  
    .getIncomingTransitions();
  341.  
    // 条件分支节点集合,userTask节点遍历完毕,迭代遍历此集合,查询条件分支对应的userTask节点
  342.  
    List<ActivityImpl> exclusiveGateways = new ArrayList<ActivityImpl>();
  343.  
    // 并行节点集合,userTask节点遍历完毕,迭代遍历此集合,查询并行节点对应的userTask节点
  344.  
    List<ActivityImpl> parallelGateways = new ArrayList<ActivityImpl>();
  345.  
    // 遍历当前节点所有流入路径
  346.  
    for (PvmTransition pvmTransition : incomingTransitions) {
  347.  
    TransitionImpl transitionImpl = (TransitionImpl) pvmTransition;
  348.  
    ActivityImpl activityImpl = transitionImpl.getSource();
  349.  
    String type = (String) activityImpl.getProperty("type");
  350.  
    /**
  351.  
    * 并行节点配置要求:<br>
  352.  
    * 必须成对出现,且要求分别配置节点ID为:XXX_start(开始),XXX_end(结束)
  353.  
    */
  354.  
    if ("parallelGateway".equals(type)) {// 并行路线
  355.  
    String gatewayId = activityImpl.getId();
  356.  
    String gatewayType = gatewayId.substring(gatewayId
  357.  
    .lastIndexOf("_") + 1);
  358.  
    if ("START".equals(gatewayType.toUpperCase())) {// 并行起点,停止递归
  359.  
    return rtnList;
  360.  
    } else {// 并行终点,临时存储此节点,本次循环结束,迭代集合,查询对应的userTask节点
  361.  
    parallelGateways.add(activityImpl);
  362.  
    }
  363.  
    } else if ("startEvent".equals(type)) {// 开始节点,停止递归
  364.  
    return rtnList;
  365.  
    } else if ("userTask".equals(type)) {// 用户任务
  366.  
    tempList.add(activityImpl);
  367.  
    } else if ("exclusiveGateway".equals(type)) {// 分支路线,临时存储此节点,本次循环结束,迭代集合,查询对应的userTask节点
  368.  
    currActivity = transitionImpl.getSource();
  369.  
    exclusiveGateways.add(currActivity);
  370.  
    }
  371.  
    }
  372.  
     
  373.  
    /**
  374.  
    * 迭代条件分支集合,查询对应的userTask节点
  375.  
    */
  376.  
    for (ActivityImpl activityImpl : exclusiveGateways) {
  377.  
    iteratorBackActivity(taskId, activityImpl, rtnList, tempList);
  378.  
    }
  379.  
     
  380.  
    /**
  381.  
    * 迭代并行集合,查询对应的userTask节点
  382.  
    */
  383.  
    for (ActivityImpl activityImpl : parallelGateways) {
  384.  
    iteratorBackActivity(taskId, activityImpl, rtnList, tempList);
  385.  
    }
  386.  
     
  387.  
    /**
  388.  
    * 根据同级userTask集合,过滤最近发生的节点
  389.  
    */
  390.  
    currActivity = filterNewestActivity(processInstance, tempList);
  391.  
    if (currActivity != null) {
  392.  
    // 查询当前节点的流向是否为并行终点,并获取并行起点ID
  393.  
    String id = findParallelGatewayId(currActivity);
  394.  
    if (StringUtil.isNull(id)) {// 并行起点ID为空,此节点流向不是并行终点,符合驳回条件,存储此节点
  395.  
    rtnList.add(currActivity);
  396.  
    } else {// 根据并行起点ID查询当前节点,然后迭代查询其对应的userTask任务节点
  397.  
    currActivity = findActivitiImpl(taskId, id);
  398.  
    }
  399.  
     
  400.  
    // 清空本次迭代临时集合
  401.  
    tempList.clear();
  402.  
    // 执行下次迭代
  403.  
    iteratorBackActivity(taskId, currActivity, rtnList, tempList);
  404.  
    }
  405.  
    return rtnList;
  406.  
    }
  407.  
     
  408.  
    /**
  409.  
    * 反向排序list集合,便于驳回节点按顺序显示
  410.  
    *
  411.  
    * @param list
  412.  
    * @return
  413.  
    */
  414.  
    private List<ActivityImpl> reverList(List<ActivityImpl> list) {
  415.  
    List<ActivityImpl> rtnList = new ArrayList<ActivityImpl>();
  416.  
    // 由于迭代出现重复数据,排除重复
  417.  
    for (int i = list.size(); i > 0; i--) {
  418.  
    if (!rtnList.contains(list.get(i - 1)))
  419.  
    rtnList.add(list.get(i - 1));
  420.  
    }
  421.  
    return rtnList;
  422.  
    }
  423.  
     
  424.  
    /**
  425.  
    * 根据当前节点,查询输出流向是否为并行终点,如果为并行终点,则拼装对应的并行起点ID
  426.  
    *
  427.  
    * @param activityImpl
  428.  
    * 当前节点
  429.  
    * @return
  430.  
    */
  431.  
    private String findParallelGatewayId(ActivityImpl activityImpl) {
  432.  
    List<PvmTransition> incomingTransitions = activityImpl
  433.  
    .getOutgoingTransitions();
  434.  
    for (PvmTransition pvmTransition : incomingTransitions) {
  435.  
    TransitionImpl transitionImpl = (TransitionImpl) pvmTransition;
  436.  
    activityImpl = transitionImpl.getDestination();
  437.  
    String type = (String) activityImpl.getProperty("type");
  438.  
    if ("parallelGateway".equals(type)) {// 并行路线
  439.  
    String gatewayId = activityImpl.getId();
  440.  
    String gatewayType = gatewayId.substring(gatewayId
  441.  
    .lastIndexOf("_") + 1);
  442.  
    if ("END".equals(gatewayType.toUpperCase())) {
  443.  
    return gatewayId.substring(0, gatewayId.lastIndexOf("_"))
  444.  
    + "_start";
  445.  
    }
  446.  
    }
  447.  
    }
  448.  
    return null;
  449.  
    }
  450.  
     
  451.  
    /**
  452.  
    * 根据流入任务集合,查询最近一次的流入任务节点
  453.  
    *
  454.  
    * @param processInstance
  455.  
    * 流程实例
  456.  
    * @param tempList
  457.  
    * 流入任务集合
  458.  
    * @return
  459.  
    */
  460.  
    private ActivityImpl filterNewestActivity(ProcessInstance processInstance,
  461.  
    List<ActivityImpl> tempList) {
  462.  
    while (tempList.size() > 0) {
  463.  
    ActivityImpl activity_1 = tempList.get(0);
  464.  
    HistoricActivityInstance activityInstance_1 = findHistoricUserTask(
  465.  
    processInstance, activity_1.getId());
  466.  
    if (activityInstance_1 == null) {
  467.  
    tempList.remove(activity_1);
  468.  
    continue;
  469.  
    }
  470.  
     
  471.  
    if (tempList.size() > 1) {
  472.  
    ActivityImpl activity_2 = tempList.get(1);
  473.  
    HistoricActivityInstance activityInstance_2 = findHistoricUserTask(
  474.  
    processInstance, activity_2.getId());
  475.  
    if (activityInstance_2 == null) {
  476.  
    tempList.remove(activity_2);
  477.  
    continue;
  478.  
    }
  479.  
     
  480.  
    if (activityInstance_1.getEndTime().before(
  481.  
    activityInstance_2.getEndTime())) {
  482.  
    tempList.remove(activity_1);
  483.  
    } else {
  484.  
    tempList.remove(activity_2);
  485.  
    }
  486.  
    } else {
  487.  
    break;
  488.  
    }
  489.  
    }
  490.  
    if (tempList.size() > 0) {
  491.  
    return tempList.get(0);
  492.  
    }
  493.  
    return null;
  494.  
    }
  495.  
     
  496.  
    /**
  497.  
    * 查询指定任务节点的最新记录
  498.  
    *
  499.  
    * @param processInstance
  500.  
    * 流程实例
  501.  
    * @param activityId
  502.  
    * @return
  503.  
    */
  504.  
    private HistoricActivityInstance findHistoricUserTask(
  505.  
    ProcessInstance processInstance, String activityId) {
  506.  
    HistoricActivityInstance rtnVal = null;
  507.  
    // 查询当前流程实例审批结束的历史节点
  508.  
    List<HistoricActivityInstance> historicActivityInstances = historyService
  509.  
    .createHistoricActivityInstanceQuery().activityType("userTask")
  510.  
    .processInstanceId(processInstance.getId()).activityId(
  511.  
    activityId).finished()
  512.  
    .orderByHistoricActivityInstanceEndTime().desc().list();
  513.  
    if (historicActivityInstances.size() > 0) {
  514.  
    rtnVal = historicActivityInstances.get(0);
  515.  
    }
  516.  
     
  517.  
    return rtnVal;
  518.  
    }
  519.  
     
  520.  
    /**
  521.  
    * *******************************************************************************************************<br>
  522.  
    * ********************************以上为查询流程驳回节点核心逻辑***********************************************<br>
  523.  
    * ********************************************************************************************************<br>
  524.  
    */
  525.  
     
  526.  
    /**
  527.  
    * ********************************************************************************<br>
  528.  
    * **********************以下为activiti 核心service
  529.  
    * set方法***************************<br>
  530.  
    * *********************************************************************************<br>
  531.  
    */
  532.  
    public void setFormService(FormService formService) {
  533.  
    this.formService = formService;
  534.  
    }
  535.  
     
  536.  
    public void setHistoryService(HistoryService historyService) {
  537.  
    this.historyService = historyService;
  538.  
    }
  539.  
     
  540.  
    public void setRepositoryService(RepositoryService repositoryService) {
  541.  
    this.repositoryService = repositoryService;
  542.  
    }
  543.  
     
  544.  
    public void setRuntimeService(RuntimeService runtimeService) {
  545.  
    this.runtimeService = runtimeService;
  546.  
    }
  547.  
     
  548.  
    public void setTaskService(TaskService taskService) {
  549.  
    this.taskService = taskService;
  550.  
    }
  551.  
     
  552.  
    /**
  553.  
    * ********************************************************************************<br>
  554.  
    * **********************以上为activiti 核心service
  555.  
    * set方法***************************<br>
  556.  
    * *********************************************************************************<br>
  557.  
    */
  558.  
     
  559.  
    /**
  560.  
    * ********************************************************************************<br>
  561.  
    * **********************以下为根据 任务节点ID 获取流程各对象查询方法**********************<br>
  562.  
    * *********************************************************************************<br>
  563.  
    */
  564.  
     
  565.  
    public void setProcessOtherService(ProcessOtherService processOtherService) {
  566.  
    this.processOtherService = processOtherService;
  567.  
    }
  568.  
     
  569.  
    /**
  570.  
    * 根据任务ID获得任务实例
  571.  
    *
  572.  
    * @param taskId
  573.  
    * 任务ID
  574.  
    * @return
  575.  
    * @throws Exception
  576.  
    */
  577.  
    private TaskEntity findTaskById(String taskId) throws Exception {
  578.  
    TaskEntity task = (TaskEntity) taskService.createTaskQuery().taskId(
  579.  
    taskId).singleResult();
  580.  
    if (task == null) {
  581.  
    throw new Exception("任务实例未找到!");
  582.  
    }
  583.  
    return task;
  584.  
    }
  585.  
     
  586.  
    /**
  587.  
    * 根据流程实例ID和任务key值查询所有同级任务集合
  588.  
    *
  589.  
    * @param processInstanceId
  590.  
    * @param key
  591.  
    * @return
  592.  
    */
  593.  
    private List<Task> findTaskListByKey(String processInstanceId, String key) {
  594.  
    return taskService.createTaskQuery().processInstanceId(
  595.  
    processInstanceId).taskDefinitionKey(key).list();
  596.  
    }
  597.  
     
  598.  
    /**
  599.  
    * 根据任务ID获取对应的流程实例
  600.  
    *
  601.  
    * @param taskId
  602.  
    * 任务ID
  603.  
    * @return
  604.  
    * @throws Exception
  605.  
    */
  606.  
    private ProcessInstance findProcessInstanceByTaskId(String taskId)
  607.  
    throws Exception {
  608.  
    // 找到流程实例
  609.  
    ProcessInstance processInstance = runtimeService
  610.  
    .createProcessInstanceQuery().processInstanceId(
  611.  
    findTaskById(taskId).getProcessInstanceId())
  612.  
    .singleResult();
  613.  
    if (processInstance == null) {
  614.  
    throw new Exception("流程实例未找到!");
  615.  
    }
  616.  
    return processInstance;
  617.  
    }
  618.  
     
  619.  
    /**
  620.  
    * 根据任务ID获取流程定义
  621.  
    *
  622.  
    * @param taskId
  623.  
    * 任务ID
  624.  
    * @return
  625.  
    * @throws Exception
  626.  
    */
  627.  
    private ProcessDefinitionEntity findProcessDefinitionEntityByTaskId(
  628.  
    String taskId) throws Exception {
  629.  
    // 取得流程定义
  630.  
    ProcessDefinitionEntity processDefinition = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService)
  631.  
    .getDeployedProcessDefinition(findTaskById(taskId)
  632.  
    .getProcessDefinitionId());
  633.  
     
  634.  
    if (processDefinition == null) {
  635.  
    throw new Exception("流程定义未找到!");
  636.  
    }
  637.  
     
  638.  
    return processDefinition;
  639.  
    }
  640.  
     
  641.  
    /**
  642.  
    * 根据任务ID和节点ID获取活动节点 <br>
  643.  
    *
  644.  
    * @param taskId
  645.  
    * 任务ID
  646.  
    * @param activityId
  647.  
    * 活动节点ID <br>
  648.  
    * 如果为null或"",则默认查询当前活动节点 <br>
  649.  
    * 如果为"end",则查询结束节点 <br>
  650.  
    *
  651.  
    * @return
  652.  
    * @throws Exception
  653.  
    */
  654.  
    private ActivityImpl findActivitiImpl(String taskId, String activityId)
  655.  
    throws Exception {
  656.  
    // 取得流程定义
  657.  
    ProcessDefinitionEntity processDefinition = findProcessDefinitionEntityByTaskId(taskId);
  658.  
     
  659.  
    // 获取当前活动节点ID
  660.  
    if (StringUtil.isNull(activityId)) {
  661.  
    activityId = findTaskById(taskId).getTaskDefinitionKey();
  662.  
    }
  663.  
     
  664.  
    // 根据流程定义,获取该流程实例的结束节点
  665.  
    if (activityId.toUpperCase().equals("END")) {
  666.  
    for (ActivityImpl activityImpl : processDefinition.getActivities()) {
  667.  
    List<PvmTransition> pvmTransitionList = activityImpl
  668.  
    .getOutgoingTransitions();
  669.  
    if (pvmTransitionList.isEmpty()) {
  670.  
    return activityImpl;
  671.  
    }
  672.  
    }
  673.  
    }
  674.  
     
  675.  
    // 根据节点ID,获取对应的活动节点
  676.  
    ActivityImpl activityImpl = ((ProcessDefinitionImpl) processDefinition)
  677.  
    .findActivity(activityId);
  678.  
     
  679.  
    return activityImpl;
  680.  
    }
  681.  
     
  682.  
    /**
  683.  
    * ********************************************************************************<br>
  684.  
    * **********************以上为根据 任务节点ID 获取流程各对象查询方法**********************<br>
  685.  
    * *********************************************************************************<br>
  686.  
    */
  687.  
    }
  688.  

posted @ 2019-06-10 14:50  albert_think  阅读(354)  评论(0编辑  收藏  举报