收藏 分享(赏)

传智播客activiti课堂笔记4.doc

上传人:weiwoduzun 文档编号:2613820 上传时间:2018-09-23 格式:DOC 页数:32 大小:799.59KB
下载 相关 举报
传智播客activiti课堂笔记4.doc_第1页
第1页 / 共32页
传智播客activiti课堂笔记4.doc_第2页
第2页 / 共32页
传智播客activiti课堂笔记4.doc_第3页
第3页 / 共32页
传智播客activiti课堂笔记4.doc_第4页
第4页 / 共32页
传智播客activiti课堂笔记4.doc_第5页
第5页 / 共32页
点击查看更多>>
资源描述

1、Activiti 第四天 组任务 网关课程安排:组任务:Candidate-user 候选人Candidate-group 候选组 (重点)网关(重点) :ExclusiveGateway 排他网关parallelGateway 并行网关InclusiveGateway 包含网关综合案例(重点)1 复习采购流程监控查询(常用,重点)当前流程实例查询,查询系统中当前正在运行所有流程,查看流程当前运行的状态结束的流程信息,主要应用于对历史业务数据进行统计分析:实现方法(掌握):分工明确,业务系统记录了业务数据,统计来源于业务系统。可能会需要 acitiviti 将流程的运行信息通过监听器写入业务系

2、统中。监听器:TaskListenerExecutionListener历史任务查询:根据流程实例 id 查询该流程执行过的所有任务根据用户 id(通常是当前用户)查询该 用户所执行过的任务流程变量:流程变量类型包括 :简单类型:string double序列化类型:自定义的 pojo,需要实现 serializable 接口。流程变量作用域:Global 全局变量:activiti 中常用,作用域最大,是整个流程实例,当流程实例结束,global 变量无效。Local 局部变量:作用域可以是一个任务 Task、或一个执行分支 Execution,当这个任务结束,local 变量无效。可以通过

3、 historyService 查询历史流程变量。注意:流程变量是 activiti 用于控制流程设置的变量,不建议流程变量中存储业务数据。流程变量使用:(重点)通过 UEL 表达式来使用流程变量控制流程的执行。通过在连线上设置 condition 条件,条件使用 UEL 表达式,表达式中使用流程变量。注意:如果 UEL 表达式中流程变量不存在会跑出异常。如果 UEL 表达式中流程变量存在,没有符合的条件,流程会执行结束。 (排他网关可以避免)全局变量设置:常用:1流程启动时设置流程变量,流程变量可以任何结点使用。runtimeService.startProcessInstanceByKey

4、(processDefinitionKey,variables)2任务完成时设置流程变量,在任务的后续结点可以使用该流程变量。taskSplete(tasked, variables)3通过当前流程实例 的 id 设置流程变量runtimeService.setVariables(processInstanceId, variables)通过:runtimeService.getVariables()方法获取全局变量processInstanceId:必须是当前正在运行的流程实例 id4通过当前待办任务的 id 设置流程变量。taskService.setVariables(taskId, v

5、ariables)通过: taskService.getVariables()方法获取全局变量taskId:必须是当前待办任务( 未完成任务)的 id2 Candidate-user 候选人2.1 什么是候选人采用固定分配方法给任务指定负责人,如果任务负责人出现变更,需要修改流程定义,就可以采用候选人分配方式,先给任务分配多个候选人,候选人通过拾取组任务进行个人任务办理。给任务分配候选人,如果分配多个候选人中间使用半角逗号分隔。2.2 什么是组任务多个候选人有资格完成该 任务,这个任务叫做组任务。组任务具备条件:任务没有设置 assignee 任务负责人任务具有候选人2.3 候选人办理任务过程

6、第一步:给任务设置候选人(多个, 中间使用半角逗号分隔)候选人是无法办理任务第二步:候选人查询组任务使用 taskService 查询,指定 candidate 候选人。第三步:候选人拾取(claim)组任务候选人拾取组任务后,该 候选人变为任务的负责人,该任务变为个人任务如果候选人拾取组任务后,不想办理该 任务,可以将个人任务归还,该个人任务变为组任务第四步:查询待办个人任务第五步:办理任务第六步:流程结束2.4 Candidate-user 办理任务 api2.4.1候选人查询组任务使用 taskService 指定 candidateUser 候选人查询组任务。/任务查询对象 TaskQ

7、uery taskQuery = taskService.createTaskQuery();/候选人String candidateUser = “zhangsan“;taskQuery.taskCandidateUser(candidateUser);/流程定义keyString processDefinitionKey = “purchasingflow“;taskQuery.processDefinitionKey(processDefinitionKey);List list = taskQuery.list();注意:查询组任务,必须指定 candidateUser 候选人,查询该

8、 候选人有资格办理的组任务。2.4.2拾取组任务通过taskService,指定任务id 和候选人拾取任务:TaskService taskService = processEngine.getTaskService();/组任务idString taskId = “5604“;/任务候选人,claim拾取后该 候选人变为任务负责人String userId = “zhangsan“;/任务拾取taskService.claim(taskId, userId);注意:如果拾取人不是该任务的候选人也可以拾取成功,在拾取之前需要校验,该 候选人是否有资格拾取该 任务./ 组任务idString t

9、askId = “6004“;/ 任务候选人,claim 拾取后该 候选人变为任务负责人String candidateUser = “zhangsan4“;/根据候选人和组任务id 查询,如果有记录说明该 候选人有资格拾取该 任务Task task = taskService.createTaskQuery().taskId(taskId).taskCandidateUser(candidateUser).singleResult();if(task!=null)/ 任务拾取taskService.claim(taskId, candidateUser);System.out.println

10、(“任务拾取成功 “);2.4.3组任务归还/ 归还组任务,由个人任务变为组任务,还可以进行任务交接Testpublic void setAssignee() / 查询任务使用TaskServiceTaskService taskService = processEngine.getTaskService();/ 当前待办任务String taskId = “6004“;/ 任务负责人String userId = “zhangsan2“;/校验userId是否是taskId的负责人,如果是负责人才可以归还组任务Task task = taskService.createTaskQuery()

11、.taskId(taskId).taskAssignee(userId).singleResult();if(task!=null)/如果设置为null ,归还组任务,该 任务没有负责人taskService.setAssignee(taskId, null);2.4.4任务交接任务负责人也可以将任务交给其它候选人办理该任务代码如下:Testpublic void setAssigneeToCandidateUser() / 查询任务使用TaskServiceTaskService taskService = processEngine.getTaskService();/ 当前待办任务Str

12、ing taskId = “6004“;/ 任务负责人String userId = “zhangsan2“;/ 校验userId是否是taskId的负责人,如果是负责人才可以归还组任务Task task = taskService.createTaskQuery().taskId(taskId).taskAssignee(userId).singleResult();if (task != null) / 将此任务交给其它候选人办理该 任务String candidateuser = “zhangsan“;/ 根据候选人和组任务id 查询,如果有记录说明该 候选人有资格拾取该 任务Task

13、task2 = taskService.createTaskQuery().taskId(taskId).taskCandidateUser(candidateuser).singleResult();if (task2 != null) / 才可以交接taskService.setAssignee(taskId, candidateuser);2.4.5查询个人任务参考个人任务章节2.4.6办理个人任务参考个人任务章节2.4.7数据表跟踪如果任务设置候选人,当前任务表中 assignee(任务负责人)是空。SELECT * FROM act_ru_task #当前任务表SELECT * FR

14、OM act_ru_identitylink #流程参与者如果任务设置候选,记录所有候选人信息任务拾取后,task 表中 assignee 记录任务的负责人3 Candidate-group 候选组3.1 什么候选组即使给任务指定了多个候选人,多个候选人都有办理任务资格,但是候选的人数有限,无法动态扩展,如果需要添加或删除候选,需要修改流程定义 文件,不利于系统 扩展。采用候选组方式解决上边的问题。给任务设置候选组,在组中有多个用户并且可以动态扩展用户,组中的用户都是候选人,候选人先拾取组任务,将组任务变为自己的个人任务,进行个人任务办理。3.2 候选组办理任务过程第一步:Activiti 会

15、自动从候选组中找用户,将这些用户作为该 任务的候选人。下边的流程同候选人办理任务过程!第二步:给任务设置候选人(多个, 中间使用半角逗号分隔)候选人是无法办理任务第三步:候选人查询组任务使用 taskService 查询,指定 candidate 候选人。第四步:候选人拾取(claim)组任务候选人拾取组任务后,该 候选人变为任务的负责人,该任务变为个人任务如果候选人拾取组任务后,不想办理该 任务,可以将个人任务归还,该个人任务变为组任务第五步:查询待办个人任务第六步:办理任务第七步:流程结束3.3 设置候选组多个组中间使用半角逗号分隔。3.4 设置组和用户信息Activiti 中采用以下表记

16、录组信息、用户信息、组和用户关系 信息SELECT * FROM act_id_group #组信息SELECT * FROM act_id_user #用户信息SELECT * FROM act_id_membership #组和用户关系信息3.4.1Api 设置方法以下设置的信息和业务系统的用户信息、角色信息保存一致。先设置组信息再设置用户信息再设置组和用户关系信息代码如下:/设置组和用户信息Testpublic void setUserGroup()IdentityService identityService = processEngine.getIdentityService();/

17、设置组信息/添加之前应该校验组信息是否存在,不存在再进行添加if(identityService.createGroupQuery().groupId(“10“).singleResult()=null)/添加新组GroupEntity groupEntity = new GroupEntity();groupEntity.setId(“10“);groupEntity.setName(“员工“);identityService.saveGroup(groupEntity);if(identityService.createGroupQuery().groupId(“11“).singleRe

18、sult()=null)/添加新组GroupEntity groupEntity = new GroupEntity();groupEntity.setId(“11“);groupEntity.setName(“部门经理“);identityService.saveGroup(groupEntity);if(identityService.createGroupQuery().groupId(“12“).singleResult()=null)/添加新组GroupEntity groupEntity = new GroupEntity();groupEntity.setId(“12“);gro

19、upEntity.setName(“总经理“);identityService.saveGroup(groupEntity);if(identityService.createGroupQuery().groupId(“13“).singleResult()=null)/添加新组GroupEntity groupEntity = new GroupEntity();groupEntity.setId(“13“);groupEntity.setName(“财务“);identityService.saveGroup(groupEntity);/设置用户信息/添加之前应该校验用户信息是否存在,不存

20、在再进行添加if(identityService.createUserQuery().userId(“zhangsan“).singleResult()=null)/添加新用户UserEntity userEntity = new UserEntity();userEntity.setId(“zhangsan“);userEntity.setFirstName(“张三“);identityService.saveUser(userEntity);if(identityService.createUserQuery().userId(“lisi“).singleResult()=null)/添加

21、新用户UserEntity userEntity = new UserEntity();userEntity.setId(“lisi“);userEntity.setFirstName(“李四“);identityService.saveUser(userEntity);if(identityService.createUserQuery().userId(“wangwu“).singleResult()=null)/添加新用户UserEntity userEntity = new UserEntity();userEntity.setId(“wangwu“);userEntity.setFi

22、rstName(“王五“);identityService.saveUser(userEntity);if(identityService.createUserQuery().userId(“zhaoliu“).singleResult()=null)/添加新用户UserEntity userEntity = new UserEntity();userEntity.setId(“zhaoliu“);userEntity.setFirstName(“赵六“);identityService.saveUser(userEntity);/设置用户和组的关系信息/采用先删除再添加identitySer

23、vice.deleteMembership(“zhangsan“, “10“);identityService.createMembership(“zhangsan“, “10“);identityService.deleteMembership(“lisi“, “11“);identityService.createMembership(“lisi“, “11“);identityService.deleteMembership(“wangwu“, “12“);identityService.createMembership(“wangwu“, “12“);identityService.d

24、eleteMembership(“zhaoliu“, “13“);identityService.createMembership(“zhaoliu“, “13“);3.4.2与业务系统 同步方法( 常用)业务系统 中存在用户信息,activiti 中也存在用户信息,需要只维护一处数据。通常采用业务系统 向 activiti 同步方法:需要将业务系统 中的用户信息和角色信息同步到 activiti 中。数据同步:业务系统-activiti 同步方法 1 :数据库触发器方法企业中在进行数据同步的常用方法,一般在一个数据库中采用此方法。业务系统 用户表-activiti 的 act_id_user

25、在业务系统 用户表添加触发器:新增、删除、修改注意:如果 act_id_user 有外键关系,需要先删除依赖关系。业务系统 角色表-activiti 的 act_id_group业务系统 角色和用户关系表activiti 的 act_id_membership方法 2 :采用即时触发 java 程序。 用户角色同步:在操作业务系统 用户角色表时执行以下操作:业务系统添加角色-activiti 添加角色业务系统修改角色activiti 修改角色业务系统删除角色activiti 删除角色,删除之前将用户角色关系表先删除(根据角色删除) 用户信息同步在操作业务系统 用户表时执行以下操作业务系统添加用

26、户-activiti 添加用户,添加用户与角色关系表业务系统修改用户-activiti 修改用户,先删除原来用户与角色关系表,再添加用户与角色关系业务系统删除用户activiti 删除用户,删除之前将用户角色关系表删除(根据用户删除)3.5 组任务办理过程 api3.5.1设置组和用户信息参考上边设置组和用户 api正式开发时,需要将业务系统 用户和角色信息同步到 activiti 中。3.5.2候选人查询组任务参考 candidate-user 的 api注意:在 activiti 的用户、组、用户和组关系表中随时添加数据,不受流程启动先后顺序影响。3.5.3拾取组任务参考 candidat

27、e-user 的 api3.5.4查询个人任务参考 candidate-user 的 api3.5.5办理个人任务参考 candidate-user 的 api3.5.6数据表跟踪和候选人不一样:SELECT * FROM act_ru_identitylink #流程参与者在 group_id_字段设置了候选组的 id4 网关4.1 排他网关4.1.1什么排他网关排他网关用于决策,选择分支执行流程,分支上需要设置 condition 条件,如果分支的条件结果 为 true,那么该 分支会通过排他网关。排他网关只会选择一条分支去执行。4.1.2定义方法图标:流程定义:4.1.3排他网关测试第一

28、步:流程定义部署第二步:启动流程实例设置 price 流程变量值,因为 price 在排他网关的两分支使用第三步:查询待办任务也可以在部门经理审核后设置 price 流程变量值,因为 price 在排他网关的两分支使用第四步:办理任务如果分支上的条件都不满足,没有一条线经过排他网关,activiti 会抛出异常:org.activiti.engine.ActivitiException: No outgoing sequence flow of the exclusive gateway exclusivegateway1 could be selected for continuing th

29、e processat org.activiti.engine.impl.bpmn.behavior.ExclusiveGatewayActivityBehavior.leave(ExclusiveGatewayActivityBehavior.java:85)如果多条分支都 满足,只会有一条线经过排他网关。上边两种情况必须在开发避免!4.2 并行网关4.2.1什么并行网关并行网关(parallelGateway) ,包括分支和汇聚两个结点,所有的分支不判断条件都经过分支结点,所有经过分支结点的分支都要进行汇聚,所有的分支全部执行完成,并行网关执行完成。Fork(分支)所有的分支不判断条件都经

30、过分支结点Join(汇聚)所有经过分支结点的分支都要进行汇聚分支的数量等于汇聚数量!4.2.2流程定义图标:注意:经过并行网关的分支结点,不需要设置 condition 条件。4.2.3并行网关测试当流程执行到并行的分支结点时,向 act_ru_execution #流程实例执行表执行并行分支(结算,入库)Execution 表中 8501 的记录数等于分支数+1只有一条记录的流程实例 id 和流程实例执行 id 相等的,这一条为流程执行主线。向当前任务表中插入两条记录(结算、入库):如果一条分支执行完成,在 execution 表中 act_id_改为并行网关汇聚结点的 id,表示分支执行完

31、成到汇聚结点等待其它分支。当一个分支结束,在当前任务表中就删除该 分支的任务。所有的分支执行完成,到汇聚结点,并行网关执行完成。所有经过的结点如下:历史活动表中,有几条分支就有几条汇聚。4.3 包含网关4.3.1什么是包含网关包含网关是排他网关和并行网关的结合体。包含网关(IncluesiveGateway) ,包括分支和汇聚两个结点,经过分支结点需要判断条件,满足条件经过分支结点,所有经过分支结点的线边最终会进行汇聚。Fork(分支)所有的分支需要判断条件,满足条件的经过分支结点Join(汇聚 )所有满足条件的分支都要进行汇聚4.3.2流程定义图标:员工类型:通过流程变量 userType

32、来表示,如果等于 1 表示普通员工,如果等于 2 表示领导注意:通过包含网关的每个分支的连线上设置 condition 条件。需求如下:领取完成体检单,对于普通员工体检内容包括 (常规项、抽血化验) ,对于领导体检内容包括 (常规项、抽血化验、增加项体检) ,其中,抽血化验完成方可吃饭,吃饭完成表示抽血化验分支就完成。设置 candition 条件:常规项体检:$userType=1 | userType=2增加项体检:$userType=2抽血化验:$userType=1 | userType=24.3.3包含网关测试包含网关与并行网关的不同就是经过分支结点的需要满足条件才进行汇聚,并行网关

33、不判断条件,所有经过分支的都经过汇聚结点。5 案例5.1 需求 将采购流程改为组任务(使用候选组) 实现 在采购流程中实现排他网关 在采购流程中实现并行网关需求描述:员工创建采购单经过部门经理审核审核通过:部门经理审核通过,如果采购金额大于等于 1 万元,由总经理审核部门经理审核通过,如果采购金额小于 1 万元,由财务审核审核不通过:部门经理审核不通过,由员工重新修改采购单进行提交总经理审核总经理审核通过由财务审核通过总经理审核不通过,由员工重新修改采购单进行提交财务审核财务审核通过并行执行财务结算和入库财务审核不通过,由员工重新修改采购单进行提交财务结算和入库两个操作可以并行执行。5.2 流

34、程定义部门经理审核通过后,通过排他网关决定走总经理审核还是财务审核。财务审核通过后,经过并行网关,财务结算和入库并行执行。审核分支设置 condition 条件:部门经理审核 :审核通过 candition:$order.price=10000 / 候选人,在act_id_user表中存在,从 act_id_membership通过group_id_ 查询出用户String candidateUser = userId;/ 指定候选人taskQuery.taskCandidateUser(candidateUser);/ 流程定义keyString processDefinitionKey =

35、 ResourcesUtil.getValue(“diagram.purchasingflow“, “purchasingProcessDefinitionKey“);taskQuery.processDefinitionKey(processDefinitionKey);List list = taskQuery.list();List orderList = new ArrayList();for (Task task : list) OrderCustom orderCustom = new OrderCustom();/下边的代码同采购单处理列表代码./ 流程实例idString pr

36、ocessInstanceId = task.getProcessInstanceId();/ 根据流程实例id 找到流程实例对象ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();/ 从流程实例对象中获取businessKeyString businessKey = processInstance.getBusinessKey();/ 根据businessKey查询业务系统/ 采购单id

37、String orderId = businessKey;PurBusOrder purBusOrder = purBusOrderMapper.selectByPrimaryKey(orderId);/ 获取采购单名称、采购金额等采购单信息/ 将purBusOrder内容拷贝到orderCustomBeanUtils.copyProperties(purBusOrder, orderCustom);/ 下边向orderCustom开始设置任务信息/ 任务id、任务标识 、任务名称/ 任务idorderCustom.setTaskId(task.getId();/ 任务标识orderCusto

38、m.setTaskDefinitionKey(task.getTaskDefinitionKey();/ 任务名称orderCustom.setTaskName(task.getName();orderList.add(orderCustom);return orderList;5.4.2.3 action查询组任务方法:代码基本上同采购单处理列表的代码:/ 采购单组任务列表RequestMapping(“/orderGroupTaskList“)public String orderGroupTaskList(HttpSession session, Model model)throws E

39、xception / 当前登陆用户ActiveUser activeuser = UserUtil.getUserFromSession(session);/ 用户idString userId = activeuser.getUserid();List list = orderService.findOrderGroupTaskList(userId);model.addAttribute(“list“, list);return “order/orderGroupTaskList“;5.4.2.4 页面5.4.3候选人拾取组任务5.4.3.1 dao不用开发。5.4.3.2 service

40、接口功能:拾取组任务接口参数:taskId 任务 id,candidateUserId 候选人接口实现 :调用 taskService,指定组任务 id 和 candidateUserId 候选人。拾取任务之前需要校验候选人是否资格拾取该组任务。Overridepublic void saveClaimTask(String taskId, String candidateUserId)throws Exception / 根据候选人和组任务id 查询,如果有记录说明该 候选人有资格拾取该 任务Task task = taskService.createTaskQuery().taskId(t

41、askId).taskCandidateUser(candidateUserId).singleResult();if (task != null) / 任务拾取taskService.claim(taskId, candidateUserId);System.out.println(“任务拾取成功 “);5.4.3.3 action拾取组任务方法:需要从页面传入 taskId 组任务 id./ 拾取组任务RequestMapping(“/claimTask“)public String claimTask(HttpSession session, String taskId)throws E

42、xception / 当前登陆用户ActiveUser activeuser = UserUtil.getUserFromSession(session);/ 用户idString userId = activeuser.getUserid();orderService.saveClaimTask(taskId, userId);/返回采购单组任务列表return “redirect:orderGroupTaskList.action“;5.4.3.4 页面修改组任务列表页面,添加“拾取组任务”连接:5.5 测试测试注意点:1、组任务( 使用候选组)准备组和用户的数据,调用 activiti 的 api 设置组、用户、组和用户关系信息正式开发,将业务系统 用户角色数据实时同步到 activiti 中。2、测试组任务办理流程a查询组任务功能b拾取组任务功能3、测试排他网关修改原来的功能是否存在 bug。4、测试并行网关结算功能和入库功能是否并行执行.6 课程总结什么是工作流?工作流是通过计算机自动管理业务流程,实现多个参与者按照预定义的流程自动执行业务流程。什么是 activiti?Activiti 是一个工作流的引擎(框架,jar 、组件) ,对业务流程的自动化管理。 Activiti 按照 bpmn2.0 标准进行流程

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 中等教育 > 小学课件

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报