1.请假流程图

2.工作流文件
holiday-request.bpmn20.xml
<definitions xmlns="http://www.omg.org/spec/BPMN//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//DI" xmlns:omgdc="http://www.omg.org/spec/DD//DC" xmlns:omgdi="http://www.omg.org/spec/DD//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"> ${approved}
conditionExpression>
sequenceFlow> <sequenceFlow sourceRef="decision" targetRef="sendRejectionMail"> <conditionExpression xsi:type="tFormalExpression"> ${!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. 此类描述的是:测试demo 2. 参考flowable手册https://tkjohn.github.io/flowable-userguide/ 3. @author juge 4. @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("") .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属性:
这里的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’一样使用静态值,而是使用一个流程变量动态指派。这个流程变量是在流程实例启动时传递的:
*/ //注意发起流程时的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
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 {
@Override public 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 {
@Override public void execute(DelegateExecution delegateExecution) {
System.out.println("send e-mail to employee " + delegateExecution.getVariable("employee")); } }
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? 3 john wants 2 of holidays. Do you approve this? y Calling the external system for employee john You have 1 tasks: 1) Holiday approved Which task would you like to complete? 1 Hi 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前端页面。
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/212363.html原文链接:https://javaforall.net
