feat: Simple设计器-延时器
This commit is contained in:
parent
46c825cb6f
commit
4c8b83d46f
|
@ -13,7 +13,8 @@ import lombok.Getter;
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public enum BpmBoundaryEventType {
|
public enum BpmBoundaryEventType {
|
||||||
|
|
||||||
USER_TASK_TIMEOUT(1,"用户任务超时");
|
USER_TASK_TIMEOUT(1,"用户任务超时"),
|
||||||
|
DELAY_TIMER_TIMEOUT(2,"触发器超时");
|
||||||
|
|
||||||
private final Integer type;
|
private final Integer type;
|
||||||
private final String name;
|
private final String name;
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
package cn.iocoder.yudao.module.bpm.enums.definition;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BPM 延时器类型枚举
|
||||||
|
*
|
||||||
|
* @author Lesan
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor
|
||||||
|
public enum BpmDelayTimerType implements IntArrayValuable {
|
||||||
|
|
||||||
|
FIXED_TIME_DURATION(1, "固定时长"),
|
||||||
|
FIXED_DATE_TIME(2, "固定日期时间");
|
||||||
|
|
||||||
|
private final Integer type;
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(BpmDelayTimerType::getType).toArray();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int[] array() {
|
||||||
|
return ARRAYS;
|
||||||
|
}
|
||||||
|
}
|
|
@ -25,6 +25,7 @@ public enum BpmSimpleModelNodeType implements IntArrayValuable {
|
||||||
START_USER_NODE(10, "发起人", "userTask"), // 发起人节点。前端的开始节点,Id 固定
|
START_USER_NODE(10, "发起人", "userTask"), // 发起人节点。前端的开始节点,Id 固定
|
||||||
APPROVE_NODE(11, "审批人", "userTask"),
|
APPROVE_NODE(11, "审批人", "userTask"),
|
||||||
COPY_NODE(12, "抄送人", "serviceTask"),
|
COPY_NODE(12, "抄送人", "serviceTask"),
|
||||||
|
DELAY_TIMER_NODE(13, "延迟器", "receiveTask"),
|
||||||
|
|
||||||
// 50 ~ 条件分支
|
// 50 ~ 条件分支
|
||||||
CONDITION_NODE(50, "条件", "sequenceFlow"), // 用于构建流转条件的表达式
|
CONDITION_NODE(50, "条件", "sequenceFlow"), // 用于构建流转条件的表达式
|
||||||
|
|
|
@ -208,5 +208,22 @@ public class BpmSimpleModelNodeVO {
|
||||||
private String rightSide;
|
private String rightSide;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Schema(description = "延迟器设置", example = "{}")
|
||||||
|
private DelaySetting delaySetting;
|
||||||
|
|
||||||
|
@Schema(description = "延迟器")
|
||||||
|
@Data
|
||||||
|
@Valid
|
||||||
|
public static class DelaySetting {
|
||||||
|
|
||||||
|
@Schema(description = "延迟时间类型", example = "1")
|
||||||
|
@NotNull(message = "延迟时间类型不能为空")
|
||||||
|
private Integer delayType;
|
||||||
|
|
||||||
|
@Schema(description = "延迟时间表达式", example = "PT1H,2025-01-01T00:00:00")
|
||||||
|
@NotEmpty(message = "延迟时间表达式不能为空")
|
||||||
|
private String delayTime;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO @芋艿:条件;建议可以固化的一些选项;然后有个表达式兜底;要支持
|
// TODO @芋艿:条件;建议可以固化的一些选项;然后有个表达式兜底;要支持
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,15 +98,20 @@ public class BpmTaskEventListener extends AbstractFlowableEngineEventListener {
|
||||||
String boundaryEventType = BpmnModelUtils.parseBoundaryEventExtensionElement(boundaryEvent,
|
String boundaryEventType = BpmnModelUtils.parseBoundaryEventExtensionElement(boundaryEvent,
|
||||||
BpmnModelConstants.BOUNDARY_EVENT_TYPE);
|
BpmnModelConstants.BOUNDARY_EVENT_TYPE);
|
||||||
BpmBoundaryEventType bpmTimerBoundaryEventType = BpmBoundaryEventType.typeOf(NumberUtils.parseInt(boundaryEventType));
|
BpmBoundaryEventType bpmTimerBoundaryEventType = BpmBoundaryEventType.typeOf(NumberUtils.parseInt(boundaryEventType));
|
||||||
if (ObjectUtil.notEqual(bpmTimerBoundaryEventType, BpmBoundaryEventType.USER_TASK_TIMEOUT)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. 处理超时
|
// 2. 处理超时
|
||||||
|
// 2.1 用户任务超时处理
|
||||||
|
if (ObjectUtil.equal(bpmTimerBoundaryEventType, BpmBoundaryEventType.USER_TASK_TIMEOUT)) {
|
||||||
String timeoutHandlerType = BpmnModelUtils.parseBoundaryEventExtensionElement(boundaryEvent,
|
String timeoutHandlerType = BpmnModelUtils.parseBoundaryEventExtensionElement(boundaryEvent,
|
||||||
BpmnModelConstants.USER_TASK_TIMEOUT_HANDLER_TYPE);
|
BpmnModelConstants.USER_TASK_TIMEOUT_HANDLER_TYPE);
|
||||||
String taskKey = boundaryEvent.getAttachedToRefId();
|
String taskKey = boundaryEvent.getAttachedToRefId();
|
||||||
taskService.processTaskTimeout(event.getProcessInstanceId(), taskKey, NumberUtils.parseInt(timeoutHandlerType));
|
taskService.processTaskTimeout(event.getProcessInstanceId(), taskKey, NumberUtils.parseInt(timeoutHandlerType));
|
||||||
}
|
}
|
||||||
|
// 2.2 触发器超时处理
|
||||||
|
if (ObjectUtil.equal(bpmTimerBoundaryEventType, BpmBoundaryEventType.DELAY_TIMER_TIMEOUT)) {
|
||||||
|
String taskKey = boundaryEvent.getAttachedToRefId();
|
||||||
|
taskService.processDelayTimerTimeout(event.getProcessInstanceId(), taskKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,7 @@ public class SimpleModelUtils {
|
||||||
static {
|
static {
|
||||||
List<NodeConvert> converts = asList(new StartNodeConvert(), new EndNodeConvert(),
|
List<NodeConvert> converts = asList(new StartNodeConvert(), new EndNodeConvert(),
|
||||||
new StartUserNodeConvert(), new ApproveNodeConvert(), new CopyNodeConvert(),
|
new StartUserNodeConvert(), new ApproveNodeConvert(), new CopyNodeConvert(),
|
||||||
|
new DelayTimerNodeConvert(),
|
||||||
new ConditionBranchNodeConvert(), new ParallelBranchNodeConvert(), new InclusiveBranchNodeConvert());
|
new ConditionBranchNodeConvert(), new ParallelBranchNodeConvert(), new InclusiveBranchNodeConvert());
|
||||||
converts.forEach(convert -> NODE_CONVERTS.put(convert.getType(), convert));
|
converts.forEach(convert -> NODE_CONVERTS.put(convert.getType(), convert));
|
||||||
}
|
}
|
||||||
|
@ -605,6 +606,45 @@ public class SimpleModelUtils {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class DelayTimerNodeConvert implements NodeConvert {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<FlowElement> convertList(BpmSimpleModelNodeVO node) {
|
||||||
|
List<FlowElement> flowElements = new ArrayList<>(2);
|
||||||
|
// 1. 构建接收任务,通过接收任务可卡住节点
|
||||||
|
ReceiveTask receiveTask = new ReceiveTask();
|
||||||
|
receiveTask.setId(node.getId());
|
||||||
|
receiveTask.setName(node.getName());
|
||||||
|
flowElements.add(receiveTask);
|
||||||
|
|
||||||
|
// 2. 添加接收任务的 Timer Boundary Event
|
||||||
|
if (node.getDelaySetting() != null) {
|
||||||
|
// 2.1 定时器边界事件
|
||||||
|
BoundaryEvent boundaryEvent = new BoundaryEvent();
|
||||||
|
boundaryEvent.setId("Event-" + IdUtil.fastUUID());
|
||||||
|
boundaryEvent.setCancelActivity(false);
|
||||||
|
boundaryEvent.setAttachedToRef(receiveTask);
|
||||||
|
// 2.2 定义超时时间
|
||||||
|
TimerEventDefinition eventDefinition = new TimerEventDefinition();
|
||||||
|
if (node.getDelaySetting().getDelayType().equals(BpmDelayTimerType.FIXED_DATE_TIME.getType())){
|
||||||
|
eventDefinition.setTimeDuration(node.getDelaySetting().getDelayTime());
|
||||||
|
}
|
||||||
|
if (node.getDelaySetting().getDelayType().equals(BpmDelayTimerType.FIXED_TIME_DURATION.getType())){
|
||||||
|
eventDefinition.setTimeDate(node.getDelaySetting().getDelayTime());
|
||||||
|
}
|
||||||
|
boundaryEvent.addEventDefinition(eventDefinition);
|
||||||
|
addExtensionElement(boundaryEvent, BOUNDARY_EVENT_TYPE, BpmBoundaryEventType.DELAY_TIMER_TIMEOUT.getType());
|
||||||
|
flowElements.add(boundaryEvent);
|
||||||
|
}
|
||||||
|
return flowElements;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BpmSimpleModelNodeType getType() {
|
||||||
|
return BpmSimpleModelNodeType.DELAY_TIMER_NODE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static String buildGatewayJoinId(String id) {
|
private static String buildGatewayJoinId(String id) {
|
||||||
return id + "_join";
|
return id + "_join";
|
||||||
}
|
}
|
||||||
|
|
|
@ -275,4 +275,11 @@ public interface BpmTaskService {
|
||||||
*/
|
*/
|
||||||
void processTaskTimeout(String processInstanceId, String taskDefineKey, Integer handlerType);
|
void processTaskTimeout(String processInstanceId, String taskDefineKey, Integer handlerType);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理 延时器 超时事件
|
||||||
|
*
|
||||||
|
* @param processInstanceId 流程示例编号
|
||||||
|
* @param taskDefineKey 任务 Key
|
||||||
|
*/
|
||||||
|
void processDelayTimerTimeout(String processInstanceId, String taskDefineKey);
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,6 +42,7 @@ import org.flowable.engine.ManagementService;
|
||||||
import org.flowable.engine.RuntimeService;
|
import org.flowable.engine.RuntimeService;
|
||||||
import org.flowable.engine.TaskService;
|
import org.flowable.engine.TaskService;
|
||||||
import org.flowable.engine.history.HistoricActivityInstance;
|
import org.flowable.engine.history.HistoricActivityInstance;
|
||||||
|
import org.flowable.engine.runtime.Execution;
|
||||||
import org.flowable.engine.runtime.ProcessInstance;
|
import org.flowable.engine.runtime.ProcessInstance;
|
||||||
import org.flowable.task.api.DelegationState;
|
import org.flowable.task.api.DelegationState;
|
||||||
import org.flowable.task.api.Task;
|
import org.flowable.task.api.Task;
|
||||||
|
@ -1238,6 +1239,24 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void processDelayTimerTimeout(String processInstanceId, String taskDefineKey) {
|
||||||
|
Execution execution = runtimeService.createExecutionQuery()
|
||||||
|
.processInstanceId(processInstanceId)
|
||||||
|
.activityId(taskDefineKey)
|
||||||
|
.singleResult();
|
||||||
|
if (execution == null) {
|
||||||
|
log.error("[processDelayTimerTimeout][processInstanceId({})activityId({}) 没有找到执行活动]",
|
||||||
|
processInstanceId, taskDefineKey);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 若存在直接触发接收任务,执行后续节点
|
||||||
|
// TODO @芋艿 这里需要帮助看一下,我不懂为啥开启了租户后就一直报错:不存在租户编号
|
||||||
|
FlowableUtils.execute(execution.getTenantId(), () -> {
|
||||||
|
runtimeService.trigger(execution.getId());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获得自身的代理对象,解决 AOP 生效问题
|
* 获得自身的代理对象,解决 AOP 生效问题
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue