基于RuoYi-Flowable-Plus的若依ruoyi-nbcio支持自定义业务表单流程(三)

news2024/11/27 11:56:53

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

gitee源代码地址

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

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

相应的后端也要做一些调整

1、启动流程修改如下:

/**
     * 启动流程实例
     */
    private R startProcess(ProcessDefinition procDef, Map<String, Object> variables) {
        if (ObjectUtil.isNotNull(procDef) && procDef.isSuspended()) {
            throw new ServiceException("流程已被挂起,请先激活流程");
        }   
        // 设置流程发起人Id到流程中,包括变量
        String userStr = TaskUtils.getUserName();
        SysUser sysUsr = sysUserService.selectUserByUserName(userStr);
 		setFlowVariables(sysUsr,variables);	
 		
 		Map<String, Object> variablesnew = variables;
 		Map<String, Object> usermap = new HashMap<String, Object>();
        List<String> userlist = new ArrayList<String>();
        boolean bparallelGateway = false;
        boolean bapprovedEG = false;
        
        //业务数据id
        String dataId = variables.get("dataId").toString();
        if(StringUtils.isNotEmpty(dataId)) {//自定义业务表单
        	//设置自定义表单dataid的数据 
            WfMyBusiness flowmybusiness = wfMyBusinessServiceImpl.getByDataId(variables.get("dataId").toString());
            String serviceImplName = flowmybusiness.getServiceImplName();
            WfCallBackServiceI flowCallBackService = (WfCallBackServiceI) SpringContextUtils.getBean(serviceImplName);
            if (flowCallBackService!=null){
              Object businessDataById = flowCallBackService.getBusinessDataById(variables.get("dataId").toString());
              variables.put("formData",businessDataById);
            }
        }
        
        //获取下个节点信息
        getNextFlowInfo(procDef, variablesnew, usermap, variables, userlist);
        
        //取出两个特殊的变量
        if(variablesnew.containsKey("bparallelGateway")) {//并行网关
        	bparallelGateway = (boolean) variablesnew.get("bparallelGateway");
        	variablesnew.remove("bparallelGateway");
        }
        if(variablesnew.containsKey("bapprovedEG")) {//通用拒绝同意排它网关
        	bapprovedEG = (boolean) variablesnew.get("bapprovedEG");
        	variablesnew.remove("bapprovedEG");
        }
      
        // 发起流程实例
        ProcessInstance processInstance = runtimeService.startProcessInstanceById(procDef.getId(), variables);
        // 第一个用户任务为发起人,则自动完成任务
        //wfTaskService.startFirstTask(processInstance, variables);
        R<Void> result = setNextAssignee(processInstance, usermap, userlist, sysUsr, variables, bparallelGateway, bapprovedEG);	
        if(StringUtils.isNotEmpty(dataId)) {//自定义业务表单
        	// 流程发起后的自定义业务更新-需要考虑两种情况,第一个发起人审批或跳过
            List<Task> tasks = taskService.createTaskQuery().processInstanceId(processInstance.getProcessInstanceId()).active().list();
            /*======================todo 启动之后  回调以及关键数据保存======================*/
            //如果保存数据前未调用必调的FlowCommonService.initActBusiness方法,就会有问题
            LoginUser sysUser = commonService.getLoginUser();
            if(tasks!=null) {
            	SysUser sysTaskUser = new SysUser();
            	List <String> listUser = new ArrayList<String>();
            	List <String> listId = new ArrayList<String>();
            	List <String> listName = new ArrayList<String>();
            	String taskUser = "";
            	String taskid = "";
            	String taskName = "";
            	int taskPriority = 0;
            	for(Task task : tasks) {
            		if(task.getAssignee() != null) {
                		sysTaskUser = commonService.getSysUserByUserName(task.getAssignee());
                		listUser.add(sysTaskUser.getNickName());
                	}
            		listId.add(task.getId());
            		listName.add(task.getName());
            	    taskPriority = task.getPriority();
            	}
            	taskUser = listUser.stream().map(String::valueOf).collect(Collectors.joining(","));
            	taskid = listId.stream().map(String::valueOf).collect(Collectors.joining(","));
            	taskName = listName.stream().map(String::valueOf).collect(Collectors.joining(","));
            	
            	WfMyBusiness business = wfMyBusinessServiceImpl.getByDataId(dataId);
    	        business.setProcessDefinitionId(procDef.getId());
    	        business.setProcessInstanceId(processInstance.getProcessInstanceId());
    	        business.setActStatus(ActStatus.doing);
    	        business.setProposer(sysUser.getUsername());
    	        business.setTaskId(taskid);
    	        business.setTaskName(taskName);
    	        business.setTaskNameId(taskid);
    	        business.setPriority(String.valueOf(taskPriority));
    	        business.setDoneUsers("");
    	        business.setTodoUsers(taskUser);
    	        wfMyBusinessService.updateById(business);
    	        //spring容器类名
    	        String serviceImplNameafter = business.getServiceImplName();
    	        WfCallBackServiceI flowCallBackServiceafter = (WfCallBackServiceI) SpringContextUtils.getBean(serviceImplNameafter);
    	        // 流程处理完后,进行回调业务层
    	        business.setValues(variables);
    	        if (flowCallBackServiceafter!=null)flowCallBackServiceafter.afterFlowHandle(business);
            }
            else {
            	WfMyBusiness business = wfMyBusinessServiceImpl.getByDataId(dataId);
    	        business.setProcessDefinitionId(procDef.getId());
    	        business.setProcessInstanceId(processInstance.getProcessInstanceId());
    	        business.setActStatus(ActStatus.pass);
    	        business.setProposer(sysUser.getUsername());
    	        business.setTaskId("");
    	        business.setTaskName("");
    	        business.setTaskNameId("");
    	        business.setDoneUsers("");
    	        business.setTodoUsers("");
    	        wfMyBusinessService.updateById(business);
    	        //spring容器类名
    	        String serviceImplNameafter = business.getServiceImplName();
    	        WfCallBackServiceI flowCallBackServiceafter = (WfCallBackServiceI) SpringContextUtils.getBean(serviceImplNameafter);
    	        // 流程处理完后,进行回调业务层
    	        business.setValues(variables);
    	        if (flowCallBackServiceafter!=null)flowCallBackServiceafter.afterFlowHandle(business);
            }
        }
        return result;	
    }

