feat(REQ-4586) - 优化节点计算异常信息的记录
This commit is contained in:
parent
d98ace2792
commit
2306a35afe
@ -1,25 +1,41 @@
|
||||
package cn.axzo.workflow.core.engine.job;
|
||||
|
||||
import cn.axzo.workflow.common.enums.ApproverEmptyHandleTypeEnum;
|
||||
import cn.axzo.workflow.common.model.NextNodePreCheckAlterDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
|
||||
import cn.axzo.workflow.core.common.utils.SpringContextUtils;
|
||||
import cn.axzo.workflow.core.deletage.BpmnTaskAssigneeSelector;
|
||||
import cn.axzo.workflow.core.listener.Alter;
|
||||
import cn.axzo.workflow.core.service.support.FlowNodeForecastService;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
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.api.query.QueryProperty;
|
||||
import org.flowable.common.engine.impl.interceptor.CommandContext;
|
||||
import org.flowable.engine.delegate.DelegateExecution;
|
||||
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
|
||||
import org.flowable.engine.impl.util.CommandContextUtil;
|
||||
import org.flowable.engine.runtime.Execution;
|
||||
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.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getApprovalMethod;
|
||||
import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getApproverEmptyHandleType;
|
||||
import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getApproverSpecify;
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* 检查节点配置是否合法
|
||||
*
|
||||
* @author wangli
|
||||
* @since 2025-07-08 19:44
|
||||
@ -35,20 +51,121 @@ public class NextActivityConfigCheckJobHandler extends AbstractJobHandler implem
|
||||
|
||||
@Override
|
||||
public void execute(JobEntity job, String configuration, VariableScope variableScope, CommandContext commandContext) {
|
||||
log.info("NextActivityConfigCheckJobHandler executing...");
|
||||
log.info("NextActivityConfigCheckJobHandler executing... 当前节点为: {}", job.getJobHandlerConfiguration());
|
||||
ProcessEngineConfigurationImpl processEngineConfiguration =
|
||||
CommandContextUtil.getProcessEngineConfiguration(commandContext);
|
||||
FlowNodeForecastService forecastService = SpringContextUtils.getBean(FlowNodeForecastService.class);
|
||||
List<FlowElement> flowElements = forecastService.performProcessForecasting(job.getProcessInstanceId(), null, job.getJobHandlerConfiguration(), false);
|
||||
String currentActivityId = job.getJobHandlerConfiguration();
|
||||
List<FlowElement> flowElements = forecastService.performProcessForecasting(job.getProcessInstanceId(), null, currentActivityId, false);
|
||||
if (CollectionUtils.isEmpty(flowElements)) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
doCheck(job, flowElements, processEngineConfiguration);
|
||||
} catch (Exception e) {
|
||||
// 有任何异常,则通过钉钉告警
|
||||
log.warn("NextActivityConfigCheckJobHandler msg: {}", e.getMessage(), e);
|
||||
Alter alter = SpringContextUtils.getBean(Alter.class);
|
||||
FlowElement flowElement = ListUtils.emptyIfNull(flowElements).stream().filter(i -> i instanceof UserTask || i instanceof ReceiveTask || i instanceof ServiceTask).findFirst().orElse(null);
|
||||
NextNodePreCheckAlterDTO alterDTO = new NextNodePreCheckAlterDTO();
|
||||
alterDTO.setProcessInstanceId(job.getProcessInstanceId());
|
||||
alterDTO.setActivityId(Objects.nonNull(flowElement) ? flowElement.getId() : null);
|
||||
alterDTO.setErrorMsg(e.getMessage());
|
||||
alter.invoke(alterDTO);
|
||||
}
|
||||
}
|
||||
|
||||
private String doCheck(JobEntity job, List<FlowElement> flowElements, ProcessEngineConfigurationImpl processEngineConfiguration) {
|
||||
AtomicReference<String> checkActivityId = new AtomicReference<>("");
|
||||
ListUtils.emptyIfNull(flowElements).stream()
|
||||
.filter(i-> i instanceof UserTask || i instanceof ReceiveTask || i instanceof ServiceTask)
|
||||
.forEach(i -> {
|
||||
.filter(i -> i instanceof UserTask || i instanceof ReceiveTask || i instanceof ServiceTask)
|
||||
.findFirst().ifPresent(flowElement -> {
|
||||
log.info("NextActivityConfigCheckJobHandler 计算节点为:{}", flowElement.getId());
|
||||
getApprovalMethod(flowElement).ifPresent(method -> {
|
||||
switch (method) {
|
||||
case autoPassed:
|
||||
case autoRejection:
|
||||
case bizSpecify:
|
||||
break;
|
||||
default:
|
||||
List<Execution> executions = processEngineConfiguration.getRuntimeService().createExecutionQuery()
|
||||
.processInstanceId(job.getProcessInstanceId())
|
||||
.orderBy((QueryProperty) () -> "START_TIME_").desc().list();
|
||||
if (CollectionUtils.isEmpty(executions)) {
|
||||
return;
|
||||
}
|
||||
// 这里只会是 human 这一种情况, 因为 nobody 在转 BPMN 协议时,Activity 直接变成了 ReceiveTask 节点了。
|
||||
List<BpmnTaskDelegateAssigner> assigners = new ArrayList<>();
|
||||
getApproverSpecify(flowElement).ifPresent(specify -> {
|
||||
assigners.addAll(approverSelect(specify.getType(), flowElement, (DelegateExecution) executions.get(0), true));
|
||||
});
|
||||
|
||||
// 审批候选人为空时的兜底
|
||||
emptyAssigneeHandle(assigners, (UserTask) flowElement, (DelegateExecution) executions.get(0));
|
||||
break;
|
||||
}
|
||||
});
|
||||
checkActivityId.set(flowElement.getId());
|
||||
});
|
||||
return checkActivityId.get();
|
||||
}
|
||||
|
||||
public List<BpmnTaskDelegateAssigner> approverSelect(String type, FlowElement flowElement,
|
||||
DelegateExecution execution,
|
||||
Boolean throwException) {
|
||||
List<BpmnTaskAssigneeSelector> selectors = new ArrayList<>(SpringContextUtils.getBeansOfType(BpmnTaskAssigneeSelector.class).values());
|
||||
List<BpmnTaskDelegateAssigner> assigners = new ArrayList<>();
|
||||
ListUtils.emptyIfNull(selectors).forEach(select -> {
|
||||
if (select.support(type)) {
|
||||
log.info("NextActivityConfigCheckJobHandler-审批任务节点 Id:{}, Name: {}, 审批人指定枚举: {}", flowElement.getId(), flowElement.getName(), type);
|
||||
List<BpmnTaskDelegateAssigner> selected = select.select(flowElement, execution, throwException);
|
||||
log.info("NextActivityConfigCheckJobHandler-审批任务节点 Id:{} 的审批人集合为: {}", flowElement.getId(), JSONUtil.toJsonStr(selected));
|
||||
assigners.addAll(selected);
|
||||
}
|
||||
});
|
||||
return assigners;
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算节点的待审批人为空时, 执行模型配置中的审批人为空时的处理方式
|
||||
*
|
||||
* @param assigners 节点计算的待审批人集合, 可能为空
|
||||
* @param userTask 当前节点
|
||||
* @param execution 当前执行实例
|
||||
*/
|
||||
private void emptyAssigneeHandle(List<BpmnTaskDelegateAssigner> assigners, UserTask userTask,
|
||||
DelegateExecution execution) {
|
||||
// 审批人为空并且当前节点设置了自动跳过条件
|
||||
if (!CollectionUtils.isEmpty(assigners)) {
|
||||
return;
|
||||
}
|
||||
log.info("NextActivityConfigCheckJobHandler-当前节点id: [{}], name: [{}] 审批人为空, 将执行审批人为空的兜底配置!", userTask.getId(), userTask.getName());
|
||||
getApproverEmptyHandleType(userTask).ifPresent(type -> {
|
||||
log.info("NextActivityConfigCheckJobHandler-节点兜底的配置模式:[{}]", type.getType());
|
||||
switch (type) {
|
||||
case autoPassed:
|
||||
case autoRejection:
|
||||
break;
|
||||
case transferToAdmin:
|
||||
try {
|
||||
assigners.addAll(approverSelect(ApproverEmptyHandleTypeEnum.transferToAdmin.getType(), userTask,
|
||||
execution, true));
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("审批人为空后转交管理员失败, 内部计算信息:" + e.getMessage());
|
||||
}
|
||||
break;
|
||||
case specifyAssignee:
|
||||
try {
|
||||
assigners.addAll(approverSelect(ApproverEmptyHandleTypeEnum.specifyAssignee.getType(), userTask,
|
||||
execution, true));
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("审批人为空后转交指定人员失败,内部计算信息:" + e.getMessage());
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user