A-A+

Activiti6.0 – 减签

2019年09月01日 技术, 默认 暂无评论 阅读 4,609 次

上一篇实现了Activiti6.0的加签功能,本篇就实现一下Activiti6.0的减签功能。

与上一篇思路相同,既然Flowable已经实现了相关的API,我就拿过来小幅度改造以后,直接使用。

所以,找到DeleteMultiInstanceExecutionCmd的所在位置,直接拷贝至项目中。此命令在Flowable中的位置如下图所示:

拷贝后的位置其实与上一篇中AddMultiInstanceExecutionCmd所在的位置相同,如下图:

相同的,直接拷贝后,代码中有较多错误,但是大部分是由于命名空间的问题导致的,还有一些比较容易解决,只有两点有些麻烦:

1. SequentialMultiInstanceBehavior中没有getLoopVariable方法。

2. SequentialMultiInstanceBehavior中没有continueSequentialMultiInstance方法。

第一点相对来说容易解决,追踪Flowable中的源码进入SequentialMultiInstanceBehavior的内部,可以发现getLoopVariable方法相对独立,只是按照传入的参数获得loopCounter而已,所以可以直接复制一份出来。

第二点就比较麻烦了,这个方法是Flowable新增的,为了使串行的多实例节点能够正常流转下去。理论上来讲,只需要将新增的流程执行实例执行一次即可产生对应的Task(可参见Flowable源码解析),但是分析了一下Flowable这块的源码,发现需要赋予流程执行实例本地参数,并且需要判断是否是子流程节点。

对于第二点来说,本次就从简了,不深究,只是满足测试即可,所以就简化了一下,只是让新增的流程执行实例执行一次。如果以后有时间的话,再具体的测试一下这块的代码。

所以关键的代码主体如下:

@Override
public Void execute(CommandContext commandContext) {
    ExecutionEntityManager executionEntityManager = commandContext.getExecutionEntityManager();
    ExecutionEntity execution = executionEntityManager.findById(executionId);

    BpmnModel bpmnModel = ProcessDefinitionUtil.getBpmnModel(execution.getProcessDefinitionId());
    Activity miActivityElement = (Activity) bpmnModel.getFlowElement(execution.getActivityId());
    MultiInstanceLoopCharacteristics multiInstanceLoopCharacteristics = miActivityElement.getLoopCharacteristics();

    if (miActivityElement.getLoopCharacteristics() == null) {
        throw new RuntimeException("No multi instance execution found for execution id " + executionId);
    }

    if (!(miActivityElement.getBehavior() instanceof MultiInstanceActivityBehavior)) {
        throw new RuntimeException("No multi instance behavior found for execution id " + executionId);
    }

    ExecutionEntity miExecution = getMultiInstanceRootExecution(execution);
    executionEntityManager.deleteChildExecutions(execution, "Delete MI execution"false);
    executionEntityManager.deleteExecutionAndRelatedData(execution, "Delete MI execution"false);

    int loopCounter = 0;
    if (multiInstanceLoopCharacteristics.isSequential()) {
        SequentialMultiInstanceBehavior miBehavior = (SequentialMultiInstanceBehavior) miActivityElement.getBehavior();
        loopCounter = getLoopVariable(execution, miBehavior.getCollectionElementIndexVariable());
    }

    if (executionIsCompleted) {
        Integer numberOfCompletedInstances = (Integer) miExecution.getVariable(NUMBER_OF_COMPLETED_INSTANCES);
        miExecution.setVariableLocal(NUMBER_OF_COMPLETED_INSTANCES, numberOfCompletedInstances + 1);
        loopCounter++;

    } else {
        Integer currentNumberOfInstances = (Integer) miExecution.getVariable(NUMBER_OF_INSTANCES);
        miExecution.setVariableLocal(NUMBER_OF_INSTANCES, currentNumberOfInstances - 1);
    }

    ExecutionEntity childExecution = executionEntityManager.createChildExecution(miExecution);
    childExecution.setCurrentFlowElement(miExecution.getCurrentFlowElement());

    if (multiInstanceLoopCharacteristics.isSequential()) {
        continueSequentialMultiInstance(commandContext, childExecution, loopCounter, miExecution, miActivityElement);
    }

    return null;
}

protected Integer getLoopVariable(DelegateExecution execution, String variableName) {
    Object value = execution.getVariableLocal(variableName);

    for(DelegateExecution parent = execution.getParent(); value == null && parent != null; parent = parent.getParent()) {
        value = parent.getVariableLocal(variableName);
    }

    return (Integer)((Integer)(value != null ? value : 0));
}

public void continueSequentialMultiInstance(CommandContext commandContext, DelegateExecution execution, int loopCounter, ExecutionEntity multiInstanceRootExecution, Activity miActivityElement) {
    try {

        if (execution.getCurrentFlowElement() instanceof SubProcess) {
            //TODO 子流程的本地参数赋值
            execution.setScope(true);
            execution.setCurrentFlowElement(miActivityElement);
        }
        commandContext.getAgenda().planOperation(new CustomeContinueMultiInstanceOperation(commandContext, (ExecutionEntity) execution, multiInstanceRootExecution, loopCounter));

    } catch (BpmnError error) {
        // re-throw business fault so that it can be caught by an Error
        // Intermediate Event or Error Event Sub-Process in the process
        throw error;
    } catch (Exception e) {
        throw new RuntimeException("Could not execute inner activity behavior of multi instance behavior", e);
    }
}

以上,如有问题,欢迎讨论指正。

觉的不错?可以关注我的公众号↑↑↑

给我留言

Copyright © 字痕随行 保留所有权利.   Theme  Ality

用户登录

分享到: