• -------------------------------------------------------------
  • ====================================

Activiti 开发案例之多实例并行子流程

技能 dewbay 2年前 (2022-01-12) 3441次浏览 已收录 0个评论 扫描二维码
文章目录[隐藏]

概念

Activiti 提供了两种基于子流程的实现:

  • 一种是内嵌子流程:子流程元素<subProcess>内嵌在主流程元素<process>之内,只能在该流程中使用该子流程,外部是无法访问到的。这种子流程一般作为局部通用逻辑处理,或者因为特定业务需要,使得比较复杂的单个主流程设计清晰直观。
  • 另一种是调用子流程:首先实现一个流程,在另一个流程中可以调用该流程,通常可以定义一些通用的流程作为这种调用子流程,供其他多个流程定义复用。这种子流程使用<callActivity>元素来进行调用,间接地嵌入到主流程中,用起来比较方便。

流程图

Activiti 开发案例之多实例并行子流程

以上是一个公司内部合同评审的内嵌子流程流程图,一个合同的通过是需要经过多个部门的层层审核,最终才得以通过。

  • 销售发起合同评审流程
  • 进入子流程,各个部门根据实际情况进行多级审批
  • 各个部门审批通过,流程结束

生成子流程

XML 部分代码

<subProcess id="subprocess" name="合同评审">
      <multiInstanceLoopCharacteristics isSequential="false" activiti:collection="assigneeList" activiti:elementVariable="assignee">
        <completionCondition>${nrOfCompletedInstances/nrOfInstances==1}</completionCondition>
      </multiInstanceLoopCharacteristics>
      <!--省略相关任务节点代码-->
</subProcess>
  • collection:存放集合,集合中可以存任意值,工作流会根据你集合里的值个数,去生成对应的子流程,这里我们存放一级审批的用户 ID。
  • elementVariable:节点流程变量,用于在流程图中代替集合中表示当前子流程的变量,对应子流程中第一个任务节点的变量名。
  • completionCondition:完成条件,这里写的表达式如果满足即可流转到下一步。

发起

成功发起之后,系统会自动生成集合数量的任务(子流程),然后在每个子流程中设置与业务流程相关的局部变量。

Map<String, Object> variables = new HashMap<>();
//4 个部门审核,生成 4 个流程,集合中获取并存放的是一级评审人
List<String> assigneeList= Arrays.asList(new String[] {"1","2","3","4"});
variables.put("assigneeList", assigneeList);
ProcessInstance in =  runtimeService.startProcessInstanceByKey("contract_review", variables);
List<Task> list = taskService.createTaskQuery().processInstanceId(in.getId()).list();
System.out.println("任务数量:"+list.size());
list.forEach(task -> {
    /**
     * 模拟几级审批(正式环境要从配置或者数据库读取),因为这里要清楚每个部门走几级审批逻辑
     * 变量存放到每个任务节点的全局任务变量中
     */
    Random r = new Random();//创建随机种子,Random 对象
    int rank = r.nextInt(3)+1;
    System.out.println("任务 ID:"+task.getId());
    System.out.println("指派人 ID:"+task.getAssignee());
   //保存在整个子流程中
    runtimeService.setVariableLocal(task.getExecutionId(),"rank",rank);
});

审核

这里只说几个比较重要的点,大家可以根据自身业务场景处理。

//获取当前任务
Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
//获取当前任务 Code
String taskCode = task.getTaskDefinitionKey();
//获取当前任务流转唯一 ID
String executionId = task.getExecutionId();
//获取当前子流程任务变量
Object rank = runtimeService.getVariableLocal(task.getExecutionId(),"rank");
//认领任务
variables.put("approve",rank);
taskService.claim(taskId, userId);
taskService.complete(taskId, variables);
//这里要判断当前子流程是一级审批、如果是二级审批或者三级审批还需要获取下级任务节点
task = taskService.createTaskQuery().executionId(executionId).active().singleResult();
//指派任务
taskService.addCandidateUser(task.getId(),reviewUserId);

小结

子流程的概念用途还是比较广泛的,基本上企业内部涉及到多部门合作的流程都有可能用到,这里需要注意的是,由于业务类型不同,每个子流程的相关逻辑判断也可能不同,这就需要在每个子流程中存储流程变量,用于各级流程逻辑判断。


露水湾 , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:Activiti 开发案例之多实例并行子流程
喜欢 (1)
[]
分享 (0)
关于作者:
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址