update 优化调整自定义监听

This commit is contained in:
gssong 2024-06-02 14:42:05 +08:00
parent 7b02ad3c00
commit 0b04ac79d0
12 changed files with 191 additions and 228 deletions

View File

@ -0,0 +1,49 @@
package org.dromara.common.core.domain.event;
import jakarta.servlet.http.HttpServletRequest;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
/**
* 总体流程监听
*
* @author may
*/
@Data
public class ProcessEvent implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 流程定义key
*/
private String key;
/**
* 业务id
*/
private String businessKey;
/**
* 状态
*/
private String status;
/**
* 当为true时为申请人节点办理
*/
private boolean submit;
/**
* 请求体
*/
private HttpServletRequest request;
}

View File

@ -0,0 +1,42 @@
package org.dromara.common.core.domain.event;
import jakarta.servlet.http.HttpServletRequest;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
/**
* 流程办理监听
*
* @author may
*/
@Data
public class ProcessTaskEvent implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 流程定义key与流程节点标识(拼接方式流程定义key_流程节点)
*/
private String keyNode;
/**
* 任务id
*/
private String taskId;
/**
* 业务id
*/
private String businessKey;
/**
* 请求体
*/
private HttpServletRequest request;
}

View File

@ -1,27 +0,0 @@
package org.dromara.workflow.annotation;
import java.lang.annotation.*;
/**
* 流程任务监听注解
*
* @author may
* @date 2023-12-27
*/
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface FlowListenerAnnotation {
/**
* 流程定义key
*/
String processDefinitionKey();
/**
* 节点id
*/
String taskDefId() default "";
}

View File

@ -0,0 +1,49 @@
package org.dromara.workflow.flowable.handler;
import org.dromara.common.core.domain.event.ProcessEvent;
import org.dromara.common.core.domain.event.ProcessTaskEvent;
import org.dromara.common.core.utils.ServletUtils;
import org.dromara.common.core.utils.SpringUtils;
import org.springframework.stereotype.Component;
/**
* 流程监听服务
*
* @author may
* @date 2024-06-02
*/
@Component
public class FlowProcessEventHandler {
/**
* @param key 流程key
* @param businessKey 业务id
* @param status 状态
* @param submit 当为true时为申请人节点办理
*/
public void processHandler(String key, String businessKey, String status, boolean submit) {
ProcessEvent processEvent = new ProcessEvent();
processEvent.setKey(key);
processEvent.setBusinessKey(businessKey);
processEvent.setStatus(status);
processEvent.setSubmit(submit);
processEvent.setRequest(ServletUtils.getRequest());
SpringUtils.context().publishEvent(processEvent);
}
/**
* 执行办理任务监听
*
* @param keyNode 流程定义key与流程节点标识(拼接方式流程定义key_流程节点)
* @param taskId 任务id
* @param businessKey 业务id
*/
public void processTaskHandler(String keyNode, String taskId, String businessKey) {
ProcessTaskEvent processTaskEvent = new ProcessTaskEvent();
processTaskEvent.setKeyNode(keyNode);
processTaskEvent.setTaskId(taskId);
processTaskEvent.setBusinessKey(businessKey);
processTaskEvent.setRequest(ServletUtils.getRequest());
SpringUtils.context().publishEvent(processTaskEvent);
}
}

View File