2、获取表单列表修改如下:

/**
     * 获取历史流程表单信息
     */
    private List<FormConf> processFormList(BpmnModel bpmnModel, HistoricProcessInstance historicProcIns, String dataId) {
        List<FormConf> procFormList = new ArrayList<>();

        List<HistoricActivityInstance> activityInstanceList = historyService.createHistoricActivityInstanceQuery()
            .processInstanceId(historicProcIns.getId()).finished()
            .activityTypes(CollUtil.newHashSet(BpmnXMLConstants.ELEMENT_EVENT_START, BpmnXMLConstants.ELEMENT_TASK_USER))
            .orderByHistoricActivityInstanceStartTime().asc()
            .list();
        List<String> processFormKeys = new ArrayList<>();
        for (HistoricActivityInstance activityInstance : activityInstanceList) {
            // 获取当前节点流程元素信息
            FlowElement flowElement = ModelUtils.getFlowElementById(bpmnModel, activityInstance.getActivityId());
            // 获取当前节点表单Key
            String formKey = ModelUtils.getFormKey(flowElement);
            if (formKey == null) {
                continue;
            }
            boolean localScope = Convert.toBool(ModelUtils.getElementAttributeValue(flowElement, ProcessConstants.PROCESS_FORM_LOCAL_SCOPE), false);
            Map<String, Object> variables;
            if (localScope) {
                // 查询任务节点参数,并转换成Map
                variables = historyService.createHistoricVariableInstanceQuery()
                    .processInstanceId(historicProcIns.getId())
                    .taskId(activityInstance.getTaskId())
                    .list()
                    .stream()
                    .collect(Collectors.toMap(HistoricVariableInstance::getVariableName, HistoricVariableInstance::getValue));
            } else {
                if (processFormKeys.contains(formKey)) {
                    continue;
                }
                variables = historicProcIns.getProcessVariables();
                processFormKeys.add(formKey);
            }  
           
            Map<String, Object> formvariables = new HashedMap<String, Object>();
            //遍历Map
            if(variables.containsKey("variables")) {
              formvariables = (Map<String, Object>)((Map<String, Object>) variables.get("variables")).get("formValue");
            }
 
            // 非节点表单此处查询结果可能有多条,只获取第一条信息
            List<WfDeployFormVo> formInfoList = deployFormMapper.selectVoList(new LambdaQueryWrapper<WfDeployForm>()
                .eq(WfDeployForm::getDeployId, historicProcIns.getDeploymentId())
                .eq(WfDeployForm::getFormKey, formKey)
                .eq(localScope, WfDeployForm::getNodeKey, flowElement.getId()));

            //@update by Brath:避免空集合导致的NULL空指针
            WfDeployFormVo formInfo = formInfoList.stream().findFirst().orElse(null);
         
            if (ObjectUtil.isNotNull(formInfo)) {
                // 旧数据 formInfo.getFormName() 为 null
                String formName = Optional.ofNullable(formInfo.getFormName()).orElse(StringUtils.EMPTY);
                String title = localScope ? formName.concat("(" + flowElement.getName() + ")") : formName;
                FormConf formConf = JsonUtils.parseObject(formInfo.getContent(), FormConf.class);
                if (null != formConf) {
                    //ProcessFormUtils.fillFormData(formConf, variables);
                	formConf.setTitle(title);
                	formConf.setFormValues(formvariables);
                    procFormList.add(formConf);
                }
            }
        }
        if(StringUtils.isNoneEmpty(dataId)) {
        	WfMyBusiness business = wfMyBusinessServiceImpl.getByDataId(dataId);
            String serviceImplName = business.getServiceImplName();
            WfCallBackServiceI flowCallBackService = (WfCallBackServiceI) SpringContextUtils.getBean(serviceImplName);
            // 流程处理完后,进行回调业务层
            if (flowCallBackService!=null){
            	Map<String, Object> customMap = new HashMap<String, Object>();
	            FormConf formConf = new FormConf();
	            Object businessDataById = flowCallBackService.getBusinessDataById(dataId);
	            customMap.put("formData",businessDataById);
	            customMap.put("routeName", business.getRouteName());
	            formConf.setFormValues(customMap);
	            procFormList.add(formConf);
            }
        }
        return procFormList;
    }

