feat: Simple设计器-延时器
This commit is contained in:
parent
46c825cb6f
commit
4c8b83d46f
|
@ -13,7 +13,8 @@ import lombok.Getter;
|
|||
@AllArgsConstructor
|
||||
public enum BpmBoundaryEventType {
|
||||
|
||||
USER_TASK_TIMEOUT(1,"用户任务超时");
|
||||
USER_TASK_TIMEOUT(1,"用户任务超时"),
|
||||
DELAY_TIMER_TIMEOUT(2,"触发器超时");
|
||||
|
||||
private final Integer type;
|
||||
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 固定
|
||||
APPROVE_NODE(11, "审批人", "userTask"),
|
||||
COPY_NODE(12, "抄送人", "serviceTask"),
|
||||
DELAY_TIMER_NODE(13, "延迟器", "receiveTask"),
|
||||
|
||||
// 50 ~ 条件分支
|
||||
CONDITION_NODE(50, "条件", "sequenceFlow"), // 用于构建流转条件的表达式
|
||||
|
|
|
@ -208,5 +208,22 @@ public class BpmSimpleModelNodeVO {
|
|||
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 @芋艿:条件;建议可以固化的一些选项;然后有个表达式兜底;要支持
|
||||
}
|
||||
|
|
|
@ -98,15 +98,20 @@ public class BpmTaskEventListener extends AbstractFlowableEngineEventListener {
|
|||
String boundaryEventType = BpmnModelUtils.parseBoundaryEventExtensionElement(boundaryEvent,
|
||||
BpmnModelConstants.BOUNDARY_EVENT_TYPE);
|
||||
BpmBoundaryEventType bpmTimerBoundaryEventType = BpmBoundaryEventType.typeOf(NumberUtils.parseInt(boundaryEventType));
|
||||
if (ObjectUtil.notEqual(bpmTimerBoundaryEventType, BpmBoundaryEventType.USER_TASK_TIMEOUT)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. 处理超时
|
||||
String timeoutHandlerType = BpmnModelUtils.parseBoundaryEventExtensionElement(boundaryEvent,
|
||||
BpmnModelConstants.USER_TASK_TIMEOUT_HANDLER_TYPE);
|
||||
String taskKey = boundaryEvent.getAttachedToRefId();
|
||||
taskService.processTaskTimeout(event.getProcessInstanceId(), taskKey, NumberUtils.parseInt(timeoutHandlerType));
|
||||
// 2.1 用户任务超时处理
|
||||
if (ObjectUtil.equal(bpmTimerBoundaryEventType, BpmBoundaryEventType.USER_TASK_TIMEOUT)) {
|
||||
String timeoutHandlerType = BpmnModelUtils.parseBoundaryEventExtensionElement(boundaryEvent,
|
||||
BpmnModelConstants.USER_TASK_TIMEOUT_HANDLER_TYPE);
|
||||
String taskKey = boundaryEvent.getAttachedToRefId();
|
||||
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 {
|
||||
List<NodeConvert> converts = asList(new StartNodeConvert(), new EndNodeConvert(),
|
||||
new StartUserNodeConvert(), new ApproveNodeConvert(), new CopyNodeConvert(),
|
||||
new DelayTimerNodeConvert(),
|
||||
new ConditionBranchNodeConvert(), new ParallelBranchNodeConvert(), new InclusiveBranchNodeConvert());
|
||||
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) {
|
||||
return id + "_join";
|
||||
}
|
||||
|
|
|
@ -275,4 +275,11 @@ public interface BpmTaskService {
|
|||
*/
|
||||
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.TaskService;
|
||||
import org.flowable.engine.history.HistoricActivityInstance;
|
||||
import org.flowable.engine.runtime.Execution;
|
||||
import org.flowable.engine.runtime.ProcessInstance;
|
||||
import org.flowable.task.api.DelegationState;
|
||||
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 生效问题
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue