一:leave.bpmn
<process id="leave" isClosed="false" isExecutable="true" name="请假流程" processType="None">
<startEvent id="_2" name="StartEvent"/>
<userTask activiti:assignee="zhangsan" activiti:exclusive="true" id="apply" name="发起申请"/>
<userTask activiti:assignee="lisi" activiti:exclusive="true" id="pmApprove" name="经理审核"/>
<userTask activiti:assignee="wangwu" activiti:exclusive="true" id="gmApprove" name="总经理审核"/>
<userTask activiti:assignee="zhaoliu" activiti:exclusive="true" id="hrApprove" name="人事审核"/>
<endEvent id="_7" name="EndEvent"/>
</process>
二:完成任务
从发起申请到总经理审批通过。
@Test
void testStartAndComplete() {
runtimeService.startProcessInstanceByKey("leave");
for (String assignee : Arrays.asList("zhangsan", "lisi", "wangwu")) {
Task task = taskService.createTaskQuery().processDefinitionKey("leave")
.taskAssignee(assignee)
.singleResult();
taskService.complete(task.getId());
}
}
三:自定义Command
MoveTaskCommand:移动任务,将当前的认为移动到指定节点上。
import org.activiti.engine.impl.interceptor.Command;
public class MoveTaskCommand implements Command<Object> {
private String currentTaskId;
private String targetTaskDefKey;
public MoveTaskCommand(String currentTaskId, String targetTaskDefKey) {
this.currentTaskId = currentTaskId;
this.targetTaskDefKey = targetTaskDefKey;
}
@Override
public Object execute(CommandContext commandContext) {
TaskEntityManager taskEntityManager = commandContext.getTaskEntityManager();
TaskEntity currentTaskEntity = taskEntityManager.findById(this.currentTaskId);
taskEntityManager.deleteTask(currentTaskEntity, "移动节点", true, true);
ExecutionEntityManager executionEntityManager = commandContext.getExecutionEntityManager();
ExecutionEntity executionEntity = executionEntityManager.findById(currentTaskEntity.getExecutionId());
Process process = ProcessDefinitionUtil.getProcess(executionEntity.getProcessDefinitionId());
FlowElement targetFlowElement = process.getFlowElement(targetTaskDefKey);
executionEntity.setCurrentFlowElement(targetFlowElement);
ActivitiEngineAgenda agenda = commandContext.getAgenda();
agenda.planContinueProcessInCompensation(executionEntity);
return null;
}
public String getCurrentTaskId() {
return currentTaskId;
}
public void setCurrentTaskId(String currentTaskId) {
this.currentTaskId = currentTaskId;
}
public String getTargetTaskDefKey() {
return targetTaskDefKey;
}
public void setTargetTaskDefKey(String targetTaskDefKey) {
this.targetTaskDefKey = targetTaskDefKey;
}
}
四:Test
当前任务为人事审批,现在要移动到第二个节点经理审批。
@Test
public void testMoveTask() {
String currentTaskId = "0794d37c-7132-11ec-8926-8239436cd258";
String targetTaskDefKey = "pmApprove";
MoveTaskCommand moveTaskCommand = new MoveTaskCommand(currentTaskId, targetTaskDefKey);
managementService.executeCommand(moveTaskCommand);
}
select * FROM ACT_RU_TASK WHERE ID_ = '0794d37c-7132-11ec-8926-8239436cd258';
delete FROM ACT_RU_TASK WHERE ID_ = '0794d37c-7132-11ec-8926-8239436cd258' and REV_ = 1;
select
E.*,
S.PROC_INST_ID_ AS PARENT_PROC_INST_ID_
FROM ACT_RU_EXECUTION E
LEFT JOIN ACT_RU_EXECUTION S ON E.SUPER_EXEC_ = S.ID_
WHERE E.ID_ = '0755ce9f-7132-11ec-8926-8239436cd258';
insert into ACT_RU_TASK (ID_, REV_, NAME_, PARENT_TASK_ID_, DESCRIPTION_, PRIORITY_, CREATE_TIME_, OWNER_, ASSIGNEE_, DELEGATION_, EXECUTION_ID_, PROC_INST_ID_, PROC_DEF_ID_, TASK_DEF_KEY_, DUE_DATE_, CATEGORY_, SUSPENSION_STATE_, TENANT_ID_, FORM_KEY_, CLAIM_TIME_)
values ('6bb7b6a4-7135-11ec-aee1-8239436cd258', 1, '经理审核', null, null, 50,
'2022-01-09 18:17:59.572', null, 'lisi', null, '0756b900-7132-11ec-8926-8239436cd258',
'0755ce9f-7132-11ec-8926-8239436cd258', 'leave:1:05562e0c-7132-11ec-8926-8239436cd258',
'pmApprove', null, null, 1, '', null, null
);
update ACT_RU_EXECUTION
set
REV_ = 5,
PROC_DEF_ID_ = 'leave:1:05562e0c-7132-11ec-8926-8239436cd258',
ACT_ID_ = 'pmApprove',
SUSPENSION_STATE_ = 1
WHERE ID_ = '0756b900-7132-11ec-8926-8239436cd258' and REV_ = 4;
delete FROM ACT_HI_TASKINST WHERE ID_ = '0794d37c-7132-11ec-8926-8239436cd258' and REV_ = 1;
insert into ACT_HI_TASKINST ( ID_, PROC_DEF_ID_, PROC_INST_ID_, EXECUTION_ID_, NAME_, PARENT_TASK_ID_, DESCRIPTION_, OWNER_, ASSIGNEE_, START_TIME_, CLAIM_TIME_, END_TIME_, DURATION_, DELETE_REASON_, TASK_DEF_KEY_, FORM_KEY_, PRIORITY_, DUE_DATE_, CATEGORY_, TENANT_ID_ ) values ( '6bb7b6a4-7135-11ec-aee1-8239436cd258', 'leave:1:05562e0c-7132-11ec-8926-8239436cd258', '0755ce9f-7132-11ec-8926-8239436cd258', '0756b900-7132-11ec-8926-8239436cd258', '经理审核', null, null, null, 'lisi', '2022-01-09 18:17:59.605', null, null, null, null, 'pmApprove', null, 50, null, null, '' );
insert into ACT_HI_ACTINST ( ID_, PROC_DEF_ID_, PROC_INST_ID_, EXECUTION_ID_, ACT_ID_, TASK_ID_, CALL_PROC_INST_ID_, ACT_NAME_, ACT_TYPE_, ASSIGNEE_, START_TIME_, END_TIME_, DURATION_, DELETE_REASON_, TENANT_ID_ ) values ( '6bafa053-7135-11ec-aee1-8239436cd258', 'leave:1:05562e0c-7132-11ec-8926-8239436cd258', '0755ce9f-7132-11ec-8926-8239436cd258', '0756b900-7132-11ec-8926-8239436cd258', 'pmApprove', '6bb7b6a4-7135-11ec-aee1-8239436cd258', null, '经理审核', 'userTask', 'lisi', '2022-01-09 18:17:59.553', null, null, null, '' );
五:SQL分析
-
act_ru_task delete当前任务并insert指定任务。 -
act_ru_execution update REV_=REV_ + 1, ACT_ID_ = < targetTaskDefKey >。 -
act_hi_taskinst delete当前正在进行的任务,然后又重新插入一条新的正在进行的任务。 -
act_hi_actinst insert一条最新的目标任务。
六:继续完成任务
原来任务执行到人事审批,后来退回到经理审批,现在经理审批完成到达总经理审批。
@Test
public void testCompleteTask() {
Task task = taskService.createTaskQuery().processDefinitionKey("leave")
.taskAssignee("lisi")
.singleResult();
taskService.complete(task.getId());
}
七:前进任务
@Test
void testStartAndComplete() {
runtimeService.startProcessInstanceByKey("leave");
Task task = taskService.createTaskQuery().processDefinitionKey("leave")
.taskAssignee("zhangsan")
.singleResult();
taskService.complete(task.getId());
}
@Test
public void testMoveTask() {
String currentTaskId = "f3c2beed-713e-11ec-aebb-8239436cd258";
String targetTaskDefKey = "hrApprove";
MoveTaskCommand moveTaskCommand = new MoveTaskCommand(currentTaskId, targetTaskDefKey);
managementService.executeCommand(moveTaskCommand);
}
经理审核直接变成人事审核了。
删除经理审核,添加人事审核。 增加人事审核活动,原来的经理审核没有结束时间仍保留着。
|