3、效果图如下:

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

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

相关文章

乡村新业态 | 直播电商引领经济发展,拓世法宝AI智能直播一体机助推乡村振兴

党的二十大报告作出加快建设数字中国、全面推进乡村振兴的战略部署&#xff0c;为进一步加强数字乡村建设、全面推进乡村振兴指明了方向。近年来&#xff0c;随着乡村新业态新模式的不断涌现&#xff0c;以直播电商为代表的数字经济为各地的农村产业升级带来了新契机。各地政府…

类文件黄色时钟解决办法

类文件黄色时钟解决办法 有时候我们的类上面会有黄色时钟&#xff0c;如下图&#xff1a; 像这种情况怎么解决呢&#xff1f;我们可以把我们的模块对应的pom.xml文件假如到maven中&#xff0c;右键pom.xml文件&#xff0c;加入到Maven项目中&#xff0c;如下图&#xff1a; …

Python实现PDF转换文件格式

最近工作中经常遇到收到其他人提供的pdf文档&#xff0c;想要编辑修改下或者复制部分内容比较困难&#xff0c;想通过现有的pdf工具软件转换文档格式&#xff0c;基本都要充钱&#xff0c;为了免费实现pdf转换工具&#xff0c;网上查了下相关技术方案&#xff0c;整理了下代码&…

【EI会议征稿】第三届高性能计算与通信工程国际学术会议(HPCCE 2023)

第三届高性能计算与通信工程国际学术会议(HPCCE 2023) 第三届高性能计算与通信工程国际学术会议&#xff08;HPCCE 2023&#xff09;将于2023年12月22-24日在长沙召开。HPCCE 2023将围绕“高性能计算与通信工程”的最新研究领域&#xff0c;为来自国内外高等院校、科学研究所、…

安防视频监控EasyCVR视频汇聚平台与萤石云平台的适配方案分析

随着科技的不断发展&#xff0c;互联网技术逐渐深入到我们生活的各个领域。其中&#xff0c;安防监控领域受益于互联网技术的发展&#xff0c;逐渐呈现出智能化、高清化、远程化的趋势。本文将介绍一种基于萤石云与EasyCVR平台的安防视频监控解决方案&#xff0c;以满足用户对安…

为什么估计的参数具有渐进高斯性?M-estimateor的渐进高斯性推导

M-estimators 在这里我们研究一种叫M-estimators的渐进高斯性。具体来说&#xff0c;如果参数估计可以用一个最小化或者最大化目标表示&#xff1a; θ o arg ⁡ min ⁡ θ ∈ Θ E [ q ( w , θ ) ] \theta _{o} \arg\min_{\theta \in \Theta }\mathbb{E}[ q(w,\theta )] θ…

HHDESK便捷功能介绍四

1 窗口切换 在文件管理界面&#xff0c;点击切换按钮&#xff0c;除了可以对左右两边窗口进行位置切换&#xff1b; 也可以直接打开该文件夹&#xff0c;并且进行图片浏览。 2 新建功能 同样是在文件管理中&#xff0c;点击新建&#xff0c;可在当前文件夹中创建各类文件&…

长连接与短连接的区别以及使用场景

文章底部有个人公众号&#xff1a;热爱技术的小郑。主要分享开发知识、学习资料、毕业设计指导等。有兴趣的可以关注一下。为何分享&#xff1f; 踩过的坑没必要让别人在再踩&#xff0c;自己复盘也能加深记忆。利己利人、所谓双赢。 短连接 1、连接->传输数据->关闭连接…

想做WMS仓库管理系统,找了好久才找到云表

公司内部仓库管理原方式均基于人工电子表格管理方式来实现收发存管理&#xff0c;没有流程化管理&#xff0c;无法保证数据的准确性和及时性&#xff0c;同时现场操作和数据核对会出现不同步的情况&#xff0c;无法提高仓库的运作效率&#xff0c;因此&#xff0c;我们基于云表…

