Based on Ruoyi-nbcio’s support for flowable process roles, and at the same time modifying the flow user to username, the process startup will be greatly adjusted (2)

For more ruoyi-nbcio functions, please see the demo system

gitee source code address

Front-end and back-end code: https://gitee.com/nbacheng/ruoyi-nbcio

Demonstration address: RuoYi-Nbcio backend management system

Continuing from the above article.

1. Obtain the exclusive gateway branch name, branch expression, and next-level task node

/**
     * Get the exclusive gateway branch name, branch expression, and next-level task node
     * @param flowElement
     * @param data
     * add by nbacheng
     */
    private Map<String, Object> GetExclusiveGatewayUser(FlowElement flowElement,Map<String, Object> variables){
    // Get all gateway branches
        List<SequenceFlow> targetFlows=((ExclusiveGateway)flowElement).getOutgoingFlows();
        // Loop through each gateway branch
        for(SequenceFlow sequenceFlow : targetFlows){
            // Get the next gateway and node data
            FlowElement targetFlowElement=sequenceFlow.getTargetFlowElement();
            //The gateway data is not empty
            if (StringUtils.isNotBlank(sequenceFlow.getConditionExpression())) {
                // Get gateway judgment conditions
            String expression = sequenceFlow.getConditionExpression();
                if (expression == null ||Boolean.parseBoolean(
                                String.valueOf(
                                FindNextNodeUtil.result(variables, expression.substring(expression.lastIndexOf("{") + 1, expression.lastIndexOf("}")))))) {
                //The next node outgoing from the gateway is the user node
                    if(targetFlowElement instanceof UserTask){
                        // Determine whether it is countersigning
                        UserTask userTask = (UserTask) targetFlowElement;
                        MultiInstanceLoopCharacteristics multiInstance = userTask.getLoopCharacteristics();
                    if (Objects.nonNull(multiInstance)) {//The next node is the countersign node
                    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;
    }

2. Obtain multi-instance countersign user information

/**
     * Obtain multi-instance countersign user information
     * @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 = commonService.getUserListByRoleId(roleId);
        for(SysUser sysuser : templist) {
          SysUser sysUserTemp = sysUserService.selectUserById(sysuser.getUserId());
          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 = sysUserService.selectUserByUserName(username);
        list.add(sysUser);
        }
        sysuserlist = list.stream().map(obj-> (String) obj.getUserName()).collect(Collectors.toList());
        }
    return sysuserlist;
    }

3. Get the next node information

/**
     * Get the next node
     *
     * @param flowTaskVo task
     * @return
     */
    @Override
    public R getNextFlowNode(WfTaskBo flowTaskVo) {
        // todo currently only supports some functions
        FlowNextDto flowNextDto = this.getNextFlowNode(flowTaskVo.getTaskId(), flowTaskVo.getVariables());
        if (flowNextDto==null) {
            return R.ok(null);
        }
        return R.ok(flowNextDto);

    }
    
    /** modify by nbacheng
     * Get the next node information, the node information on the process definition
     * @param taskId current node id
     * @param values process variables
     * @return If null is returned, it means there is no next node and the process ends
     */

    public FlowNextDto getNextFlowNode(String taskId, Map<String, Object> values) {
    //Current node
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        FlowNextDto flowNextDto = new FlowNextDto();

    if (Objects.nonNull(task)) {
        //Next task node
    if (DelegationState.PENDING.equals(task.getDelegationState())) { //Delegation processing
List<UserTask> nextUserTask = FindNextNodeUtil.getNextUserTasks(repositoryService, task, values);
if (CollectionUtils.isNotEmpty(nextUserTask)) {
flowNextDto.setType(ProcessConstants.FIXED);//The delegation is executed according to the original process, so the value is returned directly
return flowNextDto;
}
else {
return null;
}

             }
            List<UserTask> nextUserTask = FindNextNodeUtil.getNextUserTasks(repositoryService, task, values);
            List<SysUser> list = new ArrayList<SysUser>();
            if (CollectionUtils.isNotEmpty(nextUserTask)) {
                for (UserTask userTask : nextUserTask) {
                    MultiInstanceLoopCharacteristics multiInstance = userTask.getLoopCharacteristics();
                    // Countersign node
                    if (Objects.nonNull(multiInstance)) {
                    List<String> rolelist = new ArrayList<>();
                        rolelist = userTask.getCandidateGroups();
                    List<String> userlist = new ArrayList<>();
                        userlist = userTask.getCandidateUsers();
                        UserTask newUserTask = userTask;
                        if(rolelist.size() != 0 & amp; & amp; StringUtils.contains(rolelist.get(0), "${flowExp.getDynamic")) {//Make special expressions for multiple dynamic roles deal with
                        String methodname = StringUtils.substringBetween(rolelist.get(0), ".", "(");
                        Object[] argsPara=new Object[]{};
                        setMultiFlowExp(flowNextDto,newUserTask,multiInstance,methodname,argsPara);
                        }
                        else if(userlist.size() != 0 & amp; & amp; StringUtils.contains(userlist.get(0), "${flowExp.getDynamic")) {//Multiple dynamic users of expressions special handling
                        String methodname = StringUtils.substringBetween(userlist.get(0), ".", "(");
                        Object[] argsPara=new Object[]{};
                        setMultiFlowExp(flowNextDto,newUserTask,multiInstance,methodname,argsPara);
                        }
                        else if(userlist.size() != 0 & amp; & amp; StringUtils.contains(userlist.get(0), "DepManagerHandler")) {//Special treatment for department managers
                        String methodname = "getInitiatorDepManagers";
                        // Get the process initiator
ProcessInstance processInstance = runtimeService
.createProcessInstanceQuery()
.processInstanceId(task.getProcessInstanceId())
.singleResult();
String startUserId = processInstance.getStartUserId();
Object[] argsPara=new Object[]{};
argsPara=new Object[]{startUserId};
                        setMultiFlowExp(flowNextDto,newUserTask,multiInstance,methodname,argsPara);
                        }
                        else if(rolelist.size() > 0) {
for(String roleId : rolelist ){
                        List<SysUser> templist = commonService.getUserListByRoleId(roleId);
                        for(SysUser sysuser : templist) {
                          SysUser sysUserTemp = sysUserService.selectUserById(sysuser.getUserId());
                          list.add(sysUserTemp);
                          }
                        }
setMultiFlowNetDto(flowNextDto,list,userTask,multiInstance);
                        }
                        else if(userlist.size() > 0) {
                        for(String username : userlist) {
                        SysUser sysUser = sysUserService.selectUserByUserName(username);
                        list.add(sysUser);
                        }
                        setMultiFlowNetDto(flowNextDto,list,userTask,multiInstance);
                        }
                        else {
                        flowNextDto.setType(ProcessConstants.FIXED);
                        }
                  
                    } else {

                        // Read custom node attributes to determine whether you need to dynamically specify task recipients and groups. Currently, only user roles or multiple users are supported, and sub-processes and variables are not supported yet.
                        //String dataType = userTask.getAttributeValue(ProcessConstants.NAMASPASE, ProcessConstants.PROCESS_CUSTOM_DATA_TYPE);
                        //String userType = userTask.getAttributeValue(ProcessConstants.NAMASPASE, ProcessConstants.PROCESS_CUSTOM_USER_TYPE);

                        List<String> rolelist = new ArrayList<>();
                        rolelist = userTask.getCandidateGroups();
                        List<String> userlist = new ArrayList<>();
                        userlist = userTask.getCandidateUsers();
                        String assignee = userTask.getAssignee();
                        // Process loading and dynamically specify the next node to receive personnel information
                        if(assignee !=null) {
                        if(StringUtils.equalsAnyIgnoreCase(assignee, "${INITIATOR}")) {//Special treatment for the initiator
                        SysUser sysUser = new SysUser();
                        sysUser.setUserName("${INITIATOR}");
                        list.add(sysUser);
                        setAssigneeFlowNetDto(flowNextDto,list,userTask);
                        }
                        else if(StringUtils.contains(assignee, "${flowExp.getDynamicAssignee")) {//Special processing for a single dynamic user of expression
                        String methodname = StringUtils.substringBetween(assignee, ".", "(");
                        SysUser sysUser = new SysUser();
                        flowExp flowexp = SpringContextUtils.getBean(flowExp.class);
                        Object[] argsPara=new Object[]{};
                        String username = null;
                        try {
username = (String) flowexp.invokeMethod(flowexp, methodname,argsPara);
} catch (Exception e) {
e.printStackTrace();
}
                        sysUser.setUserName(username);
                        list.add(sysUser);
                        setAssigneeFlowNetDto(flowNextDto,list,userTask);
                        }
                        else if(StringUtils.contains(assignee, "${flowExp.getDynamicList")) {//Special processing for multiple dynamic users of expressions
                        String methodname = StringUtils.substringBetween(assignee, ".", "(");
                        flowExp flowexp = SpringContextUtils.getBean(flowExp.class);
                        Object[] argsPara=new Object[]{};
                        try {
                        list = (List<SysUser>) flowexp.invokeMethod(flowexp, methodname,argsPara);
} catch (Exception e) {
e.printStackTrace();
}
                        setUsersFlowNetDto(flowNextDto,list,userTask);
                        \t   
                        }
                        else if(StringUtils.contains(assignee, "${DepManagerHandler")) {//Special processing for department manager multiple users
                        String methodname = "getInitiatorDepManagers";
                        // Get the process initiator
    ProcessInstance processInstance = runtimeService
    .createProcessInstanceQuery()
    .processInstanceId(task.getProcessInstanceId())
    .singleResult();
    String startUserId = processInstance.getStartUserId();
                        flowExp flowexp = SpringContextUtils.getBean(flowExp.class);
                        Object[] argsPara=new Object[]{};
                        argsPara[0] = startUserId;
                        try {
                        list = (List<SysUser>) flowexp.invokeMethod(flowexp, methodname,argsPara);
} catch (Exception e) {
e.printStackTrace();
}
                        setUsersFlowNetDto(flowNextDto,list,userTask);
                        \t   
                        }
                        else {
                        SysUser sysUser = sysUserService.selectUserByUserName(assignee);
                    \t\t    
                    list.add(sysUser);
                    setAssigneeFlowNetDto(flowNextDto,list,userTask);
                        }
                        \t
                        }
                        else if(userlist.size()>0 & amp; & amp; StringUtils.equalsAnyIgnoreCase(userlist.get(0), "${DepManagerHandler.getUsers(execution)}")) {//Make special operations for department managers deal with
// Get the process initiator
ProcessInstance processInstance = runtimeService
.createProcessInstanceQuery()
.processInstanceId(task.getProcessInstanceId())
.singleResult();
String startUserId = processInstance.getStartUserId();
flowExp flowexp = SpringContextUtils.getBean(flowExp.class);
String manager = flowexp.getDynamicManager(startUserId);
SysUser sysUser = sysUserService.selectUserByUserName(manager);
list.add(sysUser);
setUsersFlowNetDto(flowNextDto,list,userTask);
                        }
                        else if(userlist.size() > 0) {
                        for(String username : userlist) {
                        SysUser sysUser = sysUserService.selectUserByUserName(username);
                        \t\t
                        list.add(sysUser);
                        }
                        setUsersFlowNetDto(flowNextDto,list,userTask);
                        setMultiFinishFlag(task,flowNextDto,list);
                        \t
                        }
                        else if(rolelist.size() > 0) {
for(String roleId : rolelist ){
                        List<SysUser> templist = commonService.getUserListByRoleId(roleId);
                        for(SysUser sysuser : templist) {
                          SysUser sysUserTemp = sysUserService.selectUserByUserName(sysuser.getUserName());
                          list.add(sysUserTemp);
                          }
                        }
setUsersFlowNetDto(flowNextDto,list,userTask);
setMultiFinishFlag(task,flowNextDto,list);
                        }
                        else {
                        flowNextDto.setType(ProcessConstants.FIXED);
                        }
                    }
                }
                return flowNextDto;
            } else {
                return null;
          }
       }
       return null;

    }