flowable 之駁回 多實例駁回 並行網關駁回 普通節點駁回到多實例


flowable 駁回

歡迎大家學習交流,如有不對的地方,請大家多多指教,我接下來會把flowable的所有的中國式API*都寫出來,也希望對大家有幫助,程序員只要靜下心來,其實可以產生巨大的能量,靠任何人都沒有用,唯有靠自己。學習好一門技術,還是多看看源代碼,多在實際工作中用,如果想走捷徑,想通過一本書或者一些視頻想學好,那永遠是痴心說夢。*

網上搜索了很多關於activiti的駁回方法,flowable的駁回方法,發現一個問題,基本都是在扯淡,根本無法解決商業用途,為了把這塊吃透,我最近研究了一下他們的源代碼,已在我們公司使用,暫時沒有發現問題。其實看flowable的源代碼很簡單的,就是一個命令模式,仿照他們的命令模式寫自己的就可以了,沒有太大的難度。不得不佩服flowable的作者,用命令模式規范了自己的代碼,而且把這么好的東西開源出來,從來沒有找我們要過錢,這是何等的偉大,像大神致敬。閑話不多說,直接來代碼比較干脆。

由於我們公司的流程有規范,所以有寫地方有點特殊,如果不懂的可以隨時給我留言即可,來也網絡,去也網絡。

  • 1. 判斷該節點上一個節點是不是並行網關節點
  • 2. 如果上一個節點是提交者的話要處理一下
  • 3. 添加審批意見和修改流程狀態
  • 4. 刪除現有的所有任務
  • 5. 刪除節點信息
  • 6. 駁回到disk節點
  • 6.1 如果當前節點是多實例節點 刪除當前多實例 如果目標節點不是多實例我們就創建一個孩子實例
  • 6.2 處理並行網關的多實例

    具體代碼

 public ReturnVo<String> backToStep(BackVo backVo) {
        ReturnVo<String> returnVo = new ReturnVo<>(ReturnCode.SUCCESS, "OK");
        if (backVo != null && StringUtils.isNotBlank(backVo.getTaskId())) {
            TaskEntity taskEntity = (TaskEntity) taskService.createTaskQuery().taskId(backVo.getTaskId()).singleResult();
            if (taskEntity != null){
                Activity distActivity = processDefinitionUtils.findFlowElementById(taskEntity.getProcessDefinitionId(), backVo.getDistFlowElementId());
                if (taskEntity != null && distActivity != null) {
                    //1. 判斷該節點上一個節點是不是並行網關節點
                    List<SequenceFlow> incomingFlows = distActivity.getIncomingFlows();
                    if (CollectionUtils.isNotEmpty(incomingFlows)) {
                        for (SequenceFlow sequenceFlow : incomingFlows) {
                            FlowElement upNode = sequenceFlow.getSourceFlowElement();
                            if (upNode != null && (upNode instanceof ParallelGateway || upNode instanceof InclusiveGateway)) {
                                returnVo = new ReturnVo<>(ReturnCode.FAIL, "並行節點無法駁回,請選擇其他節點!");
                                return returnVo;
                            }
                        }
                    }
                    //2. 如果上一個節點是提交者的話要處理一下
                    if (FlowConstant.FLOW_SUBMITTER.equals(distActivity.getName())) {
                        //查找發起人
                        ExtendHisprocinst extendHisprocinst = this.extendHisprocinstService.findExtendHisprocinstByProcessInstanceId(taskEntity.getProcessInstanceId());
                        if (extendHisprocinst != null) {
                            runtimeService.setVariable(taskEntity.getProcessInstanceId(), FlowConstant.FLOW_SUBMITTER, extendHisprocinst.getCreator());
                        }
                    }
                    //3. 添加審批意見和修改流程狀態
                    this.addCommentAndUpdateProcessStatus(backVo);
                    //4. 刪除現有的所有任務
                    managementService.executeCommand(new DeleteTaskCmd(taskEntity.getProcessInstanceId()));
                    //5. 刪除節點信息
                    this.deleteHisActivities(distActivity, taskEntity.getProcessInstanceId());
                    //6. 駁回到disk節點
                    Activity currActivity = processDefinitionUtils.findFlowElementById(taskEntity.getProcessDefinitionId(), taskEntity.getTaskDefinitionKey());
                    //6.1 如果當前節點是多實例節點 刪除當前多實例 如果目標節點不是多實例我們就創建一個孩子實例
                    boolean flag = false;
                    if (currActivity.getBehavior() instanceof MultiInstanceActivityBehavior){
                        ExecutionEntity executionEntity = (ExecutionEntity)runtimeService.createExecutionQuery().executionId(taskEntity.getExecutionId()).singleResult();
                        managementService.executeCommand(new DeleteMultiInstanceExecutionCmd(executionEntity.getParentId(),false));
                        flag = true;
                    }
                    //6.2 處理並行網關的多實例
                    List<Execution> executions = runtimeService.createExecutionQuery().parentId(taskEntity.getProcessInstanceId()).list();
                    if (CollectionUtils.isNotEmpty(executions) && executions.size() >1){
                        executions.forEach(execution -> {
                            ExecutionEntity e = (ExecutionEntity)execution;
                            managementService.executeCommand(new DeleteChildExecutionCmd(e));
                        });
                        flag = true;
                    }
                    if (flag) {
                        ExecutionEntity parentExecutionEntity = (ExecutionEntity)runtimeService.createExecutionQuery().executionId(taskEntity.getProcessInstanceId()).singleResult();
                        managementService.executeCommand(new AddChildExecutionCmd(parentExecutionEntity));
                    }
                    managementService.executeCommand(new JumpActivityCmd(taskEntity.getProcessInstanceId(),distActivity.getId()));
                    //TODO 7. 處理加簽的數據0
                }
            }else {
                returnVo = new ReturnVo<>(ReturnCode.FAIL, "當前任務不存在!");
            }
        } else {
            returnVo = new ReturnVo<>(ReturnCode.FAIL, "請設置相關參數!");
        }
        return returnVo;
    }

  

  • ProcessDefinitionUtils
