The flowable process based on jeecg-boot adds the department manager approval function

      Because the department manager approval has not been added in the process designer before, this function is added this time

The interface is as follows:

 At the same time, multi-instance configuration can be performed for multiple department managers, as shown in the following figure:

 1. Front-end implementation

      Mainly modify the userTask.vue file.

<template>
  <div style="margin-top: 16px">
    <el-row>
      <h4><b>设置用户类型</b></h4>
      <el-radio-group v-model="defaultTaskForm.dataType" @change="changeDataType">
        <div v-if="bDisplayUser">
          <el-radio label="ASSIGNEE">指定用户</el-radio>
          <el-radio label="INITIATOR">发起人</el-radio>
	      </div>
        <el-radio label="MANAGER">部门经理</el-radio>
        <el-radio label="USERS">候选用户</el-radio>
        <el-radio label="ROLES">候选角色</el-radio>
      </el-radio-group>
    </el-row>
    <el-row>
      <div v-if="defaultTaskForm.dataType === 'ASSIGNEE'">
        <el-select v-model="userTaskForm.assignee" filterable allow-create clearable @change="updateElementTask('assignee')">
          <el-option v-for="ak in users" :key="ak.id" :label="ak.name" :value="ak.id" />
        </el-select>
      </div>   
    </el-row>
    <el-row>
      <div v-if="defaultTaskForm.dataType === 'USERS'">
        <el-select v-model="userTaskForm.candidateUsers" filterable allow-create multiple collapse-tags @change="updateElementTask('candidateUsers')">
          <el-option v-for="uk in users" :key="uk.id" :label="uk.name" :value="uk.id" />
        </el-select>
      </div>   
    </el-row>
    <el-row>
      <div v-if="defaultTaskForm.dataType === 'ROLES'">
        <el-select v-model="userTaskForm.candidateGroups" filterable allow-create multiple collapse-tags @change="updateElementTask('candidateGroups')">
          <el-option v-for="gk in groups" :key="gk.id" :label="gk.name" :value="gk.id" />
        </el-select>
      </div>  
    </el-row>
    <el-row v-if="defaultTaskForm.dataType === 'USERS' || defaultTaskForm.dataType === 'ROLES' || defaultTaskForm.dataType === 'MANAGER'">
      <h4><b>多实例</b></h4>
      <div>
        <element-multi-instance :business-object="bpmnElement.businessObject" @multiInsEvent="multiIns"/>
      </div>  
    </el-row>
    <!-- <el-form-item label="到期时间">
      <el-input v-model="userTaskForm.dueDate" clearable @change="updateElementTask('dueDate')" />
    </el-form-item>
    <el-form-item label="跟踪时间">
      <el-input v-model="userTaskForm.followUpDate" clearable @change="updateElementTask('followUpDate')" />
    </el-form-item>
    <el-form-item label="优先级">
      <el-input v-model="userTaskForm.priority" clearable @change="updateElementTask('priority')" />
    </el-form-item> -->
  </div>
</template>

<script>
import ElementMultiInstance from "../../multi-instance/ElementMultiInstance";
export default {
  name: "UserTask",
  components: {
    ElementMultiInstance,
  },  
  props: {
    users: {//兼容老系统add by nbacheng
      type: Array,
      required: true
    },
    groups: {//兼容老系统
      type: Array,
      required: true
    },
    id: String,
    type: String
  },
  data() {
    return {
      defaultTaskForm: {
        assignee: "",
        candidateUsers: [],
        candidateGroups: [],
        dueDate: "",
        followUpDate: "",
        priority: "",
        dataType: "",
      },
      userTaskForm: {},
      bDisplayUser: true,
    };
  },
  watch: {
    id: {
      immediate: true,
      handler() {
        this.bpmnElement = window.bpmnInstances.bpmnElement;
        console.log("watch this.bpmnElement",this.bpmnElement)
        if (this.containsKey(this.bpmnElement.businessObject, 'loopCharacteristics') &&
             this.bpmnElement.businessObject.loopCharacteristics != null) {
          this.bDisplayUser = false;
          if (this.containsKey(this.bpmnElement.businessObject, 'candidateUsers') &&
               this.bpmnElement.businessObject.candidateUsers != null) {
            this.defaultTaskForm.dataType = "USERS";
          }
          if (this.containsKey(this.bpmnElement.businessObject, 'candidateUsers') &&
               this.bpmnElement.businessObject.candidateUsers === '${DepManagerHandler.getUsers(execution)}') {
            this.defaultTaskForm.dataType = "MANAGER";
          }
          if (this.containsKey(this.bpmnElement.businessObject, 'candidateGroups') &&
               this.bpmnElement.businessObject.candidateGroups != null) {
            this.defaultTaskForm.dataType = "ROLES";
          }
        }
        else {
          if (this.containsKey(this.bpmnElement.businessObject, 'assignee') &&
             this.bpmnElement.businessObject.assignee != null) {
             this.defaultTaskForm.dataType = "ASSIGNEE";
          } 
          if (this.containsKey(this.bpmnElement.businessObject, 'candidateUsers') &&
               this.bpmnElement.businessObject.candidateUsers != null) {
            this.defaultTaskForm.dataType = "USERS";
          }
          if (this.containsKey(this.bpmnElement.businessObject, 'candidateGroups') &&
               this.bpmnElement.businessObject.candidateGroups != null) {
            this.defaultTaskForm.dataType = "ROLES";
          }
          if (this.containsKey(this.bpmnElement.businessObject, 'assignee') &&
               this.bpmnElement.businessObject.assignee === '${INITIATOR}') {
            this.defaultTaskForm.dataType = "INITIATOR";
          }
          if (this.containsKey(this.bpmnElement.businessObject, 'candidateUsers') &&
               this.bpmnElement.businessObject.candidateUsers === '${DepManagerHandler.getUsers(execution)}') {
            this.defaultTaskForm.dataType = "MANAGER";
          }
        }
        this.$nextTick(() => this.resetTaskForm());
      }
    }
  },
  methods: {
    multiIns(val) { //子组件传递是否是多实例
      this.bDisplayUser = val;
    },
    containsKey(obj, key ) {
        return Object.keys(obj).includes(key);
    },
    resetTaskForm() {
      for (let key in this.defaultTaskForm) {
        let value;
        if (key === "candidateUsers" || key === "candidateGroups") {
          value = this.bpmnElement?.businessObject[key] ? this.bpmnElement.businessObject[key].split(",") : [];
        } else {
          value = this.bpmnElement?.businessObject[key] || this.defaultTaskForm[key];
        }
        this.$set(this.userTaskForm, key, value);
      }
    },
    changeDataType(val) {
      // 清空 userTaskForm 所有属性值
      //Object.keys(this.userTaskForm).forEach(key => this.userTaskForm[key] = null);
      this.userTaskForm.dataType = val;
      if (val === 'INITIATOR') {
        this.userTaskForm.assignee = "${INITIATOR}";
        this.userTaskForm.text = "流程发起人";
        const taskAttr = Object.create(null);
        taskAttr['candidateUsers'] = null;
        taskAttr['candidateGroups'] = null;
        this.userTaskForm['candidateUsers'] = null;
        this.userTaskForm['candidateGroups'] = null;
        taskAttr['assignee'] = this.userTaskForm['assignee'] || null;
        window.bpmnInstances.modeling.updateProperties(this.bpmnElement, taskAttr);
      }
      if (val === 'MANAGER') {
        this.userTaskForm.candidateUsers = "${DepManagerHandler.getUsers(execution)}";
        this.userTaskForm.text = "部门经理";
        const taskAttr = Object.create(null);
        taskAttr['assignee'] = null;
        taskAttr['candidateGroups'] = null;
        this.userTaskForm['assignee'] = null;
        this.userTaskForm['candidateGroups'] = null;
        taskAttr['candidateUsers'] = this.userTaskForm['candidateUsers'] || null;
        window.bpmnInstances.modeling.updateProperties(this.bpmnElement, taskAttr);
      }
      /*if (val === 'ASSIGNEE' && this.userTaskForm['assignee'] === '${INITIATOR}') {
        this.userTaskForm['assignee'] = null;
        const taskAttr = Object.create(null);
        taskAttr['assignee'] = null;
        window.bpmnInstances.modeling.updateProperties(this.bpmnElement, taskAttr);
      }
      if (val === 'MANAGER' && this.userTaskForm['candidateUsers'] === '${DepManagerHandler.getUsers(execution)}') {
        this.userTaskForm['candidateUsers'] = null;
        const taskAttr = Object.create(null);
        taskAttr['candidateUsers'] = null;
        window.bpmnInstances.modeling.updateProperties(this.bpmnElement, taskAttr);
      }*/
      
    },  
    updateElementTask(key) {
      const taskAttr = Object.create(null);
      if (key === "candidateUsers") {
        taskAttr[key] = this.userTaskForm[key] && this.userTaskForm[key].length ? this.userTaskForm[key].join() : null;
        if(taskAttr[key] !=null) {
          taskAttr['candidateGroups'] = null;
          taskAttr['assignee'] = null;
          this.userTaskForm['candidateGroups'] = null;
          this.userTaskForm['assignee'] = null;
        }  
      } 
      else if (key === "candidateGroups") {
        taskAttr[key] = this.userTaskForm[key] && this.userTaskForm[key].length ? this.userTaskForm[key].join() : null;
        if(taskAttr[key] !=null) {
          taskAttr['candidateUsers'] = null;
          taskAttr['assignee'] = null;
          this.userTaskForm['candidateUsers'] = null;
          this.userTaskForm['assignee'] = null;
        }  
      } 
      else if (key === "assignee") {
        taskAttr[key] = this.userTaskForm[key] && this.userTaskForm[key].length ? this.userTaskForm[key] : null;
        if(taskAttr[key] !=null) {
          taskAttr['candidateUsers'] = null;
          taskAttr['candidateGroups'] = null;
          this.userTaskForm['candidateUsers'] = null;
          this.userTaskForm['candidateGroups'] = null;
        }
      } 
      else {
        taskAttr[key] = this.userTaskForm[key] || null;
      }
      window.bpmnInstances.modeling.updateProperties(this.bpmnElement, taskAttr);
    }
  },
  beforeDestroy() {
    this.bpmnElement = null;
  }
};
</script>

