如果对activiti7不是很了解,可以先看 https://blog.csdn.net/rocklee/article/details/124615525
这章内容主要是想分享排它路由实现拒签功能的请假流程。
如下图,大的正方菱形里面实心X的就是排他路由,可实现条件流向。拟写请假的环节,请假内容在leave变量里面,这次的流程与上次不一样的有两点,一是有两种审批结果(同意和拒签),另一是视乎请假天数要不要经总监审批。

activiti没有同意或拒签的概念,但是我们可以利用流程变量加排他路由来实现。如排他路由里面开一个条件流向,将条件设为leave.status==“A”,也就是说如果部门领导审批时将status设为"A"就意味着走这个流向了,而拒签也利用这种方法实现。

同理,根据请假天数流向不同的审批部门,也是利用这种方法实现。

拟写请假单

因为leaveData后面每个审批都会更新status的值,所以统一使用taskService setvariable来更改它的值

ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();RuntimeService runtimeService = engine.getRuntimeService();String id = "study3-leave";Map<String, Object> vars = new HashMap<>();//给两级审批组分别赋予角色vars.put("dept_leader", "dept-group1,dept-group2");vars.put("hr_leader", "hr-group1");vars.put("director_leader","dir-group1");RepositoryService repositoryService = engine.getRepositoryService();System.out.println("流程定义的ID:" + ActivitiUtil.getProcessDefinitionIdByProcessKey(id,repositoryService));ProcessInstance processInstance = ActivitiUtil.launchProcessInstance(id, "businessKey-888", vars, runtimeService);System.out.println("流程定义的ID:" + processInstance.getProcessDefinitionId());System.out.println("流程实例的ID:" + processInstance.getId());//启动了流程实例后,认领了该实例的第一个user task,就是填写请假单申请String userId="我是冤大头"; String processInstanceId=processInstance.getProcessInstanceId();TaskService taskService=engine.getTaskService();Task task= ActivitiUtil.getTask(processInstanceId,"all_staff",taskService);System.out.println("businessKey:"+task.getBusinessKey());//额外的附加信息,如外部表的记录idLeaveData leaveData=new LeaveData("A003","冤大头",10,"A");taskService.setVariable(task.getId(),"leave",leaveData);System.out.println("流程变量:"+task.getProcessVariables());//暂时分不出getProcessVariables和getTaskLocalVariables有什么不一样!taskService.claim(task.getId(),userId);taskService.addComment(task.getId(),task.getProcessInstanceId(),"拟写请假单:"+userId);taskService.complete(task.getId());

审批

ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();//根据用户组查询任务TaskService taskService=engine.getTaskService();// 根据流程的key和任务负责人 查询任务String id = "study3-leave";String group= "dept-group1";List<Task> list =ActivitiUtil.getTaskList(id,group,taskService);// 输出当前用户具有的任务for (Task task : list) {System.out.println("流程实例id:" + task.getProcessInstanceId());System.out.println("任务id:" + task.getId());System.out.println("任务名称:" + task.getName());System.out.println("流程变量:"+task.getProcessVariables());//这时候,leave和上一任务创建的变量task1-var1和最新的form_id都出来了//System.out.println("局部任务变量:"+task.getTaskLocalVariables());System.out.println("请假单信息:");//输出首任务信息HistoricTaskInstance firstTask=ActivitiUtil.getFirstFinishedTask(task.getProcessInstanceId(),engine.getHistoryService());System.out.println("填写时间:"+firstTask.getCreateTime());System.out.println("递交人:"+firstTask.getAssignee());System.out.println("内容:"+task.getProcessVariables().get("leave"));System.out.println("备注:"+ActivitiUtil.getComment(firstTask.getId(),engine.getTaskService()).getFullMessage());LeaveData taskData=taskService.getVariable(task.getId(),"leave",LeaveData.class);taskData.setStatus("R");taskService.setVariable(task.getId(),"leave",taskData);taskService.claim(task.getId(),"部门用户1");taskService.addComment(task.getId(),task.getProcessInstanceId(),"拒签冤大头");taskService.complete(task.getId());LeaveData data1=ActivitiUtil.getGlobalVariable("leave",task.getProcessInstanceId(),engine.getRuntimeService());System.out.println(data1);}}

