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; }
效果图如下: