1. 候选人和处理人

候选人:candidateUser            处理人,指派人:assignee

一个task可以有多个候选人,但是只能有一个处理人

activiti6.0的数据库表结构中 ,identityLink表保存用户和task之间一对多的候选关系。处理人assignee直接是task表中的一个字段

通常情况下,系统根据流程的定义,自动为一个task指定候选人。比如有一个taskA,分配了A,B,  C三个候选人,一开始A, B, C都可以在“我的待办”中看到taskA这个任务,如果A认领了taskA,后台会将taskA的处理人设置为A,然后B,C在“我的待办”中就没有taskA这个任务了,A在没处理taskA前,A仍然可以在“我的待办”中看到taskA

2. 一个节点对应一个task

节点和task并不是同一个概念,节点是流程图中的一个节点,当会签的时候,一个节点有多个task。一个task有多个候选人,但是最终只会有一个处理人。

节点候选人可以用下面的方法设置:

先在定义一个spring组件,组件的作用是定义task的候选人,其实就是获取一个项目的项目经理,一个部门的部门经理,代码如下:

@Component
public class UserService {//获取项目经理节点的候选人public List<String> getProjectManger(String projectId){List<String> result = new ArrayList<>();if(projectId.equals("projectA")){result = Arrays.asList(new String[]{"projectA_项目经理1", "projectA_项目经理2"});}else{result = Arrays.asList(new String[]{"projectB_项目经理1", "projectB_项目经理2"});}return result;}//获取部门经理节点的候选人public List<String> getDepartmentMnager(String departmentId){List<String> result = new ArrayList<>();if(departmentId.equals("departmentA")){result = Arrays.asList(new String[]{"departmentA_部门经理1", "departmentA_部门经理2", "departmentA_部门经理3"});}else{result = Arrays.asList(new String[]{"departmentB_部门经理1", "departmentB_部门经理2"});}return result;}
}

设计这样一个简单的流程

选中第一个节点,点击下方的 Assignments,设置 Candidate users

测试代码:

public void testEntrance3(){//构造流程变量Map<String, Object> processInstanceVars = new HashMap<String, Object>();processInstanceVars.put("projectId", "projectA");processInstanceVars.put("departmentId", "departmentA");//启动流程ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("testProcess_20190119_1", processInstanceVars);//获取任务Task taskForProjectManager = taskService.createTaskQuery().processInstanceId(processInstance.getProcessInstanceId()).singleResult();//查询这个taskForProjectManager这个任务的候选处理人List<IdentityLink> projectManagerCandidateUsers = taskService.getIdentityLinksForTask(taskForProjectManager.getId());//查询待办queryNeedDealTask(projectManagerCandidateUsers);//分配处理人给  projectA_项目经理1taskForProjectManager.setAssignee("projectA_项目经理1");taskService.saveTask(taskForProjectManager);System.out.println("#############再次查询待办");//再次查询待办queryNeedDealTask(projectManagerCandidateUsers);//将任务完成taskService.complete(taskForProjectManager.getId());System.out.println("################完成后再查询待办");//再次查询待办queryNeedDealTask(projectManagerCandidateUsers);}//抽取查询待办的方法public void queryNeedDealTask(List<IdentityLink> identityLinks){for(IdentityLink identityLink : identityLinks){System.out.println("部门经理审批的候选人: " + identityLink.getUserId());//查出当前用户的待办List<Task> currentUserNeedDealTasks = taskService.createTaskQuery().taskCandidateOrAssigned(identityLink.getUserId()).list();for(Task task : currentUserNeedDealTasks){System.out.println("待办: " + task.getName() + " 流程id: " + task.getProcessInstanceId());}}}

运行结果:

部门经理审批的候选人: projectA_项目经理1
待办: 项目经理审批 流程id: 11
部门经理审批的候选人: projectA_项目经理2
待办: 项目经理审批 流程id: 11
#############再次查询待办
部门经理审批的候选人: projectA_项目经理1
待办: 项目经理审批 流程id: 11
部门经理审批的候选人: projectA_项目经理2
################完成后再查询待办
部门经理审批的候选人: projectA_项目经理1
部门经理审批的候选人: projectA_项目经理2

先定义查询一个项目的项目经理的方法,然后定义流程的时候将处理人定义为  ${userService.getProjectManger(projectId)}

方法的变量projectId在启动流程的时候通过流程变量传值。测试方法中也证实了1中关于候选人和处理人的描述

3. 会签

会签指的是一个节点有多个任务,会签通常用于一个节点需要进行投票,根据投票的结果来决定接下来的业务流程场景。activiti6.0是支持会签的,并且支持串行和并行。

3.1串行会签

选中部门经理审批这个节点,做如下设置,其中collection为  ${userService.getDepartmentMnager(departmentId)},Muti-instance Type的下拉框有 Sequential(串行),  Parallel(并行),  None三个选项,这里选择Sequential表示串行

其中Assignments点击后,在弹出的模态框中选择Fixed values,   Assignee中填写  ${manager}

代码如下:

public void testEntrance4(){//构造流程变量Map<String, Object> processInstanceVars = new HashMap<String, Object>();processInstanceVars.put("projectId", "projectA");processInstanceVars.put("departmentId", "departmentA");//启动流程ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("testProcess_20190119_1", processInstanceVars);//查询第一个任务,并完成Task taskForProjectManager =  taskService.createTaskQuery().processInstanceId(processInstance.getProcessInstanceId()).singleResult();taskService.complete(taskForProjectManager.getId());//遍历所有task,完成第二个节点while(true){Task taskForDepartmentManger =  taskService.createTaskQuery().processInstanceId(processInstance.getProcessInstanceId()).singleResult();if(taskForDepartmentManger == null){break;}taskService.complete(taskForDepartmentManger.getId());System.out.println("任务id: " + taskForDepartmentManger.getId() + " 处理人: " +taskForDepartmentManger.getAssignee());}}

输出结果:

任务id: 5019 处理人: departmentA_部门经理1
任务id: 5022 处理人: departmentA_部门经理2
任务id: 5025 处理人: departmentA_部门经理3

可以看到部门经理审批这个节点有三个任务。

3.2并行会签

在3.1的基础上,将Muti-instance Type改成Parallel即可。

运行代码

public void testEntrance4(){//构造流程变量Map<String, Object> processInstanceVars = new HashMap<String, Object>();processInstanceVars.put("projectId", "projectA");processInstanceVars.put("departmentId", "departmentA");//启动流程ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("testProcess_20190119_1", processInstanceVars);//查询第一个任务,并完成Task taskForProjectManager =  taskService.createTaskQuery().processInstanceId(processInstance.getProcessInstanceId()).singleResult();taskService.complete(taskForProjectManager.getId());//由于是并行的,这里可能会返回多个任务List<Task> taskForDepartmentMangers =  taskService.createTaskQuery().processInstanceId(processInstance.getProcessInstanceId()).list();for(Task taskForDepartmentManger : taskForDepartmentMangers){taskService.complete(taskForDepartmentManger.getId());System.out.println("任务id: " + taskForDepartmentManger.getId() + " 处理人: " +taskForDepartmentManger.getAssignee());}}

串行的时候,部门经理_1完成任务后才会生成生成部门经理_2的任务,所以查询任务的时候用singleResult,并行的时候会直接生成所有的任务,所以需要改成list

运行结果和3.1完全一样

3.3 设置节点结束条件

Completion Condition(Multi-instance)节点完成条件(多任务情况下)。在3.2的基础上设置 Completion Condition为${approvedCount>=2},approvedCount表示审批通过的个数,意思是审批通过的数量大于等于2这个节点就算完成了,即使还有其它人没有审批也直接跳过。

代码如下:

public void testEntrance4(){//构造流程变量Map<String, Object> processInstanceVars = new HashMap<String, Object>();processInstanceVars.put("projectId", "projectA");processInstanceVars.put("departmentId", "departmentA");processInstanceVars.put("approvedCount", 0);//启动流程ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("testProcess_20190119_1", processInstanceVars);//查询第一个任务,并完成Task taskForProjectManager =  taskService.createTaskQuery().processInstanceId(processInstance.getProcessInstanceId()).singleResult();taskService.complete(taskForProjectManager.getId());//由于是并行的,这里可能会返回多个任务List<Task> taskForDepartmentMangers =  taskService.createTaskQuery().processInstanceId(processInstance.getProcessInstanceId()).list();for(Task taskForDepartmentManger : taskForDepartmentMangers){try{//获取approvedCount的流程变量Integer value=(Integer)taskService.getVariable(taskForDepartmentManger.getId(), "approvedCount");taskService.setVariable(taskForDepartmentManger.getId(), "approvedCount", ++value);taskService.complete(taskForDepartmentManger.getId());System.out.println("任务id: " + taskForDepartmentManger.getId() + " 处理人: " +taskForDepartmentManger.getAssignee());}catch(ActivitiObjectNotFoundException exception){System.out.println("任务id: " + taskForDepartmentManger.getId() + " 处理人: " +taskForDepartmentManger.getAssignee() + " 这个任务不存在");}}}

在循环中修改流程变量approvedCount的值,当approvedCount大于等于2的时候,剩下的task就会被销毁了,由于代码中直接查出了三个节点,第三次循环的时候,最后一个task已经销毁了,所以会抛出异常。

activiti6.0(二)节点处理人相关推荐

  1. Activiti6.0实战-画流程图(1)

    Activiti6.0实战-目录 目录 一.画图工具选择 二.Activiti-App下载启动 三.画一个工作流 扩展 一.画图工具选择 Activiti-App(官网推荐) 我是选的这个 Activ ...

  2. 我眼中的Linux设备树(二 节点)

    二 节点(node)的表示 首先说节点的表示方法,除了根节点只用一个斜杠"/"表示外,其他节点的表示形式如"node-name@unit-address".@前 ...

  3. activiti 工作流 动态 设置 指定 节点任务人、责任人、组 的实现方式

    首先给大家看一下我的流程图: 流程文件leaveBill.bpmn <?xml version="1.0" encoding="UTF-8"?> & ...

  4. 工作流框架--Activiti6.0(一)

    工作流框架--Activiti6.0(一) 一.了解Activiti 1.1 什么是工作流? 工作流是将一组任务组织起来以完成某个经营过程:定义了任务的触发顺序和触发条件,每个任务可以由一个或多个软件 ...

  5. 超级账本Fabric 1.0多节点集群的部署(2)

    上期文章阐述了超级账本 Fabric 1.0多节点部署的方法概述,得到广大读者的关注,笔者们连夜赶工,今天发布连载之二,介绍具体搭建 Fabric 1.0 集群的步骤. 注:部署过程中大量使用了doc ...

  6. Spring Boot-2.3.7.RELEASE整合activiti-6.0示例步骤

    涉及简单审批时一般都是有人发起,再由另外一人确认审核即可! 实际项目中有时涉及利益的时候,比如常见的请假,报销等,就不是那么简单一人审核了事! 其中有权力和责任的体现,同时执行过程中也涉及业务流程管理 ...

  7. Activiti6.0版本如何显示在线流程图

    Activiti6.0版本如何显示在线流程图 Activiti6.0在线显示流程图和Activiti5.X有点差别,6.0版本去除了pvm包 5.X版本中的pvm包,但是在6.0版本并没有该包了,因此 ...

  8. VUE3.0 二. vue-cli3 配置指南

    VUE3.0 二. vue-cli3配置指南 一.vue.config.js 详解 官网地址: https://cli.vuejs.org/zh/config/ 使用vue3 的时候需要添加一个vue ...

  9. 管道的另一端上无任何进程。_历史上突然消失的二位牛人,其下落无任何记载...

    在浩瀚的历史长河中,曾发生过许许多多匪夷所思的事情,而且随着时间的流逝,这些本令人迷惑的事情就更是显得神秘了,今天小编要和你说历史中的二位牛人,他们在辉煌的时候可谓是无人不知,深受大家的敬仰,在历史上 ...

最新文章

  1. Blender中的Python脚本介绍学习教程
  2. React组件设计之边界划分原则
  3. 问题:Unable to find a 'userdata.img' file for ABI armeabi to copy into the AVD folder.
  4. 编写TA链接静态库的方法
  5. UNITY ET 框架
  6. Android 自定义view的知识梳理。
  7. 信息时代把数据当成了信息,互联网让数据真正发挥出价值,让人们相信人眼看不见的数据世界。...
  8. 最新!Dubbo 远程代码执行漏洞通告,速度升级
  9. 汽车电子EMC测试标准ISO7637-2详解
  10. 宝马 OR 奥迪?NONONO,还得看我Li Auto,新款六座SUV强势来袭
  11. 如何在ArcGIS中打开卫星影像
  12. python ttf_利用python工具生成彩色字体ttf
  13. execv bad address
  14. 2021Java春招面试:看完这篇文终于搞明白了
  15. 马甲包上架经验总结(珍贵)
  16. 出大事了,涛哥你们Java应用GC后不释放内存
  17. 无盘系统服务器虚拟内存,Windows7无盘虚拟内存如何设置
  18. 在LUAT中使用MQTT客户端
  19. flappy+bird+c语言程序,C语言实现flappy bird游戏
  20. photoshop插件制作_使用Photoshop更快地制作全景

热门文章

  1. 洛谷 P3373 线段树模板题
  2. 昊鼎王五:高级运维工程师的成长之路,总有一款适合你^_^
  3. imputation文献-A systematic evaluation of single-cell RNA-sequencing imputation methods
  4. Spring Security 集成 OIDC 项目编码 | 认证(三)
  5. 关于前端职业规划的一点思考
  6. 对于Python的get-pip.py安装教程
  7. 【ArcGIS】利用字段计算器按 OSM 道路等级生成道路速度
  8. 戴尔7060安装win10系统教程
  9. swift/dart代码规范检查工具介绍
  10. c语言编程快速收敛的圆周率计算,[原创]圆周率PI的计算(精确到几十万位)