update - 调整引擎事件的处理逻辑

This commit is contained in:
wangli 2024-03-27 13:45:25 +08:00
parent 4d4e1e2dd5
commit d1bb97de18
12 changed files with 105 additions and 131 deletions

View File

@ -63,9 +63,8 @@ public class UserTaskJsonConverter extends AbstractBpmnJsonConverter<UserTask> {
// 设置全局任务监听器
setTaskListeners(userTask);
// 设置全局执行监听器
if (!Objects.equals(NODE_STARTER, node.getType())) {
setExecutionListeners(userTask);
}
setExecutionListeners(node, userTask);
//以下是保存配置信息, 引擎完全不会 care 这里的信息
// "设置审批人"
@ -251,9 +250,10 @@ public class UserTaskJsonConverter extends AbstractBpmnJsonConverter<UserTask> {
/**
* 设置执行监听
*
* @param node
* @param userTask
*/
private static void setExecutionListeners(UserTask userTask) {
private static void setExecutionListeners(BpmnJsonNode node, UserTask userTask) {
List<FlowableListener> executionListeners = new ArrayList<>();
// 设置执行监听
@ -263,23 +263,25 @@ public class UserTaskJsonConverter extends AbstractBpmnJsonConverter<UserTask> {
executionListener.setImplementation("${engineExecutionStartListener}");
executionListeners.add(executionListener);
FlowableListener activityStartListener = new FlowableListener();
activityStartListener.setEvent(BaseExecutionListener.EVENTNAME_START);
activityStartListener.setImplementationType(IMPLEMENTATION_TYPE_DELEGATEEXPRESSION);
activityStartListener.setImplementation("${engineActivityStartEventListener}");
executionListeners.add(activityStartListener);
if (!Objects.equals(NODE_STARTER, node.getType())) {
FlowableListener activityStartListener = new FlowableListener();
activityStartListener.setEvent(BaseExecutionListener.EVENTNAME_START);
activityStartListener.setImplementationType(IMPLEMENTATION_TYPE_DELEGATEEXPRESSION);
activityStartListener.setImplementation("${engineActivityStartEventListener}");
executionListeners.add(activityStartListener);
FlowableListener activityTakeListener = new FlowableListener();
activityTakeListener.setEvent(BaseExecutionListener.EVENTNAME_TAKE);
activityTakeListener.setImplementationType(IMPLEMENTATION_TYPE_DELEGATEEXPRESSION);
activityTakeListener.setImplementation("${engineActivityTakeEventListener}");
executionListeners.add(activityTakeListener);
FlowableListener activityTakeListener = new FlowableListener();
activityTakeListener.setEvent(BaseExecutionListener.EVENTNAME_TAKE);
activityTakeListener.setImplementationType(IMPLEMENTATION_TYPE_DELEGATEEXPRESSION);
activityTakeListener.setImplementation("${engineActivityTakeEventListener}");
executionListeners.add(activityTakeListener);
FlowableListener activityEndListener = new FlowableListener();
activityEndListener.setEvent(BaseExecutionListener.EVENTNAME_END);
activityEndListener.setImplementationType(IMPLEMENTATION_TYPE_DELEGATEEXPRESSION);
activityEndListener.setImplementation("${engineActivityEndEventListener}");
executionListeners.add(activityEndListener);
FlowableListener activityEndListener = new FlowableListener();
activityEndListener.setEvent(BaseExecutionListener.EVENTNAME_END);
activityEndListener.setImplementationType(IMPLEMENTATION_TYPE_DELEGATEEXPRESSION);
activityEndListener.setImplementation("${engineActivityEndEventListener}");
executionListeners.add(activityEndListener);
}
userTask.setExecutionListeners(executionListeners);
}

View File

@ -41,7 +41,7 @@ public class CustomApproveTaskCmd implements Command<Void>, Serializable {
/**
* 不传,默认"已通过"
*/
private final String operationDesc;
private String operationDesc = "已通过";
/**
* 附件, 可为空
*/
@ -52,6 +52,14 @@ public class CustomApproveTaskCmd implements Command<Void>, Serializable {
*/
private final BpmnTaskDelegateAssigner nextApprover;
public CustomApproveTaskCmd(String taskId, String advice, List<AttachmentDTO> attachmentList,
BpmnTaskDelegateAssigner approver, BpmnTaskDelegateAssigner nextApprover) {
this.taskId = taskId;
this.advice = advice;
this.attachmentList = attachmentList;
this.approver = approver;
this.nextApprover = nextApprover;
}
public CustomApproveTaskCmd(String taskId, String advice, String operationDesc, List<AttachmentDTO> attachmentList,
BpmnTaskDelegateAssigner approver, BpmnTaskDelegateAssigner nextApprover) {
this.taskId = taskId;
@ -84,8 +92,7 @@ public class CustomApproveTaskCmd implements Command<Void>, Serializable {
batchAddAttachment(commandContext, task.getProcessInstanceId(), taskId, attachmentList, approver);
Authentication.setAuthenticatedUserId(Objects.nonNull(approver) ? approver.buildAssigneeId() : null);
addComment(commandContext, task, COMMENT_TYPE_OPERATION_DESC, StringUtils.hasText(operationDesc) ?
operationDesc : "已通过");
addComment(commandContext, task, COMMENT_TYPE_OPERATION_DESC, operationDesc);
Authentication.setAuthenticatedUserId(null);
RuntimeService runtimeService = processEngineConfiguration.getRuntimeService();

View File

@ -25,6 +25,7 @@ import org.flowable.task.api.Task;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.flowable.task.service.impl.persistence.entity.HistoricTaskInstanceEntity;
import org.flowable.task.service.impl.persistence.entity.TaskEntity;
import org.flowable.task.service.impl.persistence.entity.TaskEntityImpl;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
@ -186,6 +187,13 @@ public class CustomTaskHelper {
Authentication.setAuthenticatedUserId(null);
}
public static Comment addComment(CommandContext commandContext, String taskId, String processInstanceId,
String type, String message) {
TaskEntity task = new TaskEntityImpl();
task.setId(taskId);
task.setProcessInstanceId(processInstanceId);
return addComment(commandContext, task, type, message);
}
public static Comment addComment(CommandContext commandContext, Task task, String type, String message) {
ProcessEngineConfigurationImpl processEngineConfiguration =
CommandContextUtil.getProcessEngineConfiguration(commandContext);

View File

@ -2,11 +2,15 @@ package cn.axzo.workflow.core.engine.listener;
import cn.axzo.workflow.common.model.request.bpmn.BpmnNoticeConf;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
import cn.axzo.workflow.common.model.request.bpmn.task.ExtHiTaskSearchDTO;
import cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper;
import cn.axzo.workflow.core.engine.cmd.CustomCarbonCopyUserSelectorCmd;
import cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper;
import cn.axzo.workflow.core.engine.event.MessagePushEventBuilder;
import cn.axzo.workflow.core.engine.event.MessagePushEventImpl;
import cn.axzo.workflow.core.engine.event.MessagePushEventType;
import cn.axzo.workflow.core.repository.entity.ExtAxHiTaskInst;
import cn.axzo.workflow.core.service.ExtAxHiTaskInstService;
import cn.axzo.workflow.core.service.converter.BpmnHistoricTaskInstanceConverter;
import lombok.extern.slf4j.Slf4j;
import org.flowable.bpmn.model.Process;
@ -28,9 +32,11 @@ import org.springframework.util.StringUtils;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_OPERATION_DESC;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT;
import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getCarbonCopyConfigs;
@ -55,6 +61,8 @@ public class EngineCarbonCopyEventListener implements JavaDelegate {
@Resource
private BpmnHistoricTaskInstanceConverter historicTaskInstanceConverter;
@Resource
private ExtAxHiTaskInstService extAxHiTaskInstService;
@Resource
private String serviceVersion;
@Override
@ -80,6 +88,16 @@ public class EngineCarbonCopyEventListener implements JavaDelegate {
runtimeService.setVariable(processInstanceId,
INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT + currentActivityId, carbonUsers);
ExtHiTaskSearchDTO searchDTO = new ExtHiTaskSearchDTO();
searchDTO.setProcessInstanceId(processInstanceId);
searchDTO.setTaskDefinitionKey(currentActivityId);
extAxHiTaskInstService.queryList(searchDTO)
.stream()
.max(Comparator.comparing(ExtAxHiTaskInst::getCreateAt))
.ifPresent(i ->
CustomTaskHelper.addComment(CommandContextUtil.getCommandContext(), i.getTaskId(),
processInstanceId, COMMENT_TYPE_OPERATION_DESC, "抄送" + carbonUsers.size() + ""));
// 发送抄送事件
invokeCarbonCopy(carbonUsers, BpmnMetaParserHelper.getNoticeConfig(mainProcess), execution);
@ -87,8 +105,8 @@ public class EngineCarbonCopyEventListener implements JavaDelegate {
}
private void invokeCarbonCopy(List<BpmnTaskDelegateAssigner> carbonUsers,
Optional<BpmnNoticeConf> noticeConf,
DelegateExecution execution) {
Optional<BpmnNoticeConf> noticeConf,
DelegateExecution execution) {
if (CollectionUtils.isEmpty(carbonUsers)) {
return;
}

View File

@ -6,22 +6,24 @@ import org.springframework.core.Ordered;
/**
* 流程审批任务相关事件, 供外部引入 jar 包方式使用的钩子
* <p>
* 微服版本使用, 统一在 Server module 中进行实现扩展, 不在该 module 中实现
* 微服版本使用, 统一在 Server module 中进行实现扩展, 不在该 module 中实现.
*
* Flowable Engine onAssigned 优先级比 onCreated 更高
*
* @author shao_hua
*/
public interface BpmnTaskEventListener extends Ordered {
/**
* 用户任务已创建,未指派审核人
*/
default void onCreated(DelegateTask delegateTask) {}
/**
* 用户任务已指派审核人
*/
default void onAssigned(DelegateTask delegateTask) {}
/**
* 用户任务已创建,未指派审核人
*/
default void onCreated(DelegateTask delegateTask) {}
/**
* 用户任务已通过
* <p>

View File

@ -28,7 +28,7 @@ import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.DELETE
@Slf4j
@Component
@AllArgsConstructor
public class InternalExtAxTaskInstEventListener implements BpmnTaskEventListener {
public class InternalExtAxTaskInstEvent_min_Listener implements BpmnTaskEventListener {
private final ExtAxHiTaskInstService hiTaskInstService;
private final RuntimeService runtimeService;
@ -38,7 +38,7 @@ public class InternalExtAxTaskInstEventListener implements BpmnTaskEventListener
}
@Override
public void onCreated(DelegateTask delegateTask) {
public void onAssigned(DelegateTask delegateTask) {
ExtAxHiTaskInst entity = new ExtAxHiTaskInst();
entity.setProcInstId(delegateTask.getProcessInstanceId());
entity.setTaskDefinitionKey(delegateTask.getTaskDefinitionKey());

View File

@ -289,8 +289,7 @@ public class BpmnProcessTaskServiceImpl implements BpmnProcessTaskService {
@Transactional(rollbackFor = Exception.class)
public void approveTask(BpmnTaskAuditDTO dto) {
CommandExecutor commandExecutor = processEngineConfiguration.getCommandExecutor();
commandExecutor.execute(new CustomApproveTaskCmd(dto.getTaskId(), dto.getAdvice(), null,
dto.getAttachmentList(),
commandExecutor.execute(new CustomApproveTaskCmd(dto.getTaskId(), dto.getAdvice(), dto.getAttachmentList(),
dto.getApprover(), dto.getNextApprover()));
}

View File

@ -1,9 +1,11 @@
package cn.axzo.workflow.server.controller.listener.task;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
import cn.axzo.workflow.common.model.request.bpmn.task.ExtHiTaskSearchDTO;
import cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper;
import cn.axzo.workflow.core.engine.cmd.CustomApproveTaskCmd;
import cn.axzo.workflow.core.listener.BpmnTaskEventListener;
import cn.axzo.workflow.core.repository.entity.ExtAxHiTaskInst;
import cn.axzo.workflow.core.service.ExtAxHiTaskInstService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@ -58,10 +60,10 @@ import static cn.axzo.workflow.core.common.enums.BpmnProcessTaskResultEnum.REJEC
@Slf4j
@Component
@AllArgsConstructor
public class AutoOperatorEventListener implements BpmnTaskEventListener, Ordered {
public class AutoOperatorEvent_102_Listener implements BpmnTaskEventListener, Ordered {
@Override
public int getOrder() {
return Integer.MIN_VALUE + 103;
return Integer.MIN_VALUE + 102;
}
private final TaskService taskService;
@ -70,6 +72,19 @@ public class AutoOperatorEventListener implements BpmnTaskEventListener, Ordered
private final HistoryService historyService;
private final ExtAxHiTaskInstService extAxHiTaskInstService;
@Override
public void onAssigned(DelegateTask delegateTask) {
Process mainProcess = repositoryService.getBpmnModel(delegateTask.getProcessDefinitionId()).getMainProcess();
UserTask userTask = (UserTask) mainProcess.getFlowElement(delegateTask.getTaskDefinitionKey());
boolean exists = checkApproverExists(delegateTask, userTask, mainProcess);
if (exists) {
taskService.addComment(delegateTask.getId(), delegateTask.getProcessInstanceId(), COMMENT_TYPE_ADVICE,
"同一审批人,自动过审");
autoPass(delegateTask);
}
}
@Override
public void onCreated(DelegateTask delegateTask) {
if (log.isDebugEnabled()) {
@ -85,6 +100,7 @@ public class AutoOperatorEventListener implements BpmnTaskEventListener, Ordered
APPROVED.getStatus());
// 直接完成
taskService.complete(delegateTask.getId(), runtimeService.getVariables(delegateTask.getExecutionId()));
return;
}
@ -99,19 +115,6 @@ public class AutoOperatorEventListener implements BpmnTaskEventListener, Ordered
}
}
@Override
public void onAssigned(DelegateTask delegateTask) {
Process mainProcess = repositoryService.getBpmnModel(delegateTask.getProcessDefinitionId()).getMainProcess();
UserTask userTask = (UserTask) mainProcess.getFlowElement(delegateTask.getTaskDefinitionKey());
boolean exists = checkApproverExists(delegateTask, userTask, mainProcess);
if (exists) {
taskService.addComment(delegateTask.getId(), delegateTask.getProcessInstanceId(), COMMENT_TYPE_ADVICE,
"同一审批人,自动过审");
autoPass(delegateTask);
}
}
/**
* 校验当前的审批人是否存在过前一个节点
*
@ -141,14 +144,16 @@ public class AutoOperatorEventListener implements BpmnTaskEventListener, Ordered
FlowElement flowElement = mainProcess.getFlowElement(i.getActivityId());
BpmnMetaParserHelper.getNodeType(flowElement).ifPresent(j -> {
if (Objects.equals(NODE_TASK, j)) {
historyService.createHistoricTaskInstanceQuery()
.processInstanceId(delegateTask.getProcessInstanceId())
.taskDefinitionKey(i.getActivityId()).list()
.stream().map(HistoricTaskInstance::getAssignee)
ExtHiTaskSearchDTO searchDTO = new ExtHiTaskSearchDTO();
searchDTO.setProcessInstanceId(delegateTask.getProcessInstanceId());
searchDTO.setTaskDefinitionKey(i.getActivityId());
extAxHiTaskInstService.queryList(searchDTO)
.stream().filter(e -> Objects.equals(e.getStatus(), APPROVED.getStatus()))
.map(ExtAxHiTaskInst::getAssignee)
.filter(Objects::nonNull)
.filter(StringUtils::hasText)
.filter(k -> specialApproverComparison(k, delegateTask.getAssignee()))
.findAny().ifPresent(k -> {
exists.compareAndSet(false, true);
});
.findAny().ifPresent(k -> exists.compareAndSet(false, true));
}
});
}
@ -256,8 +261,11 @@ public class AutoOperatorEventListener implements BpmnTaskEventListener, Ordered
private void autoPass(DelegateTask delegateTask) {
ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration();
CommandExecutor commandExecutor = processEngineConfiguration.getCommandExecutor();
BpmnTaskDelegateAssigner assigner =
delegateTask.getVariable(INTERNAL_TASK_RELATION_ASSIGNEE_INFO + delegateTask.getId(),
BpmnTaskDelegateAssigner.class);
commandExecutor.execute(new CustomApproveTaskCmd(delegateTask.getId(), null, "自动通过",
Collections.emptyList(), null, null));
Collections.emptyList(), assigner, null));
// if (log.isDebugEnabled()) {

View File

@ -47,10 +47,10 @@ import static cn.axzo.workflow.core.engine.event.BizSpecifyAssigneeEventType.ADD
@Slf4j
@Component
@AllArgsConstructor
public class MessagePushTaskEventListener implements BpmnTaskEventListener, Ordered {
public class MessagePushTaskEvent_103_Listener implements BpmnTaskEventListener, Ordered {
@Override
public int getOrder() {
return Integer.MIN_VALUE + 104;
return Integer.MIN_VALUE + 103;
}
private final RuntimeService runtimeService;

View File

@ -41,7 +41,7 @@ import static cn.axzo.workflow.common.enums.ProcessTaskEventEnum.PROCESS_TASK_DE
*/
@Slf4j
@Component
public class RocketMqBpmnTaskEventListener implements BpmnTaskEventListener, Ordered {
public class RocketMqBpmnTaskEvent_101_Listener implements BpmnTaskEventListener, Ordered {
@Override
public int getOrder() {
return Integer.MIN_VALUE + 101;

View File

@ -29,7 +29,7 @@ import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_TASK_RELAT
@Slf4j
@Component
@AllArgsConstructor
public class SnapshotBpmnTaskTaskEventListener implements BpmnTaskEventListener, Ordered {
public class SnapshotBpmnTaskTaskEvent_100_Listener implements BpmnTaskEventListener, Ordered {
@Override
public int getOrder() {
return Integer.MIN_VALUE + 100;

View File

@ -1,70 +0,0 @@
package cn.axzo.workflow.server.controller.listener.task;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
import cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper;
import cn.axzo.workflow.core.listener.BpmnTaskEventListener;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.flowable.bpmn.model.Process;
import org.flowable.bpmn.model.UserTask;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.task.service.delegate.DelegateTask;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import java.util.Objects;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_INITIATOR;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_TASK_RELATION_ASSIGNEE_INFO;
import static cn.axzo.workflow.common.constant.BpmnConstants.TASK_COMPLETE_OPERATION_TYPE;
import static cn.axzo.workflow.common.enums.BpmnFlowNodeType.NODE_STARTER;
import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.APPROVED;
/**
* 仿钉钉版本的 发起人 节点自动通过处理
*
* @author wangli
* @since 2023/10/16 13:55
*/
@Slf4j
@Component
@AllArgsConstructor
public class StartNodeAutoCompleteEventListener implements BpmnTaskEventListener, Ordered {
@Override
public int getOrder() {
return Integer.MIN_VALUE + 102;
}
private final TaskService taskService;
private final RuntimeService runtimeService;
private final RepositoryService repositoryService;
@Override
public void onCreated(DelegateTask delegateTask) {
if (log.isDebugEnabled()) {
log.debug("StartNodeAutoCompleteEventListener#onCreated...{}", delegateTask.getTaskDefinitionKey());
}
Process mainProcess = repositoryService.getBpmnModel(delegateTask.getProcessDefinitionId()).getMainProcess();
UserTask userTask = (UserTask) mainProcess.getFlowElement(delegateTask.getTaskDefinitionKey());
// 这一个通用的发起人节点完全不需要审批
// 为什么要创建这个节点只是为了在审批记录中有一个发起人的记录信息而已
BpmnMetaParserHelper.getNodeType(userTask).ifPresent(nodeType -> {
if (Objects.equals(NODE_STARTER, nodeType)) {
BpmnTaskDelegateAssigner initiator = delegateTask.getVariable(INTERNAL_INITIATOR,
BpmnTaskDelegateAssigner.class);
delegateTask.setVariable(INTERNAL_TASK_RELATION_ASSIGNEE_INFO + delegateTask.getId(),
initiator);
delegateTask.setTransientVariable(TASK_COMPLETE_OPERATION_TYPE + delegateTask.getId(),
APPROVED.getStatus());
// 直接完成
taskService.complete(delegateTask.getId(), runtimeService.getVariables(delegateTask.getExecutionId()));
}
});
if (log.isDebugEnabled()) {
log.debug("StartNodeAutoCompleteEventListener#onCreated...end: {}", delegateTask.getTaskDefinitionKey());
}
}
}