传智播客activiti课堂笔记4.docx
- 文档编号:23480373
- 上传时间:2023-05-17
- 格式:DOCX
- 页数:39
- 大小:684.21KB
传智播客activiti课堂笔记4.docx
《传智播客activiti课堂笔记4.docx》由会员分享,可在线阅读,更多相关《传智播客activiti课堂笔记4.docx(39页珍藏版)》请在冰豆网上搜索。
传智播客activiti课堂笔记4
Activiti第四天组任务网关
课程安排:
组任务:
Candidate-user候选人
Candidate-group候选组(重点)
网关(重点):
ExclusiveGateway排他网关
parallelGateway并行网关
InclusiveGateway包含网关
综合案例(重点)
1复习
采购流程监控查询(常用,重点)
当前流程实例查询,查询系统中当前正在运行所有流程,查看流程当前运行的状态
结束的流程信息,主要应用于对历史业务数据进行统计分析:
实现方法(掌握):
分工明确,业务系统记录了业务数据,统计来源于业务系统。
可能会需要acitiviti将流程的运行信息通过监听器写入业务系统中。
监听器:
TaskListener
ExecutionListener
历史任务查询:
根据流程实例id查询该流程执行过的所有任务
根据用户id(通常是当前用户)查询该用户所执行过的任务
流程变量:
流程变量类型包括:
简单类型:
stringdouble…
序列化类型:
自定义的pojo,需要实现serializable接口。
流程变量作用域:
Global全局变量:
activiti中常用,作用域最大,是整个流程实例,当流程实例结束,global变量无效。
Local局部变量:
作用域可以是一个任务Task、或一个执行分支Execution,当这个任务结束,local变量无效。
可以通过historyService查询历史流程变量。
注意:
流程变量是activiti用于控制流程设置的变量,不建议流程变量中存储业务数据。
流程变量使用:
(重点)
通过UEL表达式来使用流程变量控制流程的执行。
通过在连线上设置condition条件,条件使用UEL表达式,表达式中使用流程变量。
注意:
如果UEL表达式中流程变量不存在会跑出异常。
如果UEL表达式中流程变量存在,没有符合的条件,流程会执行结束。
(排他网关可以避免)
全局变量设置:
常用:
1》流程启动时设置流程变量,流程变量可以任何结点使用。
runtimeService.startProcessInstanceByKey(processDefinitionKey,variables)
2》任务完成时设置流程变量,在任务的后续结点可以使用该流程变量。
taskSplete(tasked,variables)
3》通过当前流程实例的id设置流程变量
runtimeService.setVariables(processInstanceId,variables)
通过:
runtimeService.getVariables()方法获取全局变量
processInstanceId:
必须是当前正在运行的流程实例id
4》通过当前待办任务的id设置流程变量。
taskService.setVariables(taskId,variables)
通过:
taskService.getVariables()方法获取全局变量
taskId:
必须是当前待办任务(未完成任务)的id
2Candidate-user候选人
2.1什么是候选人
采用固定分配方法给任务指定负责人,如果任务负责人出现变更,需要修改流程定义,就可以采用候选人分配方式,先给任务分配多个候选人,候选人通过拾取组任务进行个人任务办理。
给任务分配候选人,如果分配多个候选人中间使用半角逗号分隔。
2.2什么是组任务
多个候选人有资格完成该任务,这个任务叫做组任务。
组任务具备条件:
任务没有设置assignee任务负责人
任务具有候选人
2.3候选人办理任务过程
第一步:
给任务设置候选人(多个,中间使用半角逗号分隔)
候选人是无法办理任务
第二步:
候选人查询组任务
使用taskService查询,指定candidate候选人。
第三步:
候选人拾取(claim)组任务
候选人拾取组任务后,该候选人变为任务的负责人,该任务变为个人任务
如果候选人拾取组任务后,不想办理该任务,可以将个人任务归还,该个人任务变为组任务
第四步:
查询待办个人任务
第五步:
办理任务
第六步:
流程结束
2.4Candidate-user办理任务api
候选人查询组任务
使用taskService指定candidateUser候选人查询组任务。
//任务查询对象
TaskQuerytaskQuery=taskService.createTaskQuery();
//候选人
StringcandidateUser="zhangsan";
taskQuery.taskCandidateUser(candidateUser);
//流程定义key
StringprocessDefinitionKey="purchasingflow";
taskQuery.processDefinitionKey(processDefinitionKey);
List
注意:
查询组任务,必须指定candidateUser候选人,查询该候选人有资格办理的组任务。
拾取组任务
通过taskService,指定任务id和候选人拾取任务:
TaskServicetaskService=processEngine.getTaskService();
//组任务id
StringtaskId="5604";
//任务候选人,claim拾取后该候选人变为任务负责人
StringuserId="zhangsan";
//任务拾取
taskService.claim(taskId,userId);
注意:
如果拾取人不是该任务的候选人也可以拾取成功,在拾取之前需要校验,该候选人是否有资格拾取该任务.
//组任务id
StringtaskId="6004";
//任务候选人,claim拾取后该候选人变为任务负责人
StringcandidateUser="zhangsan4";
//根据候选人和组任务id查询,如果有记录说明该候选人有资格拾取该任务
Tasktask=taskService.createTaskQuery().taskId(taskId)
.taskCandidateUser(candidateUser).singleResult();
if(task!
=null){
//任务拾取
taskService.claim(taskId,candidateUser);
System.out.println("任务拾取成功");
}
组任务归还
//归还组任务,由个人任务变为组任务,还可以进行任务交接
@Test
publicvoidsetAssignee(){
//查询任务使用TaskService
TaskServicetaskService=processEngine.getTaskService();
//当前待办任务
StringtaskId="6004";
//任务负责人
StringuserId="zhangsan2";
//校验userId是否是taskId的负责人,如果是负责人才可以归还组任务
Tasktask=taskService.createTaskQuery().taskId(taskId).taskAssignee(userId).singleResult();
if(task!
=null){
//如果设置为null,归还组任务,该任务没有负责人
taskService.setAssignee(taskId,null);
}
}
任务交接
任务负责人也可以将任务交给其它候选人办理该任务
代码如下:
@Test
publicvoidsetAssigneeToCandidateUser(){
//查询任务使用TaskService
TaskServicetaskService=processEngine.getTaskService();
//当前待办任务
StringtaskId="6004";
//任务负责人
StringuserId="zhangsan2";
//校验userId是否是taskId的负责人,如果是负责人才可以归还组任务
Tasktask=taskService.createTaskQuery().taskId(taskId)
.taskAssignee(userId).singleResult();
if(task!
=null){
//将此任务交给其它候选人办理该任务
Stringcandidateuser="zhangsan";
//根据候选人和组任务id查询,如果有记录说明该候选人有资格拾取该任务
Tasktask2=taskService.createTaskQuery().taskId(taskId)
.taskCandidateUser(candidateuser).singleResult();
if(task2!
=null){
//才可以交接
taskService.setAssignee(taskId,candidateuser);
}
}
}
查询个人任务
参考个人任务章节
办理个人任务
参考个人任务章节
数据表跟踪
如果任务设置候选人,当前任务表中assignee(任务负责人)是空。
SELECT*FROMact_ru_task#当前任务表
SELECT*FROMact_ru_identitylink#流程参与者
如果任务设置候选,记录所有候选人信息
任务拾取后,task表中assignee记录任务的负责人
3Candidate-group候选组
3.1什么候选组
即使给任务指定了多个候选人,多个候选人都有办理任务资格,但是候选的人数有限,无法动态扩展,如果需要添加或删除候选,需要修改流程定义文件,不利于系统扩展。
采用候选组方式解决上边的问题。
给任务设置候选组,在组中有多个用户并且可以动态扩展用户,组中的用户都是候选人,候选人先拾取组任务,将组任务变为自己的个人任务,进行个人任务办理。
3.2候选组办理任务过程
第一步:
Activiti会自动从候选组中找用户,将这些用户作为该任务的候选人。
下边的流程同候选人办理任务过程!
!
第二步:
给任务设置候选人(多个,中间使用半角逗号分隔)
候选人是无法办理任务
第三步:
候选人查询组任务
使用taskService查询,指定candidate候选人。
第四步:
候选人拾取(claim)组任务
候选人拾取组任务后,该候选人变为任务的负责人,该任务变为个人任务
如果候选人拾取组任务后,不想办理该任务,可以将个人任务归还,该个人任务变为组任务
第五步:
查询待办个人任务
第六步:
办理任务
第七步:
流程结束
3.3设置候选组
多个组中间使用半角逗号分隔。
3.4设置组和用户信息
Activiti中采用以下表记录组信息、用户信息、组和用户关系信息
SELECT*FROMact_id_group#组信息
SELECT*FROMact_id_user#用户信息
SELECT*FROMact_id_membership#组和用户关系信息
Api设置方法
以下设置的信息和业务系统的用户信息、角色信息保存一致。
先设置组信息
再设置用户信息
再设置组和用户关系信息
代码如下:
//设置组和用户信息
@Test
publicvoidsetUserGroup(){
IdentityServiceidentityService=processEngine.getIdentityService();
//设置组信息
//添加之前应该校验组信息是否存在,不存在再进行添加
if(identityService.createGroupQuery().groupId("10").singleResult()==null){
//添加新组
GroupEntitygroupEntity=newGroupEntity();
groupEntity.setId("10");
groupEntity.setName("员工");
identityService.saveGroup(groupEntity);
}
if(identityService.createGroupQuery().groupId("11").singleResult()==null){
//添加新组
GroupEntitygroupEntity=newGroupEntity();
groupEntity.setId("11");
groupEntity.setName("部门经理");
identityService.saveGroup(groupEntity);
}
if(identityService.createGroupQuery().groupId("12").singleResult()==null){
//添加新组
GroupEntitygroupEntity=newGroupEntity();
groupEntity.setId("12");
groupEntity.setName("总经理");
identityService.saveGroup(groupEntity);
}
if(identityService.createGroupQuery().groupId("13").singleResult()==null){
//添加新组
GroupEntitygroupEntity=newGroupEntity();
groupEntity.setId("13");
groupEntity.setName("财务");
identityService.saveGroup(groupEntity);
}
//设置用户信息
//添加之前应该校验用户信息是否存在,不存在再进行添加
if(identityService.createUserQuery().userId("zhangsan").singleResult()==null){
//添加新用户
UserEntityuserEntity=newUserEntity();
userEntity.setId("zhangsan");
userEntity.setFirstName("张三");
identityService.saveUser(userEntity);
}
if(identityService.createUserQuery().userId("lisi").singleResult()==null){
//添加新用户
UserEntityuserEntity=newUserEntity();
userEntity.setId("lisi");
userEntity.setFirstName("李四");
identityService.saveUser(userEntity);
}
if(identityService.createUserQuery().userId("wangwu").singleResult()==null){
//添加新用户
UserEntityuserEntity=newUserEntity();
userEntity.setId("wangwu");
userEntity.setFirstName("王五");
identityService.saveUser(userEntity);
}
if(identityService.createUserQuery().userId("zhaoliu").singleResult()==null){
//添加新用户
UserEntityuserEntity=newUserEntity();
userEntity.setId("zhaoliu");
userEntity.setFirstName("赵六");
identityService.saveUser(userEntity);
}
//设置用户和组的关系信息
//采用先删除再添加
identityService.deleteMembership("zhangsan","10");
identityService.createMembership("zhangsan","10");
identityService.deleteMembership("lisi","11");
identityService.createMembership("lisi","11");
identityService.deleteMembership("wangwu","12");
identityService.createMembership("wangwu","12");
identityService.deleteMembership("zhaoliu","13");
identityService.createMembership("zhaoliu","13");
}
与业务系统同步方法(常用)
业务系统中存在用户信息,activiti中也存在用户信息,需要只维护一处数据。
通常采用业务系统向activiti同步方法:
需要将业务系统中的用户信息和角色信息同步到activiti中。
数据同步:
业务系统---》activiti同步
方法1:
数据库触发器方法
企业中在进行数据同步的常用方法,一般在一个数据库中采用此方法。
业务系统用户表----》activiti的act_id_user
在业务系统用户表添加触发器:
新增、删除、修改
注意:
如果act_id_user有外键关系,需要先删除依赖关系。
业务系统角色表----》activiti的act_id_group
业务系统角色和用户关系表—》activiti的act_id_membership
方法2:
采用即时触发java程序。
●用户角色同步:
在操作业务系统用户角色表时执行以下操作:
业务系统添加角色-activiti添加角色
业务系统修改角色activiti修改角色
业务系统删除角色activiti删除角色,删除之前将用户角色关系表先删除(根据角色删除)
●用户信息同步
在操作业务系统用户表时执行以下操作
业务系统添加用户----》activiti添加用户,添加用户与角色关系表
业务系统修改用户---》activiti修改用户,先删除原来用户与角色关系表,再添加用户与角色关系
业务系统删除用户—》activiti删除用户,删除之前将用户角色关系表删除(根据用户删除)
3.5组任务办理过程api
设置组和用户信息
参考上边设置组和用户api
正式开发时,需要将业务系统用户和角色信息同步到activiti中。
候选人查询组任务
参考candidate-user的api
注意:
在activiti的用户、组、用户和组关系表中随时添加数据,不受流程启动先后顺序影响。
拾取组任务
参考candidate-user的api
查询个人任务
参考candidate-user的api
办理个人任务
参考candidate-user的api
数据表跟踪
和候选人不一样:
SELECT*FROMact_ru_identitylink#流程参与者
在group_id_字段设置了候选组的id
4网关
4.1排他网关
什么排他网关
排他网关用于决策,选择分支执行流程,分支上需要设置condition条件,如果分支的条件结果为true,那么该分支会通过排他网关。
排他网关只会选择一条分支去执行。
定义方法
图标:
流程定义:
排他网关测试
第一步:
流程定义部署
第二步:
启动流程实例
设置price流程变量值,因为price在排他网关的两分支使用
第三步:
查询待办任务
也可以在部门经理审核后设置price流程变量值,因为price在排他网关的两分支使用
第四步:
办理任务
如果分支上的条件都不满足,没有一条线经过排他网关,activiti会抛出异常:
org.activiti.engine.ActivitiException:
Nooutgoingsequenceflowoftheexclusivegateway'exclusivegateway1'couldbeselectedforcontinuingtheprocess
atorg.activiti.engine.impl.bpmn.behavior.ExclusiveGatewayActivityBehavior.leave(ExclusiveGatewayActivityBehavior.java:
85)
如果多条分支都满足,只会有一条线经过排他网关。
上边两种情况必须在开发避免!
!
!
4.2并行网关
什么并行网关
并行网关(parallelGateway),包括分支和汇聚两个结点,所有的分支不判断条件都经过分支结点,所有经过分支结点的分支都要进行汇聚,所有的分支全部执行完成,并行网关执行完成。
Fork(分支)
所有的分支不判断条件都经过分支结点
Join(汇聚)
所有经过分支结点的分支都要进行汇聚
分支的数量等于汇聚数量!
流程定义
图标:
注意:
经过并行网关的分支结点,不需要设置condition条件。
并行网关测试
当流程执行到并行的分支结点时,
向act_ru_execution#流程实例执行表执行并行分支(结算,入库)
Execution表中8501的记录数等于分
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 传智播客 activiti 课堂 笔记