基于jeecgboot的支持flowable的排它网关之后的会签功能(一)

简介: 基于jeecgboot的支持flowable的排它网关之后的会签功能(一)

gitee源代码地址

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

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

github源代码地址

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

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

 

1、流程启动修改

因为在排它网关后面直接接会签功能的话,启动不带流程设计器的approval就会报错,具体修改如下:

public Result startProcessInstanceByProcDefId(String procDefId, Map<String, Object> variables) {
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                .processDefinitionId(procDefId).latestVersion().singleResult();
        if (Objects.nonNull(processDefinition) && processDefinition.isSuspended()) {
            return Result.error("流程已被挂起,请先激活流程");
        }
        // variables.put("skip", true);
        // variables.put(ProcessConstants.FLOWABLE_SKIP_EXPRESSION_ENABLED,
        // true);
        // 设置流程发起人Id到流程中
        SysUser sysUser = iFlowThirdService.getLoginUser();
        identityService.setAuthenticatedUserId(sysUser.getUsername());
        variables.put(ProcessConstants.PROCESS_INITIATOR, sysUser.getUsername());
        
        Map<String, Object> variablesnew = variables;
        
        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();
        Map<String, Object> usermap = new HashMap<String, Object>();
        List<String> userlist = new ArrayList<String>();
        //遍历返回下一个节点信息
        for (SequenceFlow outgoingFlow : outgoingFlows) {
            //类型自己判断(获取下个节点是网关还是节点)
            FlowElement targetFlowElement = outgoingFlow.getTargetFlowElement();
            //下个是节点
           if(targetFlowElement instanceof ExclusiveGateway){// 下个出口是排它网关的话,后一个用户任务又是会签的情况下需要approval的赋值处理,否则报错
               usermap =  GetExclusiveGatewayUser(targetFlowElement,variables);//还是需要返回用户与是否并发,因为并发要做特殊处理
               userlist = (ArrayList<String>) usermap.get("approval");
               variablesnew.put("approval", userlist);
               break;
            }
        }
        
        ProcessInstance processInstance = runtimeService.startProcessInstanceById(procDefId, variablesnew);
        // 给第一步申请人节点设置任务执行人和意见
        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)) {
                if( nextFlowNode.getUserList().size() == 1 ) {
                    taskService.complete(task.getId(), variables);
                    return Result.OK("流程启动成功.");
                }
                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) {
                    return Result.OK("流程启动成功,请到我的待办里进行流程的提交流转.");
                }
                else {
                    return Result.OK("流程启动失败,请检查流程设置人员!");
                }
            }
            else {
                taskService.complete(task.getId(), variables);
                return Result.OK("流程启动成功.");
            }
        }
    }

相应的调用函数如下:

/**
     * 获取排他网关分支名称、分支表达式、下一级任务节点
     * @param flowElement
     * @param data
     * add by nbacheng
     */
    private Map<String, Object> GetExclusiveGatewayUser(FlowElement flowElement,Map<String, Object> variables){
        // 获取所有网关分支
        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 == null ||Boolean.parseBoolean(
                                String.valueOf(
                                        FindNextNodeUtil.result(variables, expression.substring(expression.lastIndexOf("{") + 1, expression.lastIndexOf("}")))))) {
                    // 网关出线的下个节点是用户节点
                    if(targetFlowElement instanceof UserTask){
                        // 判断是否是会签
                        UserTask userTask = (UserTask) targetFlowElement;
                        MultiInstanceLoopCharacteristics multiInstance = userTask.getLoopCharacteristics();
                        if (Objects.nonNull(multiInstance)) {//下个节点是会签节点
                            Map<String, Object> approvalmap = new HashMap<>();
                            List<String> getuserlist =  getmultiInstanceUsers(multiInstance,userTask);
                            approvalmap.put("approval", getuserlist);
                            if(multiInstance.isSequential()) {
                                approvalmap.put("isSequential", true);
                            }
                            else {
                                approvalmap.put("isSequential", false);
                            }
                            return approvalmap;
                        }
                    }
                }
            }
        }
        return null;
    }
    
    /**
     * 获取多实例会签用户信息
     * @param userTask
     * @param multiInstance
     *
     **/
    List<String> getmultiInstanceUsers(MultiInstanceLoopCharacteristics multiInstance,UserTask userTask) {
        List<String> sysuserlist = new ArrayList<>();
        List<String> rolelist = new ArrayList<>();
        rolelist = userTask.getCandidateGroups();
        List<String> userlist = new ArrayList<>();
        userlist = userTask.getCandidateUsers();
        if(rolelist.size() > 0) {
            List<SysUser> list = new ArrayList<SysUser>();
            for(String roleId : rolelist ){
              List<SysUser> templist = iFlowThirdService.getUsersByRoleId(roleId);
              for(SysUser sysuser : templist) {
                  SysUser sysUserTemp = iFlowThirdService.getUserByUsername(sysuser.getUsername());
                  List<String> listdepname = iFlowThirdService.getDepartNamesByUsername(sysuser.getUsername());
                  if(listdepname.size()>0){
                      sysUserTemp.setOrgCodeTxt(listdepname.get(0).toString());
                  }
                  list.add(sysUserTemp);
                }
            }
            sysuserlist = list.stream().map(obj-> (String) obj.getUsername()).collect(Collectors.toList());
           
        }
        else if(userlist.size() > 0) {
            List<SysUser> list = new ArrayList<SysUser>();
            for(String username : userlist) {
                SysUser sysUser =  iFlowThirdService.getUserByUsername(username);
                List<String> listdepname = iFlowThirdService.getDepartNamesByUsername(username);
                if(listdepname.size()>0){
                    sysUser.setOrgCodeTxt(listdepname.get(0).toString());
                }
                list.add(sysUser);
            }
            sysuserlist = list.stream().map(obj-> (String) obj.getUsername()).collect(Collectors.toList());
        }    
        return sysuserlist;
    }

效果图如下:


相关文章
|
5天前
|
监控 应用服务中间件 API
API 网关的功能用途及实现方式
API 网关的功能用途及实现方式
|
5天前
|
XML JSON 前端开发
基于若依的ruoyi-nbcio流程管理系统仿钉钉流程json转bpmn的flowable的xml格式(支持并行网关)
基于若依的ruoyi-nbcio流程管理系统仿钉钉流程json转bpmn的flowable的xml格式(支持并行网关)
32 3
|
5天前
|
移动开发 前端开发
基于flowable没有规则的并发网关流程跳转记录分析
基于flowable没有规则的并发网关流程跳转记录分析
15 0
|
5天前
|
移动开发 前端开发
flowable多对并发网关跳转的分析
flowable多对并发网关跳转的分析
|
5天前
|
移动开发 前端开发
flowable一对并发网关跳转的分析
flowable一对并发网关跳转的分析
12 0
|
5天前
|
移动开发 前端开发 数据库
ruoyi-nbcio 基于flowable规则的多重并发网关的任意跳转
ruoyi-nbcio 基于flowable规则的多重并发网关的任意跳转
16 0
|
5天前
|
移动开发 前端开发
flowable流程跳转或退回到网关上的用户节点后流程走不下去了
flowable流程跳转或退回到网关上的用户节点后流程走不下去了
19 2
|
5天前
|
XML JSON 前端开发
基于若依的ruoyi-nbcio流程管理系统仿钉钉流程json转bpmn的flowable的xml格式(排它条件网关)
基于若依的ruoyi-nbcio流程管理系统仿钉钉流程json转bpmn的flowable的xml格式(排它条件网关)
11 3
基于若依的ruoyi-nbcio流程管理系统仿钉钉流程json转bpmn的flowable的xml格式(排它条件网关)
|
5天前
基于jeecgboot的支持flowable的排它网关之后的会签功能(二)
基于jeecgboot的支持flowable的排它网关之后的会签功能(二)
12 1
|
5天前
|
缓存 应用服务中间件 Linux
如何使用OpenResty实现API网关功能
如何使用OpenResty实现API网关功能
99 0