当前位置: 首页 > news >正文

SpringBoot+Flowable快速实现工流_动态选择审批人员

前言

OA系统中的工作流不仅是企业日常运营的重要组成部分,也是实现企业数字化转型、提高工作效率和执行力的重要工具。 在国内大部分的工作流系统使用Activiti框架实现。 其实flowable也可以轻松实现工作流业务。在线体验JeecgFlow

flowable简介

Flowable是一个使用Java编写的轻量级业务流程引擎。它主要用于部署BPMN 2.0流程定义(一种用于定义流程的行业XML标准),创建这些流程定义的流程实例,进行查询,访问运行中或历史的流程实例与相关数据等。Flowable流程引擎的特点包括灵活性和可扩展性,提供了图形化的流程设计器,可以与规则引擎集成,支持多种执行环境,并且可以轻易地加入任何Java环境。

版本信息

Flowable 6.7.2

SpringBoot 2.7.12

SpringBoot整合flowable

maven依赖

<flowable.spring-boot.version>6.7.2</flowable.spring-boot.version<dependency><groupId>org.flowable</groupId><artifactId>flowable-spring-boot-starter</artifactId><version>${flowable.spring-boot.version}</version><exclusions><exclusion><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId></exclusion></exclusions>
</dependency>

配置

flowable:#关闭定时任务JOBasync-executor-activate: false#将databaseSchemaUpdate设置为true。当flowable发现库与数据库表结构不一致时,会自动将数据库表结构升级至新版本。database-schema-update: true# 自动部署验证设置:true-开启(默认)、false-关闭check-process-definitions: false#保存历史数据级别设置为full最高级别,便于历史数据的追溯history-level: full

简单两步,就可以启动boot应用。初次运行时flowable会将自动执行flowable中的初始化脚本完成工作流所需要的数据表的建立,如果指定的数据库中还未创建过flowable的相关数据表的话。

流程定义

假设现在有一个请假需求,用户提交申请表单后, 直属领导进行审批操作。 可以是通过或拒绝。并且要求不同部门的人员绑定所属的领导。 Bpmn在线建模

在这里插入图片描述

申请节点,定义用户提交数据的字段

在这里插入图片描述

申请节点, 设置了任务完成后的监听器。用于动态设置审批领导的名称。

在这里插入图片描述

直属领导申请的节点属性设置。

xml内容

<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_1" targetNamespace="http://bpmn.io/schema/bpmn"><bpmn:process id="Process_choose_leader" name="动态审批" isExecutable="true"><bpmn:startEvent id="StartEvent_1"><bpmn:outgoing>Flow_09w75kg</bpmn:outgoing></bpmn:startEvent><bpmn:sequenceFlow id="Flow_09w75kg" sourceRef="StartEvent_1" targetRef="Activity_1xn21s1" /><bpmn:userTask id="Activity_1xn21s1" name="申请" camunda:assignee="${general}"><bpmn:extensionElements><camunda:formData><camunda:formField id="days" label="请假天数" type="long" defaultValue="1" /><camunda:formField id="reason" label="请假理由" type="string" /><camunda:formField id="type" label="请假类型" type="string" /></camunda:formData><camunda:taskListener delegateExpression="${chooseLeaderListener}" event="complete" /></bpmn:extensionElements><bpmn:incoming>Flow_09w75kg</bpmn:incoming><bpmn:outgoing>Flow_1n7z9g2</bpmn:outgoing></bpmn:userTask><bpmn:sequenceFlow id="Flow_1n7z9g2" sourceRef="Activity_1xn21s1" targetRef="Activity_0474tsq" /><bpmn:userTask id="Activity_0474tsq" name="直属领导" camunda:assignee="${leader}"><bpmn:extensionElements><camunda:formData><camunda:formField id="comment" label="评论" type="string" /><camunda:formField id="imageUrl" label="图片" type="string" /></camunda:formData></bpmn:extensionElements><bpmn:incoming>Flow_1n7z9g2</bpmn:incoming><bpmn:outgoing>Flow_1lyuw6k</bpmn:outgoing></bpmn:userTask><bpmn:endEvent id="Event_10twye6"><bpmn:incoming>Flow_1lyuw6k</bpmn:incoming></bpmn:endEvent><bpmn:sequenceFlow id="Flow_1lyuw6k" sourceRef="Activity_0474tsq" targetRef="Event_10twye6" /></bpmn:process></bpmn:definitions>

代码编写

开始流程

@ApiOperation(value = "发起请假", notes = "提交请假的数据")
@PostMapping("start")
public Result<?> start(@RequestBody LeaveStartReq leaveStartReq) {log.info("start.leaveStartReq:{}", leaveStartReq);ValidatorUtils.validateEntity(leaveStartReq);//查询登陆用户String id = SecurityContextHolder.getContext().getAuthentication().getName();User loginUser = userService.getById(id);//发起流程并初始化各个用户任务节点的指定人Authentication.setAuthenticatedUserId(Optional.ofNullable(loginUser).map(m -> m.getUsername()).orElse("xxx"));Map<String, Object> variables = new HashMap<>(4);variables.put("general", Optional.ofNullable(loginUser).map(m -> m.getUsername()).orElse("mark"));ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(FlowConstant.MODEL_KEY_LEAVE, variables);//执行一个申请节点的动作userTaskService.completeApplyUserTask(processInstance.getId(), loginUser, leaveStartReq);return Results.newSuccessResult(processInstance.getId());
}

以上逻辑就是发起流程, 核心步骤就是获取登陆用户信息,并且设置流程启动参数。 在流程启动后完成第一个用户任务节点。此时流程便可以往下面流转。

完成申请任务的监听事件

@Component("chooseLeaderListener")
@Slf4j
public class ChooseLeaderListener implements TaskListener {@Autowiredprivate ISysBaseAPI sysBaseAPI;@Overridepublic void notify(DelegateTask delegateTask) {log.info("动态选择下一个用户任务节点审批人员监听器");//查询发起用户所属的部门Id集合String startUser = String.valueOf(delegateTask.getVariable("general"));List<String> myDeptIds = sysBaseAPI.getDepartIdsByUsername(startUser);//根据部门id查询负责人List<String> leaderList = new ArrayList<>();for (String myDeptId : myDeptIds) {leaderList.addAll(sysBaseAPI.getDeptHeadByDepId(myDeptId));}log.info("直属部门领导人员:{}", leaderList);//设置下一个审批节点的用户名称,注意如何是有多个领导需要同时审批,要把审批节点设置为多实例。if(CollectionUtil.isNotEmpty(leaderList)){delegateTask.setVariable("leader", leaderList.get(0));}}
}

在上一步申请节点完成后,将执行任务监听起逻辑,查询到下一个节点的审批用户名称。并且绑定到leader流程变量。此时便可以实现不同部门有不同领导。

审批通过

public void pass(PassReq passReq, User loginUser) {Task task = taskService.createTaskQuery().processInstanceId(passReq.getProcessInstanceId()).taskAssignee(loginUser.getUsername()).singleResult();//完成用户任务Map<String, Object> map = new HashMap<>(12);map.put("comment", passReq.getContent());map.put("imageUrl", imageUrl);taskService.complete(task.getId(), map);
}

审批通过操作的核心逻辑。 驳回就留给大家自己研究了。

运行效果的图

在这里插入图片描述

通过Springboot+flowable就是这么简单, 在线体验JeecgFlow


http://www.mrgr.cn/news/78681.html

相关文章:

  • 【Spring框架 二】
  • CSAPP Cache Lab(缓存模拟器)
  • 111.有效单词
  • Unity3d C# 摄像头检测敌方单位(目标层级)并在画面中标注(含源码)
  • mybatis plus如何使用mybatis xml拼接sql
  • 力扣--LCR 149.彩灯装饰记录I
  • 腾讯阅文集团Java后端开发面试题及参考答案
  • C++ STL 容器系列(三)list —— 编程世界的万能胶,数据结构中的百变精灵
  • MATLAB —— 机械臂工作空间,可达性分析
  • springboot学习-spring-boot-data-jdbc分页/排序/多表查询的例子
  • 点云处理中obb算法原理和法向量求解方法
  • PVE中VLAN的设置要点
  • 第十六届蓝桥杯模拟赛第二期题解—Java
  • 11 设计模式之代理模式(送资料案例)
  • 「Mac畅玩鸿蒙与硬件38」UI互动应用篇15 - 猜数字增强版
  • 2024前端面试经验分享
  • 【大模型实战篇】基于大模型GLM的Function Call实践
  • SQL进阶技巧:如何寻找同一批用户 | 断点分组应用【最新面试题】
  • 12 设计模式之工厂方法模式
  • 二叉搜索树讲解
  • 【C++笔记】位图和布隆过滤器
  • 开发一套ERP 第九弹 前后整合
  • burp2
  • 五:OpenStack环境准备-compute node
  • 芯片测试-射频中的单位
  • 腾讯阅文集团Android面试题及参考答案