关于activiti流程通过、驳回、会签、转办、中止、挂起等核心操作功能的封装

http://blog.csdn.net/aochuanguying/article/details/7594197

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