Activitiプロセスが拒否されました

プロジェクトアドレス:activiti-ワークフロー

一般的な承認フローには拒否機能があり、activitiが提供するインターフェースはそれを拒否しません。この記事では、activitiが提供するインターフェースを拡張することにより、プロセス拒否機能を実装します。メインコードは次のとおりです。

		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);
                }
            }
        }

invokeSequenceFlowsメソッド、特定のコードをプロジェクトで表示できます。



    /**
     * 处理撤回连线 可能存在分支
     * @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;
    }

いくつかのアイデアを整理し、ターゲットノードの定義IDを渡すオプションを拒否します。そうでない場合は、デフォルトで開始ノードの次のノードを選択します。現在、複数の承認タスクがある場合、今回実行したタスクが完了すると他の操作は実行されず、完了後に他のタスクは削除されます(承認トレースは残されません)。

主にinvokeSequenceFlowsによって処理される現在の承認プロセスには、複数のタスクが含まれる場合があります。処理方法は、現在のノードの前のタスクに並列ゲートウェイを追加し、現在の承認ノードをゲートウェイに接続し、ゲートウェイをターゲットノードに接続することです。このように、現在の承認タスクの数に関係なく、並列ゲートウェイは、前のノードがすべて完了するのを待ってから、後続のノードに進み、現在の承認タスクがすべて実行されるようにします。

おそらくプロセスはこのようなものです

ここに画像の説明を挿入
この方法は、撤退(イニシエーター操作)にも使用され、問題が発生する可能性があり、多くのテストが必要になります。

おすすめ

転載: blog.csdn.net/qq_34758074/article/details/106365223