流程的流转可以通过连线直观的展示出来,类似这样:
但是如果连线比较多的时候,就是显得比较乱,对于一些退回的连线,也可以在代码中实现,不需要连线,看起来会简洁一点,但是流程的流转并不直观,就看如何取舍了。
以下面的流程图为例,看下如何用代码实现流程节点的跳转,或者可以看作是退回操作:
假设现在流程流转到辅导员审核这个环节,如何退回学生请假环节呢?
主要是通过一个跳转命令来实现的,代码如下:
public class JumpCmd implements Command<Void> {
private String taskId;
private String targetNodeId;
public JumpCmd(String taskId, String targetNodeId) {
this.taskId = taskId;
this.targetNodeId = targetNodeId;
}
@Override
public Void execute(CommandContext commandContext) {
ActivitiEngineAgenda agenda = commandContext.getAgenda();
TaskEntityManager taskEntityManager = commandContext.getTaskEntityManager();
TaskEntity taskEntity = taskEntityManager.findById(taskId);
// 执行实例 id
String executionId = taskEntity.getExecutionId();
String processDefinitionId = taskEntity.getProcessDefinitionId();
ExecutionEntityManager executionEntityManager = commandContext.getExecutionEntityManager();
HistoryManager historyManager = commandContext.getHistoryManager();
// 执行实例对象
ExecutionEntity executionEntity = executionEntityManager.findById(executionId);
Process process = ProcessDefinitionUtil.getProcess(processDefinitionId);
FlowElement targetFlowElement = process.getFlowElement(targetNodeId);
if (targetFlowElement == null) {
throw new RuntimeException("目标节点不存在");
}
// 将历史活动表更新(当前活动结束)
historyManager.recordActivityEnd(executionEntity, "jump");
// 将目标节点设置为当前流程
executionEntity.setCurrentFlowElement(targetFlowElement);
// 跳转, 触发执行实例运转
agenda.planContinueProcessInCompensation(executionEntity);
// 从runtime 表中删除当前任务
taskEntityManager.delete(taskId);
// 将历史任务表更新, 历史任务标记为完成
historyManager.recordTaskEnd(taskId, "jump");
return null;
}
}
跳转命令JumpCmd实现activiti的命令接口Command,实现了execute方法,这是整个过程核心的代码。
基本思路:首先需要知道当前任务和目标节点的id,要想流程走到目标节点,那么就需要将当前任务的出口连线指向目标节点,这样当前任务完成之后,下一个节点就是目标节点了,同时要记得将连线恢复,使流程正常运行。
使用该命令:通过ManagementService将该命令添加到流程运转的执行栈中:
// 跳转到学生提交请假
managementService.executeCommand(new JumpCmd(task.getId(), "student_apply"));
其中student_apply是学生请假的节点id,执行命令之后,流程就从辅导员审核跳转到了学生请假了,可以查询并完成任务了:
task = taskService.createTaskQuery().taskAssignee("张三").singleResult();
taskService.complete(task.getId(),variables);
// 班长审批
task = taskService.createTaskQuery().taskAssignee("李四").singleResult();
taskService.complete(task.getId(),variables);
// 辅导员审批
task = taskService.createTaskQuery().taskAssignee("王五").singleResult();
taskService.complete(task.getId());
示例代码地址:https://github.com/qiuxinfa/activiti-study。