Springboot +Flowable,会签、或签简单使用(二)

news2024/11/28 2:51:07

一.简介

**会签:**在一个流程中的某一个 Task 上,这个 Task 需要多个用户审批,当多个用户全部审批通过,或者多个用户中的某几个用户审批通过,就算通过。
例如:之前的请假流程,假设这个请假流程需要组长和经理都审批了,才算审批通过,那么就需要设置这个 Task 是会签节点。

**或签:**意思就是 A 的请假流程提交给 B、C、D,但是并不需要 B/C/D 同时审批通过,只需要 B/C/D 中的任意一个审批即可,这就是或签,注意,我这里的表述,只需要 B/C/D 任意一个审批即可,这个审批即可以是审批通过,也可以是审批拒绝,反正只要审批,这个 UserTask 就算完成了。

二.会签流程图

首先来画一下这个请假流程图,这个流程图基本上还是和之前的一样,截图如下:
在这里插入图片描述

三.请假处理

1.前端提交请假流程

接下来看下前端如何提交请假申请,页面如下:
在这里插入图片描述
对应的 HTML 代码如下:

<h1>提交请假申请</h1>
<table>
    <tr>
        <td>请输入请假天数:</td>
        <td>
            <el-input type="text" v-model="afl.days"/>
        </td>
    </tr>
    <tr>
        <td>请输入请假理由:</td>
        <td>
            <el-input type="text" v-model="afl.reason"/>
        </td>
    </tr>
    <tr>
        <td>审批人:</td>
        <td>
            <el-select v-model="afl.approveUsers" style="width: 226px" placeholder="请选择审批人" multiple>
                <el-option
                        v-for="item in users"
                        :key="item.id"
                        :label="item.username"
                        :value="item.username"/>
            </el-select>
        </td>
    </tr>
</table>
<el-button type="primary" @click="submit">提交请假申请</el-button>

跟之前不同的是,这里的下拉框是多选的,当用户提交请假申请的时候,可以选择多个审批人,多个审批人的值将保存在 afl.approveUsers 变量中。
再来看提交请假方法,代码如下:

submit() {
    let _this = this;
    axios.post('/ask_for_leave', this.afl)
        .then(function (response) {
            if (response.data.status == 200) {
                //提交成功
                _this.$message.success(response.data.msg);
                _this.search();
            } else {
                //提交失败
                _this.$message.error(response.data.msg);
            }
        })
        .catch(function (error) {
            console.log(error);
        });
},

请求的参数截图如下:
在这里插入图片描述
看下这里提交的三个请求参数:

  1. approveUsers:这是审批当前流程的三个用户,当这三个用户都审批通过后,请假流程就通过了。
  2. days:这是请假的天数。
  3. reason:这是请假理由。

2.服务端处理请假请求

服务端如何处理这个请假请求,代码如下:

@Transactional
public RespBean askForLeave(AskForLeaveVO askForLeaveVO) {
    Map<String, Object> variables = new HashMap<>();
    askForLeaveVO.setName(SecurityContextHolder.getContext().getAuthentication().getName());
    variables.put("name", askForLeaveVO.getName());
    variables.put("days", askForLeaveVO.getDays());
    variables.put("reason", askForLeaveVO.getReason());
    variables.put("userTasks", askForLeaveVO.getApproveUsers());
    try {
        runtimeService.startProcessInstanceByKey("holidayRequest", askForLeaveVO.getName(), variables);
        return RespBean.ok("已提交请假申请");
    } catch (Exception e) {
        e.printStackTrace();
    }
    return RespBean.error("提交申请失败");
}

可以看到,从前端一共传递过来三个参数,但是执行这个流程需要四个参数,其中一个 name 表示当前登录的用户名,也就是这个请假是谁发起的。另外三个参数就是前端传来的参数。

3.服务端返回待审批数据

接下来看下服务端如何返回待审批数据,代码如下:

/**
 *待审批列表
 */
public RespBean leaveList() {
    String identity = SecurityContextHolder.getContext().getAuthentication().getName();
    //找到所有分配给你的任务
    List<Task> tasks = taskService.createTaskQuery().taskAssignee(identity).list();
    //重新组装返回的数据,为每个流程增加任务 id,方便后续执行批准或者拒绝操作
    List<Map<String, Object>> list = new ArrayList<>();
    for (int i = 0; i < tasks.size(); i++) {
        Task task = tasks.get(i);
        Map<String, Object> variables = taskService.getVariables(task.getId());
        variables.put("id", task.getId());
        list.add(variables);
    }
    return RespBean.ok("加载成功", list);
}

页面如下:
在这里插入图片描述
这个整体上分了两步:

  1. 首先查询出来当前用户所有待审批的 Task。
  2. 查询出来这些 Task 上的 variables,这是一个 Map 集合,然后我们再手动加上 id 这个参数。
    最后将组装好的 list 弄成一个 JSON 返回即可。

4.服务端批准 OR 拒绝

服务端批准或者拒绝请假流程,代码如下:

public RespBean askForLeaveHandler(ApproveRejectVO approveRejectVO) {
    try {
        Task task = taskService.createTaskQuery().taskId(approveRejectVO.getTaskId()).singleResult();
        boolean approved = approveRejectVO.getApprove();
        Map<String, Object> variables = new HashMap<String, Object>();
        variables.put("approved", approved);
        variables.put("approveUser#" + task.getAssignee(), SecurityContextHolder.getContext().getAuthentication().getName());
        taskService.complete(task.getId(), variables);
        return RespBean.ok("操作成功");
    } catch (Exception e) {
        e.printStackTrace();
    }
    return RespBean.error("操作失败");
}

批准或者拒绝,最主要的参数就是 approved,true 表示批准,false 表示拒绝。

另一方面,由于现在是会签,我们需要知道目前谁已经审批了,谁还没审批,所以这里额外多加了一个参数 approveUser#XXX,表示审批这个节点的用户名(也就是当前登录用户)。

注意这个参数的 key 我没有固定,主要是因为这个节点会有多个人审批,如果固定的话,后面审批的人会覆盖掉前面的人,所以这个节点的 key 设置成动态的了,approveUser# 后面加上处理这个节点的用户名。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/533253.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[iOS]消息传递和消息转发

消息转发和消息传递 消息转发 iOS的消息转发是指当一个对象收到一个无法响应的消息时&#xff0c;其会通过多个方法转发该消息&#xff0c;直到能够响应为止。具体来说&#xff0c;当消息接收者无法响应某个方法时&#xff0c;Objective-C消息传递机制会按照以下顺序进行转发…

路径规划算法:基于绯鲵鲣算法的路径规划算法- 附代码

路径规划算法&#xff1a;基于绯鲵鲣优化的路径规划算法- 附代码 文章目录 路径规划算法&#xff1a;基于绯鲵鲣优化的路径规划算法- 附代码1.算法原理1.1 环境设定1.2 约束条件1.3 适应度函数 2.算法结果3.MATLAB代码4.参考文献 摘要&#xff1a;本文主要介绍利用智能优化算法…

java读取word文档内容

首先在pom文件引入依赖&#xff1a; <dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>4.0.0</version> </dependency> <dependency><groupId>org.apache.poi</groupId&g…

Databend 开源周报第 93 期

Databend 是一款现代云数仓。专为弹性和高效设计&#xff0c;为您的大规模分析需求保驾护航。自由且开源。即刻体验云服务&#xff1a;https://app.databend.cn 。 Whats On In Databend 探索 Databend 本周新进展&#xff0c;遇到更贴近你心意的 Databend 。 改进 Databend …

冠珠华珍岩板闪现人民日报美好博物馆,彰显民族品牌魅力

行业唯一&#xff01;亮相美好博物馆 一块为中国品牌发声 为了贯彻落实品牌强国战略&#xff0c;展现中国优秀品牌成果&#xff0c;5月10日&#xff0c;值第7个中国品牌日来临之际&#xff0c;由人民日报社特别打造的美好博物馆主题快闪店惊艳亮相上海世博展览中心。 作为连…

【 LoRa规范及认证】

文章目录 LoRa规范及认证一、LoRaWAN全球区域规范1.美国规范2.中国规范 二、LoRaWAN认证1.LoRaWAN认证常见问题 三、中国LoRa无线电规范四、小结 LoRa规范及认证 ​ 在使用LoRa设备时&#xff0c;必须遵循各区域无线电管理规范&#xff0c;尤其是工作频率、输出功率、占空比这…

万字长文 | ChatGPT的工作原理(二)

— 6 — 嵌入的概念 神经网络 —— 至少在它们目前的设置中 —— 从根本上说是基于数字的。因此&#xff0c;如果我们要用它们来处理像文本这样的东西&#xff0c;我们就需要一种方法来用数字表示我们的文本。 当然&#xff0c;我们可以开始&#xff08;基本上就像 ChatGPT 那…

Java基础面试题突击1

&#x1f469;&#x1f3fb; 作者&#xff1a;一只IT攻城狮 &#xff0c;关注我不迷路 ❤️《java面试核心知识》突击系列&#xff0c;持续更新… &#x1f490; 面试必知必会学习路线&#xff1a;Java技术栈面试系列SpringCloud项目实战学习路线 &#x1f4dd;再小的收获*365天…

物流管理系统对电商的重要性,零代码技术起关键性作用

