基于jeecg-boot的flowable支持动态人员设置

简介: 基于jeecg-boot的flowable支持动态人员设置

今天做一个通用的支持动态人员设置,包括动态设置多实例流程。

    1、流程设置,如下图

       动态人员设置

      动态多实例设置

2、代码修改支持

getNextFlowNode下一个节点信息需要修改如下:

/**  modify by nbacheng
     * 获取下一个节点信息,流程定义上的节点信息
     * @param taskId 当前节点id
     * @param values 流程变量
     * @return 如果返回null,表示没有下一个节点,流程结束
     */
    public FlowNextDto getNextFlowNode(String taskId, Map<String, Object> values) {
      //当前节点
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        FlowNextDto flowNextDto = new FlowNextDto();
      if (Objects.nonNull(task)) {
          // 下个任务节点
        if (DelegationState.PENDING.equals(task.getDelegationState())) { //对于委派的处理
            List<UserTask> nextUserTask = FindNextNodeUtil.getNextUserTasks(repositoryService, task, values);
              if (CollectionUtils.isNotEmpty(nextUserTask)) {
                flowNextDto.setType(ProcessConstants.FIXED);//委派是按原来流程执行,所以直接赋值返回
                return flowNextDto;
              }
              else {
                return null;
              }
             }
            List<UserTask> nextUserTask = FindNextNodeUtil.getNextUserTasks(repositoryService, task, values);
            if (CollectionUtils.isNotEmpty(nextUserTask)) {
                for (UserTask userTask : nextUserTask) {
                    MultiInstanceLoopCharacteristics multiInstance = userTask.getLoopCharacteristics();
                    // 会签节点
                    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 && StringUtils.contains(rolelist.get(0), "${flowExp.getDynamic")) {//对表达式多个动态角色做特殊处理
                          String methodname = StringUtils.substringBetween(rolelist.get(0), ".", "(");
                          setMultiFlowExp(flowNextDto,newUserTask,multiInstance,methodname);
                        }
                        else if(userlist.size() != 0 && StringUtils.contains(userlist.get(0), "${flowExp.getDynamic")) {//对表达式多个动态用户做特殊处理
                          String methodname = StringUtils.substringBetween(userlist.get(0), ".", "(");
                          setMultiFlowExp(flowNextDto,newUserTask,multiInstance,methodname);
                        }
                        else 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);
                              }
                          }
              setMultiFlowNetDto(flowNextDto,list,userTask,multiInstance);
                        }
                        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);
                          }
                          setMultiFlowNetDto(flowNextDto,list,userTask,multiInstance);
                        }
                        else {
                          flowNextDto.setType(ProcessConstants.FIXED);
                        }
                  
                    } else {
                        // 读取自定义节点属性 判断是否是否需要动态指定任务接收人员、组,目前只支持用户角色或多用户,还不支持子流程和变量
                        //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();
                        // 处理加载动态指定下一节点接收人员信息
                        if(assignee !=null) {
                          if(StringUtils.equalsAnyIgnoreCase(assignee, "${INITIATOR}")) {//对发起人做特殊处理
                            List<SysUser> list = new ArrayList<SysUser>();
                            SysUser sysUser = new SysUser();
                            sysUser.setUsername("${INITIATOR}");
                            list.add(sysUser);
                            setAssigneeFlowNetDto(flowNextDto,list,userTask);
                          }
                          else if(StringUtils.contains(assignee, "${flowExp.getDynamicAssignee")) {//对表达式单个动态用户做特殊处理
                            String methodname = StringUtils.substringBetween(assignee, ".", "(");
                            List<SysUser> list = new ArrayList<SysUser>();
                            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) {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
                }
                            sysUser.setUsername(username);
                            list.add(sysUser);
                            setAssigneeFlowNetDto(flowNextDto,list,userTask);
                          }
                          else if(StringUtils.contains(assignee, "${flowExp.getDynamicList")) {//对表达式多个动态用户做特殊处理
                            String methodname = StringUtils.substringBetween(assignee, ".", "(");
                            List<SysUser> list = new ArrayList<SysUser>();
                            flowExp flowexp = SpringContextUtils.getBean(flowExp.class);
                            Object[] argsPara=new Object[]{};
                            try {
                              list = (List<SysUser>) flowexp.invokeMethod(flowexp, methodname,argsPara);
                } catch (Exception e) {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
                }
                            setUsersFlowNetDto(flowNextDto,list,userTask);
                             
                          }
                          else {
                              List<SysUser> list = new ArrayList<SysUser>();
                              SysUser sysUser =  iFlowThirdService.getUserByUsername(assignee);
                            List<String> listdepname = iFlowThirdService.getDepartNamesByUsername(assignee);
                            if(listdepname.size()>0){
                               sysUser.setOrgCodeTxt(listdepname.get(0).toString());
                            }
                            list.add(sysUser);
                            setAssigneeFlowNetDto(flowNextDto,list,userTask);
                          }
                          
                        }
                        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);
                          }
                          setUsersFlowNetDto(flowNextDto,list,userTask);
                          setMultiFinishFlag(task,flowNextDto,list);
                        }
                        else 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);
                              }
                          }
              setUsersFlowNetDto(flowNextDto,list,userTask);
              setMultiFinishFlag(task,flowNextDto,list);
                        }
                        else {
                          flowNextDto.setType(ProcessConstants.FIXED);
                        }
                    }
                }
                return flowNextDto;
            } else {
                return null;
          }
       }
       return null;
    }

 多实例用户处理修改如下:

/**
 * 多实例collect用户处理类
 *
 * @author nbacheng
 * @date 2022-10-16
 */
@AllArgsConstructor
@Component("multiInstanceHandler")
public class MultiInstanceHandler {
  public Set<String> getUserName(DelegateExecution execution) {
        Set<String> candidateUserName = new LinkedHashSet<>();
        FlowElement flowElement = execution.getCurrentFlowElement();
        if (ObjectUtil.isNotEmpty(flowElement) && flowElement instanceof UserTask) {
            UserTask userTask = (UserTask) flowElement;
            if (CollUtil.isNotEmpty(userTask.getCandidateUsers())) {
              List<String> groups = userTask.getCandidateUsers();
              if (groups.size()!= 0 && StringUtils.contains(groups.get(0), "${flowExp.getDynamic")) {
                getDynamicUsers(groups,candidateUserName);
                
        }
              else {
                candidateUserName.addAll(userTask.getCandidateUsers());
              }
              
            } else if (CollUtil.isNotEmpty(userTask.getCandidateGroups())) {
              List<String> groups = userTask.getCandidateGroups();
              if (groups.size()!= 0 && StringUtils.contains(groups.get(0), "${flowExp.getDynamic")) {
                getDynamicUsers(groups,candidateUserName);
                
        }
              else {
                  IFlowThirdService iFlowThirdService = SpringContextUtils.getBean(IFlowThirdService.class);
                  groups.forEach(item -> {
                       List<SysUser> listuserName = iFlowThirdService.getUsersByRoleId(item);
                       for(SysUser sysuser : listuserName) {
                          candidateUserName.add(sysuser.getUsername());
                       }
                  });
              } 
            }
        }
        return candidateUserName;
    }
  
  @SuppressWarnings("unchecked")
    private void getDynamicUsers(List<String> groups,Set<String> candidateUserName) {
      String methodname = StringUtils.substringBetween(groups.get(0), ".", "(");
    List<String> list = new ArrayList<String>();
    flowExp flowexp = SpringContextUtils.getBean(flowExp.class);
    Object[] argsPara=new Object[]{};
    try {
      list = (List<String>) flowexp.invokeMethod(flowexp, methodname,argsPara);
            candidateUserName.addAll(list);
    } catch (Exception e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
    }
}

流程表达式的例子如下:

/**
 * 流程表达式应用类
 * @author nbacheng
 * @date 2023-05-16
 */
@Service
public class flowExp {
  @Resource
  public  IFlowThirdService iFlowThirdService;
  
  public  String getDynamicAssignee() {//动态单个用户例子
    SysUser loginUser = iFlowThirdService.getLoginUser();
    return loginUser.getUsername();   
  }
  
  public  List<String> getDynamicList() {//动态多个用户例子
    List<String> userlist = new ArrayList<String>();
    List<SysUser> list = new ArrayList<SysUser>();
    list = iFlowThirdService.getUsersByRoleId("f6817f48af4fb3af11b9e8bf182f618b");//管理员角色
    for(SysUser sysuser : list) {
      userlist.add(sysuser.getUsername());
    }
    return userlist;
  }
  
  /**
  * 反射调用方法
  * @param newObj 实例化的一个对象
  * @param methodName 对象的方法名
  * @param args 参数数组
  * @return 返回值
  * @throws Exception
  */
  public  Object invokeMethod(Object newObj, String methodName, Object[] args)throws Exception {
    Class ownerClass = newObj.getClass();
    Class[] argsClass = new Class[args.length];
    for (int i = 0, j = args.length; i < j; i++) {
      argsClass[i] = args[i].getClass();
    }
    Method method = ownerClass.getMethod(methodName, argsClass);
    return method.invoke(newObj, args);
  }
}

3、实际流转图如下:

更多功能看演示系统

gitee源代码地址

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

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

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

相关文章
|
19天前
|
前端开发
基于若依ruoyi-nbcio支持flowable流程增加自定义业务表单(二)
基于若依ruoyi-nbcio支持flowable流程增加自定义业务表单(二)
34 1
|
19天前
|
SQL 移动开发 前端开发
基于Jeecg-boot前后端分离的flowable流程管理平台主页调整
基于Jeecg-boot前后端分离的flowable流程管理平台主页调整
14 0
|
19天前
|
SQL JavaScript 前端开发
基于若依ruoyi-nbcio支持flowable流程增加自定义业务表单(一)
基于若依ruoyi-nbcio支持flowable流程增加自定义业务表单(一)
31 2
|
19天前
基于若依ruoyi-nbcio支持flowable流程增加自定义业务表单(三)
基于若依ruoyi-nbcio支持flowable流程增加自定义业务表单(三)
18 1
|
19天前
|
移动开发 前端开发
基于jeecg-boot的flowable流程历史记录显示修改
基于jeecg-boot的flowable流程历史记录显示修改
18 0
|
19天前
基于若依ruoyi-nbcio支持flowable流程分类里增加流程应用类型
基于若依ruoyi-nbcio支持flowable流程分类里增加流程应用类型
22 1
|
19天前
|
JavaScript BI
基于jeecg-boot集成luckysheet记录
基于jeecg-boot集成luckysheet记录
25 0
|
19天前
|
移动开发 前端开发
基于jeecg-boot的flowable流程跳转功能实现
基于jeecg-boot的flowable流程跳转功能实现
15 0
|
19天前
|
前端开发
基于RuoYi-Flowable-Plus的若依ruoyi-nbcio支持自定义业务表单流程(一)
基于RuoYi-Flowable-Plus的若依ruoyi-nbcio支持自定义业务表单流程(一)
27 1
|
19天前
|
移动开发 前端开发
nbcio-boot基于jeecg的flowable支持部门经理的单个或多实例支持(前端部分)
nbcio-boot基于jeecg的flowable支持部门经理的单个或多实例支持(前端部分)
23 1