@ -1,73 +0,0 @@
package org.dromara.workflow.flowable.strategy;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.workflow.annotation.FlowListenerAnnotation;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
/**
* 流程任务监听策略
*
* @author may
* @date 2023-12-27
*/
@Component
public class FlowEventStrategy implements BeanPostProcessor {
private final Map<String, FlowTaskEventHandler> flowTaskEventHandlers = new HashMap<>();
private final Map<String, FlowProcessEventHandler> flowProcessEventHandlers = new HashMap<>();
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof FlowTaskEventHandler) {
FlowListenerAnnotation annotation = bean.getClass().getAnnotation(FlowListenerAnnotation.class);
if (null != annotation) {
if (StringUtils.isNotBlank(annotation.processDefinitionKey()) && StringUtils.isNotBlank(annotation.taskDefId())) {
String id = annotation.processDefinitionKey() + "_" + annotation.taskDefId();
if (!flowTaskEventHandlers.containsKey(id)) {
flowTaskEventHandlers.put(id, (FlowTaskEventHandler) bean);
}
}
}
}
if (bean instanceof FlowProcessEventHandler) {
FlowListenerAnnotation annotation = bean.getClass().getAnnotation(FlowListenerAnnotation.class);
if (null != annotation) {
if (StringUtils.isNotBlank(annotation.processDefinitionKey()) && StringUtils.isBlank(annotation.taskDefId())) {
if (!flowProcessEventHandlers.containsKey(annotation.processDefinitionKey())) {
flowProcessEventHandlers.put(annotation.processDefinitionKey(), (FlowProcessEventHandler) bean);
}
}
}
}
return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
}
/**
* 获取可执行bean
*
* @param key key
*/
public FlowTaskEventHandler getTaskHandler(String key) {
if (!flowTaskEventHandlers.containsKey(key)) {
return null;
}
return flowTaskEventHandlers.get(key);
}
/**
* 获取可执行bean
*
* @param key key
*/
public FlowProcessEventHandler getProcessHandler(String key) {
if (!flowProcessEventHandlers.containsKey(key)) {
return null;
}
return flowProcessEventHandlers.get(key);
}
}

View File

@ -1,20 +0,0 @@
package org.dromara.workflow.flowable.strategy;
/**
* 总体流程监听(例如: 撤销 提交 退回 )
*
* @author may
* @date 2023-12-27
*/
public interface FlowProcessEventHandler {
/**
* 执行办理任务监听
*
* @param businessKey 业务id
* @param status 状态
* @param submit 当为true时为申请人节点办理
*/
void handleProcess(String businessKey, String status, boolean submit);
}

View File

@ -1,19 +0,0 @@
package org.dromara.workflow.flowable.strategy;
/**
* 流程任务监听(例如: 节点的审批等)
*
* @author may
* @date 2023-12-27
*/
public interface FlowTaskEventHandler {
/**
* 执行办理任务监听
*
* @param taskId 任务ID
* @param businessKey 业务id
*/
void handleTask(String taskId, String businessKey);
}

View File

@ -1,31 +0,0 @@
package org.dromara.workflow.listener;
import lombok.extern.slf4j.Slf4j;
import org.dromara.workflow.annotation.FlowListenerAnnotation;
import org.dromara.workflow.flowable.strategy.FlowProcessEventHandler;
import org.springframework.stereotype.Component;
/**
* 自定义监听测试
*
* @author may
* @date 2023-12-27
*/
@Slf4j
@Component
@FlowListenerAnnotation(processDefinitionKey = "leave1")
public class TestCustomProcessHandler implements FlowProcessEventHandler {
/**
* 执行办理任务监听
*
* @param businessKey 业务id
* @param status 状态
* @param submit 当为true时为申请人节点办理
*/
@Override
public void handleProcess(String businessKey, String status, boolean submit) {
log.info("业务ID:" + businessKey + ",状态:" + status);
}
}

View File

@ -1,23 +0,0 @@
package org.dromara.workflow.listener;
import lombok.extern.slf4j.Slf4j;
import org.dromara.workflow.annotation.FlowListenerAnnotation;
import org.dromara.workflow.flowable.strategy.FlowTaskEventHandler;
import org.springframework.stereotype.Component;
/**
* 自定义监听测试
*
* @author may
* @date 2023-12-27
*/
@Slf4j
@Component
@FlowListenerAnnotation(processDefinitionKey = "leave1", taskDefId = "Activity_14633hx")
public class TestCustomTaskHandler implements FlowTaskEventHandler {
@Override
public void handleTask(String taskId, String businessKey) {
log.info("任务ID:" + taskId + ",业务ID:" + businessKey);
}
}

View File

@ -26,8 +26,7 @@ import org.dromara.workflow.domain.vo.*;
import org.dromara.workflow.flowable.CustomDefaultProcessDiagramGenerator;
import org.dromara.workflow.flowable.cmd.DeleteExecutionCmd;
import org.dromara.workflow.flowable.cmd.ExecutionChildByExecutionIdCmd;
import org.dromara.workflow.flowable.strategy.FlowEventStrategy;
import org.dromara.workflow.flowable.strategy.FlowProcessEventHandler;
import org.dromara.workflow.flowable.handler.FlowProcessEventHandler;
import org.dromara.workflow.service.IActHiProcinstService;
import org.dromara.workflow.service.IActProcessInstanceService;
import org.dromara.workflow.service.IWfNodeConfigService;
@ -75,9 +74,9 @@ public class ActProcessInstanceServiceImpl implements IActProcessInstanceService
private final TaskService taskService;
private final IActHiProcinstService actHiProcinstService;
private final ManagementService managementService;
private final FlowEventStrategy flowEventStrategy;
private final IWfTaskBackNodeService wfTaskBackNodeService;
private final IWfNodeConfigService wfNodeConfigService;
private final FlowProcessEventHandler flowProcessEventHandler;
@Value("${flowable.activity-font-name}")
private String activityFontName;
@ -460,10 +459,9 @@ public class ActProcessInstanceServiceImpl implements IActProcessInstanceService
BusinessStatusEnum.checkInvalidStatus(historicProcessInstance.getBusinessStatus());
runtimeService.updateBusinessStatus(processInstanceId, BusinessStatusEnum.INVALID.getStatus());
runtimeService.deleteProcessInstance(processInstanceId, deleteReason);
FlowProcessEventHandler processHandler = flowEventStrategy.getProcessHandler(historicProcessInstance.getProcessDefinitionKey());
if (processHandler != null) {
processHandler.handleProcess(historicProcessInstance.getBusinessKey(), BusinessStatusEnum.INVALID.getStatus(), false);
}
//流程作废监听
flowProcessEventHandler.processHandler(historicProcessInstance.getProcessDefinitionKey(),
historicProcessInstance.getBusinessKey(), BusinessStatusEnum.INVALID.getStatus(), false);
return true;
} catch (Exception e) {
e.printStackTrace();
@ -570,10 +568,9 @@ public class ActProcessInstanceServiceImpl implements IActProcessInstanceService
managementService.executeCommand(deleteExecutionCmd);
}
runtimeService.updateBusinessStatus(processInstanceId, BusinessStatusEnum.CANCEL.getStatus());
FlowProcessEventHandler processHandler = flowEventStrategy.getProcessHandler(processInstance.getProcessDefinitionKey());
if (processHandler != null) {
processHandler.handleProcess(processInstance.getBusinessKey(), BusinessStatusEnum.CANCEL.getStatus(), false);
}
//流程作废监听
flowProcessEventHandler.processHandler(processInstance.getProcessDefinitionKey(),
processInstance.getBusinessKey(), BusinessStatusEnum.CANCEL.getStatus(), false);
return true;
} catch (Exception e) {
e.printStackTrace();

View File

@ -9,8 +9,10 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.domain.dto.RoleDTO;
import org.dromara.common.core.domain.dto.UserDTO;
import org.dromara.common.core.domain.event.ProcessTaskEvent;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.service.UserService;
import org.dromara.common.core.utils.ServletUtils;
import org.dromara.common.core.utils.StreamUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.PageQuery;
@ -25,9 +27,7 @@ import org.dromara.workflow.domain.WfTaskBackNode;
import org.dromara.workflow.domain.bo.*;
import org.dromara.workflow.domain.vo.*;
import org.dromara.workflow.flowable.cmd.*;
import org.dromara.workflow.flowable.strategy.FlowEventStrategy;
import org.dromara.workflow.flowable.strategy.FlowProcessEventHandler;
import org.dromara.workflow.flowable.strategy.FlowTaskEventHandler;
import org.dromara.workflow.flowable.handler.FlowProcessEventHandler;
import org.dromara.workflow.mapper.ActHiTaskinstMapper;
import org.dromara.workflow.mapper.ActTaskMapper;
import org.dromara.workflow.service.IActTaskService;
@ -75,13 +75,13 @@ public class ActTaskServiceImpl implements IActTaskService {
private final HistoryService historyService;
private final IdentityService identityService;
private final ManagementService managementService;
private final FlowEventStrategy flowEventStrategy;
private final ActTaskMapper actTaskMapper;
private final IWfTaskBackNodeService wfTaskBackNodeService;
private final ActHiTaskinstMapper actHiTaskinstMapper;
private final IWfNodeConfigService wfNodeConfigService;
private final IWfDefinitionConfigService wfDefinitionConfigService;
private final UserService userService;
private final FlowProcessEventHandler flowProcessEventHandler;
/**
* 启动任务
@ -179,19 +179,15 @@ public class ActTaskServiceImpl implements IActTaskService {
//附件上传
AttachmentCmd attachmentCmd = new AttachmentCmd(completeTaskBo.getFileId(), task.getId(), task.getProcessInstanceId());
managementService.executeCommand(attachmentCmd);
FlowProcessEventHandler processHandler = flowEventStrategy.getProcessHandler(processInstance.getProcessDefinitionKey());
String businessStatus = WorkflowUtils.getBusinessStatus(processInstance.getBusinessKey());
//流程提交监听
if (BusinessStatusEnum.DRAFT.getStatus().equals(businessStatus) || BusinessStatusEnum.BACK.getStatus().equals(businessStatus) || BusinessStatusEnum.CANCEL.getStatus().equals(businessStatus)) {
if (processHandler != null) {
processHandler.handleProcess(processInstance.getBusinessKey(), businessStatus, true);
}
flowProcessEventHandler.processHandler(processInstance.getProcessDefinitionKey(), processInstance.getBusinessKey(), businessStatus, true);
}
runtimeService.updateBusinessStatus(task.getProcessInstanceId(), BusinessStatusEnum.WAITING.getStatus());
String key = processInstance.getProcessDefinitionKey() + "_" + task.getTaskDefinitionKey();
FlowTaskEventHandler taskHandler = flowEventStrategy.getTaskHandler(key);
if (taskHandler != null) {
taskHandler.handleTask(task.getId(), processInstance.getBusinessKey());
}
//办理监听
String keyNode = processInstance.getProcessDefinitionKey() + "_" + task.getTaskDefinitionKey();
flowProcessEventHandler.processTaskHandler(keyNode, task.getId(), processInstance.getBusinessKey());
//办理意见
taskService.addComment(completeTaskBo.getTaskId(), task.getProcessInstanceId(), TaskStatusEnum.PASS.getStatus(), StringUtils.isBlank(completeTaskBo.getMessage()) ? "同意" : completeTaskBo.getMessage());
//办理任务
@ -207,9 +203,8 @@ public class ActTaskServiceImpl implements IActTaskService {
if (pi == null) {
UpdateBusinessStatusCmd updateBusinessStatusCmd = new UpdateBusinessStatusCmd(task.getProcessInstanceId(), BusinessStatusEnum.FINISH.getStatus());
managementService.executeCommand(updateBusinessStatusCmd);
if (processHandler != null) {
processHandler.handleProcess(processInstance.getBusinessKey(), BusinessStatusEnum.FINISH.getStatus(), false);
}
flowProcessEventHandler.processHandler(processInstance.getProcessDefinitionKey(), processInstance.getBusinessKey(),
BusinessStatusEnum.FINISH.getStatus(), false);
} else {
List<Task> list = QueryUtils.taskQuery(task.getProcessInstanceId()).list();
for (Task t : list) {
@ -520,10 +515,9 @@ public class ActTaskServiceImpl implements IActTaskService {
runtimeService.updateBusinessStatus(task.getProcessInstanceId(), BusinessStatusEnum.TERMINATION.getStatus());
runtimeService.deleteProcessInstance(task.getProcessInstanceId(), StrUtil.EMPTY);
}
FlowProcessEventHandler processHandler = flowEventStrategy.getProcessHandler(historicProcessInstance.getProcessDefinitionKey());
if (processHandler != null) {
processHandler.handleProcess(historicProcessInstance.getBusinessKey(), BusinessStatusEnum.TERMINATION.getStatus(), false);
}
//流程终止监听
flowProcessEventHandler.processHandler(historicProcessInstance.getProcessDefinitionKey(),
historicProcessInstance.getBusinessKey(), BusinessStatusEnum.TERMINATION.getStatus(), false);
return true;
} catch (Exception e) {
throw new ServiceException(e.getMessage());
@ -721,10 +715,8 @@ public class ActTaskServiceImpl implements IActTaskService {
WfTaskBackNode wfTaskBackNode = wfTaskBackNodeService.getListByInstanceIdAndNodeId(task.getProcessInstanceId(), backProcessBo.getTargetActivityId());
if (ObjectUtil.isNotNull(wfTaskBackNode) && wfTaskBackNode.getOrderNo() == 0) {
runtimeService.updateBusinessStatus(processInstanceId, BusinessStatusEnum.BACK.getStatus());
FlowProcessEventHandler processHandler = flowEventStrategy.getProcessHandler(processInstance.getProcessDefinitionKey());
if (processHandler != null) {
processHandler.handleProcess(processInstance.getBusinessKey(), BusinessStatusEnum.BACK.getStatus(), false);
}
flowProcessEventHandler.processHandler(processInstance.getProcessDefinitionKey(),
processInstance.getBusinessKey(), BusinessStatusEnum.BACK.getStatus(), false);
}
//删除驳回后的流程节点
wfTaskBackNodeService.deleteBackTaskNode(processInstanceId, backProcessBo.getTargetActivityId());

View File

@ -5,6 +5,9 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.domain.event.ProcessEvent;
import org.dromara.common.core.domain.event.ProcessTaskEvent;
import org.dromara.common.core.service.WorkflowService;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StreamUtils;
@ -17,6 +20,7 @@ import org.dromara.workflow.domain.bo.TestLeaveBo;
import org.dromara.workflow.domain.vo.TestLeaveVo;
import org.dromara.workflow.mapper.TestLeaveMapper;
import org.dromara.workflow.service.ITestLeaveService;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@ -31,6 +35,7 @@ import java.util.List;
*/
@RequiredArgsConstructor
@Service
@Slf4j
public class TestLeaveServiceImpl implements ITestLeaveService {
private final TestLeaveMapper baseMapper;
@ -117,4 +122,26 @@ public class TestLeaveServiceImpl implements ITestLeaveService {
workflowService.deleteRunAndHisInstance(idList);
return baseMapper.deleteBatchIds(ids) > 0;
}
/**
* 总体流程监听(例如: 提交 退回 撤销 终止 作废等)
*
* @param processEvent 参数
*/
@EventListener(condition = "#processEvent.key=='leave1'")
public void processHandler(ProcessEvent processEvent) {
log.info("当前任务执行了{}", processEvent.toString());
}
/**
* 执行办理任务监听
*
* @param processTaskEvent 参数
*/
@EventListener(condition = "#processTaskEvent.keyNode=='leave1_Activity_14633hx'")
public void processTaskHandler(ProcessTaskEvent processTaskEvent) {
log.info("当前任务执行了{}", processTaskEvent.toString());
}
}