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()); - } }