From 59bd76a250951effff4d76147e8d03a6aba12969 Mon Sep 17 00:00:00 2001
From: new_new_new <8454518+new-twice@user.noreply.gitee.com>
Date: Wed, 10 Jun 2026 08:30:47 +0000
Subject: [PATCH] !39 Merge branch 'master' into feature/20260610
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Merge branch 'master' into feature/20260610
* fix(dqinspecttask): updateMain 子表数据仅在显式传入时才变更
* chore(system): 删除 xiSpeakFlow Bean 调试打印语句
* test(inspectimprove): 新增 inspectimprove 流程模块单元测试
---
jeecg-boot-module/jeecg-module-flow/pom.xml | 12 +
.../InspectImproveFlowTest.java | 390 ++++++++++++++++++
.../AfterDqLeaderApproveListenerTest.java | 41 ++
...fterImplDeptLeaderApproveListenerTest.java | 40 ++
...terInspectImproveCompleteListenerTest.java | 77 ++++
...fterMeasureResLeaderStoreListenerTest.java | 110 +++++
.../listener/LeaderApproveHelperTest.java | 62 +++
.../impl/DqInspectTaskServiceImpl.java | 19 +-
.../org/jeecg/JeecgSystemApplication.java | 4 -
9 files changed, 741 insertions(+), 14 deletions(-)
create mode 100644 jeecg-boot-module/jeecg-module-flow/src/test/java/org/jeecg/inspectimprove/InspectImproveFlowTest.java
create mode 100644 jeecg-boot-module/jeecg-module-flow/src/test/java/org/jeecg/inspectimprove/listener/AfterDqLeaderApproveListenerTest.java
create mode 100644 jeecg-boot-module/jeecg-module-flow/src/test/java/org/jeecg/inspectimprove/listener/AfterImplDeptLeaderApproveListenerTest.java
create mode 100644 jeecg-boot-module/jeecg-module-flow/src/test/java/org/jeecg/inspectimprove/listener/AfterInspectImproveCompleteListenerTest.java
create mode 100644 jeecg-boot-module/jeecg-module-flow/src/test/java/org/jeecg/inspectimprove/listener/AfterMeasureResLeaderStoreListenerTest.java
create mode 100644 jeecg-boot-module/jeecg-module-flow/src/test/java/org/jeecg/inspectimprove/listener/LeaderApproveHelperTest.java
diff --git a/jeecg-boot-module/jeecg-module-flow/pom.xml b/jeecg-boot-module/jeecg-module-flow/pom.xml
index 4512356..c7725bd 100644
--- a/jeecg-boot-module/jeecg-module-flow/pom.xml
+++ b/jeecg-boot-module/jeecg-module-flow/pom.xml
@@ -17,6 +17,18 @@
UTF-8
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+ false
+
+
+
+
+
org.jeecgframework.boot
diff --git a/jeecg-boot-module/jeecg-module-flow/src/test/java/org/jeecg/inspectimprove/InspectImproveFlowTest.java b/jeecg-boot-module/jeecg-module-flow/src/test/java/org/jeecg/inspectimprove/InspectImproveFlowTest.java
new file mode 100644
index 0000000..975f5a4
--- /dev/null
+++ b/jeecg-boot-module/jeecg-module-flow/src/test/java/org/jeecg/inspectimprove/InspectImproveFlowTest.java
@@ -0,0 +1,390 @@
+package org.jeecg.inspectimprove;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.Mockito.*;
+
+import com.alibaba.fastjson.JSONObject;
+import com.jeecg.weibo.exception.BusinessException;
+import org.flowable.engine.RuntimeService;
+import org.flowable.engine.delegate.DelegateExecution;
+import org.jeecg.common.system.api.ISysBaseAPI;
+import org.jeecg.inspectimprove.InspectImproveConfig.InspectImproveProperties;
+import org.jeecg.modules.demo.dqinspecttask.entity.DqInspectTask;
+import org.jeecg.modules.demo.dqinspecttask.service.IDqInspectTaskService;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import java.util.Collections;
+import java.util.List;
+
+@ExtendWith(MockitoExtension.class)
+class InspectImproveFlowTest {
+
+ @Mock
+ private InspectImproveConfig inspectImproveConfig;
+
+ @Mock
+ private ISysBaseAPI iSysBaseAPI;
+
+ @Mock
+ private IDqInspectTaskService dqInspectTaskService;
+
+ @Mock
+ private RuntimeService runtimeService;
+
+ @Mock
+ private DelegateExecution execution;
+
+ private InspectImproveFlow flow;
+ private InspectImproveProperties props;
+
+ @BeforeEach
+ void setUp() {
+ props = new InspectImproveProperties();
+ props.setBusinessKey("businessKey");
+ props.setDqDeptId("dept-001");
+ props.setLdRoleId("role-001");
+ props.setMeasureResLeaderKey("measureResLeader");
+ props.setMeasureResDeptKey("measureResDept");
+ props.setQuestionResLeaderKey("questionResLeader");
+ props.setQuestionResDeptKey("questionResDept");
+ lenient().when(inspectImproveConfig.getInspectImprove()).thenReturn(props);
+
+ // IDjInspectImproveService, FlowNodeExpression, XiSpeakConfig 未使用,传 null
+ flow = new InspectImproveFlow(inspectImproveConfig, null, null, null,
+ iSysBaseAPI, dqInspectTaskService, runtimeService);
+ }
+
+ /** 为需要 DqInspectTask 的方法设置通用 mock */
+ private void mockExecutionBusinessKey(String businessKey) {
+ when(execution.getVariable("businessKey")).thenReturn(businessKey);
+ }
+
+ private DqInspectTask mockTaskFound(String id) {
+ DqInspectTask task = new DqInspectTask();
+ task.setId(id);
+ when(dqInspectTaskService.getById(id)).thenReturn(task);
+ return task;
+ }
+
+ // ==================== 读取流程变量 ====================
+
+ @Nested
+ class ProcessVariableReaders {
+
+ @Test
+ void getIsEnd_shouldReturnValue() {
+ when(execution.getProcessInstanceId()).thenReturn("pi-001");
+ when(runtimeService.getVariable("pi-001", InspectConstant.IS_END_KEY)).thenReturn("true");
+
+ assertEquals("true", flow.getIsEnd(execution));
+ }
+
+ @Test
+ void getIsEnd_shouldReturnNullWhenNotSet() {
+ when(execution.getProcessInstanceId()).thenReturn("pi-001");
+ when(runtimeService.getVariable("pi-001", InspectConstant.IS_END_KEY)).thenReturn(null);
+
+ assertNull(flow.getIsEnd(execution));
+ }
+
+ @Test
+ void getDqDeptLeader_shouldReturnStoredValue() {
+ when(execution.getProcessInstanceId()).thenReturn("pi-001");
+ when(runtimeService.getVariable("pi-001", InspectConstant.DQ_DEPT_LEADER_KEY)).thenReturn("user1");
+
+ assertEquals("user1", flow.getDqDeptLeader(execution));
+ }
+
+ @Test
+ void getImplDeptLeader_shouldReturnStoredValue() {
+ when(execution.getProcessInstanceId()).thenReturn("pi-001");
+ when(runtimeService.getVariable("pi-001", InspectConstant.IMPL_DEPT_LEADER_KEY)).thenReturn("user2");
+
+ assertEquals("user2", flow.getImplDeptLeader(execution));
+ }
+
+ @Test
+ void getSubApproveUser_shouldReturnStoredValue() {
+ when(execution.getProcessInstanceId()).thenReturn("pi-001");
+ when(runtimeService.getVariable("pi-001", InspectConstant.SUB_APPROVE_USER_KEY)).thenReturn("user3");
+
+ assertEquals("user3", flow.getSubApproveUser(execution));
+ }
+ }
+
+ // ==================== DqInspectTask 字段读取 ====================
+
+ @Nested
+ class TaskFieldReaders {
+
+ @Test
+ void getNeedDqLeaderApprove_shouldReturnNeedApprove() {
+ mockExecutionBusinessKey("biz-001");
+ DqInspectTask task = mockTaskFound("biz-001");
+ task.setIsNeedAppro(InspectConstant.NEED_APPROVE_STR);
+
+ assertEquals(InspectConstant.NEED_APPROVE_STR, flow.getNeedDqLeaderApprove(execution));
+ }
+
+ @Test
+ void getNeedDqLeaderApprove_shouldReturnNotNeedWhenBlank() {
+ mockExecutionBusinessKey("biz-001");
+ DqInspectTask task = mockTaskFound("biz-001");
+ task.setIsNeedAppro("");
+
+ assertEquals(InspectConstant.NOT_NEED_APPROVE_STR, flow.getNeedDqLeaderApprove(execution));
+ }
+
+ @Test
+ void getNeedDqLeaderApprove_shouldReturnNotNeedWhenNull() {
+ mockExecutionBusinessKey("biz-001");
+ DqInspectTask task = mockTaskFound("biz-001");
+ task.setIsNeedAppro(null);
+
+ assertEquals(InspectConstant.NOT_NEED_APPROVE_STR, flow.getNeedDqLeaderApprove(execution));
+ }
+
+ @Test
+ void getNeedDqLeaderApprove_shouldThrowWhenTaskNotFound() {
+ mockExecutionBusinessKey("biz-001");
+ when(dqInspectTaskService.getById("biz-001")).thenReturn(null);
+
+ assertThrows(IllegalStateException.class, () -> flow.getNeedDqLeaderApprove(execution));
+ }
+
+ @Test
+ void getMeasureResLeader_shouldReturnLeaderName() {
+ mockExecutionBusinessKey("biz-001");
+ DqInspectTask task = mockTaskFound("biz-001");
+ task.setMeasureResLeader("leader1");
+
+ assertEquals("leader1", flow.getMeasureResLeader(execution));
+ }
+
+ @Test
+ void getMeasureResLeader_shouldReturnNullWhenBlank() {
+ mockExecutionBusinessKey("biz-001");
+ DqInspectTask task = mockTaskFound("biz-001");
+ task.setMeasureResLeader("");
+
+ assertNull(flow.getMeasureResLeader(execution));
+ }
+
+ @Test
+ void getSLD_shouldReturnChargeLeaderId() {
+ mockExecutionBusinessKey("biz-001");
+ DqInspectTask task = mockTaskFound("biz-001");
+ task.setChargeLeaderId("sld_user");
+
+ assertEquals("sld_user", flow.getSLD(execution));
+ }
+
+ @Test
+ void getSLD_shouldReturnNullWhenBlank() {
+ mockExecutionBusinessKey("biz-001");
+ DqInspectTask task = mockTaskFound("biz-001");
+ task.setChargeLeaderId("");
+
+ assertNull(flow.getSLD(execution));
+ }
+
+ @Test
+ void getDqLeader_shouldReturnSupDeptLeader() {
+ mockExecutionBusinessKey("biz-001");
+ DqInspectTask task = mockTaskFound("biz-001");
+ task.setSupDeptleaderid("dq_leader");
+
+ assertEquals("dq_leader", flow.getDqLeader(execution));
+ }
+ }
+
+ // ==================== ISysBaseAPI 用户查询 ====================
+
+ @Nested
+ class UserQueryMethods {
+
+ @Test
+ void getDqDeptLdUserIdList_shouldReturnUserList() {
+ List users = List.of("user1", "user2");
+ when(iSysBaseAPI.getUsersListByDeptIdAndRoleIdLocalApi("dept-001", "role-001"))
+ .thenReturn(users);
+
+ assertEquals(users, flow.getDqDeptLdUserIdList());
+ }
+
+ @Test
+ void getDqDeptLdUserIdList_shouldReturnEmptyWhenPropsIsNull() {
+ when(inspectImproveConfig.getInspectImprove()).thenReturn(null);
+
+ assertEquals(Collections.emptyList(), flow.getDqDeptLdUserIdList());
+ }
+
+ @Test
+ void getDqDeptLdUserIdListLength_shouldReturnCount() {
+ when(iSysBaseAPI.getUsersListByDeptIdAndRoleIdLocalApi("dept-001", "role-001"))
+ .thenReturn(List.of("user1", "user2"));
+
+ assertEquals(2, flow.getDqDeptLdUserIdListLength());
+ }
+
+ @Test
+ void getSDWSJ_shouldReturnUniqueUser() {
+ when(iSysBaseAPI.getUsersListByDeptIdAndRoleIdLocalApi(
+ InspectConstant.SLD_DEPT_ID, InspectConstant.SDWSJ_ROLE_ID))
+ .thenReturn(List.of("party_secretary"));
+
+ assertEquals("party_secretary", flow.getSDWSJ());
+ }
+
+ @Test
+ void getSDWSJ_shouldThrowWhenEmpty() {
+ when(iSysBaseAPI.getUsersListByDeptIdAndRoleIdLocalApi(
+ InspectConstant.SLD_DEPT_ID, InspectConstant.SDWSJ_ROLE_ID))
+ .thenReturn(Collections.emptyList());
+
+ assertThrows(BusinessException.class, () -> flow.getSDWSJ());
+ }
+
+ @Test
+ void getSDWSJ_shouldThrowWhenMultipleUsers() {
+ when(iSysBaseAPI.getUsersListByDeptIdAndRoleIdLocalApi(
+ InspectConstant.SLD_DEPT_ID, InspectConstant.SDWSJ_ROLE_ID))
+ .thenReturn(List.of("user1", "user2"));
+
+ assertThrows(BusinessException.class, () -> flow.getSDWSJ());
+ }
+ }
+
+ // ==================== 部门领导列表查询(需要 DqInspectTask) ====================
+
+ @Nested
+ class ImplDeptLeaderMethods {
+
+ @Test
+ void getImplDeptLeaderList_shouldReturnLeaders() {
+ mockExecutionBusinessKey("biz-001");
+ DqInspectTask task = mockTaskFound("biz-001");
+ task.setMeasureResDept("dept-100");
+
+ List leaders = List.of("leader1");
+ when(iSysBaseAPI.getUsersListByDeptIdAndRoleIdLocalApi("dept-100", "role-001"))
+ .thenReturn(leaders);
+
+ assertEquals(leaders, flow.getImplDeptLeaderList(execution));
+ }
+
+ @Test
+ void getImplDeptLeaderList_shouldThrowWhenMeasureResDeptBlank() {
+ mockExecutionBusinessKey("biz-001");
+ DqInspectTask task = mockTaskFound("biz-001");
+ task.setMeasureResDept("");
+
+ assertThrows(IllegalStateException.class, () -> flow.getImplDeptLeaderList(execution));
+ }
+
+ @Test
+ void getImplDeptLeaderListLength_shouldReturnCount() {
+ mockExecutionBusinessKey("biz-001");
+ DqInspectTask task = mockTaskFound("biz-001");
+ task.setMeasureResDept("dept-100");
+
+ when(iSysBaseAPI.getUsersListByDeptIdAndRoleIdLocalApi("dept-100", "role-001"))
+ .thenReturn(List.of("leader1", "leader2"));
+
+ assertEquals(2, flow.getImplDeptLeaderListLength(execution));
+ }
+ }
+
+ // ==================== JSON 数据解析 ====================
+
+ @Nested
+ class JsonParsingMethods {
+
+ @Test
+ void getMeasureResLeaderList_shouldParseCommaSeparated() {
+ JSONObject json = new JSONObject();
+ json.put("measureResLeader", "user1,user2,user3");
+
+ List result = flow.getMeasureResLeaderList(json);
+
+ assertEquals(3, result.size());
+ assertTrue(result.contains("user1"));
+ assertTrue(result.contains("user2"));
+ assertTrue(result.contains("user3"));
+ }
+
+ @Test
+ void getMeasureResLeaderList_shouldHandleJsonString() {
+ String jsonStr = "{\"measureResLeader\":\"user1,user2\"}";
+
+ List result = flow.getMeasureResLeaderList(jsonStr);
+
+ assertEquals(2, result.size());
+ }
+
+ @Test
+ void getMeasureResLeaderList_shouldReturnEmptyWhenFieldMissing() {
+ JSONObject json = new JSONObject();
+
+ List result = flow.getMeasureResLeaderList(json);
+
+ assertTrue(result.isEmpty());
+ }
+
+ @Test
+ void getMeasureResLeaderListLength_shouldReturnCount() {
+ JSONObject json = new JSONObject();
+ json.put("measureResLeader", "user1,user2,user3");
+
+ assertEquals(3, flow.getMeasureResLeaderListLength(json));
+ }
+
+ @Test
+ void getQuestionResLeaderList_shouldParse() {
+ JSONObject json = new JSONObject();
+ json.put("questionResLeader", "leader1,leader2");
+
+ List result = flow.getQuestionResLeaderList(json);
+
+ assertEquals(2, result.size());
+ }
+
+ @Test
+ void getMeasureResDeptList_shouldParse() {
+ JSONObject json = new JSONObject();
+ json.put("measureResDept", "dept1,dept2");
+
+ List result = flow.getMeasureResDeptList(json);
+
+ assertEquals(2, result.size());
+ }
+
+ @Test
+ void getMeasureResLeader_singleValue_shouldReturnString() {
+ JSONObject json = new JSONObject();
+ json.put("measureResLeader", "singleLeader");
+
+ assertEquals("singleLeader", flow.getMeasureResLeader(json));
+ }
+
+ @Test
+ void getMeasureResLeader_singleValue_shouldReturnNullWhenMissing() {
+ JSONObject json = new JSONObject();
+
+ assertNull(flow.getMeasureResLeader(json));
+ }
+
+ @Test
+ void getListSize_shouldCountCommaSeparated() {
+ assertEquals(3, flow.getListSize("a,b,c"));
+ assertEquals(1, flow.getListSize("single"));
+ assertEquals(0, flow.getListSize(""));
+ assertEquals(0, flow.getListSize(null));
+ }
+ }
+}
diff --git a/jeecg-boot-module/jeecg-module-flow/src/test/java/org/jeecg/inspectimprove/listener/AfterDqLeaderApproveListenerTest.java b/jeecg-boot-module/jeecg-module-flow/src/test/java/org/jeecg/inspectimprove/listener/AfterDqLeaderApproveListenerTest.java
new file mode 100644
index 0000000..1a08a03
--- /dev/null
+++ b/jeecg-boot-module/jeecg-module-flow/src/test/java/org/jeecg/inspectimprove/listener/AfterDqLeaderApproveListenerTest.java
@@ -0,0 +1,41 @@
+package org.jeecg.inspectimprove.listener;
+
+import static org.mockito.Mockito.*;
+
+import org.flowable.engine.RuntimeService;
+import org.flowable.task.service.delegate.DelegateTask;
+import org.jeecg.inspectimprove.InspectConstant;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+@ExtendWith(MockitoExtension.class)
+class AfterDqLeaderApproveListenerTest {
+
+ @Mock
+ private RuntimeService runtimeService;
+
+ @Mock
+ private DelegateTask delegateTask;
+
+ @Test
+ void shouldWriteDqDeptLeaderToProcessVariable() {
+ when(delegateTask.getAssignee()).thenReturn("zhangsan");
+ when(delegateTask.getProcessInstanceId()).thenReturn("proc-001");
+
+ // inspectImproveConfig and djInspectImproveService 在此监听器中未使用,传 null
+ new AfterDqLeaderApproveListener(null, null, runtimeService).notify(delegateTask);
+
+ verify(runtimeService).setVariable("proc-001", InspectConstant.DQ_DEPT_LEADER_KEY, "zhangsan");
+ }
+
+ @Test
+ void shouldSkipWhenAssigneeIsNull() {
+ when(delegateTask.getAssignee()).thenReturn(null);
+
+ new AfterDqLeaderApproveListener(null, null, runtimeService).notify(delegateTask);
+
+ verify(runtimeService, never()).setVariable(any(), any(), any());
+ }
+}
diff --git a/jeecg-boot-module/jeecg-module-flow/src/test/java/org/jeecg/inspectimprove/listener/AfterImplDeptLeaderApproveListenerTest.java b/jeecg-boot-module/jeecg-module-flow/src/test/java/org/jeecg/inspectimprove/listener/AfterImplDeptLeaderApproveListenerTest.java
new file mode 100644
index 0000000..104fd84
--- /dev/null
+++ b/jeecg-boot-module/jeecg-module-flow/src/test/java/org/jeecg/inspectimprove/listener/AfterImplDeptLeaderApproveListenerTest.java
@@ -0,0 +1,40 @@
+package org.jeecg.inspectimprove.listener;
+
+import static org.mockito.Mockito.*;
+
+import org.flowable.engine.RuntimeService;
+import org.flowable.task.service.delegate.DelegateTask;
+import org.jeecg.inspectimprove.InspectConstant;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+@ExtendWith(MockitoExtension.class)
+class AfterImplDeptLeaderApproveListenerTest {
+
+ @Mock
+ private RuntimeService runtimeService;
+
+ @Mock
+ private DelegateTask delegateTask;
+
+ @Test
+ void shouldWriteImplDeptLeaderToProcessVariable() {
+ when(delegateTask.getAssignee()).thenReturn("lisi");
+ when(delegateTask.getProcessInstanceId()).thenReturn("proc-002");
+
+ new AfterImplDeptLeaderApproveListener(null, null, runtimeService).notify(delegateTask);
+
+ verify(runtimeService).setVariable("proc-002", InspectConstant.IMPL_DEPT_LEADER_KEY, "lisi");
+ }
+
+ @Test
+ void shouldSkipWhenAssigneeIsNull() {
+ when(delegateTask.getAssignee()).thenReturn(null);
+
+ new AfterImplDeptLeaderApproveListener(null, null, runtimeService).notify(delegateTask);
+
+ verify(runtimeService, never()).setVariable(any(), any(), any());
+ }
+}
diff --git a/jeecg-boot-module/jeecg-module-flow/src/test/java/org/jeecg/inspectimprove/listener/AfterInspectImproveCompleteListenerTest.java b/jeecg-boot-module/jeecg-module-flow/src/test/java/org/jeecg/inspectimprove/listener/AfterInspectImproveCompleteListenerTest.java
new file mode 100644
index 0000000..03fcadc
--- /dev/null
+++ b/jeecg-boot-module/jeecg-module-flow/src/test/java/org/jeecg/inspectimprove/listener/AfterInspectImproveCompleteListenerTest.java
@@ -0,0 +1,77 @@
+package org.jeecg.inspectimprove.listener;
+
+import static org.mockito.Mockito.*;
+
+import org.flowable.task.service.delegate.DelegateTask;
+import org.jeecg.inspectimprove.InspectImproveConfig;
+import org.jeecg.inspectimprove.InspectImproveConfig.InspectImproveProperties;
+import org.jeecg.modules.dj.inspectimprove.entity.DjInspectImprove;
+import org.jeecg.modules.dj.inspectimprove.service.IDjInspectImproveService;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+@ExtendWith(MockitoExtension.class)
+class AfterInspectImproveCompleteListenerTest {
+
+ @Mock
+ private InspectImproveConfig inspectImproveConfig;
+
+ @Mock
+ private IDjInspectImproveService djInspectImproveService;
+
+ @Mock
+ private DelegateTask delegateTask;
+
+ private AfterInspectImproveCompleteListener listener;
+
+ @BeforeEach
+ void setUp() {
+ InspectImproveProperties props = new InspectImproveProperties();
+ props.setBusinessKey("businessKey");
+ when(inspectImproveConfig.getInspectImprove()).thenReturn(props);
+
+ listener = new AfterInspectImproveCompleteListener(inspectImproveConfig, djInspectImproveService);
+ }
+
+ @Test
+ void shouldSkipWhenBusinessKeyIsNull() {
+ when(delegateTask.getVariable("businessKey")).thenReturn(null);
+
+ listener.notify(delegateTask);
+
+ verify(djInspectImproveService, never()).getById(any());
+ }
+
+ @Test
+ void shouldSkipWhenBusinessKeyIsEmpty() {
+ when(delegateTask.getVariable("businessKey")).thenReturn("");
+
+ listener.notify(delegateTask);
+
+ verify(djInspectImproveService, never()).getById(any());
+ }
+
+ @Test
+ void shouldSkipWhenEntityNotFound() {
+ when(delegateTask.getVariable("businessKey")).thenReturn("biz-001");
+ when(djInspectImproveService.getById("biz-001")).thenReturn(null);
+
+ listener.notify(delegateTask);
+
+ verify(djInspectImproveService).getById("biz-001");
+ }
+
+ @Test
+ void shouldNotThrowWhenEntityExists() {
+ when(delegateTask.getVariable("businessKey")).thenReturn("biz-001");
+ when(djInspectImproveService.getById("biz-001")).thenReturn(new DjInspectImprove());
+
+ // 当前实现仅有 TODO,不应抛异常
+ listener.notify(delegateTask);
+
+ verify(djInspectImproveService).getById("biz-001");
+ }
+}
diff --git a/jeecg-boot-module/jeecg-module-flow/src/test/java/org/jeecg/inspectimprove/listener/AfterMeasureResLeaderStoreListenerTest.java b/jeecg-boot-module/jeecg-module-flow/src/test/java/org/jeecg/inspectimprove/listener/AfterMeasureResLeaderStoreListenerTest.java
new file mode 100644
index 0000000..cbd219a
--- /dev/null
+++ b/jeecg-boot-module/jeecg-module-flow/src/test/java/org/jeecg/inspectimprove/listener/AfterMeasureResLeaderStoreListenerTest.java
@@ -0,0 +1,110 @@
+package org.jeecg.inspectimprove.listener;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.Mockito.*;
+
+import org.flowable.task.service.delegate.DelegateTask;
+import org.jeecg.inspectimprove.InspectImproveConfig;
+import org.jeecg.inspectimprove.InspectImproveConfig.InspectImproveProperties;
+import org.jeecg.modules.demo.dqinspecttask.entity.DqInspectTask;
+import org.jeecg.modules.demo.dqinspecttask.service.IDqInspectTaskService;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import static org.mockito.Mockito.lenient;
+
+@ExtendWith(MockitoExtension.class)
+class AfterMeasureResLeaderStoreListenerTest {
+
+ @Mock
+ private InspectImproveConfig inspectImproveConfig;
+
+ @Mock
+ private IDqInspectTaskService dqInspectTaskService;
+
+ @Mock
+ private DelegateTask delegateTask;
+
+ private AfterMeasureResLeaderStoreListener listener;
+
+ @BeforeEach
+ void setUp() {
+ InspectImproveProperties props = new InspectImproveProperties();
+ props.setBusinessKey("businessKey");
+ lenient().when(inspectImproveConfig.getInspectImprove()).thenReturn(props);
+
+ listener = new AfterMeasureResLeaderStoreListener(inspectImproveConfig, dqInspectTaskService);
+ }
+
+ @Test
+ void shouldSkipWhenAssigneeIsNull() {
+ when(delegateTask.getAssignee()).thenReturn(null);
+
+ listener.notify(delegateTask);
+
+ verify(dqInspectTaskService, never()).getById(any());
+ verify(dqInspectTaskService, never()).updateById(any());
+ }
+
+ @Test
+ void shouldSkipWhenAssigneeIsEmpty() {
+ when(delegateTask.getAssignee()).thenReturn("");
+
+ listener.notify(delegateTask);
+
+ verify(dqInspectTaskService, never()).getById(any());
+ }
+
+ @Test
+ void shouldSkipWhenBusinessKeyIsNull() {
+ when(delegateTask.getAssignee()).thenReturn("zhangsan");
+ when(delegateTask.getVariable("businessKey")).thenReturn(null);
+
+ listener.notify(delegateTask);
+
+ verify(dqInspectTaskService, never()).getById(any());
+ }
+
+ @Test
+ void shouldSkipWhenBusinessKeyIsBlank() {
+ when(delegateTask.getAssignee()).thenReturn("zhangsan");
+ when(delegateTask.getVariable("businessKey")).thenReturn(" ");
+
+ listener.notify(delegateTask);
+
+ verify(dqInspectTaskService, never()).getById(any());
+ }
+
+ @Test
+ void shouldSkipWhenEntityNotFound() {
+ when(delegateTask.getAssignee()).thenReturn("zhangsan");
+ when(delegateTask.getVariable("businessKey")).thenReturn("biz-001");
+ when(dqInspectTaskService.getById("biz-001")).thenReturn(null);
+
+ listener.notify(delegateTask);
+
+ verify(dqInspectTaskService).getById("biz-001");
+ verify(dqInspectTaskService, never()).updateById(any());
+ }
+
+ @Test
+ void shouldUpdateEntityWithAssignee() {
+ when(delegateTask.getAssignee()).thenReturn("zhangsan");
+ when(delegateTask.getId()).thenReturn("task-001");
+ when(delegateTask.getVariable("businessKey")).thenReturn("biz-001");
+
+ DqInspectTask task = new DqInspectTask();
+ task.setId("biz-001");
+ when(dqInspectTaskService.getById("biz-001")).thenReturn(task);
+
+ listener.notify(delegateTask);
+
+ ArgumentCaptor captor = ArgumentCaptor.forClass(DqInspectTask.class);
+ verify(dqInspectTaskService).updateById(captor.capture());
+ assertEquals("zhangsan", captor.getValue().getMeasureResLeader());
+ }
+}
diff --git a/jeecg-boot-module/jeecg-module-flow/src/test/java/org/jeecg/inspectimprove/listener/LeaderApproveHelperTest.java b/jeecg-boot-module/jeecg-module-flow/src/test/java/org/jeecg/inspectimprove/listener/LeaderApproveHelperTest.java
new file mode 100644
index 0000000..e285b7e
--- /dev/null
+++ b/jeecg-boot-module/jeecg-module-flow/src/test/java/org/jeecg/inspectimprove/listener/LeaderApproveHelperTest.java
@@ -0,0 +1,62 @@
+package org.jeecg.inspectimprove.listener;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.Mockito.*;
+
+import org.flowable.engine.RuntimeService;
+import org.flowable.task.service.delegate.DelegateTask;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+@ExtendWith(MockitoExtension.class)
+class LeaderApproveHelperTest {
+
+ @Mock
+ private DelegateTask delegateTask;
+
+ @Mock
+ private RuntimeService runtimeService;
+
+ private static final String VAR_KEY = "test_var";
+ private static final String LOG_PREFIX = "【测试】";
+
+ @Test
+ void shouldSetVariableWhenAssigneeExists() {
+ when(delegateTask.getAssignee()).thenReturn("zhangsan");
+ when(delegateTask.getProcessInstanceId()).thenReturn("proc-001");
+
+ LeaderApproveHelper.handle(delegateTask, runtimeService, VAR_KEY, LOG_PREFIX);
+
+ verify(runtimeService).setVariable("proc-001", VAR_KEY, "zhangsan");
+ }
+
+ @Test
+ void shouldNotSetVariableWhenAssigneeIsNull() {
+ when(delegateTask.getAssignee()).thenReturn(null);
+
+ LeaderApproveHelper.handle(delegateTask, runtimeService, VAR_KEY, LOG_PREFIX);
+
+ verify(runtimeService, never()).setVariable(any(), any(), any());
+ }
+
+ @Test
+ void shouldNotSetVariableWhenAssigneeIsEmpty() {
+ when(delegateTask.getAssignee()).thenReturn("");
+
+ LeaderApproveHelper.handle(delegateTask, runtimeService, VAR_KEY, LOG_PREFIX);
+
+ verify(runtimeService, never()).setVariable(any(), any(), any());
+ }
+
+ @Test
+ void shouldUseCorrectProcessInstanceId() {
+ when(delegateTask.getAssignee()).thenReturn("lisi");
+ when(delegateTask.getProcessInstanceId()).thenReturn("proc-999");
+
+ LeaderApproveHelper.handle(delegateTask, runtimeService, VAR_KEY, LOG_PREFIX);
+
+ verify(runtimeService).setVariable("proc-999", VAR_KEY, "lisi");
+ }
+}
diff --git a/jeecg-module-supervision/src/main/java/org/jeecg/modules/demo/dqinspecttask/service/impl/DqInspectTaskServiceImpl.java b/jeecg-module-supervision/src/main/java/org/jeecg/modules/demo/dqinspecttask/service/impl/DqInspectTaskServiceImpl.java
index 5340aea..3173cfc 100644
--- a/jeecg-module-supervision/src/main/java/org/jeecg/modules/demo/dqinspecttask/service/impl/DqInspectTaskServiceImpl.java
+++ b/jeecg-module-supervision/src/main/java/org/jeecg/modules/demo/dqinspecttask/service/impl/DqInspectTaskServiceImpl.java
@@ -55,16 +55,15 @@ public class DqInspectTaskServiceImpl extends ServiceImpl dqInspectProgressList) {
validateProblemId(dqInspectTask);
dqInspectTaskMapper.updateById(dqInspectTask);
-
- //1.先删除子表数据
- dqInspectProgressMapper.deleteByMainId(dqInspectTask.getId());
-
- //2.子表数据重新插入
- if(dqInspectProgressList!=null && dqInspectProgressList.size()>0) {
- for(DqInspectProgress entity:dqInspectProgressList) {
- //外键设置
- entity.setMainId(dqInspectTask.getId());
- dqInspectProgressMapper.insert(entity);
+
+ // 仅当显式传入子表列表时才变更子表数据(null 表示不修改子表)
+ if (dqInspectProgressList != null) {
+ dqInspectProgressMapper.deleteByMainId(dqInspectTask.getId());
+ if (dqInspectProgressList.size() > 0) {
+ for (DqInspectProgress entity : dqInspectProgressList) {
+ entity.setMainId(dqInspectTask.getId());
+ dqInspectProgressMapper.insert(entity);
+ }
}
}
}
diff --git a/jeecg-module-system/jeecg-system-start/src/main/java/org/jeecg/JeecgSystemApplication.java b/jeecg-module-system/jeecg-system-start/src/main/java/org/jeecg/JeecgSystemApplication.java
index dba8ea5..a2b4104 100644
--- a/jeecg-module-system/jeecg-system-start/src/main/java/org/jeecg/JeecgSystemApplication.java
+++ b/jeecg-module-system/jeecg-system-start/src/main/java/org/jeecg/JeecgSystemApplication.java
@@ -39,10 +39,6 @@ public class JeecgSystemApplication extends SpringBootServletInitializer {
"External: \thttp://" + ip + ":" + port + path + "/doc.html\n\t" +
"Swagger文档: \thttp://" + ip + ":" + port + path + "/doc.html\n" +
"----------------------------------------------------------");
-
- // 检查是否有 xiSpeakFlow 这个 Bean
- boolean exists = application.containsBean("xiSpeakFlow");
- System.out.println("★★★ xiSpeakFlow 是否加载成功: " + exists);
}
}
\ No newline at end of file