From d24583f44a6822eab9d097390950662dbbefac16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=96=AF=E7=8B=82=E7=9A=84=E7=8B=AE=E5=AD=90Li?= <15040126243@163.com> Date: Mon, 26 Oct 2026 17:46:02 +0800 Subject: [PATCH] =?UTF-8?q?fix=20=E4=BF=AE=E5=A4=8D=20=E5=AE=9A=E6=97=B6?= =?UTF-8?q?=E4=BA=8B=E4=BB=B6=E4=BB=BB=E5=8A=A1=20=E7=AB=8B=E5=8D=B3?= =?UTF-8?q?=E5=87=BA=E5=8F=91=20=E4=B8=8D=E5=A1=AB=E4=B8=9A=E5=8A=A1id=20?= =?UTF-8?q?=E7=94=9F=E6=88=90=E5=87=BA=E6=9D=A5=E7=9A=84id=E5=89=8D?= =?UTF-8?q?=E7=AB=AF=E6=97=A0=E6=B3=95=E8=A7=A3=E6=9E=90=E6=8A=A5=E9=94=99?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../demo/DemoTimerInspectHandler.java | 13 ++--- .../domain/bo/FlowTimerTriggerBo.java | 2 +- .../service/impl/TestLeaveServiceImpl.java | 23 +++++++-- .../demo/DemoTimerInspectHandlerTest.java | 48 +++++++++++++++++++ .../impl/TestLeaveServiceImplTest.java | 17 +++++++ 5 files changed, 92 insertions(+), 11 deletions(-) create mode 100644 ruoyi-modules/ruoyi-workflow/src/test/java/org/dromara/workflow/demo/DemoTimerInspectHandlerTest.java create mode 100644 ruoyi-modules/ruoyi-workflow/src/test/java/org/dromara/workflow/service/impl/TestLeaveServiceImplTest.java diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/demo/DemoTimerInspectHandler.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/demo/DemoTimerInspectHandler.java index 21736b777..c48ef173e 100644 --- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/demo/DemoTimerInspectHandler.java +++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/demo/DemoTimerInspectHandler.java @@ -1,5 +1,6 @@ package org.dromara.workflow.demo; +import com.baomidou.mybatisplus.core.toolkit.IdWorker; import lombok.extern.slf4j.Slf4j; import org.dromara.warm.flow.core.FlowEngine; import org.dromara.warm.flow.core.entity.EventWait; @@ -10,7 +11,7 @@ import org.dromara.workflow.common.ConditionalOnEnable; import org.springframework.stereotype.Component; /** - * 定时启动 + 业务绑定示例:每日 09:00 自动创建巡检工单,并以工单主键发起审批。 + * 定时启动示例:为流程实例提供可被业务页面解析的数字业务 ID。 * *

接入要点:实现 {@link EventTaskHandler} 后引擎内置默认处理器(EventRuntimeHandler) * 自动让位,本类成为全部事件的处理入口——非本演示流程的事件必须委托默认处理器, @@ -30,7 +31,7 @@ public class DemoTimerInspectHandler implements EventTaskHandler { /** * 演示流程编码:对应设计器发布的含「定时启动」节点的定义 */ - public static final String DEMO_FLOW_CODE = "demo_timer_inspect"; + public static final String DEMO_FLOW_CODE = "demo_timer_start"; /** * 引擎内置默认处理器:兜底所有非本演示流程的事件 @@ -43,11 +44,11 @@ public class DemoTimerInspectHandler implements EventTaskHandler { @Override public void handle(EventWait wait) { if (isInspectTimerStart(wait)) { - // 业务先行:创建巡检工单,以工单主键作为 businessId 发起审批 - long l = System.currentTimeMillis(); - FlowEngine.insService().startByTimer(String.valueOf(l), wait.getDefinitionId(), + // 这里应该使用业务的id demo使用自动生成id 需要用户自行替换 + String businessId = String.valueOf(IdWorker.getId()); + FlowEngine.insService().startByTimer(businessId, wait.getDefinitionId(), wait.getNodeCode(), null, null); - log.info("巡检工单 {} 已自动发起审批: businessId={}", l, l); + log.info("定时启动示例已自动发起审批: businessId={}", businessId); return; } // 非本流程的事件:委托默认处理器,保持定时启动与边界事件原生行为 diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/FlowTimerTriggerBo.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/FlowTimerTriggerBo.java index 7508afb1a..eb769eb21 100644 --- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/FlowTimerTriggerBo.java +++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/FlowTimerTriggerBo.java @@ -26,7 +26,7 @@ public class FlowTimerTriggerBo implements Serializable { private Long waitId; /** - * 业务主键,留空时按 M{waitId}_{时间戳} 自动生成 + * 业务主键,留空时生成数字雪花 ID */ private String businessId; diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/TestLeaveServiceImpl.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/TestLeaveServiceImpl.java index 2db6ef395..491b79ced 100644 --- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/TestLeaveServiceImpl.java +++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/TestLeaveServiceImpl.java @@ -229,10 +229,13 @@ public class TestLeaveServiceImpl implements ITestLeaveService { @EventListener(condition = "#processEvent.flowCode.startsWith('demo')") public void processHandler(ProcessEvent processEvent) { log.info("当前任务执行了{}", processEvent.toString()); - TestLeave testLeave = leaveMapper.selectById(Convert.toLong(processEvent.getBusinessId())); + Long leaveId = parseLeaveId(processEvent.getBusinessId()); + if (leaveId == null) { + return; + } + TestLeave testLeave = leaveMapper.selectById(leaveId); if (ObjectUtil.isNull(testLeave)) { - // 定时启动 / 消息启动的流程带的是引擎自造 businessId(如 T2112..._1760...), - // 不是请假表主键,回写无从谈起;这里直接跳过,避免示例监听被无关流程的事件打爆。 + // 其他演示流程没有对应的请假记录。 return; } testLeave.setStatus(processEvent.getStatus()); @@ -284,11 +287,23 @@ public class TestLeaveServiceImpl implements ITestLeaveService { @EventListener(condition = "#processDeleteEvent.flowCode.startsWith('demo')") public void processDeleteHandler(ProcessDeleteEvent processDeleteEvent) { log.info("监听删除流程事件,当前任务执行了{}", processDeleteEvent.toString()); - TestLeave testLeave = leaveMapper.selectById(Convert.toLong(processDeleteEvent.getBusinessId())); + Long leaveId = parseLeaveId(processDeleteEvent.getBusinessId()); + if (leaveId == null) { + return; + } + TestLeave testLeave = leaveMapper.selectById(leaveId); if (ObjectUtil.isNull(testLeave)) { return; } leaveMapper.deleteById(testLeave.getId()); } + static Long parseLeaveId(String businessId) { + try { + return Long.valueOf(businessId); + } catch (NumberFormatException e) { + return null; + } + } + } diff --git a/ruoyi-modules/ruoyi-workflow/src/test/java/org/dromara/workflow/demo/DemoTimerInspectHandlerTest.java b/ruoyi-modules/ruoyi-workflow/src/test/java/org/dromara/workflow/demo/DemoTimerInspectHandlerTest.java new file mode 100644 index 000000000..ec1408851 --- /dev/null +++ b/ruoyi-modules/ruoyi-workflow/src/test/java/org/dromara/workflow/demo/DemoTimerInspectHandlerTest.java @@ -0,0 +1,48 @@ +package org.dromara.workflow.demo; + +import org.dromara.warm.flow.core.FlowEngine; +import org.dromara.warm.flow.core.entity.Definition; +import org.dromara.warm.flow.core.entity.EventWait; +import org.dromara.warm.flow.core.enums.EventType; +import org.dromara.warm.flow.core.service.DefService; +import org.dromara.warm.flow.core.service.InsService; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.MockedStatic; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.isNull; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.mockStatic; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +class DemoTimerInspectHandlerTest { + + @Test + void timerStartUsesNumericBusinessId() { + EventWait wait = mock(EventWait.class); + when(wait.getEventType()).thenReturn(EventType.TIMER_START.getValue()); + when(wait.getDefinitionId()).thenReturn(12L); + when(wait.getNodeCode()).thenReturn("timerStart"); + Definition definition = mock(Definition.class); + when(definition.getFlowCode()).thenReturn("demo_timer_start"); + DefService defService = mock(DefService.class); + when(defService.getById(12L)).thenReturn(definition); + InsService insService = mock(InsService.class); + + try (MockedStatic engine = mockStatic(FlowEngine.class)) { + engine.when(FlowEngine::defService).thenReturn(defService); + engine.when(FlowEngine::insService).thenReturn(insService); + + assertDoesNotThrow(() -> new DemoTimerInspectHandler().handle(wait)); + + ArgumentCaptor businessId = ArgumentCaptor.forClass(String.class); + verify(insService).startByTimer(businessId.capture(), eq(12L), eq("timerStart"), isNull(), isNull()); + assertTrue(businessId.getValue().matches("[0-9]+")); + assertTrue(Long.parseLong(businessId.getValue()) > 0); + } + } +} diff --git a/ruoyi-modules/ruoyi-workflow/src/test/java/org/dromara/workflow/service/impl/TestLeaveServiceImplTest.java b/ruoyi-modules/ruoyi-workflow/src/test/java/org/dromara/workflow/service/impl/TestLeaveServiceImplTest.java new file mode 100644 index 000000000..5a44d8fac --- /dev/null +++ b/ruoyi-modules/ruoyi-workflow/src/test/java/org/dromara/workflow/service/impl/TestLeaveServiceImplTest.java @@ -0,0 +1,17 @@ +package org.dromara.workflow.service.impl; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; + +class TestLeaveServiceImplTest { + + @Test + void ignoresEngineGeneratedBusinessIds() { + assertNull(TestLeaveServiceImpl.parseLeaveId("T2114648233624309762_1793006432000")); + assertNull(TestLeaveServiceImpl.parseLeaveId("9223372036854775808")); + assertNull(TestLeaveServiceImpl.parseLeaveId(null)); + assertEquals(123L, TestLeaveServiceImpl.parseLeaveId("123")); + } +}