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 (3)

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 previous article.

1. Set multiple instances and other related parameters

    //Set the next node process data for a single user
    private void setAssigneeFlowNetDto(FlowNextDto flowNextDto,List<SysUser> list,UserTask userTask) {
    flowNextDto.setVars(ProcessConstants.PROCESS_APPROVAL);
flowNextDto.setType(ProcessConstants.USER_TYPE_ASSIGNEE);
flowNextDto.setUserList(list);
flowNextDto.setUserTask(userTask);
    }
    
    //Set multi-user next node process data
    private void setUsersFlowNetDto(FlowNextDto flowNextDto,List<SysUser> list,UserTask userTask) {
    flowNextDto.setVars(ProcessConstants.PROCESS_APPROVAL);
        flowNextDto.setType(ProcessConstants.USER_TYPE_USERS);
        flowNextDto.setUserList(list);
        flowNextDto.setUserTask(userTask);
    }
    
    //Set the multi-instance end flag
    private void setMultiFinishFlag(Task task,FlowNextDto flowNextDto,List<SysUser> list) {
    String definitionld = runtimeService.createProcessInstanceQuery().processInstanceId(task.getProcessInstanceId()).singleResult().getProcessDefinitionId(); //Get bpm (model) object
        BpmnModel bpmnModel = repositoryService.getBpmnModel(definitionld);
        //Get the current node through the node definition key
        FlowNode flowNode = (FlowNode) bpmnModel.getFlowElement(task.getTaskDefinitionKey());
        if(flowNode instanceof UserTask ){
        UserTask curuserTask = (UserTask) flowNode;
        MultiInstanceLoopCharacteristics curmultiInstance = curuserTask.getLoopCharacteristics();
        if (Objects.nonNull(curmultiInstance)) {
        if(list.size()>1) {//When multiple people select, obtain the countersign end information written by the previous listener from redis
        String smutinstance_next_finish = Constants.MUTIINSTANCE_NEXT_FINISH + task.getProcessInstanceId();
        if(Objects.nonNull(RedisUtils.getCacheObject(smutinstance_next_finish))) {
        flowNextDto.setBmutiInstanceFinish(true);
        }
                }
        }
        }
    }
    
    //Set multi-instance process expression
    private void setMultiFlowExp(FlowNextDto flowNextDto,UserTask newUserTask,MultiInstanceLoopCharacteristics multiInstance,String methodname,Object[] argsPara) {
    List<SysUser> list = new ArrayList<SysUser>();
flowExp flowexp = SpringContextUtils.getBean(flowExp.class);
//Object[] argsPara=new Object[]{};
List<String> templist = new ArrayList<String>();
try {
templist = (List<String>) flowexp.invokeMethod(flowexp, methodname,argsPara);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
for(String sysuser : templist) {
      SysUser sysUserTemp = sysUserService.selectUserByUserName(sysuser);
      list.add(sysUserTemp);
      }
newUserTask.setAssignee("${assignee}");
newUserTask.setCandidateUsers(templist);
setMultiFlowNetDto(flowNextDto,list,newUserTask,multiInstance);
    }
    
    //Set multi-instance process data
    private void setMultiFlowNetDto(FlowNextDto flowNextDto,List<SysUser> list,UserTask userTask,MultiInstanceLoopCharacteristics multiInstance) {
    flowNextDto.setVars(ProcessConstants.PROCESS_MULTI_INSTANCE_USER);
        flowNextDto.setType(ProcessConstants.PROCESS_MULTI_INSTANCE);
        flowNextDto.setUserList(list);
        flowNextDto.setUserTask(userTask);
        if(multiInstance.isSequential()) {
        flowNextDto.setBisSequential(true);
        }
        else {
        flowNextDto.setBisSequential(false);
        }
    }

2. Example of verifying el expression

/**
     * Check el expression example
     *
     * @param map
     * @param expression
     * @return
     */
    public static Object result(Map<String, Object> map, String expression) {
    Object result = null;
    try {
FelEngine fel = new FelEngineImpl();
FelContext ctx = fel.getContext();
for (Map.Entry<String, Object> entry : map.entrySet()) {
ctx.set(entry.getKey(), entry.getValue());
System.out.print(entry.getKey() + "-" + entry.getValue());
}
String exp = "";
if (expression.indexOf("<") >0) {
exp = expression.substring(0, expression.indexOf("<"));
}
else if (expression.indexOf(">") >0) {
int index =expression.indexOf(">");
exp = expression.substring(0, index);
}
else if (expression.indexOf("==") >0) {
exp = expression.substring(0, expression.indexOf("=="));
}
exp =expression.replace(exp, ctx.get(exp).toString());
result = fel.eval(exp);
//result = fel.eval(expression);
} catch (Exception e) {
result = null;
}
    return result;
    }

3. Get the exclusive gateway branch name and whether the branch expression exists

/**
     * Get the exclusive gateway branch name and whether the branch expression exists ${approved}
     * @param flowElement
     * @param
     * add by nbacheng
     */
    public static boolean GetExclusiveGatewayExpression(FlowElement flowElement) {
    // 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.contains("${approved}")) {
            return true;
            }
            }
        }
    return false;
    }

4. The workflow task tool class mainly adds username

/**
 * Workflow task tool class
 *
 * @author konbai
 * @createTime 2022/4/24 12:42
 */
public class TaskUtils {

    public static String getUserId() {
        return String.valueOf(LoginHelper.getUserId());
    }

    public static String getUserName() {
        return LoginHelper.getUserName();
    }
    
    /**
     * Get user group information
     *
     * @return candidateGroup
     */
    public static List<String> getCandidateGroup() {
        List<String> list = new ArrayList<>();
        LoginUser user = LoginHelper.getLoginUser();
        if (ObjectUtil.isNotNull(user)) {
            if (ObjectUtil.isNotEmpty(user.getRoles())) {
                user.getRoles().forEach(role -> list.add(TaskConstants.ROLE_GROUP_PREFIX + role.getRoleId()));
            }
            if (ObjectUtil.isNotNull(user.getDeptId())) {
                list.add(TaskConstants.DEPT_GROUP_PREFIX + user.getDeptId());
            }
        }
        return list;
    }
}

5. The renderings are as follows: