工作流实战_22_flowable 驳回/回退 并行网关驳回 多实例驳回 子流程驳回

项目地址https://gitee.com/lwj/flowable.git
代码分支flowable-base
视频讲解地址https://www.bilibili.com/video/av78779999/
用户名密码
0000001test
0000002test
0000003test
0000004test

文章目录

      • 1. 场景
      • 2. 演示
      • 3. 代码分享
        • 3.1. 获取可驳回节点
        • 3.2. 驳回代码分享

1. 场景

驳回:当前处理人可以驳回历史走过的任何一个节点
1、驳回任意普通节点
2、驳回多实例节点
3、驳回并行网关节点
4、驳回子流程节点
5、子流程节点驳回主流程节点

实际情况中,为了获取可驳回的节点列表,我们做了一些规定,比方说并行网关节点,要求必须成对出现,也只能驳回到并行网关节点的 fork节点

2. 演示

由于情况很多,截图反而不能重点讲述驳回的事情,这里只截一张图,如果想看详情请查看视频里面的讲解
在这里插入图片描述

3. 代码分享

3.1. 获取可驳回节点

public List<FlowNodeVo> getBackNodesByProcessInstanceId(String taskId,String processInstanceId) {List<FlowNodeVo> backNods = new ArrayList<>();TaskEntity taskEntity = (TaskEntity) taskService.createTaskQuery().taskId(taskId).singleResult();String currActId = taskEntity.getTaskDefinitionKey();//获取运行节点表中usertaskString sql = "select t.* from act_ru_actinst t where t.ACT_TYPE_ = 'userTask' " +" and t.PROC_INST_ID_=#{processInstanceId} and t.END_TIME_ is not null ";List<ActivityInstance> activityInstances = runtimeService.createNativeActivityInstanceQuery().sql(sql).parameter("processInstanceId", processInstanceId).list();//获取运行节点表的parallelGateway节点并出重sql = "SELECT t.ID_, t.REV_,t.PROC_DEF_ID_,t.PROC_INST_ID_,t.EXECUTION_ID_,t.ACT_ID_, t.TASK_ID_, t.CALL_PROC_INST_ID_, t.ACT_NAME_, t.ACT_TYPE_, " +" t.ASSIGNEE_, t.START_TIME_, max(t.END_TIME_) as END_TIME_, t.DURATION_, t.DELETE_REASON_, t.TENANT_ID_" +" FROM  act_ru_actinst t WHERE t.ACT_TYPE_ = 'parallelGateway' AND t.PROC_INST_ID_ = #{processInstanceId} and t.END_TIME_ is not null" +" and t.ACT_ID_ <> #{actId} GROUP BY t.act_id_";List<ActivityInstance> parallelGatewaies = runtimeService.createNativeActivityInstanceQuery().sql(sql).parameter("processInstanceId", processInstanceId).parameter("actId", currActId).list();//排序if (CollectionUtils.isNotEmpty(parallelGatewaies)) {activityInstances.addAll(parallelGatewaies);activityInstances.sort(Comparator.comparing(ActivityInstance::getEndTime));}//分组节点int count = 0;Map<ActivityInstance, List<ActivityInstance>> parallelGatewayUserTasks = new HashMap<>();List<ActivityInstance> userTasks = new ArrayList<>();ActivityInstance currActivityInstance = null;for (ActivityInstance activityInstance : activityInstances) {if (BpmnXMLConstants.ELEMENT_GATEWAY_PARALLEL.equals(activityInstance.getActivityType())) {count++;if (count % 2 != 0) {List<ActivityInstance> datas = new ArrayList<>();currActivityInstance = activityInstance;parallelGatewayUserTasks.put(currActivityInstance, datas);}}if (BpmnXMLConstants.ELEMENT_TASK_USER.equals(activityInstance.getActivityType())) {if (count % 2 == 0) {userTasks.add(activityInstance);} else {if (parallelGatewayUserTasks.containsKey(currActivityInstance)) {parallelGatewayUserTasks.get(currActivityInstance).add(activityInstance);}}}}//组装人员名称List<HistoricTaskInstance> historicTaskInstances = historyService.createHistoricTaskInstanceQuery().processInstanceId(processInstanceId).finished().list();Map<String, List<HistoricTaskInstance>> taskInstanceMap = new HashMap<>();List<String> userCodes = new ArrayList<>();historicTaskInstances.forEach(historicTaskInstance -> {userCodes.add(historicTaskInstance.getAssignee());String taskDefinitionKey = historicTaskInstance.getTaskDefinitionKey();if (taskInstanceMap.containsKey(historicTaskInstance.getTaskDefinitionKey())) {taskInstanceMap.get(taskDefinitionKey).add(historicTaskInstance);} else {List<HistoricTaskInstance> tasks = new ArrayList<>();tasks.add(historicTaskInstance);taskInstanceMap.put(taskDefinitionKey, tasks);}});//组装usertask的数据List<User> userList = identityService.createUserQuery().userIds(userCodes).list();Map<String, String> activityIdUserNames = this.getApplyers(processInstanceId, userList, taskInstanceMap);if (CollectionUtils.isNotEmpty(userTasks)) {userTasks.forEach(activityInstance -> {FlowNodeVo node = new FlowNodeVo();node.setNodeId(activityInstance.getActivityId());node.setNodeName(activityInstance.getActivityName());node.setEndTime(activityInstance.getEndTime());node.setUserName(activityIdUserNames.get(activityInstance.getActivityId()));backNods.add(node);});}//组装会签节点数据if (MapUtils.isNotEmpty(taskInstanceMap)) {parallelGatewayUserTasks.forEach((activity, activities) -> {FlowNodeVo node = new FlowNodeVo();node.setNodeId(activity.getActivityId());node.setEndTime(activity.getEndTime());StringBuffer nodeNames = new StringBuffer("会签:");StringBuffer userNames = new StringBuffer("审批人员:");if (CollectionUtils.isNotEmpty(activities)){activities.forEach(activityInstance -> {nodeNames.append(activityInstance.getActivityName()).append(",");userNames.append(activityIdUserNames.get(activityInstance.getActivityId())).append(",");});node.setNodeName(nodeNames.toString());node.setUserName(userNames.toString());backNods.add(node);}});}//去重合并List<FlowNodeVo> datas = backNods.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() ->new TreeSet<>(Comparator.comparing(nodeVo -> nodeVo.getNodeId()))), ArrayList::new));//排序datas.sort(Comparator.comparing(FlowNodeVo::getEndTime));return datas;}

3.2. 驳回代码分享

public ReturnVo<String> backToStepTask(BackTaskVo backTaskVo) {ReturnVo<String> returnVo = null;TaskEntity taskEntity = (TaskEntity) taskService.createTaskQuery().taskId(backTaskVo.getTaskId()).singleResult();//1.把当前的节点设置为空if (taskEntity != null) {//2.设置审批人taskEntity.setAssignee(backTaskVo.getUserCode());taskService.saveTask(taskEntity);//3.添加驳回意见this.addComment(backTaskVo.getTaskId(), backTaskVo.getUserCode(), backTaskVo.getProcessInstanceId(),CommentTypeEnum.BH.toString(), backTaskVo.getMessage());//4.处理提交人节点FlowNode distActivity = flowableBpmnModelService.findFlowNodeByActivityId(taskEntity.getProcessDefinitionId(), backTaskVo.getDistFlowElementId());if (distActivity != null) {if (FlowConstant.FLOW_SUBMITTER.equals(distActivity.getName())) {ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(taskEntity.getProcessInstanceId()).singleResult();runtimeService.setVariable(backTaskVo.getProcessInstanceId(), FlowConstant.FLOW_SUBMITTER_VAR, processInstance.getStartUserId());}}//5.删除节点this.deleteActivity(backTaskVo.getDistFlowElementId(), taskEntity.getProcessInstanceId());List<String> executionIds = new ArrayList<>();//6.判断节点是不是子流程内部的节点if (flowableBpmnModelService.checkActivitySubprocessByActivityId(taskEntity.getProcessDefinitionId(),backTaskVo.getDistFlowElementId())&& flowableBpmnModelService.checkActivitySubprocessByActivityId(taskEntity.getProcessDefinitionId(),taskEntity.getTaskDefinitionKey())){//6.1 子流程内部驳回Execution executionTask = runtimeService.createExecutionQuery().executionId(taskEntity.getExecutionId()).singleResult();String parentId = executionTask.getParentId();List<Execution> executions = runtimeService.createExecutionQuery().parentId(parentId).list();executions.forEach(execution -> executionIds.add(execution.getId()));this.moveExecutionsToSingleActivityId(executionIds,backTaskVo.getDistFlowElementId());}else {//6.2 普通驳回List<Execution> executions = runtimeService.createExecutionQuery().parentId(taskEntity.getProcessInstanceId()).list();executions.forEach(execution -> executionIds.add(execution.getId()));this.moveExecutionsToSingleActivityId(executionIds,backTaskVo.getDistFlowElementId());}returnVo = new ReturnVo<>(ReturnCode.SUCCESS, "驳回成功!");} else {returnVo = new ReturnVo<>(ReturnCode.FAIL, "不存在任务实例,请确认!");}return returnVo;}

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

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

相关文章

真相了!AI 程序员:我们根本没有 80w 年薪好么?

去年大家曾热议一篇文章《已毕业年薪就80万&#xff0c;没出校门就抢光&#xff0c;AI人才真这么值钱&#xff1f;》&#xff0c;大多数业内人士都表示&#xff0c;其实这是幸存者偏差&#xff0c;有人拿到80万&#xff0c;但不是全部。笔者综合了BOSS招聘、拉勾网、猎聘、领英…

ECS控制台实例搜索的优化与改进

摘要&#xff1a; 搜索功能是控制台非常重要的功能&#xff0c;承载着实例管理入口的作用&#xff0c;应该好用&#xff0c;快速和准确。然而&#xff0c;ECS控制台实例列表的搜索功能经常被吐槽不好用&#xff0c;痛点主要有以下三点&#xff1a; 每次搜索之前需要选择搜索类型…

Wpf中的sqlite数据库的连接和迁移

首先你需要安装如图的三个第三方包&#xff0c;创建APi项目并且将此项目设置为启动项第二步&#xff0c;在你的APi项目里面创建context文件夹&#xff0c;在此文件夹下创建你所需要的类&#xff08;数据库的表&#xff09;&#xff0c;在类中创建字段&#xff08;数据库中的字段…

python request url 转义_Python爬虫入门笔记

来源&#xff1a;blog.csdn.net/weixin_44864260爬虫四大步骤&#xff1a;1.获取页面源代码2.获取标签3.正则表达式匹配4.保存数据1. 获取页面源代码5个小步骤:1.伪装成浏览器2.进一步包装请求3.网页请求获取数据4.解析并保存5.返回数据代码&#xff1a;import urllib.request,…

ECS TAG功能详解

摘要&#xff1a; Tag&#xff08;标签&#xff09;&#xff0c;阿里云提供的一种标记资源的方式&#xff0c;对资源添加标签可以方便地对资源进行标记&#xff0c;从而方便的进行资源的批量管理&#xff0c;现在ECS可以使用Tag标记的资源主要有以下几种&#xff1a;实例、磁盘…

日本三大移动通信运营商已重启华为手机销售;高通与LG和解 签署新的5年期专利授权协议; Facebook加密货币Libra被审查...

戳蓝字“CSDN云计算”关注我们哦&#xff01;嗨&#xff0c;大家好&#xff0c;重磅君带来的【云重磅】特别栏目&#xff0c;如期而至&#xff0c;每周五第一时间为大家带来重磅新闻。把握技术风向标&#xff0c;了解行业应用与实践&#xff0c;就交给我重磅君吧&#xff01;重…

工作流实战_21_flowable 加签 任务向前加签 向后加签

项目地址https://gitee.com/lwj/flowable.git代码分支flowable-base视频讲解地址https://www.bilibili.com/video/av78471660/ 用户名密码0000001test0000002test0000003test0000004test文章目录1. 场景分析2. 演示&#xff1a;3. 代码分享3.1. 加签的方法3.2. 审批环节处理1.…

视频直播常见问题与解决办法汇总【系列二—直播截图】

摘要&#xff1a; 使用场景 用户常需要对视频直播的内容进行分析。例如&#xff0c;需要对直播中的某一帧的内容作为封面图片或者对于直播内容进行鉴黄以查看内容合法性等需求。因此&#xff0c;视频直播提供了实时截图功能满足用户的截图需求。 截图功能介绍 截图功能配置 配置…

hibernate 复合主键 根据主键删除_Python 之 MySql“未解之谜”11--主键 id 那些事

主键 id 用自增和 uuid 有什么区别&#xff1f;● uuid 有 16 个字节&#xff0c;比 int(4 byte)和 bigint(8 byte)占用更多存储空间有大量数据的时候 uuid 主键不会像自增主键那样越界&#xff0c;如果使用自增 id&#xff0c;字段类型一般选择 bigint● 如果 InnoDB 表的数据…

上万条数据撕开微博热搜的真相!

戳蓝字“CSDN云计算”关注我们哦&#xff01;作者 | 徐麟&#xff0c;某互联网公司数据分析狮来源 | 数据森麟&#xff08;id&#xff1a;shujusenlin&#xff09;吃瓜前言关于新浪微博&#xff0c;向来都是各路吃瓜群众聚集之地&#xff0c;大家在微博中可以尽情吃瓜&#xff…

机器学习与Scikit Learn学习库

摘要&#xff1a; 本文介绍机器学习相关的学习库Scikit Learn&#xff0c;包含其安装及具体识别手写体数字案例&#xff0c;适合机器学习初学者入门Scikit Learn。在我科研的时候&#xff0c;机器学习&#xff08;ML&#xff09;是计算机科学领域中最先吸引我的一门学科。虽然这…

工作流实战_19_flowable 任务委派

项目地址https://gitee.com/lwj/flowable.git代码分支flowable-base视频讲解地址https://www.bilibili.com/video/av78294766/ 用户名密码0000001test0000002test0000003test0000004test文章目录场景分析1. 演示2. 代码分享3. 委派的执行处理场景分析 解释&#xff1a;委派 A…

【视频点播最佳实践】使用OSS SDK上传视频到点播

摘要&#xff1a; 场景 点播上传SDK缺乏需要的语言版本&#xff08;如C/C、Go等&#xff09;或相应的功能&#xff08;如网络流上传、追加上传&#xff09;&#xff0c;可以直接使用OSS的SDK进行上传。 准备工作 确认已开通点播服务并完成了相关配置。确认已准备了阿里云账号AK…

Aruba 推出Instant On 为中小型企业提供安全、高速的无线连接

戳蓝字“CSDN云计算”关注我们哦&#xff01;让你过几天没有Wi-Fi的生活&#xff0c;是一种什么样的感受&#xff1f;在现代人的生活里&#xff0c;离不开Wi-Fi已经成为日常&#xff0c;超市、酒店、住宅、医院、高铁……你能想到的所有场景几乎都已经部署了Wi-Fi。从个人角度来…

NSURLProtocol 拦截 NSURLSession 请求时body丢失问题解决方案探讨

摘要&#xff1a; “IP直连方案”主要在于解决DNS污染、省去DNS解析时间&#xff0c;通常情况下我们可以在项目中使用 NSURLProtocol 拦截 NSURLSession 请求&#xff0c;下面将支持 Post 请求中面临的一个挑战&#xff0c;以及应对策略介绍一下。 “IP直连方案”主要在于解决D…

工作流实战_18_flowable 流程任务的转办

项目地址https://gitee.com/lwj/flowable.git代码分支flowable-base视频讲解地址https://www.bilibili.com/video/av78184848/ 用户名密码0000001test0000002test0000003test0000004test文章目录1. 演示2. 代码分享1. 演示 2. 代码分享 public ReturnVo<String> turnTa…

深入解读:获Forrester大数据能力高评价的阿里云DataWorks思路与能力

摘要&#xff1a; Forrester发布了Now Tech: Cloud Data Warehouse Q1 2018报告&#xff0c;报告对云化数据仓库&#xff08;Cloud Data Warehouse, CDW&#xff09;的主要功能、区域表现、细分市场和典型客户等进行了全面评估。 1.前言 本文基于Now Tech: Cloud Data Warehous…

用C语言倒置字符串

要逆置这个字符串&#xff0c;有很多种方法&#xff0c;在此说一次比较巧妙的方法 首先&#xff0c;逆置这个字符串&#xff0c;可以考虑单独的把每个单词都逆序一下&#xff0c;在对整个字符串进行逆序 考虑本题中的I like beijing. 首先对I、like、beijing. 中的每个单词逆序…

java中怎么把生成文件到项目根目录_[SpringBoot2.X] 02- 项目结构介绍

POM文件继承Spring Boot 的父级依赖&#xff0c;只有继承它项目才是 Spring Boot 项目。 spring-boot-starter-parent 是一个特殊的 starter&#xff0c;它用来提供相关的 Maven 默认依赖。使用它之后&#xff0c;常用的包依赖可以省去 version 标签。也就是继承的是springboot…

大咖云集、精彩议题、独家内容,2019 AI ProCon震撼来袭!(日程出炉)

2019年9月5-7日&#xff0c;面向AI技术人的年度盛会—— 2019 AI开发者大会 AI ProCon&#xff0c;火热来袭&#xff01; 继2018 年由CSDN成功举办AI 开发者大会一年之后&#xff0c;全球AI市场正发生着巨大的变化。顶尖科技企业和创新力量不断地进行着技术的更迭和应用的推进。…