什么是物流管理系统 物流管理系统是一种软件系统&#xff0c;用于管理和协调货物的移动。它涵盖了物流计划、物流执行、物流跟踪和数据分析等方面&#xff0c;可以帮助企业优化供应链&#xff0c;提高运营效率和客户满意度。它包括了仓储管理、配送管理、运输管理、订单管理、…

编织数据结构的艺术:双向带头循环链表的华丽实现

上一篇博客&#xff0c;我们了解并实现了单向不带头不循环链表&#xff0c;而本篇博客会讲解链表中的王者&#xff1a;双向带头循环链表。 概述 双向带头循环链表的特点是&#xff1a; 每个结点内部&#xff0c;既有指向上一个结点的前驱指针prev&#xff0c;也有指向下一个…

《C++入门攻略》(小白向)

函数 函数、输入、传参 在程序中使用函数时&#xff0c;你必须先声明它然后再定义声明的目的是告诉编译器你即将要定义的函数的名字是什么&#xff0c;返回值的类型是什么以及参数是什么而定义则是告诉编译器这个函数的功能是什么。假如我们不声明&#xff0c;那么该函数就不能…

vue快速上手教程与简单安装

目录 vue简介 vue实例 通过 CDN 使用 Vue NPM 方法 介绍 下载 使用 vue简介 Vue.js 是一套构建用户界面的渐进式框架。 Vue 只关注视图层&#xff0c; 采用自底向上增量开发的设计。 Vue 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。 vue实例…

ping包过程之arp(地址解析协议)

0,怎么引出arp地址解析协议的呢&#xff1f; 在硬件层次上进行的数据帧交换必须有正确的接口地址&#xff08;既是MAC地址&#xff09;。但是&#xff0c; T C P / I P有自己的地址&#xff1a; 32 bit的I P地址。知道主机的 I P地址并不能让内核发送一帧数据给主机。内核&…

二十、Zipkin持久化链路跟踪

目录 Zipkin持久化 使用mysql数据库持久化 1、创建zipkin数据库 2、启动zipkin使用以下脚本 3、访问接口&#xff08;配置了sleuth链路跟踪&#xff09; 使用ElasticSearch持久化 zipkin启动脚本 Zipkin持久化 Zipkin server默认会将追踪数据信息保存在内存中&#xff0…

NoSQL之Redis配置与数据库常用命令

目录 一、关系型数据库与非关系型数据库概述1.1 关系型数据库1.2 非关系型数据库 二、关系型数据库与非关系型数据库的区别2.1 数据的存储方式不一样2.2 扩展的方式不同2.3 对事务性的支持不同 三、非关系型数据库产生背景四、Redis简介4.1 Redis的单线程模式4.2 Redis优点4.3 …

B2B 客户支持,如何做好?

多年来&#xff0c;基于尖端技术的现代和个性化客户体验一直主导着企业对消费者&#xff08;B2C&#xff09;领域。然而&#xff0c;在企业对企业&#xff08;B2B&#xff09;行业中&#xff0c;出色的客户体验变得比以往任何时候都更加重要。许多组织正在开发类似于B2C市场中个…

无延迟直播/超低延迟直播快速接入的示例

简要说明 接入无延迟直播/超低延迟直播播放前&#xff0c;需确保直播间频道是无延迟频道&#xff0c;SDK中使用无延迟与常规播放无异&#xff0c;只需加入若干配置就可以快速接入。 什么是无延迟/超低延迟直播&#xff0c;可参见我的这篇文章&#xff1a; 无延时直播/超低延时…

Java 基础进阶篇(十四)—— File类常用方法

File 类的对象代表操作系统的文件&#xff08;文件、文件夹&#xff09;&#xff0c;File 类在 java.io.File 包下。 File 类提供了诸如&#xff1a;创建文件对象代表文件&#xff0c;获取文件信息&#xff08;大小、修改时间&#xff09;、删除文件、创建文件&#xff08;文件…

【软件测试与质量保证】期末复习2(HITWH)(软件测试部分)

更多复习资料在下方链接获取&#xff1b;包括复习笔记&#xff08;有具体习题&#xff09;、习题答案以及设计题示例 链接&#xff1a;复习资料 复习笔记里的习题不包含答案&#xff0c;具体答案在【云班课答案】文件夹中&#xff0c;顺序都是一一对应的&#xff0c;喜欢刷题可…

进程间通信之管道篇

&#x1f3c6;一、进程间通信目的 1.1什么是通信 进程是具有独立性的&#xff0c;而我们要实现进程间通信的目标&#xff0c;是需要开辟空间和创造方法的。 通信目的&#xff1a; 1、数据传输&#xff1a;一个进程需要将它的数据发送给另一个进程 2、资源共享&#xff1a;…