首页 > 其他分享 >基于RuoYi-Flowable-Plus的若依ruoyi-nbcio支持自定义业务表单流程(三)

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

时间:2023-10-25 18:02:27浏览次数:39  
标签:dataId 自定义 business Flowable variables RuoYi new null String


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

gitee源代码地址

演示地址: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、效果图如下:

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

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

标签:dataId,自定义,business,Flowable,variables,RuoYi,new,null,String
From: https://blog.51cto.com/u_15070324/8023625

相关文章

  • 基于RuoYi-Flowable-Plus的若依ruoyi-nbcio支持自定义业务表单流程(二)
    更多ruoyi-nbcio功能请看演示系统gitee源代码地址演示地址:RuoYi-Nbcio后台管理系统   之前讲到了流程保存的时候还要看是否是自定义业务流程应用类型,若是保存的时候不再检查是否有关联表单。    那接下来就需要一个自己进行自定义表的流程关联工作了。1、见下图,在流程管......
  • 新手教程系类:群晖NAS如何自定义域名?保姆级教程包教包会
    感谢各位亲的大力支持,本店推出一些列新手教程希望能帮到你。对于个性化或者访问速度有着更高要求的用户,往往最后都会想给自己整个自定义域名,毕竟能够拥有一个专属的域名来访问自己的NAS,还是很方便的,今天就来更新一下DSM7版本的保姆级教程01申请公网IP公网IP是一定要有的,......
  • SpringBoot内容协商(Content Negotiation)二 —— 自定义消息转换器(MessageConverter)
    SpringBoot内置的消息转换器SpringBoot没有处理返回yaml格式的数据,这里需要手动添加处理这种返回格式的支持。导入依赖<dependency><groupId>com.fasterxml.jackson.dataformat</groupId><artifactId>jackson-dataformat-yaml</artifactId></dependency>添加配......
  • [linux] 自定义触摸板功能
    现在ubuntu最新版本使用wayland管理输入。而不是x11了,网上有很多教程建议使用的软件都不能用,搞不好还就把原来系统内置的一些东西搞坏了。在x11(xorg)下可以使用touchegg搭配touche使用,但是在wayland下不行。这里发一个目前实测可以用的自定义触摸板功能的软件叫fusumahttps://githu......
  • 如何在iEDA中添加自定义Tcl命令
    注:ScriptEngine和UserShell头文件和实现在iEDA/src/utility/tcl/ScriptEngine.hh路径下1使用ScriptEngine自定义Tcl命令ScriptEngine是Tcl命令解析器,包含命令、命令选项、解析器等一系列工具。用户可以使用ScriptEngine中的接口轻松实现自定义Tcl命令文件结......
  • uniapp 预览pdf app端使用自定义导航时铺满全屏,需要留出导航栏
    1、安装pdf预览插件:hybrid插件(网上资料很多) 2、封装预览vue页面(重点在加粗部分,使用原生导航没有问题,但是使用自定义导航就把状态栏全部盖住了)<template><viewclass="page"><web-view:webview-styles="webviewStyles":src="src"></web-view>&l......
  • 微信小程序--5. 如下图将顶部导航栏的地方改成自定义样式
    5.如下图将顶部导航栏的地方改成自定义样式1)配置app.json{"window":{"navigationStyle":"custom"//增加这行}} 2)、封装顶部导航栏的样式创建组件文件夹及文件miniprogram\components\navigation-bar\index//components/navigation-bar/index.wxml<!......
  • 基于mutation的自定义指令以监听用户使用f12修改dom
    昨天写了功能后,就又封了一个指令,可以直接应用于ui框架的input组件上贴贴:preventChange/index.jsexportconstpreventChange={inserted(el,binding){constelTag=el.tagName.toLowerCase();//获取当前dom下类型为password的input标签constpasswordI......
  • LambdaUpdateWrapper 自定义修改
    当我们想要在原有的数据上添加新的数据的时候,我们需要一个更新操作,但是<Iservice>接口一般是根据ID进行修改当我们需要根据指定的条件设置值时,就需要自己写SQL但是这个办法会出现SQL错误并且很麻烦所以我们可以自定义一个wrapper来进行修改。 这是全部的代码 这是我们要......
  • 【ChatGPT系列】Python自定义打印各种颜色的日志
    如何在控制台和文件中同时输出日志?要将日志同时输出到文件和控制台,可以创建并配置一个额外的StreamHandler,然后将其添加到Logger中。下面是一个示例代码,演示如何将日志同时输出到文件和控制台:importlogging#创建Logger对象logger=logging.getLogger("example_logger")......