feat(REQ-4586) - 新增节点配置提前校验逻辑

This commit is contained in:
wangli 2025-07-09 10:51:04 +08:00
parent bd716ed44f
commit d98ace2792
3 changed files with 90 additions and 1 deletions

View File

@ -22,6 +22,7 @@ import cn.axzo.workflow.core.engine.job.AsyncRemindTaskJobHandler;
import cn.axzo.workflow.core.engine.job.AsyncResetApproversUserTaskJobHandler; import cn.axzo.workflow.core.engine.job.AsyncResetApproversUserTaskJobHandler;
import cn.axzo.workflow.core.engine.job.AsyncTermNodeAlterJobHandler; import cn.axzo.workflow.core.engine.job.AsyncTermNodeAlterJobHandler;
import cn.axzo.workflow.core.engine.job.AsyncTransferUserTaskJobHandler; import cn.axzo.workflow.core.engine.job.AsyncTransferUserTaskJobHandler;
import cn.axzo.workflow.core.engine.job.NextActivityConfigCheckJobHandler;
import cn.axzo.workflow.core.engine.job.exception.handle.CustomAsyncJobLogClearTraceExceptionHandler; import cn.axzo.workflow.core.engine.job.exception.handle.CustomAsyncJobLogClearTraceExceptionHandler;
import cn.axzo.workflow.core.engine.job.exception.handle.CustomAsyncRunnableExceptionExceptionHandler; import cn.axzo.workflow.core.engine.job.exception.handle.CustomAsyncRunnableExceptionExceptionHandler;
import cn.axzo.workflow.core.engine.persistence.CustomMybatisHistoricProcessInstanceDataManager; import cn.axzo.workflow.core.engine.persistence.CustomMybatisHistoricProcessInstanceDataManager;
@ -120,6 +121,7 @@ public class FlowableConfiguration {
configuration.addCustomJobHandler(new AsyncApproveTaskWithFormJobHandler()); configuration.addCustomJobHandler(new AsyncApproveTaskWithFormJobHandler());
configuration.addCustomJobHandler(new AsyncRemindTaskJobHandler(refreshProperties)); configuration.addCustomJobHandler(new AsyncRemindTaskJobHandler(refreshProperties));
configuration.addCustomJobHandler(new AsyncResetApproversUserTaskJobHandler(extAxHiTaskInstService)); configuration.addCustomJobHandler(new AsyncResetApproversUserTaskJobHandler(extAxHiTaskInstService));
configuration.addCustomJobHandler(new NextActivityConfigCheckJobHandler());
configurers.forEach(i -> configuration.addCustomJobHandler(i.getJobHandler())); configurers.forEach(i -> configuration.addCustomJobHandler(i.getJobHandler()));
// 异步任务异常重试时间间隔 // 异步任务异常重试时间间隔
configuration.setDefaultFailedJobWaitTime(30); configuration.setDefaultFailedJobWaitTime(30);

View File

@ -0,0 +1,54 @@
package cn.axzo.workflow.core.engine.job;
import cn.axzo.workflow.core.common.utils.SpringContextUtils;
import cn.axzo.workflow.core.service.support.FlowNodeForecastService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.ListUtils;
import org.flowable.bpmn.model.FlowElement;
import org.flowable.bpmn.model.ReceiveTask;
import org.flowable.bpmn.model.ServiceTask;
import org.flowable.bpmn.model.UserTask;
import org.flowable.common.engine.impl.interceptor.CommandContext;
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.flowable.engine.impl.util.CommandContextUtil;
import org.flowable.job.service.JobHandler;
import org.flowable.job.service.impl.persistence.entity.JobEntity;
import org.flowable.variable.api.delegate.VariableScope;
import org.springframework.util.CollectionUtils;
import java.util.List;
/**
* TODO
*
* @author wangli
* @since 2025-07-08 19:44
*/
@Slf4j
public class NextActivityConfigCheckJobHandler extends AbstractJobHandler implements JobHandler {
public static final String TYPE = "next-activity-config-check";
@Override
public String getType() {
return TYPE;
}
@Override
public void execute(JobEntity job, String configuration, VariableScope variableScope, CommandContext commandContext) {
log.info("NextActivityConfigCheckJobHandler executing...");
ProcessEngineConfigurationImpl processEngineConfiguration =
CommandContextUtil.getProcessEngineConfiguration(commandContext);
FlowNodeForecastService forecastService = SpringContextUtils.getBean(FlowNodeForecastService.class);
List<FlowElement> flowElements = forecastService.performProcessForecasting(job.getProcessInstanceId(), null, job.getJobHandlerConfiguration(), false);
if (CollectionUtils.isEmpty(flowElements)) {
return;
}
ListUtils.emptyIfNull(flowElements).stream()
.filter(i-> i instanceof UserTask || i instanceof ReceiveTask || i instanceof ServiceTask)
.forEach(i -> {
});
}
}

View File

@ -13,6 +13,7 @@ import cn.axzo.workflow.core.deletage.BpmnTaskCalculateDTO;
import cn.axzo.workflow.core.deletage.BpmnTaskDelegate; import cn.axzo.workflow.core.deletage.BpmnTaskDelegate;
import cn.axzo.workflow.core.deletage.MockTaskAssigneeSelector; import cn.axzo.workflow.core.deletage.MockTaskAssigneeSelector;
import cn.axzo.workflow.core.engine.cmd.CustomAbortProcessInstanceAsyncCmd; import cn.axzo.workflow.core.engine.cmd.CustomAbortProcessInstanceAsyncCmd;
import cn.axzo.workflow.core.engine.job.NextActivityConfigCheckJobHandler;
import cn.axzo.workflow.core.util.DingTalkUtils; import cn.axzo.workflow.core.util.DingTalkUtils;
import cn.hutool.json.JSONUtil; import cn.hutool.json.JSONUtil;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
@ -21,10 +22,14 @@ import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
import org.flowable.bpmn.model.FlowElement; import org.flowable.bpmn.model.FlowElement;
import org.flowable.bpmn.model.Process; import org.flowable.bpmn.model.Process;
import org.flowable.bpmn.model.UserTask; import org.flowable.bpmn.model.UserTask;
import org.flowable.engine.ManagementService;
import org.flowable.engine.delegate.DelegateExecution; import org.flowable.engine.delegate.DelegateExecution;
import org.flowable.engine.delegate.ExecutionListener; import org.flowable.engine.delegate.ExecutionListener;
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.flowable.engine.impl.util.CommandContextUtil; import org.flowable.engine.impl.util.CommandContextUtil;
import org.flowable.engine.impl.util.ProcessDefinitionUtil; import org.flowable.engine.impl.util.ProcessDefinitionUtil;
import org.flowable.job.service.TimerJobService;
import org.flowable.job.service.impl.persistence.entity.TimerJobEntity;
import org.springframework.beans.factory.ObjectProvider; import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.cloud.context.config.annotation.RefreshScope;
@ -35,6 +40,7 @@ import org.springframework.util.StringUtils;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
@ -84,7 +90,6 @@ public class EngineExecutionStartListener implements ExecutionListener {
@Resource @Resource
private SupportRefreshProperties refreshProperties; private SupportRefreshProperties refreshProperties;
@Override @Override
public void notify(DelegateExecution execution) { public void notify(DelegateExecution execution) {
String currentActivityId = execution.getCurrentActivityId(); String currentActivityId = execution.getCurrentActivityId();
@ -98,11 +103,39 @@ public class EngineExecutionStartListener implements ExecutionListener {
// version=1.2.1-SNAPSHOT 开始才给 process 节点增加了 serverVersion 属性 // version=1.2.1-SNAPSHOT 开始才给 process 节点增加了 serverVersion 属性
Optional<String> processServerVersion = getProcessServerVersion(mainProcess); Optional<String> processServerVersion = getProcessServerVersion(mainProcess);
if (processServerVersion.isPresent()) { if (processServerVersion.isPresent()) {
// 创建检查下个节点的配置
createCheckNextActivityJob(execution.getProcessInstanceId(), currentActivityId);
calcTaskAssigner121(execution, userTask, processServerVersion.get(), assigneeListVariableName, calcTaskAssigner121(execution, userTask, processServerVersion.get(), assigneeListVariableName,
currentActivityId); currentActivityId);
} else { } else {
calcTaskAssignerDefault(execution, userTask, currentActivityId, assigneeListVariableName); calcTaskAssignerDefault(execution, userTask, currentActivityId, assigneeListVariableName);
} }
}
/**
* 提前检查下个节点的配置是否异常
*/
private void createCheckNextActivityJob(String processInstanceId, String activityId) {
ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration();
ManagementService managementService = processEngineConfiguration.getManagementService();
// 创建一个只执行一次的 Job
managementService.executeCommand(commandContext -> {
TimerJobService timerJobService = CommandContextUtil.getTimerJobService();
TimerJobEntity timerJobEntity = timerJobService.createTimerJob();
timerJobEntity.setJobType("timer");
timerJobEntity.setJobHandlerType(NextActivityConfigCheckJobHandler.TYPE); // 这里填写你自定义的 JobHandler 类型
timerJobEntity.setProcessInstanceId(processInstanceId);
timerJobEntity.setExecutionId(null);
timerJobEntity.setDuedate(new Date()); // 立即执行
timerJobEntity.setRepeat(null); // 不重复
timerJobEntity.setRetries(1);
timerJobEntity.setJobHandlerConfiguration(activityId); // 可选传递参数
timerJobService.scheduleTimerJob(timerJobEntity);
return null;
});
} }
private void calcTaskAssigner121(DelegateExecution execution, UserTask userTask, String processServerVersion, private void calcTaskAssigner121(DelegateExecution execution, UserTask userTask, String processServerVersion,