Merge remote-tracking branch 'origin/feature/REQ-2924' into feature/REQ-2924

This commit is contained in:
wangli 2024-09-12 14:48:12 +08:00
commit d05c42b606
5 changed files with 198 additions and 84 deletions

View File

@ -38,6 +38,7 @@ public enum BpmnTaskRespCode implements IModuleRespCode {
PROCESS_CANT_SET_ASSIGNEE("021", "当前审批状态不允许设置审批人"),
ASSIGNER_NUMBER_EXCEEDS_NUMBER_LIMIT("022", String.format("人员数量超过限制,节点审批人限制数量为: %d!", APPROVAL_ASSIGNER_LIMIT_NUMBER)),
BACK_TARGET_ACTIVITY_NOT_EXISTS("023", "回退到指定节点【{}】失败!"),
BACK_NODE_CANNOT_REACHABLE("024", "退回节点【{}】不可达,不允许退回"),
;
private final String code;

View File

@ -0,0 +1,91 @@
package cn.axzo.workflow.core.common.utils;
import org.flowable.bpmn.model.EventSubProcess;
import org.flowable.bpmn.model.FlowElement;
import org.flowable.bpmn.model.FlowElementsContainer;
import org.flowable.bpmn.model.FlowNode;
import org.flowable.bpmn.model.SequenceFlow;
import org.flowable.bpmn.model.StartEvent;
import org.flowable.bpmn.model.SubProcess;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class BpmnModelUtils {
/**
* 节点是否可达
* @param process
* @param sourceElement
* @param targetElement
* @return
*/
public static boolean isReachable(org.flowable.bpmn.model.Process process, FlowNode sourceElement, FlowNode targetElement) {
return isReachable(process, sourceElement, targetElement, new HashSet<>());
}
public static boolean isReachable(org.flowable.bpmn.model.Process process, FlowNode sourceElement, FlowNode targetElement, Set<String> visitedElements) {
// Special case: start events in an event subprocess might exist as an execution and are most likely be able to
// reach the target
// when the target is in the event subprocess, but should be ignored as they are not 'real' runtime executions
// (but rather waiting for trigger)
if (sourceElement instanceof StartEvent && isInEventSubprocess(sourceElement)) {
return false;
}
// No outgoing seq flow: could be the end of eg . the process or an embedded subprocess
if (sourceElement.getOutgoingFlows().isEmpty()) {
visitedElements.add(sourceElement.getId());
FlowElementsContainer parentElement = process.findParent(sourceElement);
if (parentElement instanceof SubProcess) {
sourceElement = (SubProcess) parentElement;
// 子流程的结束节点若目标节点在该子流程中说明无法到达返回false
if (((SubProcess) sourceElement).getFlowElement(targetElement.getId()) != null) {
return false;
}
} else {
return false;
}
}
if (sourceElement.getId().equals(targetElement.getId())) {
return true;
}
// To avoid infinite looping, we must capture every node we visit
// and check before going further in the graph if we have already
// visited the node.
visitedElements.add(sourceElement.getId());
// 当前节点能够到达子流程且目标节点在子流程中说明可以到达返回true
if (sourceElement instanceof SubProcess && ((SubProcess) sourceElement).getFlowElement(targetElement.getId()) != null) {
return true;
}
List<SequenceFlow> sequenceFlows = sourceElement.getOutgoingFlows();
if (sequenceFlows != null && !sequenceFlows.isEmpty()) {
for (SequenceFlow sequenceFlow : sequenceFlows) {
String targetRef = sequenceFlow.getTargetRef();
FlowNode sequenceFlowTarget = (FlowNode) process.getFlowElement(targetRef, true);
if (sequenceFlowTarget != null && !visitedElements.contains(sequenceFlowTarget.getId())) {
boolean reachable = isReachable(process, sequenceFlowTarget, targetElement, visitedElements);
if (reachable) {
return true;
}
}
}
}
return false;
}
protected static boolean isInEventSubprocess(FlowNode flowNode) {
FlowElementsContainer flowElementsContainer = flowNode.getParentContainer();
while (flowElementsContainer != null) {
if (flowElementsContainer instanceof EventSubProcess) {
return true;
}
if (flowElementsContainer instanceof FlowElement) {
flowElementsContainer = ((FlowElement) flowElementsContainer).getParentContainer();
} else {
flowElementsContainer = null;
}
}
return false;
}
}

View File

@ -1,34 +1,39 @@
package cn.axzo.workflow.core.engine.cmd;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskBackAuditDTO;
import cn.axzo.workflow.core.engine.job.AsyncApproveTaskJobHandler;
import cn.axzo.workflow.core.common.exception.WorkflowEngineException;
import cn.axzo.workflow.core.common.utils.BpmnModelUtils;
import cn.axzo.workflow.core.engine.job.AsyncBackTaskJobHandler;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.flowable.bpmn.model.FlowElement;
import org.flowable.bpmn.model.FlowNode;
import org.flowable.bpmn.model.Process;
import org.flowable.common.engine.impl.interceptor.CommandContext;
import org.flowable.engine.TaskService;
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.flowable.engine.impl.util.CommandContextUtil;
import org.flowable.engine.impl.util.ProcessDefinitionUtil;
import org.flowable.job.service.JobService;
import org.flowable.job.service.impl.persistence.entity.JobEntity;
import org.flowable.task.api.Task;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.flowable.task.api.history.HistoricTaskInstanceQuery;
import org.flowable.task.service.TaskService;
import org.flowable.task.service.impl.persistence.entity.TaskEntity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.Serializable;
import java.util.Objects;
import static cn.axzo.workflow.core.common.code.BpmnTaskRespCode.BACK_NODE_CANNOT_REACHABLE;
import static cn.axzo.workflow.core.common.code.BpmnTaskRespCode.BACK_TARGET_ACTIVITY_NOT_EXISTS;
import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.validTask;
@Slf4j
public class CustomBackTaskAsyncCmd extends AbstractCommand<String> implements Serializable {
private static final long serialVersionUID = 1773108485033787095L;
private static final Logger log = LoggerFactory.getLogger(CustomBackTaskAsyncCmd.class);
private final BpmnTaskBackAuditDTO dto;
public CustomBackTaskAsyncCmd(BpmnTaskBackAuditDTO dto) {
@ -41,17 +46,25 @@ public class CustomBackTaskAsyncCmd extends AbstractCommand<String> implements S
CommandContextUtil.getProcessEngineConfiguration(commandContext);
HistoricTaskInstanceQuery taskQuery =
processEngineConfiguration.getHistoryService().createHistoricTaskInstanceQuery();
TaskService taskService = processEngineConfiguration.getTaskService();
TaskService taskService = processEngineConfiguration.getTaskServiceConfiguration().getTaskService();
HistoricTaskInstance historicTaskInstance = taskQuery.taskId(dto.getTaskId()).singleResult();
Task task = taskService.createTaskQuery().taskId(dto.getTaskId()).singleResult();
if (Objects.isNull(task)) {
log.info("任务不存在: {}", dto.getTaskId());
}
validTask(historicTaskInstance, (TaskEntity) task, dto.getApprover(), null);
TaskEntity taskEntity = taskService.getTask(dto.getTaskId());
validTask(historicTaskInstance, taskEntity, dto.getApprover(), dto.getNodeTypes());
return startAsync(processEngineConfiguration, task);
Process process = ProcessDefinitionUtil.getProcess(taskEntity.getProcessDefinitionId());
FlowElement targetFlowElement = process.getFlowElement(dto.getToActivityId(), true);
if (Objects.isNull(targetFlowElement)) {
throw new WorkflowEngineException(BACK_TARGET_ACTIVITY_NOT_EXISTS, dto.getToActivityId());
}
FlowElement sourceFlowElement = process.getFlowElement(taskEntity.getTaskDefinitionKey(), true);
// 退回节点到当前节点不可达到不允许退回
if (!BpmnModelUtils.isReachable(process, (FlowNode) sourceFlowElement, (FlowNode) targetFlowElement)) {
throw new WorkflowEngineException(BACK_NODE_CANNOT_REACHABLE, dto.getToActivityId());
}
return startAsync(processEngineConfiguration, taskEntity);
}
private String startAsync(ProcessEngineConfigurationImpl processEngineConfiguration, Task task) {

View File

@ -2,18 +2,21 @@ package cn.axzo.workflow.core.engine.cmd;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskBackAuditDTO;
import cn.axzo.workflow.core.common.exception.WorkflowEngineException;
import cn.axzo.workflow.core.common.utils.BpmnModelUtils;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.bpmn.model.FlowElement;
import org.flowable.bpmn.model.FlowNode;
import org.flowable.bpmn.model.Process;
import org.flowable.common.engine.impl.identity.Authentication;
import org.flowable.common.engine.impl.interceptor.CommandContext;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.flowable.engine.impl.util.CommandContextUtil;
import org.flowable.engine.impl.util.ProcessDefinitionUtil;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.flowable.task.api.history.HistoricTaskInstanceQuery;
import org.flowable.task.service.TaskService;
import org.flowable.task.service.impl.persistence.entity.TaskEntity;
import java.io.Serializable;
@ -26,6 +29,7 @@ import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_ADVICE
import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_OPERATION_DESC;
import static cn.axzo.workflow.common.constant.BpmnConstants.TASK_COMPLETE_OPERATION_TYPE;
import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.BACKED;
import static cn.axzo.workflow.core.common.code.BpmnTaskRespCode.BACK_NODE_CANNOT_REACHABLE;
import static cn.axzo.workflow.core.common.code.BpmnTaskRespCode.BACK_TARGET_ACTIVITY_NOT_EXISTS;
import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.addComment;
import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.batchAddAttachment;
@ -40,14 +44,14 @@ public class CustomBackTaskCmd extends AbstractCommand<Void> implements Serializ
private final BpmnTaskBackAuditDTO dto;
private static String operationDesc = "回退至";
private static final String OPERATION_DESC = "回退至";
@Override
public String paramToJsonString() {
Map<String, Object> params = new HashMap<>();
params.put("taskId", dto.getTaskId());
params.put("advice", dto.getAdvice());
params.put("operationDesc", operationDesc);
params.put("operationDesc", OPERATION_DESC);
params.put("attachmentList", JSON.toJSONString(dto.getAttachmentList()));
params.put("approver", JSON.toJSONString(dto.getApprover()));
params.put("nodeTypes", JSON.toJSONString(dto.getNodeTypes()));
@ -61,36 +65,40 @@ public class CustomBackTaskCmd extends AbstractCommand<Void> implements Serializ
@Override
public Void execute(CommandContext commandContext) {
ProcessEngineConfigurationImpl processEngineConfiguration =
CommandContextUtil.getProcessEngineConfiguration(commandContext);
CommandContextUtil.getProcessEngineConfiguration(commandContext);
HistoricTaskInstanceQuery taskQuery =
processEngineConfiguration.getHistoryService().createHistoricTaskInstanceQuery();
TaskService taskService = processEngineConfiguration.getTaskService();
processEngineConfiguration.getHistoryService().createHistoricTaskInstanceQuery();
TaskService taskService = processEngineConfiguration.getTaskServiceConfiguration().getTaskService();
HistoricTaskInstance historicTaskInstance = taskQuery.taskId(dto.getTaskId()).singleResult();
TaskEntity task = (TaskEntity) taskService.createTaskQuery().taskId(dto.getTaskId()).singleResult();
TaskEntity task = taskService.getTask(dto.getTaskId());
validTask(historicTaskInstance, task, dto.getApprover(), dto.getNodeTypes());
BpmnModel bpmnModel = processEngineConfiguration.getRepositoryService().getBpmnModel(historicTaskInstance.getProcessDefinitionId());
FlowElement flowElement = bpmnModel.getFlowElement(dto.getToActivityId());
if (Objects.isNull(flowElement)) {
Process process = ProcessDefinitionUtil.getProcess(task.getProcessDefinitionId());
FlowElement targetFlowElement = process.getFlowElement(dto.getToActivityId(), true);
if (Objects.isNull(targetFlowElement)) {
throw new WorkflowEngineException(BACK_TARGET_ACTIVITY_NOT_EXISTS, dto.getToActivityId());
}
FlowElement sourceFlowElement = process.getFlowElement(task.getTaskDefinitionKey(), true);
// 退回节点到当前节点不可达到不允许退回
if (!BpmnModelUtils.isReachable(process, (FlowNode) sourceFlowElement, (FlowNode) targetFlowElement)) {
throw new WorkflowEngineException(BACK_NODE_CANNOT_REACHABLE, dto.getToActivityId());
}
batchAddAttachment(commandContext, task.getProcessInstanceId(), dto.getTaskId(), dto.getAttachmentList(), dto.getApprover());
Authentication.setAuthenticatedUserId(dto.getApprover().buildAssigneeId());
addComment(commandContext, task, COMMENT_TYPE_ADVICE, dto.getAdvice());
addComment(commandContext, task, COMMENT_TYPE_OPERATION_DESC, operationDesc + flowElement.getName());
addComment(commandContext, task, COMMENT_TYPE_OPERATION_DESC, OPERATION_DESC + targetFlowElement.getName());
Authentication.setAuthenticatedUserId(null);
RuntimeService runtimeService = processEngineConfiguration.getRuntimeService();
task.setTransientVariable(TASK_COMPLETE_OPERATION_TYPE + dto.getTaskId(), BACKED.getStatus());
runtimeService.createChangeActivityStateBuilder()
.processInstanceId(task.getProcessInstanceId())
.moveActivityIdsToSingleActivityId(Collections.singletonList(task.getTaskDefinitionKey()), dto.getToActivityId())
.changeState();
.processInstanceId(task.getProcessInstanceId())
.moveActivityIdsToSingleActivityId(Collections.singletonList(task.getTaskDefinitionKey()), dto.getToActivityId())
.changeState();
return null;
}

View File

@ -63,6 +63,7 @@ import static cn.axzo.workflow.core.common.code.BpmnTaskRespCode.ASSIGNER_NUMBER
import static cn.axzo.workflow.core.common.code.BpmnTaskRespCode.TASK_COMPLETE_FAIL_ASSIGN_NOT_SELF;
import static cn.axzo.workflow.core.common.code.BpmnTaskRespCode.TASK_COMPLETE_FAIL_NOT_EXISTS;
import static cn.axzo.workflow.core.common.code.BpmnTaskRespCode.TASK_HAS_BEEN_COMPLETE;
import static cn.axzo.workflow.core.common.code.BpmnTaskRespCode.TASK_TYPE_MISMATCH;
import static org.flowable.task.api.Task.DEFAULT_PRIORITY;
/**
@ -80,13 +81,13 @@ public class CustomTaskHelper {
return;
}
ProcessEngineConfigurationImpl processEngineConfiguration =
CommandContextUtil.getProcessEngineConfiguration(commandContext);
CommandContextUtil.getProcessEngineConfiguration(commandContext);
Map<String, Object> executionVariables = new HashMap<>();
executionVariables.put("assigneeName", newTaskAssignee.buildAssigneeId());
RuntimeService runtimeService = processEngineConfiguration.getRuntimeService();
Execution subExecution = runtimeService.addMultiInstanceExecution(originTask.getTaskDefinitionKey(),
originTask.getProcessInstanceId(), executionVariables);
originTask.getProcessInstanceId(), executionVariables);
setParentTaskId(originTask, subExecution);
}
@ -96,19 +97,19 @@ public class CustomTaskHelper {
return;
}
ProcessEngineConfigurationImpl processEngineConfiguration =
CommandContextUtil.getProcessEngineConfiguration(commandContext);
CommandContextUtil.getProcessEngineConfiguration(commandContext);
RuntimeService runtimeService = processEngineConfiguration.getRuntimeService();
runtimeService.deleteMultiInstanceExecution(originTask.getExecutionId(), false);
}
private static void setParentTaskId(TaskEntity originTask, Execution subExecution) {
CommandContextUtil.getEntityCache().findInCache(TaskEntity.class).stream()
.filter(i -> Objects.equals(i.getExecutionId(), subExecution.getId()))
.findAny().ifPresent(i -> i.setParentTaskId(originTask.getId()));
.filter(i -> Objects.equals(i.getExecutionId(), subExecution.getId()))
.findAny().ifPresent(i -> i.setParentTaskId(originTask.getId()));
CommandContextUtil.getEntityCache().findInCache(HistoricTaskInstanceEntity.class).stream()
.filter(i -> Objects.equals(i.getExecutionId(), subExecution.getId()))
.findAny().ifPresent(i -> i.setParentTaskId(originTask.getId()));
.filter(i -> Objects.equals(i.getExecutionId(), subExecution.getId()))
.findAny().ifPresent(i -> i.setParentTaskId(originTask.getId()));
}
/**
@ -121,7 +122,7 @@ public class CustomTaskHelper {
public static void validTask(HistoricTaskInstance historicTaskInstance, TaskEntity taskEntity,
BpmnTaskDelegateAssigner originTaskAssigner, List<BpmnFlowNodeType> nodeTypes) {
if (Objects.nonNull(historicTaskInstance) &&
(Objects.nonNull(historicTaskInstance.getEndTime()) || Objects.isNull(taskEntity))) {
(Objects.nonNull(historicTaskInstance.getEndTime()) || Objects.isNull(taskEntity))) {
throw new WorkflowEngineException(TASK_HAS_BEEN_COMPLETE);
}
@ -154,7 +155,7 @@ public class CustomTaskHelper {
//不包含对应的任务
if (!nodeTypes.contains(nodeType)) {
// log.warn(TASK_TYPE_MISMATCH.getMessage(), nodeType.getDesc(), nodeTypes.stream().map(BpmnFlowNodeType::getDesc).collect(Collectors.joining(",")));
throw new WorkflowEngineException(ASSIGNER_NUMBER_EXCEEDS_NUMBER_LIMIT, nodeType.getDesc(), nodeTypes.stream().map(BpmnFlowNodeType::getDesc).collect(Collectors.joining(",")));
throw new WorkflowEngineException(TASK_TYPE_MISMATCH, nodeType.getDesc(), nodeTypes.stream().map(BpmnFlowNodeType::getDesc).collect(Collectors.joining(",")));
}
}
}
@ -171,14 +172,14 @@ public class CustomTaskHelper {
TaskEntity taskEntity,
List<BpmnTaskDelegateAssigner> targetAssigneeList) {
ProcessEngineConfigurationImpl processEngineConfiguration =
CommandContextUtil.getProcessEngineConfiguration(commandContext);
CommandContextUtil.getProcessEngineConfiguration(commandContext);
RuntimeService runtimeService = processEngineConfiguration.getRuntimeService();
// 这个节点下所有审批人快照
String activityListSnapshot =
INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT + taskEntity.getTaskDefinitionKey();
INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT + taskEntity.getTaskDefinitionKey();
List<BpmnTaskDelegateAssigner> taskAssignerListSnapshot =
runtimeService.getVariable(taskEntity.getProcessInstanceId(), activityListSnapshot, List.class);
runtimeService.getVariable(taskEntity.getProcessInstanceId(), activityListSnapshot, List.class);
AtomicInteger existsCount = new AtomicInteger();
taskAssignerListSnapshot.forEach(i -> {
targetAssigneeList.forEach(j -> {
@ -228,12 +229,12 @@ public class CustomTaskHelper {
return;
}
ProcessEngineConfigurationImpl processEngineConfiguration =
CommandContextUtil.getProcessEngineConfiguration(commandContext);
CommandContextUtil.getProcessEngineConfiguration(commandContext);
TaskService taskService = processEngineConfiguration.getTaskService();
Authentication.setAuthenticatedUserId(assigner.buildAssigneeId());
attachmentList.forEach(dto -> {
Attachment attachment = taskService.createAttachment(dto.getType().getType(), taskId, processInstanceId,
dto.getName(), dto.getDescription(), dto.getUrl());
dto.getName(), dto.getDescription(), dto.getUrl());
taskService.saveAttachment(attachment);
});
Authentication.setAuthenticatedUserId(null);
@ -256,7 +257,7 @@ public class CustomTaskHelper {
return;
}
ProcessEngineConfigurationImpl processEngineConfiguration =
CommandContextUtil.getProcessEngineConfiguration(commandContext);
CommandContextUtil.getProcessEngineConfiguration(commandContext);
String userId = Authentication.getAuthenticatedUserId();
CommentEntity comment = processEngineConfiguration.getCommentEntityManager().create();
@ -281,7 +282,7 @@ public class CustomTaskHelper {
public static Attachment addAttachment(CommandContext commandContext, Task task, AttachmentDTO attachmentDto) {
ProcessEngineConfigurationImpl processEngineConfiguration =
CommandContextUtil.getProcessEngineConfiguration(commandContext);
CommandContextUtil.getProcessEngineConfiguration(commandContext);
AttachmentEntity attachment = processEngineConfiguration.getAttachmentEntityManager().create();
attachment.setName(attachmentDto.getName());
attachment.setProcessInstanceId(task.getProcessInstanceId());
@ -297,11 +298,11 @@ public class CustomTaskHelper {
ExecutionEntity processInstance = null;
if (task.getProcessInstanceId() != null) {
processInstance =
processEngineConfiguration.getExecutionEntityManager().findById(task.getProcessInstanceId());
processEngineConfiguration.getExecutionEntityManager().findById(task.getProcessInstanceId());
}
processEngineConfiguration.getHistoryManager().createAttachmentComment((TaskEntity) task, processInstance,
attachmentDto.getName(), true);
attachmentDto.getName(), true);
return attachment;
}
@ -320,15 +321,15 @@ public class CustomTaskHelper {
* @return
*/
public static Task createVirtualTask(CommandContext commandContext, ExtAxHiTaskInstService extAxHiTaskInstService
, String processInstanceId, String nodeName, String taskDefinitionKey, String advice,
, String processInstanceId, String nodeName, String taskDefinitionKey, String advice,
BpmnTaskDelegateAssigner assigner,
String extTaskInstStatus, AddComment addComment) {
ProcessEngineConfigurationImpl processEngineConfiguration =
CommandContextUtil.getProcessEngineConfiguration(commandContext);
CommandContextUtil.getProcessEngineConfiguration(commandContext);
HistoryService historyService = processEngineConfiguration.getHistoryService();
HistoricProcessInstance processInstance =
historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
TaskService taskService = processEngineConfiguration.getTaskService();
IdGenerator idGenerator = processEngineConfiguration.getIdGenerator();
@ -345,12 +346,12 @@ public class CustomTaskHelper {
if (Objects.nonNull(assigner)) {
CommandContextUtil.getEntityCache().findInCache(TaskEntity.class).stream()
.filter(i -> Objects.equals(i.getId(), task.getId())).findAny()
.ifPresent(i -> i.setAssignee(assigner.buildAssigneeId()));
.filter(i -> Objects.equals(i.getId(), task.getId())).findAny()
.ifPresent(i -> i.setAssignee(assigner.buildAssigneeId()));
CommandContextUtil.getEntityCache().findInCache(HistoricTaskInstanceEntity.class).stream()
.filter(i -> Objects.equals(i.getId(), task.getId())).findAny()
.ifPresent(i -> i.setAssignee(assigner.buildAssigneeId()));
.filter(i -> Objects.equals(i.getId(), task.getId())).findAny()
.ifPresent(i -> i.setAssignee(assigner.buildAssigneeId()));
}
// 添加审批意见
@ -359,7 +360,7 @@ public class CustomTaskHelper {
addComment(commandContext, task, addComment);
CustomTaskHelper.createExtTaskInst(extAxHiTaskInstService, task.getProcessInstanceId(), task.getId(),
task.getTaskDefinitionKey(), assigner, extTaskInstStatus);
task.getTaskDefinitionKey(), assigner, extTaskInstStatus);
task.setTransientVariable(TASK_COMPLETE_OPERATION_TYPE + task.getId(), extTaskInstStatus);
// 保存任务
@ -378,7 +379,7 @@ public class CustomTaskHelper {
public static Task completeVirtualTask(CommandContext commandContext, Task task) {
ProcessEngineConfigurationImpl processEngineConfiguration =
CommandContextUtil.getProcessEngineConfiguration(commandContext);
CommandContextUtil.getProcessEngineConfiguration(commandContext);
TaskService taskService = processEngineConfiguration.getTaskService();
taskService.complete(task.getId());
return task;
@ -415,10 +416,10 @@ public class CustomTaskHelper {
return delegateAssigners;
}
return new ArrayList<>(delegateAssigners.stream()
.filter(i -> StringUtils.hasText(i.getPersonId()))
.filter(i -> !Objects.equals(i.getPersonId(), "null"))
.collect(Collectors.toMap(BpmnTaskDelegateAssigner::getPersonId, Function.identity(), (s, t) -> s))
.values());
.filter(i -> StringUtils.hasText(i.getPersonId()))
.filter(i -> !Objects.equals(i.getPersonId(), "null"))
.collect(Collectors.toMap(BpmnTaskDelegateAssigner::getPersonId, Function.identity(), (s, t) -> s))
.values());
}
/**
@ -445,27 +446,27 @@ public class CustomTaskHelper {
List<BpmnTaskDelegateAssigner> result = new ArrayList<>();
List<HistoricTaskInstance> taskInstances = historyService.createHistoricTaskInstanceQuery()
.processInstanceId(processInstanceId)
.orderByHistoricTaskInstanceStartTime()
.desc().list();
.processInstanceId(processInstanceId)
.orderByHistoricTaskInstanceStartTime()
.desc().list();
List<BpmnHistoricTaskInstanceVO> vos = historicTaskInstanceConverter.toVosSkipSystemOperation(taskInstances,
serviceVersion);
serviceVersion);
Map<String, HistoricVariableInstance> variableInstanceMap =
// 不能使用框架提供的历史变量 API 查询, BUG
historyService.createNativeHistoricVariableInstanceQuery()
.sql("select * from ACT_HI_VARINST t where t.proc_inst_id_= #{processInstanceId}")
.parameter("processInstanceId", processInstanceId)
.list().stream()
.collect(Collectors.toMap(HistoricVariableInstance::getVariableName,
Function.identity(), (s, t) -> s));
// 不能使用框架提供的历史变量 API 查询, BUG
historyService.createNativeHistoricVariableInstanceQuery()
.sql("select * from ACT_HI_VARINST t where t.proc_inst_id_= #{processInstanceId}")
.parameter("processInstanceId", processInstanceId)
.list().stream()
.collect(Collectors.toMap(HistoricVariableInstance::getVariableName,
Function.identity(), (s, t) -> s));
vos.forEach(vo -> {
HistoricVariableInstance assginerSnapshot =
variableInstanceMap.getOrDefault(INTERNAL_TASK_RELATION_ASSIGNEE_INFO + vo.getTaskId(),
null);
variableInstanceMap.getOrDefault(INTERNAL_TASK_RELATION_ASSIGNEE_INFO + vo.getTaskId(),
null);
if (Objects.isNull(assginerSnapshot)) {
assginerSnapshot =
variableInstanceMap.getOrDefault(OLD_INTERNAL_TASK_RELATION_ASSIGNEE_INFO_SNAPSHOT + vo.getTaskId(), null);
variableInstanceMap.getOrDefault(OLD_INTERNAL_TASK_RELATION_ASSIGNEE_INFO_SNAPSHOT + vo.getTaskId(), null);
}
if (Objects.nonNull(assginerSnapshot)) {
BpmnTaskDelegateAssigner assigner = BpmnTaskDelegateAssigner.toObjectCompatible(assginerSnapshot.getValue());
@ -481,27 +482,27 @@ public class CustomTaskHelper {
ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration(commandContext);
Process process = ProcessDefinitionUtil.getProcess(processDefinitionId);
List<String> taskDefinitionKeys = process.getFlowElements().stream()
.filter(i -> Objects.equals(BpmnMetaParserHelper.getNodeType(i).orElse(null), BpmnFlowNodeType.NODE_CARBON_COPY))
.map(FlowElement::getId)
.collect(Collectors.toList());
.filter(i -> Objects.equals(BpmnMetaParserHelper.getNodeType(i).orElse(null), BpmnFlowNodeType.NODE_CARBON_COPY))
.map(FlowElement::getId)
.collect(Collectors.toList());
if (CollectionUtils.isEmpty(taskDefinitionKeys)) {
return Collections.emptyList();
}
List<HistoricVariableInstance> variableInstances = processEngineConfiguration.getHistoryService().createHistoricVariableInstanceQuery()
.variableNameLike(INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT)
.processInstanceId(processInstanceId)
.list();
.variableNameLike(INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT)
.processInstanceId(processInstanceId)
.list();
if (CollectionUtils.isEmpty(variableInstances)) {
return Collections.emptyList();
}
List<BpmnTaskDelegateAssigner> result = new ArrayList<>();
taskDefinitionKeys.forEach(j -> {
variableInstances.stream()
.filter(i -> Objects.equals(i.getVariableName(), INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT + j))
.findFirst().ifPresent(i -> {
result.addAll((List<BpmnTaskDelegateAssigner>) i.getValue());
});
.filter(i -> Objects.equals(i.getVariableName(), INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT + j))
.findFirst().ifPresent(i -> {
result.addAll((List<BpmnTaskDelegateAssigner>) i.getValue());
});
});
return result;
}