1. 任意节点跳转以及原理
- 常规节点跳转
- 跳转到目标节点
- 跳转到目标节点的入线
- 跳转到目标节点的上一个节点并触发连线的条件计算
- 多实例节点的跳转
- 普通节点跳转到多实例节点
- 多实例节点跳转到普通节点
比如总经理审批节点跳转到请假申请节点:
思路:
- 可以获取总经理审批节点对应的任务 ID, 实例 ID, 执行实例 ID
- 可以通过
planContiuneProcessInCompensation
方法让当前执行的实例按照我们预期的效果流转 - 我们可以将当前执行实例中的
currentFlowElement
字段设置为请假申请
节点 XML 中的 id 值; - 因为执行实例运转之后, 当前的任务节点并没有被删除, 所以需要手工删除;
- 历史表跳转之前的任务节点也不会被完成, 需要手工进行完成.
1.1. 实现方案
- 获取
ActivitiEngineAgenda
commandContext.getExecutionEntityManager()
获取 ExecutionEntityManagercommandContext.getTaskEntityManager()
获取 TaskEntityManager- 设置执行实例的运行节点
- 触发执行实例运转
- 设置删除当前的任务节点
- 更新历史实例表以及历史任务表, 当前的任务节点为完成状态
1 |
|
1.2. 测试场景
假设有如下流程定义:
1 |
|
结构如下:
start -> userTask1 -> userTask2 -> end
使用如下的执行顺序:
- startProcessInstance
- complete 任务 userTask1
- 执行
ManagementService().executeCommand(new JumpCmd("7502", "userTask1"))
- complete 任务 userTask1
- 执行
ManagementService().executeCommand(new JumpCmd("7502", "userTask1"))
然后查询 ACT_HI_ACTINST
表, 能够看到如下执行轨迹:
ID_ | PROC_DEF_ID_ | PROC_INST_ID_ | EXECUTION_ID_ | ACT_ID_ | TASK_ID_ | CALL_PROC_INST_ID_ | ACT_NAME_ | ACT_NAME_ | ASSIGNEE_ | START_TIME_ | END_TIME_ | DURATION_ | DELETE_REASON_ | TENANT_ID_ |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
6 | my-process:1:3 | 4 | 5 | start | startEvent | 2019-03-04 00:37:54.328 | 2019-03-04 00:37:54.330 | 2 | “” | |||||
7 | my-process:1:3 | 4 | 5 | userTask1 | 8 | userTask1 | userTask | destiny1 | 2019-03-04 00:37:54.331 | 2019-03-04 00:38:19.920 | 25589 | “” | ||
2501 | my-process:1:3 | 4 | 5 | userTask2 | 2502 | userTask2 | userTask | destiny2 | 2019-03-04 00:38:19.933 | 2019-03-04 00:38:44.834 | 24901 | jump | “” | |
5001 | my-process:1:3 | 4 | 5 | userTask1 | 5002 | userTask1 | userTask | destiny1 | 2019-03-04 00:38:44.848 | 2019-03-04 00:39:02.232 | 17384 | “” | ||
7501 | my-process:1:3 | 4 | 5 | userTask2 | 7502 | userTask2 | userTask | destiny2 | 2019-03-04 00:39:02.245 | 2019-03-04 00:39:19.718 | 17473 | jump | “” | |
10001 | my-process:1:3 | 4 | 5 | userTask1 | 10002 | userTask1 | userTask | destiny1 | 2019-03-04 00:39:19.743 | “” |
可以看到我们已经完成了简单条件下的跳转
1.3. 关于自由跳转时历史活动不更新问题的解决
之前遇到一个错误的写法:
1 |
|
与上文中正确写法的不同之处在于数据库更新操作的顺序. 但仅仅更换顺序也会到导致历史表中数据无法正确结束.
问题的原因在于第 25 行的时候已经为执行实例执行了 setCurrentFlowElement()
操作, 设置了最新的流程元素, 所以如果在后面再执行对 ACT_HI_ACTINST
的更新, 就无法找到正确的 FlowElement. 所以需要将 historyManager.recordActivityEnd(executionEntity, "jump");
放在第 25 行之前
2. 跳转到目标节点的入线
假设有如下流程定义:
1 |
|
将原先的跳转命令类稍作修改:
1 |
|
- 通过连线触发实例的时候, 连线上的条件不会参与计算
- 只有实例经过节点, 网关的时候, 连线上的条件才会经过计算
3. 跳转到目标节点入线连接的节点
因为实例是从节点离开, 因此后面的连线是可以参与运算的
1 |
|