package org.springblade.mdm.flow.service;
|
import org.flowable.engine.HistoryService;
|
import org.flowable.engine.RuntimeService;
|
import org.flowable.engine.TaskService;
|
import org.flowable.engine.history.HistoricActivityInstance;
|
import org.flowable.engine.runtime.Execution;
|
import org.flowable.task.api.Task;
|
import org.flowable.task.api.history.HistoricTaskInstance;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.stereotype.Service;
|
import org.springframework.transaction.annotation.Transactional;
|
|
import java.util.List;
|
import java.util.Map;
|
@Service
|
public class FlowableBackWithAssigneeService {
|
@Autowired
|
private RuntimeService runtimeService;
|
|
@Autowired
|
private TaskService taskService;
|
|
@Autowired
|
private HistoryService historyService;
|
|
/**
|
* 将流程退回到指定任务节点并指定新的处理人
|
* @param currentTaskId 当前任务ID
|
* @param targetActivityId 目标活动节点ID
|
* @param newAssignee 新的处理人
|
* @param comment 退回意见
|
* @param variables 流程变量
|
*/
|
@Transactional
|
public void backToTaskWithNewAssignee(String currentTaskId,
|
String targetActivityId,
|
String newAssignee,
|
String comment,
|
Map<String, Object> variables) {
|
// 获取当前任务
|
Task currentTask = taskService.createTaskQuery()
|
.taskId(currentTaskId)
|
.singleResult();
|
|
if (currentTask == null) {
|
throw new RuntimeException("当前任务不存在");
|
}
|
|
String processInstanceId = currentTask.getProcessInstanceId();
|
|
// 添加评论
|
if (comment != null && !comment.trim().isEmpty()) {
|
taskService.addComment(currentTaskId, processInstanceId, comment);
|
}
|
|
// 验证目标节点是否存在
|
validateTargetActivity(processInstanceId, targetActivityId);
|
|
// 使用运行时服务跳转到目标节点
|
runtimeService.createChangeActivityStateBuilder()
|
.processInstanceId(processInstanceId)
|
.moveActivityIdTo(currentTask.getTaskDefinitionKey(), targetActivityId)
|
.changeState();
|
|
// 获取新创建的任务(退回后产生的任务)
|
Task newTask = taskService.createTaskQuery()
|
.processInstanceId(processInstanceId)
|
.taskDefinitionKey(targetActivityId)
|
.singleResult();
|
|
if (newTask != null) {
|
// 设置新的处理人
|
if (newAssignee != null && !newAssignee.trim().isEmpty()) {
|
taskService.setAssignee(newTask.getId(), newAssignee);
|
}
|
|
// 设置流程变量
|
if (variables != null && !variables.isEmpty()) {
|
taskService.setVariables(newTask.getId(), variables);
|
}
|
}
|
|
// 删除当前任务
|
taskService.deleteTask(currentTaskId, "退回流程并指定新处理人: " + newAssignee);
|
}
|
|
/**
|
* 退回并保留原处理人信息(记录历史)
|
*/
|
@Transactional
|
public void backToTaskWithOriginalAssignee(String currentTaskId,
|
String targetActivityId,
|
String comment) {
|
Task currentTask = taskService.createTaskQuery()
|
.taskId(currentTaskId)
|
.singleResult();
|
|
if (currentTask == null) {
|
throw new RuntimeException("当前任务不存在");
|
}
|
|
String processInstanceId = currentTask.getProcessInstanceId();
|
|
// 获取目标节点的历史任务信息
|
HistoricTaskInstance historicTask = historyService.createHistoricTaskInstanceQuery()
|
.processInstanceId(processInstanceId)
|
.taskDefinitionKey(targetActivityId)
|
.orderByHistoricTaskInstanceEndTime().desc()
|
.list()
|
.stream()
|
.findFirst()
|
.orElse(null);
|
|
String originalAssignee = historicTask != null ? historicTask.getAssignee() : null;
|
|
// 执行退回操作
|
backToTaskWithNewAssignee(currentTaskId, targetActivityId, originalAssignee, comment, null);
|
}
|
|
/**
|
* 验证目标活动节点是否存在
|
*/
|
private void validateTargetActivity(String processInstanceId, String targetActivityId) {
|
List<HistoricActivityInstance> targetActivities = historyService
|
.createHistoricActivityInstanceQuery()
|
.processInstanceId(processInstanceId)
|
.activityId(targetActivityId)
|
.list();
|
|
if (targetActivities.isEmpty()) {
|
throw new RuntimeException("目标节点不存在于流程实例中");
|
}
|
}
|
|
/**
|
* 获取可退回的节点列表(用户任务节点)
|
*/
|
public List<HistoricActivityInstance> getBackableUserTasks(String processInstanceId) {
|
return historyService.createHistoricActivityInstanceQuery()
|
.processInstanceId(processInstanceId)
|
.activityType("userTask")
|
.orderByHistoricActivityInstanceStartTime().desc()
|
.list();
|
}
|
|
/**
|
* 获取指定节点的历史处理人
|
*/
|
public String getHistoricAssignee(String processInstanceId, String activityId) {
|
HistoricTaskInstance historicTask = historyService.createHistoricTaskInstanceQuery()
|
.processInstanceId(processInstanceId)
|
.taskDefinitionKey(activityId)
|
.orderByHistoricTaskInstanceEndTime().desc()
|
.list()
|
.stream()
|
.findFirst()
|
.orElse(null);
|
|
return historicTask != null ? historicTask.getAssignee() : null;
|
}
|
}
|