区块链服务网络BSN季度版本迭代说明【2023年Q3】

根据区块链服务网络发展联盟计划安排&#xff0c;BSN将每周进行一个小的版本迭代&#xff0c;每季度进行一个大的版本迭代&#xff0c;目前区块链服务网络&#xff08;BSN&#xff09;已完成最新季度版本迭代。 我们将按照BSN官方专网&#xff08;国内版和国际版&#xff09;、…

网络工程师知识点5

71、什么是FTP&#xff1f; FTP是文件传输协议。 FTP传输数据时支持两种传输模式&#xff1a;ASCII模式和二进制模式。 需要TCP的21号端口来建立控制连接 需要TCP的20号端口来建立数据连接 72、什么是telnet&#xff1f; Telnet提供了一个交互式操作界面&#xff0c;允许终端远…

用Eclipse写java代码

1.新建项目 2.选择创建java项目 3.输入项目名称&#xff0c;选择specific JRE 可以选1.8版本的&#xff0c;finish 4.在src中新建包&#xff0c;包名为项目名.包名 5.在包中新建类 如何修改eclipse字体大小 看这里 6.写代码&#xff0c;写好之后运行 报错a jni error…

问:TCP/IP协议栈在内核态的好还是用户态的好

“TCP/IP协议栈到底是内核态的好还是用户态的好&#xff1f;” 问题的根源在于&#xff0c;干嘛非要这么刻意地去区分什么内核态和用户态。 引子 为了不让本文成为干巴巴的说教&#xff0c;在文章开头&#xff0c;我以一个实例分析开始。 最近一段时间&#xff0c;我几乎每…

ASEMI整流桥GBJ2510参数:拆析其关键性能特点

编辑-Z 在众多的电力电子元件中&#xff0c;GBJ2510整流桥以其高效能和可靠性赢得了工业领域的广泛认可。这款设备是在电力系统、直流电源等一系列设备中不可或缺的组件。本文将详细反析GBJ2510整流桥参数的关键性能特点&#xff0c;以帮助用户更加全面地理解和使用这种电子设…

微信小程序用 canvas 实现手写签名弹框(全网最最最详细!!)

文章目录 一、签字面板效果图二、WXML文件三、JS文件四、WXSS文件五、小Tips ~ 一、签字面板效果图 二、WXML文件 &#x1f338;点击弹出手写签名面板事件 <van-button type"default" bindtap"handWrittenSign">点击弹出手写签名弹框</van-butt…

通过电商API接口,代购系统可以获取到商品、订单、物流等多种信息

代购系统需要接入电商API接口&#xff0c;以便实现与电商平台的交互与数据共享。通过电商API接口&#xff0c;代购系统可以获取到商品、订单、物流等多种信息&#xff0c;同时也可以完成下单、支付、退货等多种操作。 对于用户来说&#xff0c;接入电商API接口可以提供以下好处…

Linux性能基础:CPU、内存、磁盘等概述

目录 1. CPU 1.1. CPU常见品牌 1.2. CPU性能概述 ① CPU主频 ② CPU位数 ③ CPU缓存指令集 ④ CPU核心数 ⑤ IPC 1.3. 上下文切换 1.4. 进程与线程 ① 进程 ② 线程 2. 内存 2.1. 内存主频 2.2. 内存带宽 2.3. 内存分类 2.4. 内存的分配 2.5. 内存的回收 2.6. 内存泄漏 3. 磁盘…

Mysql系列---【linux安装mysql8.1.0】

1.下载安装包 官网链接: https://dev.mysql.com/downloads/mysql/ 注意:linux查看glibc版本的命令: rpm -qa|grep glibc 2.把下载的包上传到/opt/app/middles目录下 注意: 速度可能有点慢。 3.解压压缩包 #xz解压 xz -d mysql-8.1.0-linux-glibc2.17-x86_64.tar.xz #tar解压 t…

c++仿写小波分解和去噪代码(只使用基础库)

小波分解C版本 C代码 参考了一些Github的代码 最终代码可从链接下载。 main函数如果打不开的话&#xff0c;使用 #include <iostream> #include <vector> #include <fstream> #include "wavelet.h"int main() {// 读取原始信号数据std::ifstrea…

用户生成内容vs专业生成内容:谁主海外社媒营销江山?

随着社交媒体和数字营销的崛起&#xff0c;海外社媒营销已经成为各大品牌推广产品和服务的一种主要方式。然而&#xff0c;在选择最佳策略时&#xff0c;品牌经常会面临一个关键的问题&#xff1a;是使用用户生成内容&#xff08;UGC&#xff09;还是专业生成内容&#xff08;P…