Processus Activiti rejeté

Adresse du projet: activiti-workflow

Il y aura une fonction de rejet dans le flux d'approbation général, et l'interface fournie par activiti ne la rejette pas. Cet article implémente la fonction de rejet de processus en étendant l'interface fournie par activiti. Le code principal est le suivant

		String processInstanceId = taskCurrent.getProcessInstanceId();
        FlowElement targetFlowElement = null;
        if (StringUtil.isNotEmpty(processRejectParam.getTargetNodeId())) {
    
    
            //找到目标节点元素
            targetFlowElement = bpmnModel.getMainProcess().getFlowElement(processRejectParam.getTargetNodeId());
        } else {
    
    
        	//开始节点的下一个节点
            targetFlowElement = BpmnUtil.startEventNextTaskId(bpmnModel);
        }
        //当前待审批节点定义Id集合
        List<Task> taskList = taskService.createTaskQuery().processInstanceId(processInstanceId).list();

        if (CollectionUtil.isNotEmpty(taskList)) {
    
    
            BpmnModel newBpmnModel = bpmnModel;
            Map<String, List<SequenceFlow>> stringListMap = BpmnUtil.invokeSequenceFlows(newBpmnModel, taskList, targetFlowElement);

            for (Task task : taskList) {
    
    
                //记录原活动方向
                List<SequenceFlow> oriSequenceFlows = new ArrayList<>();
                //当前节点
                oriSequenceFlows.addAll(stringListMap.get(task.getTaskDefinitionKey()));
                FlowNode currentFlowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(task.getTaskDefinitionKey());
                try {
    
    
                    Map<String, Object> variables = new HashMap<>();
                    //当前操作节点
                    if(task.getId().equals(taskCurrent.getId())){
    
    
                        //设置当前审批人为提交人
                        taskService.setAssignee(task.getId(), userId);
                        // 保存任务评价
                        if (StringUtil.isNotEmpty(rejectComment)) {
    
    
                            taskService.addComment(task.getId(), task.getProcessInstanceId(), rejectComment);
                        }
                        //设置节点状态
                        taskService.setVariablesLocal(task.getId(), variables);
                        //完成
                        taskService.complete(task.getId());
                    }else{
    
    
                        //完成
                        taskService.complete(task.getId());
                        //删除任务
                        historyService.deleteHistoricTaskInstance(task.getId());
                    }
                } catch (Exception e) {
    
    
                    e.printStackTrace();
                    throw new ProcessException("流程撤回异常,异常原因:" + e.getMessage());
                } finally {
    
    
                    //恢复原方向
                    currentFlowNode.setOutgoingFlows(oriSequenceFlows);
                }
            }
        }

La méthode invokeSequenceFlows, le code spécifique peut être affiché dans le projet.



    /**
     * 处理撤回连线 可能存在分支
     * @param bpmnModel
     * @param taskList
     * @param targetFlowElement
     * @return
     */
    public static Map<String,List<SequenceFlow>> invokeSequenceFlows(BpmnModel bpmnModel , List<Task> taskList, FlowElement targetFlowElement) {
    
    
        Map<String,List<SequenceFlow>> flowElements = new HashMap<>(2);
        //并行网关
        ParallelGateway parallelGateway = new ParallelGateway();
        parallelGateway.setId("parallelGateway" + targetFlowElement.getId());
        parallelGateway.setBehavior(new ParallelGatewayActivityBehavior());
        List<SequenceFlow> parallelSequenceFlowInCome = new ArrayList<>();
        for (Task task : taskList) {
    
    
            //当前节点
            FlowNode currentFlowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(task.getTaskDefinitionKey());
            flowElements.put(currentFlowNode.getId(),currentFlowNode.getOutgoingFlows());

            //重新绘制流程图,从当前节点到到并行网关
            List<SequenceFlow> parallelSequenceFlowList = new ArrayList<>();
            SequenceFlow parallelSequenceFlow = new SequenceFlow();
            parallelSequenceFlow.setId("newSequenceFlowId" + System.currentTimeMillis());
            parallelSequenceFlow.setSourceFlowElement(currentFlowNode);
            parallelSequenceFlow.setTargetFlowElement(parallelGateway);
            parallelSequenceFlowList.add(parallelSequenceFlow);
            parallelSequenceFlowInCome.add(parallelSequenceFlow);
            currentFlowNode.setOutgoingFlows(parallelSequenceFlowList);
        }
        //重新绘制流程图,从并行网关到开始节点
        List<SequenceFlow> newSequenceFlowList = new ArrayList<>();
        //绘制连线,加入流程信息,并组装到流程图
        SequenceFlow newSequenceFlow = new SequenceFlow();
        newSequenceFlow.setId("newSequenceFlowId" + targetFlowElement.getId());
        newSequenceFlow.setSourceFlowElement(parallelGateway);
        newSequenceFlow.setTargetFlowElement(targetFlowElement);
        newSequenceFlowList.add(newSequenceFlow);
        parallelGateway.setIncomingFlows(parallelSequenceFlowInCome);
        parallelGateway.setOutgoingFlows(newSequenceFlowList);

        return flowElements;
    }

Triez certaines idées, rejetez l'option de passer l'ID de définition du nœud cible, sinon sélectionnez le nœud suivant du nœud de départ par défaut. S'il y a plusieurs tâches d'approbation à l'heure actuelle, aucune autre opération ne sera effectuée lorsque les tâches exécutées cette fois seront terminées, et les autres tâches seront supprimées une fois terminées (sans laisser de traces d'approbation).

Le processus d'approbation actuel principalement traité par invokeSequenceFlows peut avoir plusieurs tâches. La méthode de traitement consiste à ajouter une passerelle parallèle à la tâche devant le nœud actuel, à connecter le nœud d'approbation actuel à la passerelle et la passerelle au nœud cible. De cette manière, quel que soit le nombre de tâches d'approbation, la passerelle parallèle attend que tous les nœuds précédents se terminent avant de continuer vers les nœuds suivants, garantissant que les tâches d'approbation en cours sont toutes exécutées.

Probablement le processus est comme ça

Insérez la description de l'image ici
Cette méthode est également utilisée pour le retrait (fonctionnement de l'initiateur), il peut y avoir des problèmes et de nombreux tests sont nécessaires.

Je suppose que tu aimes

Origine blog.csdn.net/qq_34758074/article/details/106365223
conseillé
Classement