@Component
public class ProcessDefinitionUtils {

    @Autowired
    private RepositoryService repositoryService;

    /**
     * 獲取end節點
     *
     * @param processDefId
     * @return FlowElement
     */
    public FlowElement findEndFlowElement(String processDefId) {
        Process process = repositoryService.getBpmnModel(processDefId).getMainProcess();
        Collection<FlowElement> list = process.getFlowElements();
        for (FlowElement f : list) {
            if (f instanceof EndEvent) {
                return f;
            }
        }
        return null;
    }

    /**
     * 獲取指定節點的節點信息
     *
     * @param processDefId
     * @param flowElementId
     * @return FlowElement
     */
    public Activity findFlowElementById(String processDefId, String flowElementId) {
        Process process = repositoryService.getBpmnModel(processDefId).getMainProcess();
        return (Activity) process.getFlowElement(flowElementId);
    }

}

  

addCommentAndUpdateProcessStatus 這個方法是添加審批意見和更新流程狀態,由於流程狀態沒有,我這里擴展了一張表,狀態主要有審批中,駁回,暫存,轉辦,撤回,終止等等狀態

/**
     * 添加審批意見和修改流程狀態
     * @param baseProcessVo 基本流程任務參數
     */
    protected void addCommentAndUpdateProcessStatus(BaseProcessVo baseProcessVo) {
        //兼容處理
        if (StringUtils.isBlank(baseProcessVo.getProcessInstanceId())){
            Task task = taskService.createTaskQuery().taskId(baseProcessVo.getTaskId()).singleResult();
            if (task != null) {
                baseProcessVo.setProcessInstanceId(task.getProcessInstanceId());
            }
        }
        //1.添加審批意見
        FlowCommentVo flowCommentVo = new FlowCommentVo(baseProcessVo.getTaskId(), baseProcessVo.getUserCode(),
                baseProcessVo.getProcessInstanceId(), baseProcessVo.getMessage(), baseProcessVo.getCommentTypeEnum().toString());
        this.addFlowComment(flowCommentVo);
        //2.修改流程實例的狀態
        ExtendHisprocinst extendHisprocinst = new ExtendHisprocinst(baseProcessVo.getProcessInstanceId(), baseProcessVo.getProcessStatusEnum().toString());
        extendHisprocinstService.updateStatusByProcessInstanceId(extendHisprocinst);
        //3.TODO 生成索引
    }

    /**
     * 添加審批意見
     * @param flowCommentVo
     */
    private void addFlowComment(FlowCommentVo flowCommentVo) {
        FlowCommentCmd cmd = new FlowCommentCmd(flowCommentVo.getTaskId(), flowCommentVo.getUserId(),
                flowCommentVo.getProcessInstanceId(), flowCommentVo.getType(), flowCommentVo.getMessage());
        managementService.executeCommand(cmd);
    }

 DeleteTaskCmd 刪除任務命令

