基于若依的ruoyi-nbcio流程管理系统修复自定义业务表单的收回功能

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

gitee源代码地址

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

演示地址:RuoYi-Nbcio后台管理系统

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

gitee源代码地址

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

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

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

       这个功能在已办任务里,就是用户可以通过已办任务,而且最好是发起人可以进行任务的收回,收回后可以重新进行业务流程提交。

     具体的代码如下,同时在自定义业务提交的时候做一个判断,符合这种情况可以进行提交:

@Override@Transactional(rollbackFor = Exception.class)public R recallProcess(WfTaskBo bo) {// 当前任务 listtaskList<Task>  listtask = taskService.createTaskQuery().processInstanceId(bo.getProcInsId()).active().list();if (listtask == null || listtask.size()==0) {throw new FlowableException("流程未启动或已执行完成,无法收回");}if (taskService.createTaskQuery().taskId(listtask.get(0).getId()).singleResult().isSuspended()) {throw new FlowableException("任务处于挂起状态");}List<Task> procInsId = taskService.createNativeTaskQuery().sql("select * from ACT_HI_TASKINST where PROC_INST_ID_ = #{procInsId} ORDER BY START_TIME_ desc").parameter("procInsId", bo.getProcInsId()).list();String processInstanceId = listtask.get(0).getProcessInstanceId();//  获取所有历史任务(按创建时间升序)List<HistoricTaskInstance> hisTaskList = historyService.createHistoricTaskInstanceQuery().processInstanceId(processInstanceId).orderByTaskCreateTime().asc().list();if (CollectionUtil.isEmpty(hisTaskList) || hisTaskList.size() < 2) {log.error("当前流程 【{}】 审批节点 【{}】正在初始节点无法收回", processInstanceId, listtask.get(0).getName());throw new FlowableException(String.format("当前流程 【%s】 审批节点【%s】正在初始节点无法收回", processInstanceId, listtask.get(0).getName()));}//  第一个任务HistoricTaskInstance startTask = hisTaskList.get(0);//若操作用户不是发起人,不能收回if(!StringUtils.equalsAnyIgnoreCase(LoginHelper.getUsername(), startTask.getAssignee())) {throw new FlowableException("操作用户不是发起人,不能收回");}//  当前任务HistoricTaskInstance currentTask = hisTaskList.get(hisTaskList.size() - 1);BpmnModel bpmnModel = repositoryService.getBpmnModel(listtask.get(0).getProcessDefinitionId());//  获取第一个活动节点FlowNode startFlowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(startTask.getTaskDefinitionKey());//  获取当前活动节点FlowNode currentFlowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(currentTask.getTaskDefinitionKey());//  临时保存当前活动的原始方向List<SequenceFlow> originalSequenceFlowList = new ArrayList<>(currentFlowNode.getOutgoingFlows());//  清理活动方向currentFlowNode.getOutgoingFlows().clear();//  建立新方向SequenceFlow newSequenceFlow = new SequenceFlow();newSequenceFlow.setId("newSequenceFlowId");newSequenceFlow.setSourceFlowElement(currentFlowNode);newSequenceFlow.setTargetFlowElement(startFlowNode);List<SequenceFlow> newSequenceFlowList = new ArrayList<>();newSequenceFlowList.add(newSequenceFlow);//  当前节点指向新的方向currentFlowNode.setOutgoingFlows(newSequenceFlowList);//  完成当前任务for(Task task : listtask) {taskService.addComment(task.getId(), listtask.get(0).getProcessInstanceId(),FlowComment.RECALL.getType(), "发起人收回");taskService.setAssignee(task.getId(), startTask.getAssignee());taskService.complete(task.getId());}//  重新查询当前任务Task nextTask = taskService.createTaskQuery().processInstanceId(processInstanceId).singleResult();if (ObjectUtil.isNotNull(nextTask)) {taskService.setAssignee(nextTask.getId(), startTask.getAssignee());//taskService.complete(nextTask.getId());;//跳过流程发起节点}//自定义业务处理idString dataId = bo.getDataId();if(StringUtils.isNotEmpty(dataId)) {WfMyBusiness business = wfMyBusinessService.getByDataId(dataId);//更新删除自定义业务任务关联表与流程历史表,以便可以重新发起流程。if (business != null) {business.setActStatus(ActStatus.recall);business.setTodoUsers("");business.setDoneUsers("");business.setProposer("");business.setTaskName("");business.setTaskId("");business.setTaskNameId("");wfMyBusinessService.updateById(business);}	}// 删除运行和历史的节点信息 this.deleteActivity(procInsId.get(1).getTaskDefinitionKey(), bo.getProcInsId(), dataId);//  恢复原始方向currentFlowNode.setOutgoingFlows(originalSequenceFlowList);return R.ok("发起人收回成功");}
try {LambdaQueryWrapper<WfMyBusiness> wfMyBusinessLambdaQueryWrapper = new LambdaQueryWrapper<>();wfMyBusinessLambdaQueryWrapper.eq(WfMyBusiness::getDataId, dataId);WfMyBusiness business = wfMyBusinessService.getOne(wfMyBusinessLambdaQueryWrapper);if (business==null || (business != null && business.getActStatus().equals(ActStatus.stop)) || (business != null && business.getActStatus().equals(ActStatus.recall))){if(processDefinition==null) {return R.fail("自定义表单也没关联流程定义表,流程没定义关联自定义表单"+wfCustomForm.getId());}boolean binit = wfCommonService.initActBusiness(wfCustomForm.getBusinessName(), dataId, serviceName, processDefinition.getKey(), processDefinition.getId(), wfCustomForm.getRouteName());if(!binit) {return R.fail("自定义表单也没关联流程定义表,流程没定义关联自定义表单"+wfCustomForm.getId());}WfMyBusiness businessnew = wfMyBusinessService.getOne(wfMyBusinessLambdaQueryWrapper);//流程实例关联初始化结束if (StrUtil.isNotBlank(businessnew.getProcessDefinitionId())){return this.startProcessByDefId(businessnew.getProcessDefinitionId(),variables);}return this.startProcessByDefKey(businessnew.getProcessDefinitionKey(),variables);}else {return R.fail("已经存在这个dataid实例,不要重复申请:"+dataId);}} catch (Exception e) {e.printStackTrace();throw new RuntimeException();} 	

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

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

相关文章

微信小程序-----全局配置与页面配置

目录 前言 全局配置文件 一、window 1. 小程序窗口的组成部分 2. window 节点常用的配置项 3. 设置导航栏的标题 4. 设置导航栏的背景色 5. 设置导航栏的标题颜色 6. 全局开启下拉刷新功能 7. 设置下拉刷新时窗口的背景色 8. 设置下拉刷新时 loading 的样式 9. 设置…

dolphinscheduler分布式集群部署指南(小白版)

1.Apache DolphinScheduler概述 官方文档地址&#xff1a;https://dolphinscheduler.apache.org/zh-cn/docs/3.1.9 1.1.DolphinScheduler简介 摘自官网&#xff1a;Apache DolphinScheduler 是一个分布式易扩展的可视化DAG工作流任务调度开源系统。适用于企业级场景&#xf…

Hcie datacom实验手册哪里下载!

一、官方下载 首先&#xff0c;最直接的方式就是从华为官方网站下载Hcie Datacom实验手册。作为华为认证体系的核心资料&#xff0c;官方下载的内容是最全面、最准确的。您只需要访问华为官方网站&#xff0c;在搜索框中输入“Hcie Datacom实验手册”&#xff0c;即可找到相应…

十、Qt 操作PDF文件

《一、QT的前世今生》 《二、QT下载、安装及问题解决(windows系统)》《三、Qt Creator使用》 ​​​ 《四、Qt 的第一个demo-CSDN博客》 《五、带登录窗体的demo》 《六、新建窗体时&#xff0c;几种窗体的区别》 《七、Qt 信号和槽》 《八、Qt C 毕业设计》 《九、Qt …

考研英语打卡

[爱心]长难句分享第三十一天解析 [玫瑰]【词汇】&#xff1a;• astonishing [əˈstɑːnɪʃɪŋ] adj. 令人惊讶的• purchase [ˈpɜːrtʃəs] n. 购买• upmarket [ˌʌpˈmɑːrkɪt] adj. 高级的• grocery [ˈɡroʊsəri] n. 食品杂货店• chain [tʃeɪn] n. 连锁店…

【Linux驱动】Linux的中断系统 | 中断的重要数据结构

&#x1f431;作者&#xff1a;一只大喵咪1201 &#x1f431;专栏&#xff1a;《Linux驱动》 &#x1f525;格言&#xff1a;你只管努力&#xff0c;剩下的交给时间&#xff01; 目录 &#x1f3c0;Linux系统的中断⚽中断分类软中断和硬中断中断的上半部和下半部 ⚽tasklet⚽工…

普冉32位单片机 PY32C642,M0+内核,1.7 V ~ 5.5 V宽工作电压

PY32C642 单片机采用高性能的 32 位 ARM Cortex-M0内核&#xff0c;宽电压工作范围。嵌入 24Kbytes Flash 和 3 Kbytes SRAM 存储器&#xff0c;最高工作频率 24 MHz。包含多种不同封装类型产品。工作温度范围为-40C ~ 85C&#xff0c;工作电压范围 1.7 V ~ 5.5 V。1 路 12 位A…

myBatis框架中resultMap的简单使用

MyBatis中的ResultMap是用来映射SQL查询结果集和Java对象之间关系的配置。通过ResultMap&#xff0c;我们可以定义如何将查询结果中的列映射到Java对象的属性上。 ResultMap包含了多个ResultMapping&#xff0c;每个ResultMapping定义了一个列与属性之间的映射关系。我们可以指…

深度强化学习的变道策略:Harmonious Lane Changing via Deep Reinforcement Learning

偏理论&#xff0c;假设情况不易发生 摘要 多智能体强化学习的换道策略&#xff0c;不同的智能体在每一轮学习后交换策略&#xff0c;达到零和博弈。 和谐驾驶仅依赖于单个车辆有限的感知结果来平衡整体和个体效率&#xff0c;奖励机制结合个人效率和整体效率的和谐。 Ⅰ. 简…

在Excel中如何打开VBA,这里提供两种方法

想在Excel中创建或添加自己的自定义Visual Basic脚本吗&#xff1f;第一步是了解如何在Excel中打开VBA编辑器。 在易用性和整体功能方面&#xff0c;没有其他电子表格应用程序能与Excel相提并论。无论你想做什么&#xff0c;只要你能深入挖掘Excel的深层菜单&#xff0c;就有很…

正点原子imx6ull网络环境配置:开发板和电脑通过网线直连、电脑WiFi上网

1.硬件连接 开发板通过网线连接电脑。电脑连接wifi 2.VMware设置 2.1添加桥接模式和NAT模式 1&#xff09;打开vm设置 2&#xff09;设置网络适配器为桥接模式&#xff0c;不要勾选 “赋值物理网络连接状态” 3&#xff09; 添加一个网络适配器并设置成NAT模式&#xff0c;…

阿里云服务器怎么样?阿里云服务器优势、价格及常见问题

阿里云服务器ECS英文全程Elastic Compute Service&#xff0c;云服务器ECS是一种安全可靠、弹性可伸缩的云计算服务&#xff0c;阿里云提供多种云服务器ECS实例规格&#xff0c;如ECS经济型e实例、通用算力型u1、ECS计算型c7、通用型g7、GPU实例等&#xff0c;阿里云服务器网al…

vue3.2二次封装antd vue 中的Table组件,原有参数属性不变

vue3.2中的<script setup>语法 在项目中多处使用到表格组件,所以进行了一个基础的封装,主要是通过antd vue 中表格的slots配置项,通过配合插槽来进行封装自定义表格; 这次主要的一个功能是编辑之后变成input框 修改了之后变成完成发送请求重新渲染表格&#xff1a; 子…

redis数据安全(二)数据持久化 RDB

目录 一、RDB快照持久化 原理 二、RDB快照持久化配置&#xff08;redis.conf&#xff09;&#xff1a; 三、触发RDB备份&#xff1a; 1、自动备份&#xff0c;需配置备份规则&#xff1a; 2、手动执行命令备份&#xff08;save | bgsave&#xff09;&#xff1a; 3、flus…

Unity Shader 的模板测试效果

模板测试是渲染管线中逐片元操作的一环&#xff0c;它的作用是筛选出指定模板的片元&#xff0c;而不符合模板的片元会被舍弃&#xff0c;从而做到一个遮罩的效果。 以下是Unity中实践的一个效果&#xff1a; 场景中可以看出&#xff0c;熊模型和茶壶模型都在差不多的位置&am…

用原型实现Class的各项语法

本人之前对Class一直不够重视。平时对原型的使用&#xff0c;也仅限于在构造函数的prototype上挂属性。原型尚且用不着&#xff0c;更何况你Class只是原型的一颗语法糖&#xff1f; 直到公司开始了一个webgis项目&#xff0c;使用openlayers。看了下openlayers的代码&#xff0…

头像空白问题

当用户没有设置头像时&#xff0c;我们可以使用用户名第一个字来当头像 主要涉及一个截取&#xff0c;截取字符串第一个字 变量名.charAt(0) 如果变量名为null或者undefine 那么就会报错 使用可选链操作符 &#xff1f; 当前面的值为nul或undefine时&#xff0c;就不会执行…

HTML--CSS--盒子模型

在CSS模型中&#xff0c;所有元素都可以看做是一个盒子&#xff0c;这个盒子的组成部分&#xff1a; content 内容&#xff0c;文本或者图片 padding 内边距&#xff0c;定义内容到边框的距离 margin 外边距&#xff0c;定义当前元素与其他元素之间的距离 border 边框&#xff…

Android13获取存储空间大小

内部存储 1、总大小 public static long getInternalStorageSize(Context context) {File filesDir context.getFilesDir();return filesDir.getTotalSpace(); } 2、可用空间大小 public static long getFreeSpace(Context context) {File filesDir context.getFilesDir(…

第10章 通信业务

文章目录 10.1.1 通信行业1、通信行业的界定2、通信行业的特点 10.1.2 通信企业10.1.3 通信终端1、通信终端的分类2、终端发展趋势 10.2.1 通信业务的定义及分类10.2.2 基础电信业务1、第一类基础电信业务A11 固定通信业务A12 蜂窝移动通信业务A13 第一类卫星通信业务A14 第一类…