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

基于jeecg-boot的flowable流程加签功能实现

   

更多nbcio-boot功能请看演示系统

gitee源代码地址

后端代码: https://gitee.com/nbacheng/nbcio-boot

前端代码:https://gitee.com/nbacheng/nbcio-vue.git

在线演示(包括H5) : http://122.227.135.243:9888

      今天我们实现nbcio-boot的flowable的流程加签功能。

一、加签的几个概念

1、向前加签

任务在 A 这里,A 这个时候需要 B 核对一下,等 B 核对之后又回到 A 这里,这时 A 才能继续自己的任务

2、向后加签

任务在 A 这里,A 这个时候需要 B 处理这个事情,处理完毕之后就不用管了,继续后面的审批环节

3、多实例加签

任务只能对多实例任务进行加签,其它无效

二、前端实现

界面代码如下:

<!--加签流程--><a-modal :z-index="100" :title="addSignTitle" @cancel="addSignOpen = false" :visible.sync="addSignOpen" :width="'40%'" append-to-body><el-form ref="addSignForm" :model="addSignForm" label-width="160px"><el-form-item label="加签类型" prop="addSignType" :rules="[{ required: true, message: '请选择加签类型', trigger: 'blur' }]"><el-radio-group v-model="addSignForm.addSignType" @change="changeAddSignType"><el-radio :label="0">前加签</el-radio><el-radio :label="1">后加签</el-radio><el-radio :label="2">多实例加签</el-radio></el-radio-group></el-form-item><el-form-item label="用户选择" prop="addSignUsers" :rules="[{ required: true, message: '请选择用户', trigger: 'blur' }]"><j-select-user-by-dep v-model="addSignForm.addSignUsers" /></el-form-item><el-form-item label="处理意见" prop="comment" :rules="[{ required: true, message: '请输入处理意见', trigger: 'blur' }]"><el-input type="textarea" v-model="addSignForm.comment" placeholder="请输入处理意见" /></el-form-item><el-form-item label="附件"  prop="commentFileDto.fileurl"><j-upload v-model="addSignForm.commentFileDto.fileurl"   ></j-upload></el-form-item></el-form><span slot="footer" class="dialog-footer"><el-button @click="addSignOpen = false">取 消</el-button><el-button type="primary" @click="addSignComplete(true)">确 定</el-button></span></a-modal>

加签实现代码如下:

/** 加签 */handleAddSign() {this.addSignOpen = true;this.addSignTitle = "前加签流程";},changeAddSignType(val) {this.addSignForm.addSignType = val;if(this.addSignForm.addSignType === 0) {this.addSignTitle = "前加签流程";}if(this.addSignForm.addSignType === 1) {this.addSignTitle = "后加签流程";}if(this.addSignForm.addSignType === 2) {this.addSignTitle = "多实例加签流程";}console.log("changeAddSignType =",val);console.log("this.addSignTitle =",this.addSignTitle);},/** 加签任务 */addSignComplete() {if (!this.addSignForm.addSignUsers ) {this.$message.error("请选择用户");return;}// 流程信息this.addSignForm.deployId = this.$route.query && this.$route.query.deployId;this.addSignForm.taskId = this.$route.query && this.$route.query.taskId;this.addSignForm.procInsId = this.$route.query && this.$route.query.procInsId;this.addSignForm.instanceId = this.$route.query && this.$route.query.procInsId;// 初始化表单this.addSignForm.procDefId = this.$route.query && this.$route.query.procDefId;this.addSignForm.businessKey = this.$route.query && this.$route.query.businessKey;this.addSignForm.category = this.$route.query && this.$route.query.category;this.addSignForm.dataId = this.$route.query && this.$route.query.businessKey;//节点类型this.addSignForm.nodeType = this.$route.query && this.$route.query.nodeType;//online表单id和数据idthis.addSignForm.onlineId = this.$route.query && this.$route.query.onlineId;if (this.addSignForm.category === 'online') {this.addSignForm.onlineDataId = this.$route.query && this.$route.query.businessKey;}  //对formdesigner后续加签审批的时候需要用到this.addSignForm.values = this.taskForm.values;console.log("this.addSignForm=",this.addSignForm);if(this.addSignForm.addSignType === 2) {multiInstanceAddSignTask(this.addSignForm).then(response => {this.$message.success(response.message);this.addSignOpen = false;this.goBack();});}else {addSignTask(this.addSignForm).then(response => {this.$message.success(response.message);this.addSignOpen = false;this.goBack();});}},

实现效果图如下:

三、后端主要代码

@Overridepublic void addTasksBefore(String processInstanceId, String assignee, Set<String> assignees, String description) {addTask(processInstanceId, assignee, assignees, description, Boolean.FALSE);}@Overridepublic void addTasksAfter(String processInstanceId, String assignee, Set<String> assignees, String description) {addTask(processInstanceId, assignee, assignees, description, Boolean.TRUE);}@Override@Transactional(rollbackFor = Exception.class)public void addTask(String processInstanceId, String assignee, Set<String> assignees, String description,Boolean flag) {TaskEntityImpl task = (TaskEntityImpl) taskService.createTaskQuery().processInstanceId(processInstanceId).taskAssignee(assignee).singleResult();Assert.notNull(task, String.format("分配人 [%s] 没有待处理任务", assignee));//如果是加签再加签String parentTaskId = task.getParentTaskId();if (StrUtil.isBlank(parentTaskId)) {task.setOwner(assignee);task.setAssignee(null);task.setCountEnabled(true);if (flag) {task.setScopeType("after");} else {task.setScopeType("before");}// 设置任务为空执行者taskService.saveTask(task);}//添加加签数据this.createSignSubTasks(assignee, assignees, task);//添加审批意见String type = flag ? FlowComment.HJQ.getType() : FlowComment.QJQ.getType();taskService.addComment(task.getId(), processInstanceId, type, description);}/*** 创建加签子任务* @param assignees 被加签人* @param assignee 加签人* @param taskEntity 父任务*/private void createSignSubTasks(String assignee, Set<String> assignees, TaskEntity taskEntity) {if (CollectionUtil.isNotEmpty(assignees)) {//1.创建被加签人的任务列表assignees.forEach(userId -> {if (StrUtil.isNotBlank(userId)) {this.createSubTask(taskEntity, taskEntity.getId(), userId);}});String parentTaskId = taskEntity.getParentTaskId();if (StrUtil.isBlank(parentTaskId)) {parentTaskId = taskEntity.getId();}String finalParentTaskId = parentTaskId;//2.创建加签人的任务并执行完毕String taskId = taskEntity.getId();if (StrUtil.isBlank(taskEntity.getParentTaskId())) {Task task = this.createSubTask(taskEntity, finalParentTaskId, assignee);taskId = task.getId();}Task taskInfo = taskService.createTaskQuery().taskId(taskId).singleResult();if (ObjectUtil.isNotNull(taskInfo)) {taskService.complete(taskId);}//如果是候选人,需要删除运行时候选不中的数据。long candidateCount = taskService.createTaskQuery().taskId(parentTaskId).taskCandidateUser(assignee).count();if (candidateCount > 0) {taskService.deleteCandidateUser(parentTaskId, assignee);}}}public String getMultiInstanceActAssigneeParam(String processDefinitionId, String actId) {AtomicReference<String> resultParam = new AtomicReference<>();ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(processDefinitionId).singleResult();//获取bpmnModel并转为modelNodeBpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinition.getId());//获取主流程Process mainProcess = bpmnModel.getMainProcess();//获取用户任务节点类型,深入子流程mainProcess.findFlowElementsOfType(UserTask.class, true).forEach(userTask -> {String userTaskId = userTask.getId();if (userTaskId.equals(actId)) {Object behavior = userTask.getBehavior();if (ObjectUtil.isNotNull(behavior)) {//并行多实例节点if (behavior instanceof ParallelMultiInstanceBehavior) {ParallelMultiInstanceBehavior parallelMultiInstanceBehavior =(ParallelMultiInstanceBehavior) behavior;String collectionElementVariable = parallelMultiInstanceBehavior.getCollectionElementVariable();if (ObjectUtil.isNotEmpty(collectionElementVariable)) {resultParam.set(collectionElementVariable);}}//串行多实例节点if (behavior instanceof SequentialMultiInstanceBehavior) {SequentialMultiInstanceBehavior sequentialMultiInstanceBehavior =(SequentialMultiInstanceBehavior) behavior;String collectionElementVariable = sequentialMultiInstanceBehavior.getCollectionElementVariable();if (ObjectUtil.isNotEmpty(collectionElementVariable)) {resultParam.set(collectionElementVariable);}}}}});return resultParam.get();}

四、实际效果图如下:

相关文章:

基于jeecg-boot的flowable流程加签功能实现

更多nbcio-boot功能请看演示系统 gitee源代码地址 后端代码&#xff1a; https://gitee.com/nbacheng/nbcio-boot 前端代码&#xff1a;https://gitee.com/nbacheng/nbcio-vue.git 在线演示&#xff08;包括H5&#xff09; &#xff1a; http://122.227.135.243:9888 今天我…...

day-03 基于TCP的服务器端/客户端

一.理解TCP和UDP TCP&#xff08;Transmission Control Protocol&#xff09;和UDP&#xff08;User Datagram Protocol&#xff09;是两种常见的传输层协议&#xff0c;用于在计算机网络中提供可靠的数据传输。 1.TCP&#xff1a; 连接导向&#xff1a;TCP是一种面向连接的…...

匿名对象和一般对象的区别

1.格式的不同 一般对象的格式&#xff1a; ​ Object obj new Object(); ​ 匿名对象的格式&#xff1a; ​ new Object(); 2.作为参数传递机制的不同 2.1先看看一般对象的使用机制 执行步骤&#xff1a; 1.首先程序进入main()函数&#xff0c;执行Object obj&#xff0c;…...

[MyBatis系列⑥]注解开发

&#x1f343;作者简介&#xff1a;准大三本科网络工程专业在读&#xff0c;持续学习Java&#xff0c;努力输出优质文章 ⭐MyBatis系列①&#xff1a;增删改查 ⭐MyBatis系列②&#xff1a;两种Dao开发方式 ⭐MyBatis系列③&#xff1a;动态SQL ⭐MyBatis系列④&#xff1a;核心…...

[ACL2023] Exploring Lottery Prompts for Pre-trained Language Models

Exploring Lottery Prompts for Pre-trained Language Models 文章链接 清深的工作&#xff0c;比较有意思的一篇。作者先给出假设&#xff0c;对于分类问题&#xff0c;在有限的语料空间内总能找到一个prompt让这个问题分类正确&#xff0c;作者称之为lottery prompt。为此&…...

【Python编程】将同一种图片分类到同一文件夹下,并且将其分类的路径信息写成txt文件进行保存

注&#xff1a;数据结构同上一篇博文类似 一、代码 import os import cv2 import shutilpath0os.getcwd()\\apple\\RGB path1os.getcwd()\\apple\\tof_confidence # path2os.getcwd()\\apple\\tof_depth # path3os.getcwd()\\apple\\tof_depthRGB # path4os.getcwd()\\apple\…...

单例模式的相关知识

饿汉模式 package Thread; class Singleton{private static Singleton instance new Singleton();public static Singleton getInstance(){return instance;}private Singleton(){} }public class demo1 {public static void main(String[] args) {Singleton S1 Singleton.ge…...

vue问题相关记录

1. vue的 nextTick的原理 首先vue实现响应式并不是数据发生变化后dom立即更新&#xff0c;而是按照一定的策略 异步执行dom更新的。 vue在修改数据后&#xff0c;试图不会立即进行更新&#xff0c;而是要等同一事件循环机制内所有数据变化完成之后&#xff0c;在统一更新 next…...

skywalking服务部署

一、前言 Apache SkyWalking 是一个开源的分布式跟踪、监控和诊断系统&#xff0c;旨在帮助用户监控和诊断分布式应用程序、微服务架构和云原生应用的性能和健康状况。它提供了可视化的分析工具&#xff0c;帮助开发人员和运维团队深入了解应用程序的性能、调用链和异常情况 …...

【uni-app】压缩图片并添加水印

总体思路 dom 结点 这里的 cvHeight 和 cvWidth 初始时要设置为你后续需要压缩后的最大宽高。假设我们在图片上传后图片最大为 350 * 350 <u-upload :fileList"baseInfoFormData.entrustFileList" afterRead"afterFileRead" multiple></u-uploa…...

《每天十分钟》-红宝书第4版-变量、作用域与内存

最近有点忙&#xff0c;好长时间没抄经了&#xff0c;今天继续&#xff0c;之前语言基础相对简单&#xff0c;跳过一部分操作符。 变量 js 的变量是特殊的松散类型&#xff0c;由于没有规则定义变量必须包含什么数据类型&#xff0c;变量的值和数据类型在脚本生命期内可以改变…...

NFTScan | 08.21~08.27 NFT 市场热点汇总

欢迎来到由 NFT 基础设施 NFTScan 出品的 NFT 生态热点事件每周汇总。周期&#xff1a;2023.08.21~ 2023.08.27 NFT Hot News 01/ NFT 品牌体验平台 Recur 将于 11 月 16 日彻底关闭&#xff0c;此前曾获 5000 万美元融资 8 月 21 日&#xff0c;NFT 品牌体验平台 Recur 在 X…...

【Java 中级】一文精通 Spring MVC - 数据验证(七)

&#x1f449;博主介绍&#xff1a; 博主从事应用安全和大数据领域&#xff0c;有8年研发经验&#xff0c;5年面试官经验&#xff0c;Java技术专家&#xff0c;WEB架构师&#xff0c;阿里云专家博主&#xff0c;华为云云享专家&#xff0c;51CTO 专家博主 ⛪️ 个人社区&#x…...

css奇数偶数选择器

前端项目开发中&#xff0c;需要根据行数的奇数和偶数的不同&#xff0c;设置不同的颜色显示&#xff0c;以在视觉上给用户以良好的浏览体验&#xff0c;这里就需要使用css奇数偶数选择器。 主要用的&#xff1a;:nth-of-type或者:nth-child。 方式一:nth-child div:nth-chi…...

【算法】双指针求解盛最多水的容器

Problem: 11. 盛最多水的容器 文章目录 题目解析算法原理讲解复杂度Code 题目解析 首先我们来解析一下本题 题目中说到&#xff0c;要找出其中的两条线&#xff0c;使得它们与 x 轴共同构成的容器可以容纳最多的水。 那我们现在来看最外侧的两根&#xff0c;一个高度为8&#…...

浅析SAS协议:设备接入与探测

文章目录 SAS设备初始化OOB信号SAS设备间OOB交互场景一&#xff1a;SAS设备两边同时发送SAS COMINIT信号场景二&#xff1a;SAS设备A先发送COMINIT信号场景三&#xff1a;SAS设备B错过COMINIT信号 SAS与SATA设备间OOB交互场景一&#xff1a;SATA设备未响应COMSAS信号场景二&…...

RISC-V IOPMP实际用例-Andes SoC‘s Rapid-k模型

安全之安全(security)博客目录导读 2023 RISC-V中国峰会 安全相关议题汇总 说明&#xff1a;本文参考RISC-V 2023中国峰会如下议题&#xff0c;版权归原作者所有。...

【高阶数据结构】哈希表详解

文章目录 前言1. 哈希的概念2. 哈希冲突3. 哈希函数3.1 直接定址法3.2 除留余数法--(常用)3.3 平方取中法--(了解)3.4 折叠法--(了解)3.5 随机数法--(了解)3.6 数学分析法--(了解) 4. 哈希冲突的解决方法及不同方法对应的哈希表实现4.1 闭散列&#xff08;开放定址法&#xff0…...

C#与西门子PLC1500的ModbusTcp服务器通信4--搭建ModbusTcp客户端

1、客户端选择 客户端可以是一个程序或一个设备&#xff0c;这里我以C#WINFORM程序来实现客户机与PLC的Modbustcp服务器通信&#xff0c;开发环境是VS2019&#xff0c;.NET Framework版本是4.7.2 2、创建winform程序 3、引入Nmodbus4协议 找到项目&#xff0c;找到引用&…...

性能调优篇 二、Jvm监控及诊断工具-命令行篇

目录 一、概述1、简单命令行工具 二、jps&#xff1a;查看正在运行的Java程序&#xff08;掌握&#xff09;1、是什么&#xff1f;2、测试3、基本语法 三、jstat&#xff1a;查看jvm统计信息&#xff08;掌握&#xff09;1、是什么&#xff1f;2、基本语法3、补充 四、jinfo&am…...

Fooocus启动时modules报错的解决方法

原理&#xff1a;是由于其他程序的安装导致modules的版本不对&#xff0c;先卸载现有版本&#xff0c;再运行run.bat让其自动安装响应的modules版本。 1、cmd运行windows dos终端。 2、将Fooocus_win64_1-1-1035文件夹备份&#xff0c;rename为Fooocus_win64_1-1-1035backup文…...

RSA私钥解密操作

RSA私钥解密操作 一、背景二、操作三、常见问题3.1 invalid key format3.2 解密的数据太长3.3 Decryption error 一、背景 项目数据库中存放的敏感字段已使用rsa加密的方式&#xff0c;将内容加密成密文存放, 现在需要在使用的时候&#xff0c;使用私钥进行解密。 二、操作 …...

数据库基本知识

基本概念 数据 描述事物的符号记录称为数据&#xff0c;数字&#xff0c;文字&#xff0c;图形&#xff0c;图像&#xff0c;声音&#xff0c;档案记录等都是数据 数据是以“记录”的形式按照统一的格式进行存储的&#xff0c;而不是杂乱无章的 相同格式和类型的数据统一存…...

使用Redis统计网站的UV/DAU

HyperLogLog/BitMap 统计UV、DAU需要用到Redis的高级数据类型 M public class RedisKeyUtil {private static final String PREFIX_UV "uv";private static final String PREFIX_DAU "dau";// a single days UVpublic static String getUVKey(String …...

【python】报错:ImportError: DLL load failed: 找不到指定的模块 的详细解决办法

原因&#xff1a;安装的包与python版本不一致 解决方法&#xff1a; 查看python版本&#xff1a; #python / #python -V Python 3.7.9 (tags/v3.7.9:13c94747c7, Aug 17 2020, 18:58:18) [MSC v.1900 64 bit (AMD64)] on win32只查看python第三方模块&#xff08;库、包&…...

SemrushBot蜘蛛爬虫屏蔽方式

查看访问日志时候发现有SemrushBot爬虫 屏蔽方法&#xff1a; 使用robots.txt文件是一种标准的协议,用于告诉搜索引擎哪些页面可以和不能被爬取,如想禁止Googlebot爬取整个网站的话,可以在该文件中添加以下内容: User-agent: Googlebot Disallow: / 对于遵循robots协议的蜘蛛…...

6 ssh面密登录

1. 首先进入自己的家目录&#xff0c;执行命令 [atguiguhadoop102 .ssh]$ ssh-keygen -t rsa然后敲&#xff08;三个回车&#xff09;&#xff0c;就会生成两个文件id_rsa&#xff08;私钥&#xff09;、id_rsa.pub&#xff08;公钥&#xff09; 2. 将公钥拷贝到要免密登录的…...

基于微信小程序的汽车租赁系统的设计与实现ljx7y

汽车租赁系统&#xff0c;主要包括管理员、用户二个权限角色&#xff0c;对于用户角色不同&#xff0c;所使用的功能模块相应不同。本文从管理员、用户的功能要求出发&#xff0c;汽车租赁系统系统中的功能模块主要是实现管理员后端&#xff1b;首页、个人中心、汽车品牌管理、…...

优化学习体验的在线考试系统

随着互联网的发展&#xff0c;在线教育逐渐成为学习的主要方式之一。在线考试系统作为在线教育的重要组成部分&#xff0c;对于学习者提供了更为便捷和灵活的学习方式。但是&#xff0c;如何优化学习体验&#xff0c;提高学习效果&#xff0c;仍然是在线考试系统需要解决的问题…...

1267. 统计参与通信的服务器

题目描述&#xff1a; 这里有一幅服务器分布图&#xff0c;服务器的位置标识在 m * n 的整数矩阵网格 grid 中&#xff0c;1 表示单元格上有服务器&#xff0c;0 表示没有。 如果两台服务器位于同一行或者同一列&#xff0c;我们就认为它们之间可以进行通信。 请你统计并返回能…...