public class DeleteTaskCmd implements Command<Void> {

    private String processInstanceId;

    public DeleteTaskCmd(String processInstanceId) {
        this.processInstanceId = processInstanceId;
    }

    @Override
    public Void execute(CommandContext commandContext) {
        TaskEntityManager taskEntityManager = CommandContextUtil.getTaskEntityManager(commandContext);
        ExecutionEntityManager executionEntityManager = org.flowable.engine.impl.util.CommandContextUtil.getExecutionEntityManager(commandContext);
        List<ExecutionEntity> executionEntities = executionEntityManager.findChildExecutionsByProcessInstanceId(processInstanceId);
        executionEntities.forEach(executionEntity -> taskEntityManager.deleteTasksByExecutionId(executionEntity.getId()));
        return null;
    }
}

 AddChildExecutionCmd 添加一個流程實例下面的執行實例

public class AddChildExecutionCmd implements Command<Void> {

    private ExecutionEntity parentExecutionEntity;

    public AddChildExecutionCmd(ExecutionEntity parentExecutionEntity) {
        this.parentExecutionEntity = parentExecutionEntity;
    }

    @Override
    public Void execute(CommandContext commandContext) {
        ExecutionEntityManager executionEntityManager = CommandContextUtil.getExecutionEntityManager(commandContext);
        executionEntityManager.createChildExecution(parentExecutionEntity);
        return null;
    }
}

  DeleteChildExecutionCmd 刪除執行實例

public class DeleteChildExecutionCmd implements Command<Void> {

    private ExecutionEntity child;

    public DeleteChildExecutionCmd(ExecutionEntity child) {
        this.child = child;
    }

    @Override
    public Void execute(CommandContext commandContext) {
        ExecutionEntityManager executionEntityManager = CommandContextUtil.getExecutionEntityManager(commandContext);
        executionEntityManager.delete(child,true);
        return null;
    }
}

  JumpActivityCmd 執行跳轉

public class JumpActivityCmd implements Command<Void> {

    private String target;
    private String processInstanceId;

    public JumpActivityCmd(String processInstanceId, String target) {
        this.processInstanceId = processInstanceId;
        this.target = target;
    }

    @Override
    public Void execute(CommandContext commandContext) {
        ExecutionEntityManager executionEntityManager = CommandContextUtil.getExecutionEntityManager(commandContext);
        List<ExecutionEntity> executionEntities = executionEntityManager.findChildExecutionsByParentExecutionId(processInstanceId);
        Process process = ProcessDefinitionUtil.getProcess(executionEntities.get(0).getProcessDefinitionId());
        FlowNode targetFlowElement = (FlowNode) process.getFlowElement(target);
        FlowableEngineAgenda agenda = CommandContextUtil.getAgenda();
        executionEntities.forEach(execution -> {
            execution.setCurrentFlowElement(targetFlowElement);
            agenda.planContinueProcessInCompensation(execution);
        });
        return null;
    }

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM