22. flowable 驳回 回退 并行网关驳回 多实例驳回 子流程驳回
小学生05101 2019-12-10 20:33:01 2287 收藏 2
分类专栏: Flowable基础 文章标签: flowable flowable企业级
版权
项目地址:https://gitee.com/lwj/flowable.git 分支flowable-base
视频讲解地址 https://www.bilibili.com/video/av78779999/
驳回:当前处理人可以驳回历史走过的任何一个节点
1、驳回任意普通节点
2、驳回多实例节点
3、驳回并行网关节点
4、驳回子流程节点
5、子流程节点驳回主流程节点
实际情况中,为了获取可驳回的节点列表,我们做了一些规定,比方说并行网关节点,要求必须成对出现,也只能驳回到并行网关节点的 fork节点
一、演示
由于情况很多,截图反而不能重点讲述驳回的事情,这里只截一张图,如果想看详情请查看视频里面的讲解
二、代码分享
2.1 获取可驳回节点
public List<FlowNodeVo> getBackNodesByProcessInstanceId(String taskId,String processInstanceId) { List<FlowNodeVo> backNods = new ArrayList<>(); TaskEntity taskEntity = (TaskEntity) taskService.createTaskQuery().taskId(taskId).singleResult(); String currActId = taskEntity.getTaskDefinitionKey(); //获取运行节点表中usertask String sql = "select t.* from act_ru_actinst t where t.ACT_TYPE_ = 'userTask' " + " and t.PROC_INST_ID_=#{processInstanceId} and t.END_TIME_ is not null "; List<ActivityInstance> activityInstances = runtimeService.createNativeActivityInstanceQuery().sql(sql) .parameter("processInstanceId", processInstanceId) .list(); //获取运行节点表的parallelGateway节点并出重 sql = "SELECT t.ID_, t.REV_,t.PROC_DEF_ID_,t.PROC_INST_ID_,t.EXECUTION_ID_,t.ACT_ID_, t.TASK_ID_, t.CALL_PROC_INST_ID_, t.ACT_NAME_, t.ACT_TYPE_, " + " t.ASSIGNEE_, t.START_TIME_, max(t.END_TIME_) as END_TIME_, t.DURATION_, t.DELETE_REASON_, t.TENANT_ID_" + " FROM act_ru_actinst t WHERE t.ACT_TYPE_ = 'parallelGateway' AND t.PROC_INST_ID_ = #{processInstanceId} and t.END_TIME_ is not null" + " and t.ACT_ID_ <> #{actId} GROUP BY t.act_id_"; List<ActivityInstance> parallelGatewaies = runtimeService.createNativeActivityInstanceQuery().sql(sql) .parameter("processInstanceId", processInstanceId) .parameter("actId", currActId) .list(); //排序 if (CollectionUtils.isNotEmpty(parallelGatewaies)) { activityInstances.addAll(parallelGatewaies); activityInstances.sort(Comparator.comparing(ActivityInstance::getEndTime)); } //分组节点 int count = 0; Map<ActivityInstance, List<ActivityInstance>> parallelGatewayUserTasks = new HashMap<>(); List<ActivityInstance> userTasks = new ArrayList<>(); ActivityInstance currActivityInstance = null; for (ActivityInstance activityInstance : activityInstances) { if (BpmnXMLConstants.ELEMENT_GATEWAY_PARALLEL.equals(activityInstance.getActivityType())) { count++; if (count % 2 != 0) { List<ActivityInstance> datas = new ArrayList<>(); currActivityInstance = activityInstance; parallelGatewayUserTasks.put(currActivityInstance, datas); } } if (BpmnXMLConstants.ELEMENT_TASK_USER.equals(activityInstance.getActivityType())) { if (count % 2 == 0) { userTasks.add(activityInstance); } else { if (parallelGatewayUserTasks.containsKey(currActivityInstance)) { parallelGatewayUserTasks.get(currActivityInstance).add(activityInstance); } } } } //组装人员名称 List<HistoricTaskInstance> historicTaskInstances = historyService.createHistoricTaskInstanceQuery() .processInstanceId(processInstanceId).finished().list(); Map<String, List<HistoricTaskInstance>> taskInstanceMap = new HashMap<>(); List<String> userCodes = new ArrayList<>(); historicTaskInstances.forEach(historicTaskInstance -> { userCodes.add(historicTaskInstance.getAssignee()); String taskDefinitionKey = historicTaskInstance.getTaskDefinitionKey(); if (taskInstanceMap.containsKey(historicTaskInstance.getTaskDefinitionKey())) { taskInstanceMap.get(taskDefinitionKey).add(historicTaskInstance); } else { List<HistoricTaskInstance> tasks = new ArrayList<>(); tasks.add(historicTaskInstance); taskInstanceMap.put(taskDefinitionKey, tasks); } }); //组装usertask的数据 List<User> userList = identityService.createUserQuery().userIds(userCodes).list(); Map<String, String> activityIdUserNames = this.getApplyers(processInstanceId, userList, taskInstanceMap); if (CollectionUtils.isNotEmpty(userTasks)) { userTasks.forEach(activityInstance -> { FlowNodeVo node = new FlowNodeVo(); node.setNodeId(activityInstance.getActivityId()); node.setNodeName(activityInstance.getActivityName()); node.setEndTime(activityInstance.getEndTime()); node.setUserName(activityIdUserNames.get(activityInstance.getActivityId())); backNods.add(node); }); } //组装会签节点数据 if (MapUtils.isNotEmpty(taskInstanceMap)) { parallelGatewayUserTasks.forEach((activity, activities) -> { FlowNodeVo node = new FlowNodeVo(); node.setNodeId(activity.getActivityId()); node.setEndTime(activity.getEndTime()); StringBuffer nodeNames = new StringBuffer("会签:"); StringBuffer userNames = new StringBuffer("审批人员:"); if (CollectionUtils.isNotEmpty(activities)){ activities.forEach(activityInstance -> { nodeNames.append(activityInstance.getActivityName()).append(","); userNames.append(activityIdUserNames.get(activityInstance.getActivityId())).append(","); }); node.setNodeName(nodeNames.toString()); node.setUserName(userNames.toString()); backNods.add(node); } }); } //去重合并 List<FlowNodeVo> datas = backNods.stream().collect( Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(nodeVo -> nodeVo.getNodeId()))), ArrayList::new)); //排序 datas.sort(Comparator.comparing(FlowNodeVo::getEndTime)); return datas; }
2.2、驳回代码分享
public ReturnVo<String> backToStepTask(BackTaskVo backTaskVo) { ReturnVo<String> returnVo = null; TaskEntity taskEntity = (TaskEntity) taskService.createTaskQuery().taskId(backTaskVo.getTaskId()).singleResult(); //1.把当前的节点设置为空 if (taskEntity != null) { //2.设置审批人 taskEntity.setAssignee(backTaskVo.getUserCode()); taskService.saveTask(taskEntity); //3.添加驳回意见 this.addComment(backTaskVo.getTaskId(), backTaskVo.getUserCode(), backTaskVo.getProcessInstanceId(), CommentTypeEnum.BH.toString(), backTaskVo.getMessage()); //4.处理提交人节点 FlowNode distActivity = flowableBpmnModelService.findFlowNodeByActivityId(taskEntity.getProcessDefinitionId(), backTaskVo.getDistFlowElementId()); if (distActivity != null) { if (FlowConstant.FLOW_SUBMITTER.equals(distActivity.getName())) { ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(taskEntity.getProcessInstanceId()).singleResult(); runtimeService.setVariable(backTaskVo.getProcessInstanceId(), FlowConstant.FLOW_SUBMITTER_VAR, processInstance.getStartUserId()); } } //5.删除节点 this.deleteActivity(backTaskVo.getDistFlowElementId(), taskEntity.getProcessInstanceId()); List<String> executionIds = new ArrayList<>(); //6.判断节点是不是子流程内部的节点 if (flowableBpmnModelService.checkActivitySubprocessByActivityId(taskEntity.getProcessDefinitionId(), backTaskVo.getDistFlowElementId()) && flowableBpmnModelService.checkActivitySubprocessByActivityId(taskEntity.getProcessDefinitionId(), taskEntity.getTaskDefinitionKey())){ //6.1 子流程内部驳回 Execution executionTask = runtimeService.createExecutionQuery().executionId(taskEntity.getExecutionId()).singleResult(); String parentId = executionTask.getParentId(); List<Execution> executions = runtimeService.createExecutionQuery().parentId(parentId).list(); executions.forEach(execution -> executionIds.add(execution.getId())); this.moveExecutionsToSingleActivityId(executionIds,backTaskVo.getDistFlowElementId()); }else { //6.2 普通驳回 List<Execution> executions = runtimeService.createExecutionQuery().parentId(taskEntity.getProcessInstanceId()).list(); executions.forEach(execution -> executionIds.add(execution.getId())); this.moveExecutionsToSingleActivityId(executionIds,backTaskVo.getDistFlowElementId()); } returnVo = new ReturnVo<>(ReturnCode.SUCCESS, "驳回成功!"); } else { returnVo = new ReturnVo<>(ReturnCode.FAIL, "不存在任务实例,请确认!"); } return returnVo; }
————————————————
原文链接:https://blog.csdn.net/liuwenjun05101/article/details/103482334