zoukankan      html  css  js  c++  java
  • Activiti 多个并发子流程的应用

    应用场景:

    多个部门发起资金计划,最后统一到财务部审批,每个部门发起资金计划是一个子流程,财务部审批是多个部门的计划同时审批,审批完成后,再提交上级领导审批。

    流程如下:

    并发子流程

    要解决以上问题,需要实现多个子流程并行处理的功能。在Activiti5有一个比较强的节点属性就是多实例,它可以支持多实例的子流程,多实例任务,多实体脚本等。目前支持多实例的节点类型有:

    多实例还有并行、串行区分。以下解释一下什么是并行与串行

    并行代表同时进行,如把任务分给5个人来处理,这5个人同时会收到任务,并且可以同时处理,不受各自的影响。

    串行代表工作或任务由一个人完成后,再由另一个人去处理,直至全部完成,每个任务依赖于前一个任务完成。

    会签任务即可以由activiti多实例任务节点来实现,(上一博客有介绍如何开发设计会签任务)

    在Activiti的定义中,生成多实例的定义很简单,只需要如下类似去生成以下标签,则可以完成多实例的声明,如下所示,我们要支持并行节点的多实例的定义

    多实例人工任务

    Java代码  收藏代码
    1. <userTask activiti:assignee="${assignee}" id="SignTask2" name="财务主管会签">  
    2.     <extensionElements>  
    3.         <activiti:taskListener  
    4.             class="com.hotent.platform.service.bpm.listener.TaskSignCreateListener"  
    5.             event="create" />  
    6.         <activiti:taskListener  
    7.             class="com.hotent.platform.service.bpm.listener.TaskAssignListener"  
    8.             event="assignment" />  
    9.         <activiti:taskListener  
    10.             class="com.hotent.platform.service.bpm.listener.TaskCompleteListener"  
    11.             event="complete" />  
    12.     </extensionElements>  
    13.     <multiInstanceLoopCharacteristics  
    14.         activiti:elementVariable="assignee" isSequential="false"  
    15.         activiti:collection="${taskUserAssignService.getSignUser(execution)}">  
    16.         <completionCondition>${signComplete.isComplete(execution) }  
    17.         </completionCondition>  
    18.     </multiInstanceLoopCharacteristics>  
    19. </userTask>  

    多实例子流程

    Java代码  收藏代码
    1. <subProcess activiti:assignee="${assignee}" id="SubProcess1"  
    2.     name="部门资金计划流程">  
    3.     <startEvent activiti:initiator="startUser" id="startEvent2"  
    4.         name="开始" />  
    5.     <endEvent id="endEvent1" name="结束1" />  
    6.     <userTask id="task3" name="助理填写">  
    7.         <documentation />  
    8.         <extensionElements>  
    9.             <activiti:taskListener  
    10.                 class="com.hotent.platform.service.bpm.listener.TaskCreateListener"  
    11.                 event="create" />  
    12.             <activiti:taskListener  
    13.                 class="com.hotent.platform.service.bpm.listener.TaskAssignListener"  
    14.                 event="assignment" />  
    15.             <activiti:taskListener  
    16.                 class="com.hotent.platform.service.bpm.listener.TaskCompleteListener"  
    17.                 event="complete" />  
    18.         </extensionElements>  
    19.     </userTask>  
    20.     <userTask id="task4" name="部门领导审查">  
    21.         <documentation />  
    22.         <extensionElements>  
    23.             <activiti:taskListener  
    24.                 class="com.hotent.platform.service.bpm.listener.TaskCreateListener"  
    25.                 event="create" />  
    26.             <activiti:taskListener  
    27.                 class="com.hotent.platform.service.bpm.listener.TaskAssignListener"  
    28.                 event="assignment" />  
    29.             <activiti:taskListener  
    30.                 class="com.hotent.platform.service.bpm.listener.TaskCompleteListener"  
    31.                 event="complete" />  
    32.         </extensionElements>  
    33.     </userTask>  
    34.     <sequenceFlow sourceRef="startEvent2" targetRef="task3"  
    35.         id="sequenceFlow1" name="" />  
    36.     <sequenceFlow sourceRef="task3" targetRef="task4" id="sequenceFlow2"  
    37.         name="" />  
    38.     <sequenceFlow sourceRef="task4" targetRef="endEvent1" id="sequenceFlow3"  
    39.         name="" />  
    40.     <extensionElements>  
    41.         <activiti:executionListener event="start"  
    42.             class="com.hotent.platform.service.bpm.listener.StartEventListener" />  
    43.         <activiti:executionListener event="end"  
    44.             class="com.hotent.platform.service.bpm.listener.EndEventListener" />  
    45.     </extensionElements>  
    46.     <multiInstanceLoopCharacteristics  
    47.         activiti:elementVariable="assignee" isSequential="false"  
    48.         activiti:collection="${taskUserAssignService.getMultipleUser(execution)}" />  
    49. </subProcess>  

    所以关键的配置属性:

    Java代码  收藏代码
    1. <multiInstanceLoopCharacteristics  
    2.         activiti:elementVariable="assignee" isSequential="false"  
    3.         activiti:collection="${taskUserAssignService.getSignUser(execution)}">  
    4.         <completionCondition>${signComplete.isComplete(execution) }  
    5.         </completionCondition>  
    6.     </multiInstanceLoopCharacteristics>  

    我们在控制多实例的个数或人数时,是通过taskUserAssignService的getSignUser获取或getMultipleUser(execution)其集合的个数,从而决定产生多少个实体任务或子流程。

    如实现子流程多实例的获取人数,则来自:

    Java代码  收藏代码
    1. /** 
    2.      * 获取多实体子流程的执行用户集合 
    3.      * @param execution 
    4.      * @return 
    5.      * @throws Execption 
    6.      */  
    7.     public List<String> getMultipleUser(ActivityExecution execution) throws Exception{  
    8.           
    9.         String nodeId=execution.getActivity().getId();  
    10.         ExecutionEntity executionEnt=(ExecutionEntity) execution;  
    11.           
    12.         List<String> userIds=(List<String>)execution.getVariable(BpmConst.SUBPRO_MULTI_USERIDS);  
    13.           
    14.         if(userIds!=null) return userIds;  
    15.         Map<String,FlowNode> nodeMap= NodeCache.getByActDefId(executionEnt.getProcessDefinitionId());  
    16.         FlowNode subProcessNode=nodeMap.get(nodeId);  
    17.         FlowNode firstNode=subProcessNode.getSubFirstNode();  
    18.           
    19.         FlowNode secodeNode=firstNode.getNextFlowNodes().get(0);  
    20.           
    21.         List<String> userList=nodeUserMapLocal.get().get(secodeNode.getNodeId());  
    22.           
    23.         logger.debug("userList size:" + userList.size());  
    24.           
    25.         execution.setVariable(BpmConst.SUBPRO_MULTI_USERIDS, userList);  
    26.         return userList;  
    27.     }  

    因为该方法会被调用多次,所以其实现的思路是第一次其集合是来自用户的界面选择的人员列表,第一次之后,放到流程变量中去,在后续的获取中,直接从流程变量中获取。

    然后在任务的创建的监听器中,从流程变量assignee中获取当前任务的执行人。以上的实现还有一细节就是要解决如何查找到子流程中的第一个任务节点,并且把对应的任务人员授给这任务节点。

    更多资讯请加QQ了解1361783075

  • 相关阅读:
    606. Construct String from Binary Tree
    696. Count Binary Substrings
    POJ 3255 Roadblocks (次短路)
    POJ 2823 Sliding Window (单调队列)
    POJ 1704 Georgia and Bob (博弈)
    UVa 1663 Purifying Machine (二分匹配)
    UVa 10801 Lift Hopping (Dijkstra)
    POJ 3281 Dining (网络流之最大流)
    UVa 11100 The Trip, 2007 (题意+贪心)
    UVaLive 4254 Processor (二分+优先队列)
  • 原文地址:https://www.cnblogs.com/redxun-cn/p/redxun_1.html
Copyright © 2011-2022 走看看