芋道-------如何实现工作流退回后重新提交到之前退回的节点

一、概述

      上一节,我们讲过了工作流如何退回到申请人,接下来我们来讲一讲,如何重新提交。这里重新提交可以是再走一遍正常流程,同时也可以是直接跳过中间的步骤,直接继续给上一步退回的人审批。文章中会提及这两种情况。

       首先,我们可以看到,在芋道的工作流中有一个好处是在业务表中与工作流关联起来了,同时也为当前的状态设置了单独的字段。所以这样我们能很容易的判断出来,当前节点处于什么状态。

二、逻辑梳理

    思路如下:首先在流程详情页面中,判断当前的节点的上一个节点是什么状态,然后拿到退回节点的状态,因为下一步我们将根据这个状态,把原本不可更改的详情页,改成可编辑的,这样用户才可以修改后重新提交。然后重新提交后,我们需要对业务表进行更新,同时需要继续启动流程。

总结:1、将task中所有任务按照时间进行排序,找到倒数第二个task即当前节点的上一个。

           2、然后判断result是否为‘5’(驳回),如果是,将标识isRerurn改成true。

           3、修改页面信息,对于申请信息,我们要考虑,何时可编辑,何时只能查看;对于审批任务何时可以显示,何时不需要显示。

           4、后台更新业务表、继续启动流程。

三、代码实现

1、判断当前节点的任务是否是被退回的

      为什么判断的是上一个节点,而不是当前节点,因为,当前节点一定是已经由上一个节点处理过后,才得到的结果。因此,我们要判断是由退回走到当前节点的还是正常流程通过走过来的。

     经过查看后台代码,发现result为5的表示的是当前任务节点是被驳回状态,同时在前台我们可以看到他已经按照时间顺序排好,因此我们只要判断数组中第二个位置的result是否为5即可,这个时候将标识isReturn设为true。

2、修改审批界面 --- 审批任务

    由于如果是重新提交,根据业务需求页面上就不需要审批任务这个模块,只留一个编辑表单信息就可以,所以这里加了条件限制,判断如果不是申请人就不显示审批任务。

3、修改审批界面 --- 申请信息组件值传递

      然后我们将 isReturn 和 runningTasks 这两个参数传到组件中,isReturn是是否是退回的标识,runningTasks是,当前登录人的任务列表。

      因为具体业务的表单信息,属于动态的,所以这里面他们引用了组件,我们需要把参数信息传到对应的表单页面,这样表单页面拿到信息,进而判断出什么时候可以编辑的,什么时候显示的。

     这里讲一下为什么传递这两个参数,首先,我们单纯的知道了什么时候退回,并不能控制住审批信息的显示和编辑,因为如果只是知道当前节点属于退回后的节点,其他人再进入到页面的时候,也会显示重新提交这个界面。

    所以我们还需要判断当前登录的人,是否是要退回到某个节点的人,在进行处理。这个时候,我们发现既有的代码中有一段runningTasks的逻辑,他其实就是将当前任务中需要登录用户处理的任务存起来,这样我们其实只要判断,这个runningTasks中是否有值即可,如果他有值,证明这个节点其实已经走到了当前登录的用户这里了,如果同时他又是退回后的节点,那么它就可以编辑该界面。

4、修改审批界面 --- 申请信息界面
<template><div class="app-container"><!-- <el-form ref="form" :model="form" label-width="100px"><el-form-item label="开始时间:" prop="startTime">{{ parseTime(form.startTime, "{y}-{m}-{d}") }}</el-form-item><el-form-item label="结束时间:" prop="endTime">{{ parseTime(form.endTime, "{y}-{m}-{d}") }}</el-form-item><el-form-item label="请假类型:" prop="type"><dict-tag :type="DICT_TYPE.BPM_OA_LEAVE_TYPE" :value="form.type" /></el-form-item><el-form-item label="原因:" prop="reason"> {{ form.reason }}</el-form-item></el-form> --><!-- 对话框(添加 / 修改) --><el-form ref="form" :model="form" label-width="100px"><el-form-item label="开始时间:" prop="startTime"><template v-if="isReturn && runningTasks.length != 0"><el-date-pickerv-model="form.startTime"type="date":editable="!isReturn"></el-date-picker></template><template v-else>{{ parseTime(form.startTime, "{y}-{m}-{d}") }}</template></el-form-item><el-form-item label="结束时间:" prop="endTime"><template v-if="isReturn && runningTasks.length != 0"><el-date-pickerv-model="form.endTime"type="date":editable="!isReturn"></el-date-picker></template><template v-else>{{ parseTime(form.endTime, "{y}-{m}-{d}") }}</template></el-form-item><el-form-item label="请假类型:" prop="type"><template v-if="isReturn && runningTasks.length != 0"><el-select v-model="form.type"><el-optionv-for="dict in typeDictData":key="parseInt(dict.value)":label="dict.label":value="parseInt(dict.value)"/></el-select></template><template v-else><dict-tag :type="DICT_TYPE.BPM_OA_LEAVE_TYPE" :value="form.type" /></template></el-form-item><el-form-item label="原因:" prop="reason"><template v-if="isReturn && runningTasks.length != 0"><el-input v-model="form.reason"></el-input></template><template v-else>{{ form.reason }}</template></el-form-item><el-form-item v-if="isReturn && runningTasks.length != 0"><el-button type="primary" @click="submitForm">重新提交</el-button></el-form-item></el-form></div>
</template><script>
import { updateLeave, getLeave } from "@/api/bpm/leave";
import { getDictDatas, DICT_TYPE } from "@/utils/dict";
export default {name: "BpmOALeaveDetail",components: {},props: {id: {type: [String, Number],default: undefined,},isReturn: {type: [Boolean],default: undefined,},runningTasks: {type: [Array],default: undefined,},},data() {return {leaveId: Number, // 请假编号// 表单参数form: {startTime: undefined,endTime: undefined,type: undefined,reason: undefined,},typeDictData: getDictDatas(DICT_TYPE.BPM_OA_LEAVE_TYPE),};},created() {this.leaveId = this.id || this.$route.query.id;if (!this.leaveId) {this.$message.error("未传递 id 参数,无法查看 OA 请假信息");return;}console.log("🚀 ~ runningTasks:",this.isReturn,this.runningTasks,this.runningTasks.length);this.getDetail();},methods: {/** 获得请假信息 */getDetail() {getLeave(this.leaveId).then((response) => {this.form = response.data;});},/** 提交按钮 */submitForm() {this.$refs["form"].validate((valid) => {if (!valid) {return;}// 添加的提交updateLeave(this.form).then((response) => {this.$modal.msgSuccess("重新提交成功!");this.$tab.closeOpenPage({ path: "/bpm/oa/leave" });});});},},
};
</script>
5、后台处理
Controller:
    @PutMapping("/update")public CommonResult<Long> updateLeave(@RequestBody BpmOALeaveUpdateReqVO updateReqVO){return success(leaveService.updateLeave(updateReqVO));}
Service :
    Long updateLeave( BpmOALeaveUpdateReqVO updateReqVO);

ServiceIml:

    public Long updateLeave(BpmOALeaveUpdateReqVO updateReqVO) {// 插入 OA 请假单long day = LocalDateTimeUtil.between(updateReqVO.getStartTime(), updateReqVO.getEndTime()).toDays();BpmOALeaveDO leave = BpmOALeaveConvert.INSTANCE.convert(updateReqVO).setUserId(SecurityFrameworkUtils.getLoginUserId()).setDay(day).setId(updateReqVO.getId()).setResult(BpmProcessInstanceResultEnum.PROCESS.getResult());leaveMapper.updateById(leave);List<BpmTaskRespVO> taskList = taskService.getTaskListByProcessInstanceId(updateReqVO.getProcessInstanceId());List<String> returnTaskKeyList = new ArrayList<>();returnTaskKeyList.add(taskList.get(0).getDefinitionKey());runtimeService.createChangeActivityStateBuilder().processInstanceId(updateReqVO.getProcessInstanceId()).moveActivityIdsToSingleActivityId(returnTaskKeyList, // 当前要跳转的节点列表( 1 或多)taskList.get(1).getDefinitionKey()) // targetKey 跳转到的节点(1).changeState();// 更新任务拓展表为通过 审批记录中添加对应节点信息taskExtMapper.updateByTaskId(new BpmTaskExtDO().setTaskId(taskList.get(0).getId()).setResult(BpmProcessInstanceResultEnum.APPROVE.getResult()).setReason("重新提交"));// 更新 BPM 流程//taskService.approveTask(getLoginUserId(), reqVO);leaveMapper.updateById(new BpmOALeaveDO().setId(leave.getId()).setProcessInstanceId(updateReqVO.getProcessInstanceId()));return leave.getId();}

注释中的 taskService.approveTask(getLoginUserId(), reqVO); 就是退回后还按照正常顺序流程走的写法 ;而现在的写法是重新提交后直接跳到退回的那个节点

以上就是实现工作流退回后重新提交到之前退回的节点全部流程。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

全面解读视频生成模型Sora

2024年2月15日&#xff0c;OpenAI在其官网发布了《Video generation models as world simulators》的报告&#xff0c;该报告提出了作为世界模拟器的视频生成模型Sora。 OpenAI对Sora介绍如下&#xff1a; We explore large-scale training of generative models on video dat…

echarts制作两个柱状图

let colorList[#02ce8b,#ffbe62,#f17373]; let data1 [90,80,70,50] option { title:[{ // 第一个标题text: 环保检测, // 主标题textStyle: { // 主标题样式color: #333,fontWeight: bold,fontSize: 16},left: 20%, // 定位到适合的位置top: 10%, // 定位到适合的位置},{ //…

【Redis】理论进阶篇------Redis的持久化

一、前言 前面学习了Redis的相关的十大数据类型以及用SpringBoot集成我们的Redis的工具代码的书写。从这篇文章开始&#xff0c;就会从Redis相关的一些理论&#xff08;也是面试和工作的热点知识&#xff09;如&#xff1a;Redis的持久化、Redis的订阅发布模型、Redis集群环境搭…

wayland(xdg_wm_base) + egl + opengles 纹理贴图进阶实例(四)

文章目录 前言一、使用gstreamer 获取 pattern 图片二、代码实例1. pattern 图片作为纹理数据源的代码实例1.1 基于opengles2.0 接口的 egl_wayland_texture2_1.c1.2 基于opengles3.0 接口的 egl_wayland_texture3_1.c2. xdg-shell-client-protocol.h 和 xdg-shell-protocol.c3…

【C/C++】实现Reactor高并发服务器 完整版

代码结构 文件介绍 InetAddress.h InetAddress类 ip和端口设置 Socket.h Socket类 设置fd Epoll.h epollfd 管理类 Channel.h Channel类 管理epoll以及对应回调函数实现 EventLoop.h EventLoop事件循环类 TcpServer.h 服务器类 tcpepoll.cpp 主函数 InetAddress.h #if…

阿里云服务器被攻击黑洞了怎么办?

今天一个用户使用阿里云服务器遭受DDOS攻击&#xff0c;收到了攻击的提醒短信&#xff0c;服务器也进入黑洞&#xff0c;联系到了德迅云安全&#xff0c;询问有什么解决办法。目前网络攻击事件频发&#xff0c;相信不少用户都曾收到过类似的攻击短信。今天德迅云安全就分享下&a…

模板(函数模板)---C++

模板目录 模板1.模板概念&#xff12;.泛型编程 1.函数模板1.1 函数模板语法1.2 函数模板注意事项1.3 普通函数与函数模板的区别1.4 普通函数与函数模板的调用规则1.5 模板的局限性1.6 函数模板案例 模板 1.模板概念 模板就是建立通用的模具&#xff0c;大大提高复用性。 模板…

Leetcoder Day16| 二叉树 part05

语言&#xff1a;Java/C 513.找树左下角的值 给定一个二叉树的 根节点 root&#xff0c;请找出该二叉树的 最底层 最左边 节点的值。 假设二叉树中至少有一个节点。 示例 1: 输入: root [2,1,3] 输出: 1示例 2: 输入: [1,2,3,4,null,5,6,null,null,7] 输出: 7 本题需要满足两…

3个密码学相关的问题

一、离散对数问题&#xff08;Discrete Logarithm Problem, DLP&#xff09; 问题描述&#xff1a;给定 有限阿贝尓群 G中的2个元素a和b&#xff0c;找出最小的正整数x满足&#xff1a;b a ^^ x &#xff08;或者证明这样的x不存在&#xff09;。 二、阶数问题&#xff08;O…

【STM32】硬件SPI读写W25Q64芯片

目录 基础知识回顾&#xff1a; SPI外设简介 SPI框图 主模式全双工连续传输 非连续传输 初始化SPI外设 核心代码 - 交换一个字节 硬件接线图 Code 程序配置过程 MySPI.c MySPI.h W25Q64.c W25Q64.h W25Q64_Ins.h main.c 基础知识回顾&#xff1a; 【STM32】SP…

【压缩感知基础】Nyquist采样定理

Nyquist定理&#xff0c;也被称作Nyquist采样定理&#xff0c;是由哈里奈奎斯特在1928年提出的&#xff0c;它是信号处理领域的一个重要基础定理。它描述了连续信号被离散化为数字信号时&#xff0c;采样的要求以避免失真。 数学表示 Nyquist定理的核心内容可以描述如下&…

命令执行讲解和函数

命令执行漏洞简介 命令执行漏洞产生原因 应用未对用户输入做严格得检查过滤&#xff0c;导致用户输入得参数被当成命令来执行 命令执行漏洞的危害 1.继承Web服务程序的权限去执行系统命会或读写文件 2.反弹shell&#xff0c;获得目标服务器的权限 3.进一步内网渗透 远程代…

自己动手写编译器:使用 PDA 实现增强和属性语法的解析

在前面章节中我们了解了增强语法和属性语法&#xff0c;特别是看到了这两种语法的结合体&#xff0c;本节我们看看如何使用前面我们说过的自顶向下自动机来实现这两种语法结合体的解析&#xff0c;这里使用的方法也是成熟编译器常用的一种语法解析算法。 首先我们先给出上一节…

【运维】站点可靠性工程介绍:研发,运维,SRE,Devops的关系

文章目录 1、什么是SRE2、SRE与研发、运维的区别 1、什么是SRE 站点可靠性工程&#xff08;SRE&#xff09; 是 IT 运维的软件工程方案。 SRE 团队使用软件作为工具&#xff0c;来管理系统、解决问题并实现运维任务自动化。 SRE 执行的任务以前通常由运维团队手动执行&#x…

URL、DNS过滤,AV---防火墙综合实验

拓扑图 该实验之前的配置请看我的上一篇博客&#xff0c;这里仅配置URL、DNS过滤&#xff0c;AV 需求 8&#xff0c;分公司内部的客户端可以通过域名访问到内部的服务器 这次的拓扑图在外网多增加了一个DNS服务器和HTTP服务器 DNS服务器IP&#xff1a;40.0.0.30 HTTP服务器…

计算机视觉主要知识点

计算机视觉是指利用计算机和算法来解析和理解图片和视频中的内容。这是一个跨学科领域&#xff0c;融合了计算机科学、图像处理、机器学习和模式识别等多方面的技术。以下是一些计算机视觉入门的基本知识点&#xff1a; 主要知识点 图像基础&#xff1a; 像素&#xff1a;图片…

文献学习-1-Continuum Robots for Medical Interventions

Chapt 5. 连续体机构分析 5.1 文献学习 5.1.1 Continuum Robots for Medical Interventions Authors: PIERRE E. DUPONT , Fellow IEEE, NABIL SIMAAN , Fellow IEEE, HOWIE CHOSET , Fellow IEEE, AND CALEB RUCKER , Member IEEE 连续体机器人在医学上得到了广泛的应用&a…

深度学习基础之《TensorFlow框架(4)—Operation》

一、常见的OP 1、举例 类型实例标量运算add&#xff0c;sub&#xff0c;mul&#xff0c;div&#xff0c;exp&#xff0c;log&#xff0c;greater&#xff0c;less&#xff0c;equal向量运算concat&#xff0c;slice&#xff0c;splot&#xff0c;canstant&#xff0c;rank&am…

通配符ssl证书产品

SSL数字证书可以对网站传输数据进行加密以及对服务器的身份进行认证。然而&#xff0c;随着互联网的发展&#xff0c;不管是个人还是企事业单位创建的域名网站越来越多&#xff0c;单域名SSL数字证书无法满足需求&#xff0c;因此通配符SSL证书应运而生。今天就随SSL盾小编了解…

【elk查日志 elastic(kibana)】

文章目录 概要具体的使用方式一&#xff1a;查找接口调用历史二&#xff1a;查找自己的打印日志三&#xff1a;查找错误日志 概要 每次查日志&#xff0c;我都需要别人帮我&#xff0c;时间长了总觉得不好意思&#xff0c;所以这次下定决心好好的梳理一下&#xff0c;怎么查日…