基于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();}

四、实际效果图如下:

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

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

相关文章

uni-app打包后安卓不显示地图及相关操作详解

新公司最近用uni-app写app&#xff0c;之前的代码有很多问题&#xff0c;正好趁着改bug的时间学习下uni-app。 问题现象&#xff1a; 使用uni-app在浏览器调试的时候&#xff0c;地图是展示的&#xff0c;但是打包完成后&#xff0c;在app端是空白的。咱第一次写app&#xff…

视频云存储/安防监控EasyCVR视频汇聚平台分发rtsp流时,出现“用户已过期”提示该如何解决?

视频云存储/安防监控EasyCVR视频汇聚平台基于云边端智能协同&#xff0c;支持海量视频的轻量化接入与汇聚、转码与处理、全网智能分发、视频集中存储等。音视频流媒体视频平台EasyCVR拓展性强&#xff0c;视频能力丰富&#xff0c;具体可实现视频监控直播、视频轮播、视频录像、…

2023企业Hyper-V备份解决方案!

虚拟技术已成为IT基础设施的核心元素&#xff0c;企业长期依赖虚拟机&#xff08;VM&#xff09;为应用程序提供工作负载。Hyper-V是一款广受欢迎的虚拟化平台&#xff0c;多年来已日臻完善&#xff0c;并在各类规模的公司中得到广泛应用。 随着虚拟机使用的普及&…

FPGA使用MIG调用SODIMM内存条接口教程,提供vivado工程源码和技术支持

目录 1、前言免责声明 2、SODIMM内存条简介3、设计思路框架视频输入视频缓存MIG配置调用SODIMM内存条VGA时序视频输出 4、vivado工程详解5、上板调试验证6、福利&#xff1a;工程代码的获取 1、前言 FPGA应用中&#xff0c;数据缓存是一大重点&#xff0c;不管是图像处理还是A…

搭建开发环境-操作系统篇(一键搭建开发环境)

概述 所谓工欲善其事必先利其器&#xff0c;搭环境往往是开发过程中卡出很多初学者的拦路虎。 对于很多老鸟来说&#xff0c;很多东西都已经习惯成自然&#xff0c;也就没有刻意和初学者说。但对于很多初学者&#xff0c;却是受益良多。 这个系列&#xff0c;先从操作系统开始…

ES基础操作

1.创建索引 在 Postman 中&#xff0c;向 ES 服务器发 PUT 请求 &#xff1a; http://127.0.0.1:9200/shopping 后台日志 重复发送 PUT 请求添加索引 &#xff1a; http://127.0.0.1:9200/shopping &#xff0c;会返回错误信息 : 2.获取单个索引相关信息 在 Postman 中&#…

IDC发布《亚太决策支持型分析数据平台评估》报告,亚马逊云科技位列“领导者”类别

日前&#xff0c;领先的IT市场研究和咨询公司IDC发布《2023年亚太地区&#xff08;不含日本&#xff09;决策支持型分析数据平台供应商评估》1报告&#xff0c;亚马逊云科技位列“领导者”类别。IDC认为&#xff0c;亚马逊云科技在解决方案的协同性、敏捷性、完整性、及时性、经…

[C++] string类常用接口的模拟实现

文章目录 1、前言2、遍历2.1 operator[ ]下标方式2.2 迭代器2.3 范围for2.4 c_str 3、容量相关3.1 size&#xff08;大小&#xff09;3.2 capacity&#xff08;容量&#xff09;3.3 empty&#xff08;判空&#xff09;3.4 clear&#xff08;清理&#xff09;3.5 reserve3.6 res…

idea连接linux远程docker详细教程操作

1&#xff1a;修改docker配置文件docker.service vi /usr/lib/systemd/system/docker.service2&#xff1a;找到 ExecStart&#xff0c;在最后面添加 -H tcp://0.0.0.0:2375 # for containers run by docker ExecStart/usr/bin/dockerd -H fd:// --containerd/run/containerd/…

Android动态添加和删除控件/布局

一、引言 最近在研究RecyclerView二级列表的使用方法&#xff0c;需要实现的效果如下。 然后查了一些博客&#xff0c;觉得实现方式太过复杂&#xff0c;而且这种方式也不是特别受推荐&#xff0c;所以请教了别人&#xff0c;得到了一种感觉还不错的实现方式。实现的思路为&…

