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

flowable 駁回

歡迎你們學習交流,若有不對的地方,請你們多多指教,我接下來會把flowable的全部的中國式API*都寫出來,也但願對你們有幫助,程序員只要靜下心來,其實能夠產生巨大的能量,靠任何人都沒有用,惟有靠本身。學習好一門技術,仍是多看看源代碼,多在實際工做中用,若是想走捷徑,想經過一本書或者一些視頻想學好,那永遠是癡心說夢。*java

網上搜索了不少關於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 這個方法是添加審批意見和更新流程狀態,因爲流程狀態沒有,我這裏擴展了一張表,狀態主要有審批中,駁回,暫存,轉辦,撤回,終止等等狀態ide

/**
     * 添加審批意見和修改流程狀態
     * @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 添加一個流程實例下面的執行實例this

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 刪除執行實例spa

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;
    }
相關文章
相關標籤/搜索