From 3d180b49481c710119d7c2e375896698b5f0c478 Mon Sep 17 00:00:00 2001
From: zhouz <>
Date: Wed, 22 Jul 2026 14:39:49 +0800
Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E6=AD=A3=E5=8F=AF=E7=94=A8?=
=?UTF-8?q?=E5=BA=93=E5=AD=98=E8=BF=87=E6=BB=A4=E4=B8=8E=E6=B5=8B=E8=AF=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../iostorinvdtl/IostorinvDtlMapper.xml | 12 +--
.../iostorinv/IostorInvServiceImplTest.java | 78 +++++++++++++++++++
.../IostorInvServiceLocalSpringTest.java | 23 ------
3 files changed, 84 insertions(+), 29 deletions(-)
create mode 100644 nl-module-wms/nl-module-wms-server/src/test/java/cn/code/nl/module/wms/service/iostorinv/IostorInvServiceImplTest.java
diff --git a/nl-module-wms/nl-module-wms-server/src/main/resources/mapper/iostorinvdtl/IostorinvDtlMapper.xml b/nl-module-wms/nl-module-wms-server/src/main/resources/mapper/iostorinvdtl/IostorinvDtlMapper.xml
index 0711072a..0b15695c 100644
--- a/nl-module-wms/nl-module-wms-server/src/main/resources/mapper/iostorinvdtl/IostorinvDtlMapper.xml
+++ b/nl-module-wms/nl-module-wms-server/src/main/resources/mapper/iostorinvdtl/IostorinvDtlMapper.xml
@@ -24,12 +24,12 @@
SELECT
FROM wms_group_plate gp
INNER JOIN wms_structattr sa ON sa.storagevehicle_code = gp.vehicle_code
- LEFT JOIN base_materialbase mb ON mb.material_id = gp.material_id AND mb.is_deleted = 0
+ LEFT JOIN base_materialbase mb ON mb.material_id = gp.material_id AND mb.deleted = 0
WHERE sa.stor_id = #{reqVO.storId}
AND gp.status = '可用'
AND gp.qty - gp.frozen_qty > 0
- AND gp.is_deleted = 0
- AND sa.is_deleted = 0
+ AND gp.deleted = 0
+ AND sa.deleted = 0
AND gp.material_code LIKE CONCAT('%', #{reqVO.materialCode}, '%')
@@ -47,12 +47,12 @@
SELECT
FROM wms_group_plate gp
INNER JOIN wms_structattr sa ON sa.storagevehicle_code = gp.vehicle_code
- LEFT JOIN base_materialbase mb ON mb.material_id = gp.material_id AND mb.is_deleted = 0
+ LEFT JOIN base_materialbase mb ON mb.material_id = gp.material_id AND mb.deleted = 0
WHERE sa.stor_id = #{storId}
AND gp.status = '可用'
AND gp.qty - gp.frozen_qty > 0
- AND gp.is_deleted = 0
- AND sa.is_deleted = 0
+ AND gp.deleted = 0
+ AND sa.deleted = 0
AND gp.vehicle_code IN
#{vehicleCode}
diff --git a/nl-module-wms/nl-module-wms-server/src/test/java/cn/code/nl/module/wms/service/iostorinv/IostorInvServiceImplTest.java b/nl-module-wms/nl-module-wms-server/src/test/java/cn/code/nl/module/wms/service/iostorinv/IostorInvServiceImplTest.java
new file mode 100644
index 00000000..c2c9c1f6
--- /dev/null
+++ b/nl-module-wms/nl-module-wms-server/src/test/java/cn/code/nl/module/wms/service/iostorinv/IostorInvServiceImplTest.java
@@ -0,0 +1,78 @@
+package cn.code.nl.module.wms.service.iostorinv;
+
+import cn.code.nl.module.wms.controller.admin.iostorinv.vo.AvailableInventoryRespVO;
+import cn.code.nl.module.wms.controller.admin.iostorinv.vo.ExpandAvailableInventoryReqVO;
+import cn.code.nl.module.wms.dal.mysql.iostorinvdtl.IostorinvDtlMapper;
+import org.junit.jupiter.api.Test;
+
+import java.io.InputStream;
+import java.lang.reflect.Field;
+import java.lang.reflect.Proxy;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+class IostorInvServiceImplTest {
+
+ @Test
+ @SuppressWarnings("unchecked")
+ void expandAvailableInventoryShouldDeduplicateBoxesAndKeepWarehouseIsolation() throws Exception {
+ List queriedVehicleCodes = new ArrayList<>();
+ IostorinvDtlMapper mapper = (IostorinvDtlMapper) Proxy.newProxyInstance(
+ IostorinvDtlMapper.class.getClassLoader(), new Class>[]{IostorinvDtlMapper.class},
+ (proxy, method, args) -> {
+ if (!"selectAvailableInventoryByVehicleCodes".equals(method.getName())) {
+ throw new UnsupportedOperationException(method.getName());
+ }
+ assertEquals("STOR-001", args[0]);
+ queriedVehicleCodes.addAll((Collection) args[1]);
+ return List.of(inventory("BOX-001", "PCSN-001", "STOR-001"),
+ inventory("BOX-001", "PCSN-002", "STOR-001"));
+ });
+ IostorInvServiceImpl service = new IostorInvServiceImpl();
+ Field mapperField = IostorInvServiceImpl.class.getDeclaredField("iostorinvDtlMapper");
+ mapperField.setAccessible(true);
+ mapperField.set(service, mapper);
+
+ ExpandAvailableInventoryReqVO reqVO = new ExpandAvailableInventoryReqVO();
+ reqVO.setStorId("STOR-001");
+ reqVO.setVehicleCodes(List.of("BOX-001", "BOX-001"));
+
+ List result = service.expandAvailableInventory(reqVO);
+
+ assertEquals(List.of("BOX-001"), queriedVehicleCodes);
+ assertEquals(2, result.size());
+ assertTrue(result.stream().allMatch(item -> "BOX-001".equals(item.getVehicleCode())));
+ assertTrue(result.stream().allMatch(item -> "STOR-001".equals(item.getStorId())));
+ assertEquals(2, result.stream().map(AvailableInventoryRespVO::getPcsn).distinct().count());
+ }
+
+ @Test
+ void availableInventorySqlShouldFilterWarehouseStatusDeletedAndAvailableQuantity() throws Exception {
+ String mapperResource = "mapper/iostorinvdtl/IostorinvDtlMapper.xml";
+ try (InputStream input = Thread.currentThread().getContextClassLoader().getResourceAsStream(mapperResource)) {
+ assertNotNull(input, "Mapper XML 应存在于测试类路径");
+ String sql = new String(input.readAllBytes(), StandardCharsets.UTF_8);
+ assertTrue(sql.contains("sa.stor_id = #{storId}"));
+ assertTrue(sql.contains("gp.status = '可用'"));
+ assertTrue(sql.contains("gp.qty - gp.frozen_qty > 0"));
+ assertTrue(sql.contains("gp.deleted = 0"));
+ assertTrue(sql.contains("sa.deleted = 0"));
+ assertTrue(sql.contains("mb.deleted = 0"));
+ }
+ }
+
+ private static AvailableInventoryRespVO inventory(String vehicleCode, String pcsn, String storId) {
+ AvailableInventoryRespVO inventory = new AvailableInventoryRespVO();
+ inventory.setVehicleCode(vehicleCode);
+ inventory.setPcsn(pcsn);
+ inventory.setStorId(storId);
+ return inventory;
+ }
+
+}
diff --git a/nl-module-wms/nl-module-wms-server/src/test/java/cn/code/nl/module/wms/service/iostorinv/IostorInvServiceLocalSpringTest.java b/nl-module-wms/nl-module-wms-server/src/test/java/cn/code/nl/module/wms/service/iostorinv/IostorInvServiceLocalSpringTest.java
index 438a6295..b6615b70 100644
--- a/nl-module-wms/nl-module-wms-server/src/test/java/cn/code/nl/module/wms/service/iostorinv/IostorInvServiceLocalSpringTest.java
+++ b/nl-module-wms/nl-module-wms-server/src/test/java/cn/code/nl/module/wms/service/iostorinv/IostorInvServiceLocalSpringTest.java
@@ -1,22 +1,17 @@
package cn.code.nl.module.wms.service.iostorinv;
import cn.code.nl.module.wms.controller.admin.iostorinv.vo.IostorInvCreateReqVO;
-import cn.code.nl.module.wms.controller.admin.iostorinv.vo.AvailableInventoryRespVO;
-import cn.code.nl.module.wms.controller.admin.iostorinv.vo.ExpandAvailableInventoryReqVO;
import jakarta.annotation.Resource;
import jakarta.validation.ConstraintViolationException;
import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.Disabled;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
import java.time.LocalDateTime;
import java.util.Collections;
-import java.util.List;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.junit.jupiter.api.Assertions.assertEquals;
@SpringBootTest
@ActiveProfiles("local")
@@ -40,22 +35,4 @@ class IostorInvServiceLocalSpringTest {
.anyMatch(violation -> violation.getPropertyPath().toString().contains("details")));
}
- /**
- * 本地库数据前置:仓库 stor-1 的 BOX-001 有两个可用子卷,另一仓库也存在 BOX-001。
- * 当前仓库没有可移植的 WMS 本地测试数据集,避免向开发库写入固定业务数据,准备好上述数据后可手动启用。
- */
- @Test
- @Disabled("需要 local 数据库预置跨仓库 BOX-001 测试数据")
- void expandAvailableInventoryShouldReturnAllChildrenOnceAndOnlyFromRequestedWarehouse() {
- ExpandAvailableInventoryReqVO reqVO = new ExpandAvailableInventoryReqVO();
- reqVO.setStorId("stor-1");
- reqVO.setVehicleCodes(List.of("BOX-001", "BOX-001"));
-
- List result = iostorInvService.expandAvailableInventory(reqVO);
-
- assertEquals(2, result.size());
- assertTrue(result.stream().allMatch(item -> "BOX-001".equals(item.getVehicleCode())));
- assertTrue(result.stream().allMatch(item -> "stor-1".equals(item.getStorId())));
- assertEquals(2, result.stream().map(AvailableInventoryRespVO::getPcsn).distinct().count());
- }
}