航空电子设备中的TSN通讯架构—直升机

前言 以太网正在迅速取代传统网络&#xff0c;成为航空电子设备和任务系统的核心高速网络。本文提出了以太网时间敏感网络(TSN)在航空电子设备上应用的技术优势问题。在实际应用中&#xff0c;TSN已成为一个具有丰富的机制和协议的工具箱&#xff0c;可满足与时间和可靠性相关…

从 0 到 1 读懂:哈希表

哈希表 一、什么是哈希表&#xff1f;二、两种散列函数构造方法1、直接定址法2、除留余数法&#xff08;常用&#xff09; 三、散列地址冲突四、常用冲突处理1、负载因子调节&#xff08;减少冲突概率&#xff09;2、开放定址法&#xff08;闭散列&#xff09;&#xff08;1&am…

【运维】linkis1.3.2添加jdbc引擎(添加mysql、greenplum、starrocks、doris数据源查询)与配合多数据源管理提交任务初探

文章目录 一. 引擎的安装1. 前置工作2. 获取引擎插件3. 上传和加载4. 引擎刷新4.1. 重启刷新4.2. 检查引擎是否刷新成功 二. 测试mysql、starrocks与doris数据库1. 通过shell提交任务2. 通过(IDE)shell进行提交3. 通过接口提交 三. 添加greenplum四. 通过linkis的数据源管理提交…

【韩顺平 零基础30天学会Java】程序流程控制(2days)

day1 程序流程控制&#xff1a;顺序控制、分支控制、循环控制 顺序控制&#xff1a;从上到下逐行地执行&#xff0c;中间没有任何判断和跳转。 Java中定义变量时要采用合法的前向引用。 分支控制if-else&#xff1a;单分支、双分支和多分支。 单分支 import java.util.Scann…

Appium-移动端自动测试框架,如何入门?

Appium是一个开源跨平台移动应用自动化测试框架。 既然只是想学习下Appium如何入门&#xff0c;那么我们就直奔主题。文章结构如下&#xff1a; 1、为什么要使用Appium&#xff1f; 2、如何搭建Appium工具环境?(超详细&#xff09; 3、通过demo演示Appium的使用 4、Appium如何…

《学爸》成爆款背后,马栏山以BOT模式示范“文化+科技”路径

文|智能相对论 作者|范柔丝 今年暑期档的爆款电影&#xff0c;必有《学爸》一席之地。 这部给众多深陷教育旋涡的家长带来深刻思考的电影&#xff0c;就是马栏山视频文创产业园经过3年筹备&#xff0c;首部本土孵化出品的教育现实体裁院线大电影。 据猫眼专业版数据&#x…

优于立方复杂度的 Rust 中矩阵乘法

中途&#xff1a;三次矩阵乘法 一、说明 几年前&#xff0c;我在 C 年编写了 Strassen 矩阵乘法算法的实现&#xff0c;最近在 Rust 中重新实现了它&#xff0c;因为我继续学习该语言。这是学习 Rust 性能特征和优化技术的有用练习&#xff0c;因为尽管 Strassen 的算法复杂性优…

【LLM数据篇】预训练数据集+指令生成sft数据集

note 在《Aligning Large Language Models with Human: A Survey》综述中对LLM数据分类为典型的人工标注数据、self-instruct数据集等优秀的开源sft数据集&#xff1a;alpaca_data、belle、千言数据集、firefly、moss-003-sft-data多轮对话数据集等 文章目录 note构造指令实例…

【Linux】网络层协议:IP

我们必须接受批评&#xff0c;因为它可以帮助我们走出自恋的幻象&#xff0c;不至于长久在道德和智识上自我陶醉&#xff0c;在自恋中走向毁灭&#xff0c;事实上我们远比自己想象的更伪善和幽暗。 文章目录 一、IP和TCP之间的关系&#xff08;提供策略 和 提供能力&#xff09…

QT 基本对话框

包括&#xff1a; 1.标准文件对话框 dialog.h #ifndef DIALOG_H #define DIALOG_H#include <QDialog> #include <QTextCodec> #include <QLabel> #include <QLineEdit> #include <QPushButton> #include <QGridLayout> #include <QFr…