2. Backend implementation

1. Add the execution class DepManagerHandler of the department manager as follows:

package com.nbcio.modules.flowable.listener;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.flowable.bpmn.model.FlowElement;
import org.flowable.bpmn.model.UserTask;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.delegate.DelegateExecution;
import org.flowable.engine.runtime.ProcessInstance;
import org.jeecg.common.util.SpringContextUtils;
import org.springframework.stereotype.Component;

import com.nbcio.modules.flowable.apithird.service.IFlowThirdService;

import cn.hutool.core.util.ObjectUtil;
import lombok.AllArgsConstructor;

/**
 * 部门经理处理类
 *
 * @author nbacheng
 * @date 2023-08-06
 */
@AllArgsConstructor
@Component("DepManagerHandler")
public class DepManagerHandler {

	private IFlowThirdService flowThirdService = SpringContextUtils.getBean(IFlowThirdService.class);
	RuntimeService runtimeService = SpringContextUtils.getBean(RuntimeService.class);

	public List<String> getUsers(DelegateExecution execution) {
		List<String> assignUserName = new ArrayList<String>();
		FlowElement flowElement = execution.getCurrentFlowElement();
        if (ObjectUtil.isNotEmpty(flowElement) && flowElement instanceof UserTask) {
            UserTask userTask = (UserTask) flowElement;
            if ( StringUtils.isNotEmpty(userTask.getAssignee())) {
            	if(StringUtils.contains(userTask.getAssignee(),"DepManagerHandler")) {
            		 // 获取流程发起人
            		ProcessInstance processInstance = runtimeService
                            .createProcessInstanceQuery()
                            .processInstanceId(execution.getProcessInstanceId())
                            .singleResult();
                    String startUserId = processInstance.getStartUserId();
                    // 获取部门负责人列表
            		List<String> depIds = flowThirdService.getDepartIdsByUsername(startUserId);
            		List<String> DepHeadlist = new ArrayList<String>();
            		for(String depId: depIds) {
            			List<String> depList = flowThirdService.getDeptHeadByDepId(depId);
            			if(depList != null) {
            				DepHeadlist.addAll(depList);
            			}
            			
            		}
            		// 部门负责人列表去重
            		if(!DepHeadlist.isEmpty() ) {
            		    for (String str : DepHeadlist) {
            		        if (!assignUserName.contains(str)) {
            		        	assignUserName.add(str);
            		        }
            		    }
            		}
            	}
            }
        }    
        return assignUserName;
		
	}
}

2. Considering the complexity, set the next approver, do not do any processing here, and let the initiator complete the submission process.

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 if(nextFlowNode.getUserTask().getCandidateUsers().size()>0 && StringUtils.equalsAnyIgnoreCase(nextFlowNode.getUserTask().getCandidateUsers().get(0), "${DepManagerHandler.getUsers(execution)}")) {//对部门经理做特殊处理								
								//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("多实例会签流程启动成功.");
					}

3. getNextFlowNode adds special handling for relevant department managers

/**  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), ".", "(");
                        	Object[] argsPara=new Object[]{};
                        	setMultiFlowExp(flowNextDto,newUserTask,multiInstance,methodname,argsPara);
                        }
                        else if(userlist.size() != 0 && StringUtils.contains(userlist.get(0), "${flowExp.getDynamic")) {//对表达式多个动态用户做特殊处理
                        	String methodname = StringUtils.substringBetween(userlist.get(0), ".", "(");
                        	Object[] argsPara=new Object[]{};
                        	setMultiFlowExp(flowNextDto,newUserTask,multiInstance,methodname,argsPara);
                        }
                        else if(userlist.size() != 0 && StringUtils.contains(userlist.get(0), "DepManagerHandler")) {//对部门经理做特殊处理
                        	String methodname = "getInitiatorDepManagers";
                        	// 获取流程发起人
	                   		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) {
                        	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 && StringUtils.equalsAnyIgnoreCase(userlist.get(0), "${DepManagerHandler.getUsers(execution)}")) {//对部门经理做特殊处理
                        	List<SysUser> list = new ArrayList<SysUser>();
	                   		// 获取流程发起人
	                   		ProcessInstance processInstance = runtimeService
	                                   .createProcessInstanceQuery()
	                                   .processInstanceId(task.getProcessInstanceId())
	                                   .singleResult();
	                        String startUserId = processInstance.getStartUserId();
	                        //获取部门经理
	                   		list = getInitiatorDepManagers(startUserId);    
	                   		List<String> listCandidateUsers = new ArrayList<String>();
	                   		for(SysUser sysUser: list) {
	                   			String username = sysUser.getUsername();
	                   			listCandidateUsers.add(username);
	                   		}
	                   		userTask.setCandidateUsers(listCandidateUsers);//对于多实例要覆盖原先的值
	                   		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) {
									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) {
									e.printStackTrace();
								}
                        		setUsersFlowNetDto(flowNextDto,list,userTask);
                        	   
                        	}
                        	else if(StringUtils.contains(assignee, "${DepManagerHandler")) {//对部门经理多用户做特殊处理
                        		String methodname = "getInitiatorDepManagers";
                        		List<SysUser> list = new ArrayList<SysUser>();
                        		// 获取流程发起人
    	                   		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);
                        	   
                        	}
                        	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 && StringUtils.equalsAnyIgnoreCase(userlist.get(0), "${DepManagerHandler.getUsers(execution)}")) {//对部门经理做特殊处理
                        	List<SysUser> list = new ArrayList<SysUser>();
	                   		// 获取流程发起人
	                   		ProcessInstance processInstance = runtimeService
	                                   .createProcessInstanceQuery()
	                                   .processInstanceId(task.getProcessInstanceId())
	                                   .singleResult();
	                           String startUserId = processInstance.getStartUserId();
	                   		list = getInitiatorDepManagers(startUserId);
	                   		if(list.size()> 1) {
	                   		  setUsersFlowNetDto(flowNextDto,list,userTask);
	                       	  setMultiFinishFlag(task,flowNextDto,list);
	                   		}
	                   		else {
	                   			setUsersFlowNetDto(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;

    }

4. The multi-instance processing class increases the processing of department managers

package com.nbcio.modules.flowable.listener;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.nbcio.modules.flowable.apithird.entity.SysUser;
import com.nbcio.modules.flowable.apithird.service.IFlowThirdService;
import com.nbcio.modules.flowable.utils.flowExp;

import lombok.AllArgsConstructor;

import org.apache.commons.lang3.StringUtils;
import org.flowable.bpmn.model.FlowElement;
import org.flowable.bpmn.model.UserTask;
import org.flowable.engine.delegate.DelegateExecution;
import org.jeecg.common.util.SpringContextUtils;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

/**
 * 多实例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 if (groups.size()!= 0 && StringUtils.contains(groups.get(0), "DepManagerHandler")) {
            		getInitiatorDepManagers(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();
		}
    }
	
    @SuppressWarnings("unchecked")
	private void getInitiatorDepManagers(Set<String> candidateUserName) {
    	String methodname = "getInitiatorDepManagers";
		List<String> list = new ArrayList<String>();
		flowExp flowexp = SpringContextUtils.getBean(flowExp.class);
		Object[] argsP

5. Increase the acquisition of department managers in the expression

//获取发起人部门经理
  	public  List<String> getInitiatorDepManagers(String startUserId) {
  		// 获取部门负责人列表
  		List<String> depIds = iFlowThirdService.getDepartIdsByUsername(startUserId);
  		List<String> DepHeadlist = new ArrayList<String>();
  		for(String depId: depIds) {
  			List<String> depList = iFlowThirdService.getDeptHeadByDepId(depId);
  			if(depList != null) {
  				DepHeadlist.addAll(depList);
  			}
  			
  		}
  		// 部门负责人列表去重
  		List<String> listUserName = new ArrayList<String>();
  		if(!DepHeadlist.isEmpty() ) {
  		    for (String str : DepHeadlist) {
  		        if (!listUserName.contains(str)) {
  		        	listUserName.add(str);
  		        }
  		    }
  		}
  		return listUserName;
  		
  	}
	
	/**
	* 反射调用方法
	* @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);
	}

Guess you like

Origin blog.csdn.net/qq_40032778/article/details/132202775