显示请假单列表

ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();//列出请假单实例String id = "study3-leave";List<HistoricProcessInstance> processInstances=ActivitiUtil.getProcessInstances(id,engine.getHistoryService());int tasksId=1;for (HistoricProcessInstance p:processInstances){HistoricTaskInstance firstTask=ActivitiUtil.getFirstFinishedTask(p.getId(),engine.getHistoryService());HistoricTaskInstance task=ActivitiUtil.getLastFinishedTask(p.getId(),engine.getHistoryService(),true);LeaveData leaveData=ActivitiUtil.getGlobalVariable("leave", p.getId(), engine.getRuntimeService());System.out.println("任务"+(tasksId++)+":"+p.getId());System.out.println("  状态:"+(p.getEndTime()==null?"在单":"**已完结**"));System.out.println("  拟写人:"+firstTask.getAssignee());System.out.println("  拟写时间:"+firstTask.getClaimTime());if (p.getEndTime()==null) {System.out.println("  内容:" + leaveData);}else {System.out.println("  完结时间:"+p.getEndTime());System.out.println("  内容:" + ActivitiUtil.getGlobalVariable("leave", p.getId(), engine.getHistoryService()));System.out.println("  审批耗时时长:" + Duration.ofMillis(p.getDurationInMillis()).toString());}System.out.println("  ======");List<HistoricTaskInstance> tasks=ActivitiUtil.getFinishedTasks(p.getId(),engine.getHistoryService());System.out.println("  已完成环节:"+tasks.stream().map(m->m.getName()).collect(Collectors.joining(",")));System.out.println("  最后审批信息:"+task.getName());System.out.println("    审批时间:"+task.getClaimTime());System.out.println("    审批人:"+task.getAssignee());System.out.println("    审批状态:"+(leaveData.getStatus().equals("A")?"同意审批":"拒签"));Comment comment=ActivitiUtil.getComment(task.getId(),engine.getTaskService());if (comment!=null) {System.out.println("    批注:" +comment.getFullMessage());}System.out.println("    流程实例变量:"+task.getProcessVariables());if (p.getEndTime()==null) {System.out.println("  ======");System.out.println("  下一个审批环节:" + ActivitiUtil.getNextTasks(p.getId(), engine.getTaskService()).stream().map(m -> m.getName()).collect(Collectors.joining(",")));}}

结果显示:

任务1:5ca4b33e-cf7a-11ec-b845-3863bb4563c2状态:在单拟写人:陈大文拟写时间:Mon May 09 17:28:19 CST 2022内容:MyActivitiTest3.LeaveData(staffId=A001, staffName=陈大文, days=3, status=A)======已完成环节:1.填写请假申请,2.部门领导审批最后审批信息:2.部门领导审批审批时间:Mon May 09 17:39:35 CST 2022审批人:部门用户1审批状态:同意审批批注:同意流程实例变量:{dept_leader=dept-group1,dept-group2, director_leader=dir-group1, hr_leader=hr-group1, leave=MyActivitiTest3.LeaveData(staffId=A001, staffName=陈大文, days=3, status=A), form_id=form-888}======下一个审批环节:3.总监审批
任务2:40702b82-cf7c-11ec-b7b3-3863bb4563c2状态:在单拟写人:陈大文2拟写时间:Mon May 09 17:41:50 CST 2022内容:MyActivitiTest3.LeaveData(staffId=A002, staffName=陈大文2, days=2, status=A)======已完成环节:1.填写请假申请,2.部门领导审批最后审批信息:2.部门领导审批审批时间:Mon May 09 17:42:25 CST 2022审批人:部门用户1审批状态:同意审批批注:同意流程实例变量:{director_leader=dir-group1, dept_leader=dept-group1,dept-group2, hr_leader=hr-group1, leave=MyActivitiTest3.LeaveData(staffId=A002, staffName=陈大文2, days=2, status=A), form_id=form-888}======下一个审批环节:4.HR领导审批
任务3:c6621778-cfff-11ec-a65f-3863bb4563c2状态:在单拟写人:我是冤大头拟写时间:Tue May 10 09:23:19 CST 2022内容:MyActivitiTest3.LeaveData(staffId=A003, staffName=冤大头, days=10, status=R)======已完成环节:1.填写请假申请,2.部门领导审批最后审批信息:2.部门领导审批审批时间:Tue May 10 09:24:54 CST 2022审批人:部门用户1审批状态:拒签批注:拒签冤大头流程实例变量:{director_leader=dir-group1, dept_leader=dept-group1,dept-group2, hr_leader=hr-group1, leave=MyActivitiTest3.LeaveData(staffId=A003, staffName=冤大头, days=10, status=R), proc-var=12345}======下一个审批环节:1.填写请假申请

Activiti7实战二:实现具有拒签功能的请假2层审批流程相关推荐

  1. Quarkus 实战二:开发REST ful 服务实现简单的curd功能

    Quarkus 实战二:开发REST ful 服务实现简单的curd 概述 Quarkus集成了RESTEasy,这是一种用于定义REST API的JAX-RS实现 参考文档: Quarkus 文档 ...

  2. java 搜索业务怎么写_Java项目实战第11天:搜索功能的实现

    原标题:Java项目实战第11天:搜索功能的实现 今天是刘小爱自学Java的第110天. 感谢你的观看,谢谢你. 话不多说,开始今天的学习: 事先说明:关于今天的搜索功能实现. 并没有使用到倒排索引这 ...

  3. GridView实战二:使用ObjectDataSource数据源控件(自定义缓存机制实现Sort)

    参考资料:http://www.cnblogs.com/fsjohnhuang/archive/2011/12/17/2291200.html 因为使用ObjectDataSource自带的缓存机制无 ...

  4. Taro多端开发实现原理与项目实战(二)

    Taro多端开发实现原理与项目实战(二) 多端电商平台项目概述及开发准备 学习了前面的基础知识和进阶后是否跃跃欲试?我们准备了一个电商平台的项目来和大家一起实践使用 Taro 开发电商平台. 项目概述 ...

  5. 微信小程序-001-抽签功能-006-我的抽签-主界面

    微信小程序-001-抽签功能-006-我的抽签-主界面 目录 一.wxml 二.js pages.chouqian.setqian.setqian 一.wxml <view wx:for=&qu ...

  6. 微信小程序-001-抽签功能-008-简单登录

    微信小程序-001-抽签功能-008-简单登录 目录 一.wxml 二.js pages.login.login 一.wxml <button open-type="getUserIn ...

  7. python游戏开发框架_用Python和Pygame写游戏-从入门到精通(实战二:恶搞俄罗斯方块1)...

    游戏是为了什么而存在的?Bingo,是为了娱乐~ 在这个最高主题之前,技术啥的什么都无所谓! 前一段时间,有位姓刘的网友用Pygame写了个俄罗斯方块,在用py2exe打包的时候遇到一些问题,和我交流 ...

  8. 牛客网SQL实战二刷 | Day2

    「牛客网SQL实战二刷」是个系列学习笔记博文,每天解析6道SQL题目- 今天是第7-12 题!该系列的其他博文,可在「我的博客」 中查看- 每篇笔记的格式大致为,三大板块: 大纲 题目(题目描述.思路 ...

  9. JSTL实战二之基础

    JSTL实战二之基础 一.JSTL的灵感 JSTL的设计灵感来自JavaScript和XPath WEB编程基于http,而http是简单的协议,所有的数据以字符形式提交,而java是一种强类型的语言 ...

最新文章

  1. XIV Open Cup named after E.V. Pankratiev. GP of Europe
  2. java sql 返回 json_java访问oracle 返回json 实践(一)
  3. usaco Mother's Milk
  4. linux 禁止SU 登录
  5. 作为程序员,这些梗你都答得上来吗?
  6. [ARM-assembly]-A64指令集合总结
  7. html 定义函数调用函数,请问HTML function函数怎么定义和调用?
  8. 牛客 - Yuki with emofunc and playf(同余最短路)
  9. php 顺序结构,顺序存储结构php实现
  10. 60-420-020-使用-存储过程-使用存储过程和函数插入大数据量
  11. 解决博易博客后台文章管理页面无法显示分页的问题
  12. 浅谈一下对runloop的理解
  13. 8086汇编基础 inc 自加一
  14. java kryo 序列化_Kryo序列化
  15. Uboot启动分析--start.S启动分析(1)
  16. 要么到岗,要么离职!马斯克:特斯拉「远程办公」到此结束
  17. ShapeExplorer
  18. 万圣节html代码大全,方舟生存进化249万圣节新版本代码大全分享
  19. 为什么说一站式移动办公SaaS平台一定是未来!
  20. 做好织梦dedecms安全防护全部方法

热门文章

  1. Linux下释放内存
  2. 如何查看网站的收录与排名
  3. 2020.05.26
  4. 三个指标怎么做分层图_分层性能指标以及在哪里找到它们
  5. 移动端网页开发-vh/vw/rem
  6. U811.1接口EAI系列之二--生成销售出库单调用U8的EAI通用处理方法--PowerBuilder语言...
  7. 超强技巧分享,如何将人民币大小写转换?
  8. 硬盘保护技术的原理和实践初探
  9. KindEditor 自定义插件
  10. BRINSON理论 - 投资组合表现的决定因素