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工作流相关推荐

  1. 项目集成Flowable工作流

    企业级项目集成Flowable工作流,基于(师父)的开源项目的集成,此开源项目是师傅十几年的经验和实战总结而成,直接可以用于企业开发,旨为帮助更多需要帮助的人! 说明 链接 项目开原地址 https: ...

  2. flowable工作流的使用

    flowable工作流相关概念和ui图的使用: flowable工作流里面有几个比较重要的概念. 其中就是一个使用processEngine对象, processEngine对象可以调用flowabl ...

  3. flowable工作流技术学习

    一.flowable工作流引擎中文文档 Flowable BPMN 用户手册 (v 6.3.0) 这个文档内容太多,稍微看看就好,具体学习还得从demo里面去学习. 二.flowable项目下载地址与 ...

  4. Flowable工作流实战快速入门(一)

    文章目录 1. 工作流入门介绍 1.1 什么是工作流? 1.2 工作流的原理 1.3 BPM 1.4 BPMN 1.5 Activiti 还是flowable? 2. flowable入门helloW ...

  5. Flowable工作流入门

    Flowable工作流入门 本文链接:https://blog.csdn.net/qq_37059838/article/details/83576097 原作者:吕小小布 下载地址:Flowable ...

  6. 一文带你学会linux系统 史上最全linux命令大全

    一文带你学会linux系统 史上最全linux命令大全 文章目录 linux系统简介 linux命令 1.启动网络命令 2.pwd命令 2.ls命令 3.cd命令 4.mkdir命令 5.rmdir命 ...

  7. Flowable工作流引擎

    Flowable工作流引擎 Flowable-基础篇(根据BV1Pb4y1p7Ku整理) 一.简介 Flowable是BPMN的一个基于java的软件实现,不过Flowable不仅仅包括BPMN,还有 ...

  8. 初识flowable工作流-实现简单请假流程SpringBoot+VUE

    一.前言 大家好,因为目前手里需要用到flowable工作流,之前没有接触过,所以在这里记录一下学习的进度,开始后台使用SpringCloud分布式框架和前端Vue框架实现一个简单的请假流程. 二.代 ...

  9. SpringBoot整合Flowable工作流引擎框架

    Flowable工作流引擎框架介绍 一个Java编写的轻量级业务流程引擎,为开发人员.系统管理员和业务用户提供工作流和业务流程管理(BPM)平台. 不仅包括BPMN,还有DMN决策表和CMMN Cas ...

  10. 为什么要使用flowable工作流

    为什么使用flowable工作流 1.在使用工作流之前 通常我们的处理方式是状态驱动方式(数据库与中设置Status字段). 痛点: 一方面:整个流程定义不够清晰.业务流程是分散在各个业务阶段中的,从 ...

最新文章

  1. 利用systemd 实现 tomcat 多实例
  2. gdb 设置一个函数, 出现4个断点的原因
  3. html text width,HTML5 Text Canvas rotate in case text width is larger than maximum width allowed
  4. Linux - 修改Cent OS系统的的hostname、配置DNS映射
  5. scale 和 transform-origin 实现线条从左侧进入,右侧离开效果
  6. mysql update nowait_mysql innodb之select for update nowait
  7. 诺基亚是“不跟随”还是跟不上?
  8. 【英语学习】【English L06】U02 Food L3 Peking roast duck
  9. Mac安装telnet
  10. arm9处理器 java_ARM处理器系列介绍
  11. 微信小程序 之wx.previewImage图片预览(单张图片预览)
  12. android手机截屏代码,Android手机截屏代码
  13. 短网址还原 php,php简单实现短网址(短链)还原的方法(测试可用)
  14. CODING 携手 Thoughtworks 助力老百姓大药房打造”自治、自决、自动”的敏捷文化
  15. WPF自定义日期时间控件
  16. 当年明月 Vs. 阎崇年
  17. 展厅设计全面优化企业形象,取得客户的信任为合作打下良好的基础
  18. 电弧故障保护装置的产能、产量、销量、销售额、价格及未来趋势
  19. 从计算机移桌面文件转件到硬盘,win10系统如何将桌面文件转移到其他磁盘?
  20. tta部署_TTA、丰源轮胎云平台项目战略合作交接仪式

热门文章

  1. word java api_Java中的Word文档创建API
  2. 笔记本装机软件+网站大合集+磁盘管理
  3. 信息系统项目管理师进度管理论文范例
  4. SIM800(GPRS)拨号上网失败未能连接服务器
  5. 特征选择 | MATLAB实现特征变量相关性系数图和显著性检验
  6. 下载Python OpenCV相关资料方法整理
  7. 解决cmd命令行乱码问题
  8. 微信小程序+springboot+shiro实现登录
  9. 傅里叶变换与希尔伯特变换
  10. C++二叉树的 前中后序遍历(学C++必看必会)深度优先遍历详解