基于若依ruoyi-nbcio支持flowable流程角色,同时修改流转用户为username,流程启动做大调整(三)

news2024/10/7 12:28:54

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

 gitee源代码地址

 前后端代码: ruoyi-nbcio: nbcio-boot的若依版本,基于ruoyi-flowable-plus和flowable6.7.2,目前处于移植功能阶段,目标是打造一个最好的若依平台上flowable流程管理系统开源版本,希望有需要的同仁一起打造。如果觉得这个项目对你有帮助,麻烦点个star。

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

    接上一个文章。

1、设置多实例等相关参数

 
    //设置单用户下一节点流程数据
    private void setAssigneeFlowNetDto(FlowNextDto flowNextDto,List<SysUser> list,UserTask userTask) {
    	flowNextDto.setVars(ProcessConstants.PROCESS_APPROVAL);
	    flowNextDto.setType(ProcessConstants.USER_TYPE_ASSIGNEE);
	    flowNextDto.setUserList(list);
	    flowNextDto.setUserTask(userTask);
    }
    
    //设置多用户下一节点流程数据
    private void setUsersFlowNetDto(FlowNextDto flowNextDto,List<SysUser> list,UserTask userTask) {
    	flowNextDto.setVars(ProcessConstants.PROCESS_APPROVAL);
        flowNextDto.setType(ProcessConstants.USER_TYPE_USERS);
        flowNextDto.setUserList(list);
        flowNextDto.setUserTask(userTask);
    }
    
    //设置多实例结束标志
    private void setMultiFinishFlag(Task task,FlowNextDto flowNextDto,List<SysUser> list) {
    	String definitionld = runtimeService.createProcessInstanceQuery().processInstanceId(task.getProcessInstanceId()).singleResult().getProcessDefinitionId();        //获取bpm(模型)对象
        BpmnModel bpmnModel = repositoryService.getBpmnModel(definitionld);
        //通过节点定义key获取当前节点
        FlowNode flowNode = (FlowNode) bpmnModel.getFlowElement(task.getTaskDefinitionKey());
        if(flowNode instanceof UserTask ){
        	UserTask curuserTask = (UserTask) flowNode;
        	MultiInstanceLoopCharacteristics curmultiInstance = curuserTask.getLoopCharacteristics();
        	if (Objects.nonNull(curmultiInstance)) {
        		if(list.size()>1) {//多人选择的时候,从redis获取之前监听器写入的会签结束信息
        		   String smutinstance_next_finish = Constants.MUTIINSTANCE_NEXT_FINISH + task.getProcessInstanceId(); 	
        	       if(Objects.nonNull(RedisUtils.getCacheObject(smutinstance_next_finish))) {
        		      flowNextDto.setBmutiInstanceFinish(true);
        	       }
                }
        	}
        }
    }
    
    //设置多实例流程表达式
    private void setMultiFlowExp(FlowNextDto flowNextDto,UserTask newUserTask,MultiInstanceLoopCharacteristics multiInstance,String methodname,Object[] argsPara) {
    	List<SysUser> list = new ArrayList<SysUser>();
		flowExp flowexp = SpringContextUtils.getBean(flowExp.class);
		//Object[] argsPara=new Object[]{};
		List<String> templist = new ArrayList<String>();
		try {
			templist = (List<String>) flowexp.invokeMethod(flowexp, methodname,argsPara);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		for(String sysuser : templist) {
      		SysUser sysUserTemp = sysUserService.selectUserByUserName(sysuser);
      		list.add(sysUserTemp);
      	}
		newUserTask.setAssignee("${assignee}");
		newUserTask.setCandidateUsers(templist);
		setMultiFlowNetDto(flowNextDto,list,newUserTask,multiInstance);
    }
    
    //设置多实例流程数据
    private void setMultiFlowNetDto(FlowNextDto flowNextDto,List<SysUser> list,UserTask userTask,MultiInstanceLoopCharacteristics multiInstance) {
    	flowNextDto.setVars(ProcessConstants.PROCESS_MULTI_INSTANCE_USER);
        flowNextDto.setType(ProcessConstants.PROCESS_MULTI_INSTANCE);
        flowNextDto.setUserList(list);
        flowNextDto.setUserTask(userTask);
        if(multiInstance.isSequential()) {
        	flowNextDto.setBisSequential(true);
        }
        else {
        	flowNextDto.setBisSequential(false);
        }
    }

2、校验el表达示例

/**
     * 校验el表达示例
     *
     * @param map
     * @param expression
     * @return
     */
    public static Object result(Map<String, Object> map, String expression) {
    	Object result = null; 
    	try {
	        FelEngine fel = new FelEngineImpl();
	        FelContext ctx = fel.getContext();
	        for (Map.Entry<String, Object> entry : map.entrySet()) {
	            ctx.set(entry.getKey(), entry.getValue());
	            System.out.print(entry.getKey() + "-"+ entry.getValue());
	        }
	        String exp = "";
	        if (expression.indexOf("<") >0) {
	        	exp = expression.substring(0, expression.indexOf("<"));
	        }
	        else if (expression.indexOf(">") >0) {
	        	int index =expression.indexOf(">");
	        	exp = expression.substring(0, index);
	        }
	        else if (expression.indexOf("==") >0) {
	        	exp = expression.substring(0, expression.indexOf("=="));
	        }
	        exp =expression.replace(exp, ctx.get(exp).toString());
	        result = fel.eval(exp);
	        //result = fel.eval(expression);
		} catch (Exception e) {
			result = null;	
		}
    	 return result;
    }

3、获取排他网关分支名称、分支表达式是否存在

/**
     * 获取排他网关分支名称、分支表达式是否存在${approved}
     * @param flowElement
     * @param 
     * add by nbacheng
     */
    public static boolean GetExclusiveGatewayExpression(FlowElement flowElement) {
    	// 获取所有网关分支
        List<SequenceFlow> targetFlows=((ExclusiveGateway)flowElement).getOutgoingFlows();
        // 循环每个网关分支
        for(SequenceFlow sequenceFlow : targetFlows){
            // 获取下一个网关和节点数据
            FlowElement targetFlowElement=sequenceFlow.getTargetFlowElement();
            // 网关数据不为空
            if (StringUtils.isNotBlank(sequenceFlow.getConditionExpression())) {
                // 获取网关判断条件
            	String expression = sequenceFlow.getConditionExpression();
            	if(expression.contains("${approved}")) {
            		return true;
            	}
            }
        }    
    	return false;   	
    }

4、工作流任务工具类主要是增加username

/**
 * 工作流任务工具类
 *
 * @author konbai
 * @createTime 2022/4/24 12:42
 */
public class TaskUtils {

    public static String getUserId() {
        return String.valueOf(LoginHelper.getUserId());
    }

    public static String getUserName() {
        return LoginHelper.getUserName();
    }
    
    /**
     * 获取用户组信息
     *
     * @return candidateGroup
     */
    public static List<String> getCandidateGroup() {
        List<String> list = new ArrayList<>();
        LoginUser user = LoginHelper.getLoginUser();
        if (ObjectUtil.isNotNull(user)) {
            if (ObjectUtil.isNotEmpty(user.getRoles())) {
                user.getRoles().forEach(role -> list.add(TaskConstants.ROLE_GROUP_PREFIX + role.getRoleId()));
            }
            if (ObjectUtil.isNotNull(user.getDeptId())) {
                list.add(TaskConstants.DEPT_GROUP_PREFIX + user.getDeptId());
            }
        }
        return list;
    }
}

5、效果图如下:

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

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

相关文章

【项目】Http服务器

【项目】Http服务器 项目简介 背景&#xff1a; http协议被广泛使用&#xff0c;从移动端&#xff0c;pc端浏览器&#xff0c;http协议无疑是打开互联网应用窗口的重要协议&#xff0c;http在网络应用层中的地位不可撼动&#xff0c;是能准确区分前后台的重要协议。 描述&a…

MD5 绕过第一式:弱比较绕过

文章目录 参考环境MD5韧性脆弱性md5() 隐式类型转换字符串连接数学运算布尔判断相等运算符 科学计数法科学计数法前缀 0E 与 0e PHP8 与 PHP 其他版本下字符串转化为数值的具体规则PHP8数值字符串优化 其他版本更为详细的讲解 字符串与字符串的弱比较字符串与数值的弱比较0e215…

git查看自己所在的分支

很多时候可能大家不太想切换其他工具&#xff0c;又不知道自己是否在自己需要操作的分支 可以直接终端执行 git branch此时 他就会在终端将所有的本地分支输出出来 并特殊标注自己所在的分支 这样我们就可以进一步去做自己想要做的操作了 当然 随着各种编辑器的发展 这个命令…

视频剪辑软件哪个好? 2023年最新功能解析

如今聊到视频的话题&#xff0c;大家可能都注意到近年来火爆的抖音短视频。从图片到动画&#xff0c;从动画到视频。时代在发展&#xff0c;技术在更新。到了近几年小视频也火了&#xff0c;其实不乏缺有视频剪辑软件的功劳。现在不少朋友在业余时间都喜欢剪辑视频来丰富自己的…

支撑电动汽车规模化,特来电智能化升级群充产品

9月26日&#xff0c;中国领先的充电网生态运营商特来电重磅发布智能群充4.0产品&#xff0c;标志着特来电群充产品体系进一步升级&#xff0c;充电行业迎来更高质量、更高性能的设备与系统&#xff0c;充电网基础设施将更好地支撑大规模电动汽车的发展。 群充技术路线引领充电…

音频处理基础的一些笔记碎片

感谢 B 站上关于 EQ 扫盲视频分享 &#x1f50a;声音变好听-让均衡器改变你的音色|均衡器怎么调&#xff1f;&#xff08;adobe audition 2020基础教程&#xff09; 简要内容 a. 人耳能够听到的频率 20HZ-20000HZ&#xff1b; b. 人耳普遍认为低于 80HZ 是噪声&#xff1b; c. …

华为智能企业上网行为管理安全解决方案(1)

华为智能企业上网行为管理安全解决方案&#xff08;1&#xff09; 课程地址方案背景需求分析企业上网行为概述企业上网行为安全风险分析企业上网行为管理需求分析 方案设计组网架构设备选型设备简介行为管理要点分析方案功能概述 课程地址 本方案相关课程资源已在华为O3社区发…

MQTT协议知识梳理,看完你就懂了!

一.MQTT简介 MQTT是基于TCP/IP协议栈构建的异步通信消息协议&#xff0c;是一种轻量级的发布/订阅信息传输协议。MQTT在时间和空间上&#xff0c;将消息发送者与接受者分离&#xff0c;可以在不可靠的网络环境中进行扩展。 适用于设备硬件存储空间有限或网络带宽有限的场景。物…

SpringBoot 员工管理---通用模板 ---苍穹外卖day2

感谢点击 希望你有所收获! 目录 1.新增员工 需求分析:根据页面原型进行业务分析 接口设计 数据库设计 代码开发 功能测试 如何在接口文档中统一添加JWT令牌 ​ 获取当前登录员工的ID 2.员工分页查询 需求分析 代码开发 如何将日期格式化 ​3.启用禁用员工 1.新…

软件设计模式——工厂模式

摘要 本博文主要介绍软件设计模式中工厂模式&#xff0c;其中工厂设计模式的扩展为简单工厂(Simple Factory)、工厂方法(Factory Method)、抽象工厂(Abstract Factory)三种。 一、简单工厂(Simple Factory) 主要分析设计模式 - 简单工厂(Simple Factory)&#xff0c;它把实例…

day07_方法

今日内容 零、 复习昨日 一、作业讲解 二、方法[重点] 零、 复习昨日 一、作业讲解 package com.qf.homework;import java.util.Scanner;/*** desc*/ public class Homework {public static void main(String[] args) {/*** --------------------* 边写边测试* 以结果倒推* …

HTML详细基础(二)文件路径

目录 一.相对路径 二.绝对路径 三.超链接标签 四.锚点链接 首先&#xff0c;扩展一些HTML执行的原理&#xff1a; htmL(hypertext markup Language) 是一种规范&#xff08;或者说是一种标准&#xff09;&#xff0c;它通过标记符&#xff08;tag&#xff09;来标记要显示…

D课堂 | 什么是DNS?DNS是怎么运作的?

想象一下&#xff0c;你在一个陌生的城市&#xff0c;想去一家餐厅品尝美食。你知道这家餐厅的名字&#xff0c;但却不知道它的具体位置。 这时&#xff0c;你可能会打开手机地图&#xff0c;输入餐厅的名字&#xff0c;然后地图会告诉你如何到达那里。 在互联网世界里&#xf…

向量数据库库Milvus Cloud2.3 的QA问题

1. Milvus 从 2.2.x 升级至 2.3.x 的最大变化是什么? 如果用一句话来总结,那就是使用的场景更加丰富了。具体可以从两个方面来体现,即部署环境和用户的使用感。 例如,从部署环境来看,Milvus 原来只支持 X86 架构的 CPU,版本升级后,不仅可以支持 GPU,还能够支持 ARM 架构…

二叉树MFC实现

设有一颗二叉树如下&#xff1b; 这似乎是一颗经常用作示例的二叉树&#xff1b; 对树进行遍历的结果是&#xff0c; 先序为&#xff1a;3、2、2、3、8、6、5、4&#xff0c; 中序为&#xff1a;2、2、3、3、4、5、6、8&#xff0c; 后序为2、3、2、4、5、6、8、3&#xff1b…

Kubernetes 学习总结(38)—— Kubernetes 与云原生的联系

一、什么是云原生&#xff1f; 伴随着云计算的浪潮&#xff0c;云原生概念也应运而生&#xff0c;而且火得一塌糊涂&#xff0c;大家经常说云原生&#xff0c;却很少有人告诉你到底什么是云原生&#xff0c;云原生可以理解为“云”“原生”&#xff0c;Cloud 可以理解为应用程…

深入浅出DAX:数据分析

深入浅出DAX&#xff1a;数据分析 01、区间分析 1. 数据区间分析 在Power BI中&#xff0c;选择“主页”→“输入数据”&#xff0c;创建“区间辅助表”&#xff0c;如图1所示。 ■ 图1 区间辅助表 创建度量值M.区间次数&#xff0c;表达式如下&#xff1a; M.区间次数 VA…

POJ 2991 Crane 线段树

一、题目大意 我们有一台起重机的机械臂&#xff0c;它由多个节相连组成&#xff0c;如下所示。 起初的时候&#xff0c;所有的节之间的角度都是180度&#xff0c;是竖直的&#xff0c;我们可以扭转其中任意两个节的角度&#xff0c;每一次移动后题目需要输出题目最后一个点相…

干货 | 工商业用户负荷分析与预测系统项目

以下内容整理自2023年夏季学期大数据能力提升项目《大数据实践课》同学们所做的期末答辩汇报。 我们将从六个方面进行展示。 第一部分是项目背景与需求分析。在“双碳”目标的大背景下&#xff0c;能源电力行业面临着深刻的变革&#xff0c;负荷预测作用也更加突出。虚拟电厂由…

蓝牙无线IP网络多功能多媒体音柱带遥控

SV-29810T-蓝牙无线IP网络多功能多媒体音柱带遥控 蓝牙无线IP网络多功能多媒体音柱SV-29810T产品用途&#xff1a; ◆室外室内豪华型防水音柱式一体化网络音频解码扬声器&#xff0c;用于广播分区音频解码、声音还原作用◆应用场地如火车站、地铁、教堂、工厂、仓库、公园停车…