工作流:一文让你学会使用flowable工作流
1.请假流程图
下图是 一个请假申请的简单流程图
(1)申请人通过发起流程进行请假申请,给经理发送一个待审批事项;
(2)经理在待办列表选择事项,进行审批,approved同意或者rejected驳回操作,并触发不同的事件;
(3)如果经理approved,则触发Enter holidays in external system事件,并给流程发起人发送一个待办事项;
(4)如果经理rejected,则触发Send out rejection email事件,给申请人发送一个请假不批的邮件,流程结束;
(5)如果是(3),申请人需要处理待办任务进行休假,流程结束。
2.工作流文件
holiday-request.bpmn20.xml
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:xsd="http://www.w3.org/2001/XMLSchema"xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC"xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI"xmlns:flowable="http://flowable.org/bpmn"typeLanguage="http://www.w3.org/2001/XMLSchema"expressionLanguage="http://www.w3.org/1999/XPath"targetNamespace="http://www.flowable.org/processdef"><process id="holidayRequest" name="Holiday Request" isExecutable="true"><startEvent id="startEvent"/><sequenceFlow sourceRef="startEvent" targetRef="approveTask"/><userTask id="approveTask" name="Approve or reject request" flowable:candidateGroups="managers"/><sequenceFlow sourceRef="approveTask" targetRef="decision"/><exclusiveGateway id="decision"/><sequenceFlow sourceRef="decision" targetRef="externalSystemCall"><conditionExpression xsi:type="tFormalExpression"><![CDATA[${approved}]]></conditionExpression></sequenceFlow><sequenceFlow sourceRef="decision" targetRef="sendRejectionMail"><conditionExpression xsi:type="tFormalExpression"><![CDATA[${!approved}]]></conditionExpression></sequenceFlow><serviceTask id="externalSystemCall" name="Enter holidays in external system" flowable:class="com.example.flowable.holiday.CallExternalSystemDelegate"/><sequenceFlow sourceRef="externalSystemCall" targetRef="holidayApprovedTask"/><userTask id="holidayApprovedTask" name="Holiday approved" flowable:assignee="${employee}"/><sequenceFlow sourceRef="holidayApprovedTask" targetRef="approveEnd"/><serviceTask id="sendRejectionMail" name="Send out rejection email" flowable:class="com.example.flowable.holiday.SendRejectionMail"/><sequenceFlow sourceRef="sendRejectionMail" targetRef="rejectEnd"/><endEvent id="approveEnd"/><endEvent id="rejectEnd"/></process></definitions>
3.pom文件
依赖的jar包如下:
<dependency><groupId>org.flowable</groupId><artifactId>flowable-engine</artifactId><version>6.4.2</version>
</dependency>
<dependency><groupId>com.h2database</groupId><artifactId>h2</artifactId><scope>runtime</scope>
</dependency>
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope>
</dependency>
<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope>
</dependency>
<dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>1.7.21</version>
</dependency>
<dependency><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId><version>1.7.21</version>
</dependency>
2.源码
(1)HolidayRequest类为测试主类
package com.example.flowable.holiday;import org.flowable.engine.*;
import org.flowable.engine.impl.cfg.StandaloneProcessEngineConfiguration;
import org.flowable.engine.repository.Deployment;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.engine.task.Comment;
import org.flowable.task.api.Task;import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;/**1. 此类描述的是:测试demo2. 参考flowable手册https://tkjohn.github.io/flowable-userguide/3. @author juge4. @version 2021/9/9 9:54
*/
public class HolidayRequest {public static void main(String[] args) {//1.创建一个独立(standalone)配置ProcessEngineConfiguration cfg = new StandaloneProcessEngineConfiguration()/*.setJdbcUrl("jdbc:h2:mem:flowable;DB_CLOSE_DELAY=-1").setJdbcUsername("sa").setJdbcPassword("").setJdbcDriver("org.h2.Driver")*/.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/flowable?autoReconnect=true&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true").setJdbcUsername("root").setJdbcPassword("123456").setJdbcDriver("com.mysql.jdbc.Driver")//如果数据表不存在的时候,自动创建数据表.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);//2.创建流程引擎ProcessEngine processEngine = cfg.buildProcessEngine();// 使用BPMN 2.0定义process。存储为XML,同时也是可以可视化的。NPMN 2.0标准可以让技术人员与业务人员都参与讨论业务流程中来//3.利用流程引擎部署流程RepositoryService repositoryService = processEngine.getRepositoryService();Deployment deployment = repositoryService.createDeployment().addClasspathResource("holiday-request.bpmn20.xml").deploy();//4.根据流程部署实例id获取流程定义实例ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().deploymentId(deployment.getId()).singleResult();System.out.println("Found process definition : " + processDefinition.getName());//5.启动process实例//5.1需要一些初始化的变量,这里我们简单的从Scanner中获取,一般在线上会通过接口传递过来(发起流程的表单)//5.1.1 scanner输入类似于web前端表单输入Scanner scanner= new Scanner(System.in);System.out.println("Who are you?");String employee = scanner.nextLine();System.out.println("How many holidays do you want to request?");Integer nrOfHolidays = Integer.valueOf(scanner.nextLine());System.out.println("Why do you need them?");String description = scanner.nextLine();//5.1.2 此处代码类似web后端获取前端表单传来的字段Map<String, Object> variables = new HashMap<String, Object>();variables.put("employee", employee);variables.put("nrOfHolidays", nrOfHolidays);variables.put("description", description);//6.发起流程RuntimeService runtimeService = processEngine.getRuntimeService();ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("holidayRequest", variables);//7.经理查询待办任务TaskService taskService = processEngine.getTaskService();/*将第一个任务指派给"经理(managers)"组,而第二个用户任务指派给请假申请的提交人。因此需要为第一个任务添加candidateGroups属性:<userTask id="approveTask" name="Approve or reject request" flowable:candidateGroups="managers"/>这里的candidateGroups,中文一般成为候选组,实际是一组用户的带号,在实际使用中可以写用户的角色id,或者组织机构(岗位、职位)id等当用户查看待办列表时,后台根据用户的id查询角色id,然后用角色id替换managers即可查询到对应的任务列表*/List<Task> tasks = taskService.createTaskQuery().taskCandidateGroup("managers").list();//8.经理处理审批任务//实际一般为用户在web前端页面的待办任务列表,此处演示为控制台输入输出人机交互System.out.println("You have " + tasks.size() + " tasks:");for (int i=0; i<tasks.size(); i++) {System.out.println((i+1) + ") " + tasks.get(i).getName());}System.out.println("Which task would you like to complete?");//8.1 选择要处理的任务//此处一般为web前端页面,点击“同意”或“驳回”的按钮,同意为"y",驳回为"n"int taskIndex = Integer.valueOf(scanner.nextLine());Task task = tasks.get(taskIndex - 1);//使用任务Id获取特定流程实例的变量Map<String, Object> processVariables = taskService.getVariables(task.getId());System.out.println(processVariables.get("employee") + " wants " +processVariables.get("nrOfHolidays") + " of holidays. Do you approve this?");//8.2 编写任务处理意见,并进行approved or rejected的操作//此处一般为web前端页面,点击“同意”或“驳回”的按钮,同意为"y",驳回为"n"boolean approved = scanner.nextLine().toLowerCase().equals("y");//8.3 完成任务//此处代码一般写在web后端,接收到前端的同意或驳回的参数,完成任务variables = new HashMap<String, Object>();variables.put("approved", approved);//注意先保存意见,再完成任务,否则任务完成后找不到if (approved){Comment comment = taskService.addComment(task.getId(), processInstance.getProcessInstanceId(), "同意休假");comment.setUserId("manager");taskService.saveComment(comment);}else{Comment comment = taskService.addComment(task.getId(), processInstance.getProcessInstanceId(), "不允许休假");comment.setUserId("manager");taskService.saveComment(comment);}taskService.complete(task.getId(), variables);//9.申请人查询待办事务/*并如下所示为第二个任务添加assignee属性。请注意我们没有像上面的’managers’一样使用静态值,而是使用一个流程变量动态指派。这个流程变量是在流程实例启动时传递的:<userTask id="holidayApprovedTask" name="Holiday approved" flowable:assignee="${employee}"/>*///注意发起流程时的employee,最好为申请人或者审批人的id或其他唯一字段tasks = taskService.createTaskQuery().taskAssignee(employee).list();//10.申请人处理休假任务System.out.println("You have " + tasks.size() + " tasks:");for (int i=0; i<tasks.size(); i++) {System.out.println((i+1) + ") " + tasks.get(i).getName());}if (tasks.size() > 0){System.out.println("Which task would you like to complete?");//10.1 选择要处理的任务taskIndex = Integer.valueOf(scanner.nextLine());task = tasks.get(taskIndex - 1);//使用任务Id获取特定流程实例的变量processVariables = taskService.getVariables(task.getId());System.out.println("Hi " + processVariables.get("employee") + "please use your holidays !");//10.2 完成任务variables = new HashMap<String, Object>();Comment comment1 = taskService.addComment(task.getId(), processInstance.getProcessInstanceId(), processVariables.get("employee") + "休假中");comment1.setUserId("employe");taskService.saveComment(comment1);taskService.complete(task.getId(), variables);}//展示审批意见List<Comment> taskComments = taskService.getProcessInstanceComments(processInstance.getProcessInstanceId());for (Comment comment:taskComments){System.out.println("审批人:"+comment.getUserId()+ ",审批意见:" + comment.getFullMessage() + ",审批时间:" + comment.getTime());}//展示流程流转的历史记录/*HistoryService historyService = processEngine.getHistoryService();List<HistoricActivityInstance> activities =historyService.createHistoricActivityInstanceQuery().processInstanceId(processInstance.getId()).finished().orderByHistoricActivityInstanceEndTime().asc().list();for (HistoricActivityInstance activity : activities) {System.out.println(activity.getActivityId() + " took "+ activity.getDurationInMillis() + " milliseconds");}*/}
}
(2)CallExternalSystemDelegate类为Enter holidays in external system事件的执行类
package com.example.flowable.holiday;import org.flowable.engine.delegate.DelegateExecution;
import org.flowable.engine.delegate.JavaDelegate;public class CallExternalSystemDelegate implements JavaDelegate {@Overridepublic void execute(DelegateExecution delegateExecution) {System.out.println("Calling the external system for employee "+ delegateExecution.getVariable("employee"));}
}
(3)SendRejectionMail类为Send out rejection email事件的执行类
ackage com.example.flowable.holiday;import org.flowable.engine.delegate.DelegateExecution;
import org.flowable.engine.delegate.JavaDelegate;public class SendRejectionMail implements JavaDelegate {@Overridepublic void execute(DelegateExecution delegateExecution) {System.out.println("send e-mail to employee "+ delegateExecution.getVariable("employee"));}
}
源码下载地址:
https://download.csdn.net/download/juligang320/22333758?spm=1001.2014.3001.5501
3.测试
启动HolidayRequest类进行测试,控制台日志如下:
Found process definition : Holiday Request
Who are you?
john
How many holidays do you want to request?
2
Why do you need them?
go to ...You have 3 tasks:
1) Approve or reject request
2) Approve or reject request
3) Approve or reject request
Which task would you like to complete?
3john wants 2 of holidays. Do you approve this?
yCalling the external system for employee johnYou have 1 tasks:
1) Holiday approved
Which task would you like to complete?
1Hi johnplease use your holidays !审批人:employe,审批意见:john休假中,审批时间:Thu Sep 09 15:13:51 CST 2021
审批人:manager,审批意见:同意休假,审批时间:Thu Sep 09 15:13:47 CST 2021
4 说明
一般工作流使用的是web方式,web前端页面输入,后端进行逻辑处理并输出到前端页面展示。HolidayRequest类中的demo,输入采用scanner,控制台代替web前端页面。
以上列子主要参考一下文档:
flowable官方手册:https://tkjohn.github.io/flowable-userguide/
欢迎交流!
工作流:一文让你学会使用flowable工作流相关推荐
- 项目集成Flowable工作流
企业级项目集成Flowable工作流,基于(师父)的开源项目的集成,此开源项目是师傅十几年的经验和实战总结而成,直接可以用于企业开发,旨为帮助更多需要帮助的人! 说明 链接 项目开原地址 https: ...
- flowable工作流的使用
flowable工作流相关概念和ui图的使用: flowable工作流里面有几个比较重要的概念. 其中就是一个使用processEngine对象, processEngine对象可以调用flowabl ...
- flowable工作流技术学习
一.flowable工作流引擎中文文档 Flowable BPMN 用户手册 (v 6.3.0) 这个文档内容太多,稍微看看就好,具体学习还得从demo里面去学习. 二.flowable项目下载地址与 ...
- Flowable工作流实战快速入门(一)
文章目录 1. 工作流入门介绍 1.1 什么是工作流? 1.2 工作流的原理 1.3 BPM 1.4 BPMN 1.5 Activiti 还是flowable? 2. flowable入门helloW ...
- Flowable工作流入门
Flowable工作流入门 本文链接:https://blog.csdn.net/qq_37059838/article/details/83576097 原作者:吕小小布 下载地址:Flowable ...
- 一文带你学会linux系统 史上最全linux命令大全
一文带你学会linux系统 史上最全linux命令大全 文章目录 linux系统简介 linux命令 1.启动网络命令 2.pwd命令 2.ls命令 3.cd命令 4.mkdir命令 5.rmdir命 ...
- Flowable工作流引擎
Flowable工作流引擎 Flowable-基础篇(根据BV1Pb4y1p7Ku整理) 一.简介 Flowable是BPMN的一个基于java的软件实现,不过Flowable不仅仅包括BPMN,还有 ...
- 初识flowable工作流-实现简单请假流程SpringBoot+VUE
一.前言 大家好,因为目前手里需要用到flowable工作流,之前没有接触过,所以在这里记录一下学习的进度,开始后台使用SpringCloud分布式框架和前端Vue框架实现一个简单的请假流程. 二.代 ...
- SpringBoot整合Flowable工作流引擎框架
Flowable工作流引擎框架介绍 一个Java编写的轻量级业务流程引擎,为开发人员.系统管理员和业务用户提供工作流和业务流程管理(BPM)平台. 不仅包括BPMN,还有DMN决策表和CMMN Cas ...
- 为什么要使用flowable工作流
为什么使用flowable工作流 1.在使用工作流之前 通常我们的处理方式是状态驱动方式(数据库与中设置Status字段). 痛点: 一方面:整个流程定义不够清晰.业务流程是分散在各个业务阶段中的,从 ...
最新文章
- 利用systemd 实现 tomcat 多实例
- gdb 设置一个函数, 出现4个断点的原因
- html text width,HTML5 Text Canvas rotate in case text width is larger than maximum width allowed
- Linux - 修改Cent OS系统的的hostname、配置DNS映射
- scale 和 transform-origin 实现线条从左侧进入,右侧离开效果
- mysql update nowait_mysql innodb之select for update nowait
- 诺基亚是“不跟随”还是跟不上?
- 【英语学习】【English L06】U02 Food L3 Peking roast duck
- Mac安装telnet
- arm9处理器 java_ARM处理器系列介绍
- 微信小程序 之wx.previewImage图片预览(单张图片预览)
- android手机截屏代码,Android手机截屏代码
- 短网址还原 php,php简单实现短网址(短链)还原的方法(测试可用)
- CODING 携手 Thoughtworks 助力老百姓大药房打造”自治、自决、自动”的敏捷文化
- WPF自定义日期时间控件
- 当年明月 Vs. 阎崇年
- 展厅设计全面优化企业形象,取得客户的信任为合作打下良好的基础
- 电弧故障保护装置的产能、产量、销量、销售额、价格及未来趋势
- 从计算机移桌面文件转件到硬盘,win10系统如何将桌面文件转移到其他磁盘?
- tta部署_TTA、丰源轮胎云平台项目战略合作交接仪式