基于Jeecg-boot的flowable流程支持拒绝同意流程操作(二)

简介: 基于Jeecg-boot的flowable流程支持拒绝同意流程操作(二)

更多功能看演示系统

gitee源代码地址

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

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

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

       因为看很多朋友需要这种同意拒绝的排它网关流程,因为之前还不支持的第一个发起人后面的这种排它网关操作,所以这部分完善这个功能。

1、FindNextNodeUtil类增加一个方法

/**
     * 获取排他网关分支名称、分支表达式是否存在${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;     
    }

2、启动流程里增加下面信息

//取出两个特殊的变量
        if(variablesnew.containsKey("bparallelGateway")) {//并行网关
          bparallelGateway = (boolean) variablesnew.get("bparallelGateway");
          variablesnew.remove("bparallelGateway");
        }
        if(variablesnew.containsKey("bapprovedEG")) {//通用拒绝同意排它网关
          bapprovedEG = (boolean) variablesnew.get("bapprovedEG");
          variablesnew.remove("bapprovedEG");
        }

3、getNextFlowInfo修改如下:

private void getNextFlowInfo(ProcessDefinition processDefinition, Map<String, Object> variablesnew, Map<String, Object> usermap,
                           Map<String, Object> variables, List<String> userlist) {
    String definitionld = processDefinition.getId();        //获取bpm(模型)对象
        BpmnModel bpmnModel = repositoryService.getBpmnModel(definitionld);
        //传节点定义key获取当前节点
        List<org.flowable.bpmn.model.Process> processes =  bpmnModel.getProcesses();
        //只处理发起人后面排它网关再后面是会签的情况,其它目前不考虑
        //List<UserTask> userTasks = process.findFlowElementsOfType(UserTask.class);
        List<FlowNode> flowNodes = processes.get(0).findFlowElementsOfType(FlowNode.class);
        List<SequenceFlow> outgoingFlows = flowNodes.get(1).getOutgoingFlows();
        //遍历返回下一个节点信息
        for (SequenceFlow outgoingFlow : outgoingFlows) {
            //类型自己判断(获取下个节点是网关还是节点)
            FlowElement targetFlowElement = outgoingFlow.getTargetFlowElement();
            //下个是节点
           if(targetFlowElement instanceof ExclusiveGateway){// 下个出口是排它网关的话,后一个用户任务又是会签的情况下需要approval的赋值处理,否则报错
             usermap =  GetExclusiveGatewayUser(targetFlowElement,variables);//还是需要返回用户与是否并发,因为并发要做特殊处理
             if(usermap != null) {
             userlist = (ArrayList<String>) usermap.get("approval");
               variablesnew.put("approval", userlist);
             }
             if(FindNextNodeUtil.GetExclusiveGatewayExpression(targetFlowElement)) {//下个出口是通用拒绝同意排它网关
               variablesnew.put("bapprovedEG",true);
             }
             break;
            }
           if(targetFlowElement instanceof ParallelGateway){// 下个出口是并行网关的话,直接需要进行complete,否则报错
             variablesnew.put("bparallelGateway",true);
           }
        }

4、setNextAssignee 修改如下:

/**
   * 设置下个节点信息处理人员
   *  add by nbacheng
   *           
   * @param variablesnew, usermap,
   *      userlist, sysUser, variables,  bparallelGateway
   *            
   * @return
   */
  private Result setNextAssignee(ProcessInstance processInstance, Map<String, Object> usermap,
                             List<String> userlist, SysUser sysUser, Map<String, Object> variables,
                             boolean bparallelGateway, boolean bapprovedEG) {
    // 给第一步申请人节点设置任务执行人和意见
    if((usermap.containsKey("isSequential")) && !(boolean)usermap.get("isSequential")) {//并发会签会出现2个以上需要特殊处理
      List<Task> nexttasklist = taskService.createTaskQuery().processInstanceId(processInstance.getProcessInstanceId()).active().list();
        int i=0;
        for (Task nexttask : nexttasklist) {
           String assignee = userlist.get(i).toString();  
           taskService.addComment(nexttask.getId(), processInstance.getProcessInstanceId(),
              FlowComment.NORMAL.getType(), sysUser.getRealname() + "发起流程申请");
             taskService.setAssignee(nexttask.getId(), assignee);
             i++;
        }
        return Result.OK("多实例会签流程启动成功.");
      }
    else {// 给第一步申请人节点设置任务执行人和意见
      Task task = taskService.createTaskQuery().processInstanceId(processInstance.getProcessInstanceId()).active()
        .singleResult();
      if (Objects.nonNull(task)) {
        taskService.addComment(task.getId(), processInstance.getProcessInstanceId(),
            FlowComment.NORMAL.getType(), sysUser.getRealname() + "发起流程申请");
        taskService.setAssignee(task.getId(), sysUser.getUsername());
        //taskService.complete(task.getId(), variables);
      }
      // 获取下一个节点数据及设置数据
      FlowNextDto nextFlowNode = flowTaskService.getNextFlowNode(task.getId(), variables);
      if(Objects.nonNull(nextFlowNode)) {
        Map<String, Object> nVariablesMap = taskService.getVariables(task.getId());
        if (Objects.nonNull(task)) {
          if(nVariablesMap.containsKey("SetAssigneeTaskListener")) {//是否通过动态设置审批人的任务监听器
            taskService.complete(task.getId(), variables);
            Task nexttask = taskService.createTaskQuery().processInstanceId(processInstance.getProcessInstanceId()).active().singleResult();
            taskService.setAssignee(nexttask.getId(), nVariablesMap.get("SetAssigneeTaskListener").toString());
            return Result.OK("通过动态设置审批人的任务监听器流程启动成功.");
            }
        }
        if(Objects.nonNull(nextFlowNode.getUserList())) {
          if( nextFlowNode.getUserList().size() == 1 ) {
            if (nextFlowNode.getUserList().get(0) != null) {
              if(StringUtils.equalsAnyIgnoreCase(nextFlowNode.getUserList().get(0).getUsername(), "${INITIATOR}")) {//对发起人做特殊处理
                taskService.complete(task.getId(), variables);
                return Result.OK("流程启动成功给发起人.");
              }
              else {
                taskService.complete(task.getId(), variables);
                  return Result.OK("流程启动成功.");
              }
            }
            else {
              return Result.error("审批人不存在,流程启动失败!");
            }
            
          }
          else if(nextFlowNode.getType() == ProcessConstants.PROCESS_MULTI_INSTANCE ) {//对多实例会签做特殊处理或者以后在流程设计进行修改也可以
                    Map<String, Object> approvalmap = new HashMap<>();
                    List<String> sysuserlist = nextFlowNode.getUserList().stream().map(obj-> (String) obj.getUsername()).collect(Collectors.toList());
            approvalmap.put("approval", sysuserlist);
            taskService.complete(task.getId(), approvalmap);
            if(!nextFlowNode.isBisSequential()){//对并发会签进行assignee单独赋值
                List<Task> nexttasklist = taskService.createTaskQuery().processInstanceId(processInstance.getProcessInstanceId()).active().list();
                int i=0;
                for (Task nexttask : nexttasklist) {
                   String assignee = sysuserlist.get(i).toString(); 
                       taskService.setAssignee(nexttask.getId(), assignee);
                       i++;
                }
               
              }
            return Result.OK("多实例会签流程启动成功.");
          }
          else if(nextFlowNode.getUserList().size() > 1) {
            if (bparallelGateway) {//后一个节点是并行网关的话
              taskService.complete(task.getId(), variables);
              return Result.OK("流程启动成功.");
            }
            else {
              return Result.OK("流程启动成功,请到我的待办里进行流程的提交流转.");
            }
          }
          else {
            return Result.OK("流程启动失败,请检查流程设置人员!");
          }
        }
        else {//对跳过流程做特殊处理
          List<UserTask> nextUserTask = FindNextNodeUtil.getNextUserTasks(repositoryService, task, variables);
                if (CollectionUtils.isNotEmpty(nextUserTask)) {
                  List<FlowableListener> listlistener = nextUserTask.get(0).getTaskListeners();
                  if(CollectionUtils.isNotEmpty(listlistener)) {
                    String tasklistener =  listlistener.get(0).getImplementation();
                    if(StringUtils.contains(tasklistener, "AutoSkipTaskListener")) {
                      taskService.complete(task.getId(), variables);
                  return Result.OK("流程启动成功.");
                    }else {
                      return Result.OK("流程启动失败,请检查流程设置人员!");
                    }
                  }else {
                    return Result.OK("流程启动失败,请检查流程设置人员!");
                  }
                  
                }
                else {
                  return Result.OK("流程启动失败,请检查流程设置人员!");
                }
        }
      }
      else {
        if(bapprovedEG) {
          return Result.OK("通用拒绝同意流程启动成功,请到我的待办里进行流程的提交流转.");
        }
        taskService.complete(task.getId(), variables);
        return Result.OK("流程启动成功.");
      }
    }
  }

5、效果图如下:

 

相关文章
|
存储 XML Java
Flowable工作流-高级篇
Flowable工作流-高级篇
9948 1
|
XML 存储 JavaScript
Flowable学习笔记(二、BPMN 2.0-基础 )
Flowable学习笔记(二、BPMN 2.0-基础 )
4764 0
Flowable学习笔记(二、BPMN 2.0-基础 )
|
XML 数据可视化 Java
|
移动开发 前端开发
基于Jeecg-boot的flowable流程支持拒绝同意流程操作
基于Jeecg-boot的flowable流程支持拒绝同意流程操作
599 0
|
移动开发 前端开发
基于jeecg-boot的flowable流程自定义业务退回撤回或驳回到发起人后的再次流程提交
基于jeecg-boot的flowable流程自定义业务退回撤回或驳回到发起人后的再次流程提交
1320 0
|
移动开发 前端开发
基于jeecg-boot的flowable流程审批时增加下一个审批人设置
基于jeecg-boot的flowable流程审批时增加下一个审批人设置
1687 0
|
XML 前端开发 Java
SpringBoot整合Flowable【08】- 前后端如何交互
本文详细介绍了如何通过 Flowable 的 BpmnModel API 以编程方式动态构建 BPMN 流程模型,而无需依赖 XML 文件。文章从实际业务场景出发,探讨了前端传递参数实现流程创建的可行性,并通过代码示例展示了整个实现过程。 主要内容包括:定义流程实体与节点结构、创建控制器处理请求、服务层实现流程模型转换及部署、递归构建任务节点和子节点、创建任务监听器和表单属性等关键方法。最后通过 curl 命令测试接口,验证流程部署成功。 虽然此方法灵活强大,但复杂流程的构建需编写大量代码。建议封装常用元素(如开始/结束事件、网关等),提升开发效率和代码可维护性。
1220 0
SpringBoot整合Flowable【08】- 前后端如何交互
|
前端开发 Java API
SpringBoot整合Flowable【07】- 驳回节点任务
本文通过绩效流程的业务场景,详细介绍了如何在Flowable工作流引擎中实现任务驳回功能。具体步骤包括:获取目标任务节点和当前任务节点信息,进行必要的判空和逻辑校验,调用API完成节点回退,并清理相关脏数据(如历史任务和变量)。最后通过测试验证了驳回功能的正确性,确保流程能够成功回退到指定节点并清除中间产生的冗余数据。此功能在实际业务中非常有用,能够满足上级驳回自评等需求。
3016 0
SpringBoot整合Flowable【07】- 驳回节点任务
|
前端开发
基于jeecgboot的flowable流程支持退回到发起人节点表单修改功能
基于jeecgboot的flowable流程支持退回到发起人节点表单修改功能
1527 0

热门文章

最新文章