From 85a288e4f2f26f9d87c73168d2047ed22ac51a0d Mon Sep 17 00:00:00 2001 From: ouyangxq <775153912@qq.com> Date: Tue, 25 Aug 2026 08:12:58 +0800 Subject: [PATCH] fix: preserve overseas pallet identity --- .../gateway/HttpWarehouseResourceGateway.java | 3 +- .../HttpWarehouseResourceGatewayTest.java | 61 +++++++++++++++++++ .../phase4-overseas-client-services.mjs | 8 +-- .../phase4-overseas-inbound-operations.mjs | 10 +-- 4 files changed, 72 insertions(+), 10 deletions(-) create mode 100644 lastleg-service/src/test/java/com/baiyue/lastleg/inboundplan/pda/gateway/HttpWarehouseResourceGatewayTest.java diff --git a/lastleg-service/src/main/java/com/baiyue/lastleg/inboundplan/pda/gateway/HttpWarehouseResourceGateway.java b/lastleg-service/src/main/java/com/baiyue/lastleg/inboundplan/pda/gateway/HttpWarehouseResourceGateway.java index 62c41435f..7aff90d5b 100644 --- a/lastleg-service/src/main/java/com/baiyue/lastleg/inboundplan/pda/gateway/HttpWarehouseResourceGateway.java +++ b/lastleg-service/src/main/java/com/baiyue/lastleg/inboundplan/pda/gateway/HttpWarehouseResourceGateway.java @@ -1,5 +1,6 @@ package com.baiyue.lastleg.inboundplan.pda.gateway; +import com.fasterxml.jackson.annotation.JsonAlias; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpStatusCode; import org.springframework.http.HttpStatus; @@ -141,7 +142,7 @@ public class HttpWarehouseResourceGateway implements WarehouseResourceGateway { } private record WarehousePalletResponse(WarehousePalletData data) {} - private record WarehousePalletData(long id, String palletCode, long warehouseId, long locationId, + private record WarehousePalletData(@JsonAlias("palletId") long id, String palletCode, long warehouseId, long locationId, String status, String fbaWarehouseCode, int version) {} private record ReserveEnvelope(ReserveData data) {} private record ReserveData(long lockId) {} diff --git a/lastleg-service/src/test/java/com/baiyue/lastleg/inboundplan/pda/gateway/HttpWarehouseResourceGatewayTest.java b/lastleg-service/src/test/java/com/baiyue/lastleg/inboundplan/pda/gateway/HttpWarehouseResourceGatewayTest.java new file mode 100644 index 000000000..188ff9c41 --- /dev/null +++ b/lastleg-service/src/test/java/com/baiyue/lastleg/inboundplan/pda/gateway/HttpWarehouseResourceGatewayTest.java @@ -0,0 +1,61 @@ +package com.baiyue.lastleg.inboundplan.pda.gateway; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.http.MediaType; +import org.springframework.test.util.ReflectionTestUtils; +import org.springframework.test.web.client.MockRestServiceServer; +import org.springframework.web.client.RestClient; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo; +import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess; + +class HttpWarehouseResourceGatewayTest { + private HttpWarehouseResourceGateway gateway; + private MockRestServiceServer server; + + @BeforeEach + void setUp() { + RestClient.Builder builder = RestClient.builder(); + server = MockRestServiceServer.bindTo(builder).build(); + gateway = new HttpWarehouseResourceGateway(); + ReflectionTestUtils.setField(gateway, "restClientBuilder", builder); + ReflectionTestUtils.setField(gateway, "baseUrl", "http://warehouse"); + ReflectionTestUtils.setField(gateway, "internalToken", "test-token"); + gateway.initializeClient(); + } + + @Test + void resolveMapsCanonicalPalletIdInsteadOfSilentlyUsingZero() { + server.expect(requestTo("http://warehouse/internal/v1/warehouse-pallets/resolve/PAL-1")) + .andRespond(withSuccess(""" + {"code":"200","data":{"palletId":2092040891261427713,"palletCode":"PAL-1", + "warehouseId":2092040869757231105,"locationId":2092040891076878337, + "status":"IDLE","fbaWarehouseCode":"ABE3","version":3}} + """, MediaType.APPLICATION_JSON)); + + WarehouseResourceGateway.WarehousePalletReference result = gateway.resolvePallet("PAL-1"); + + assertThat(result.palletId()).isEqualTo(2092040891261427713L); + assertThat(result.warehouseId()).isEqualTo(2092040869757231105L); + assertThat(result.locationId()).isEqualTo(2092040891076878337L); + server.verify(); + } + + @Test + void ensureDropshipStillMapsWarehouseEntityId() { + server.expect(requestTo("http://warehouse/internal/v1/warehouse-pallets/ensure-dropship")) + .andRespond(withSuccess(""" + {"code":"200","data":{"id":2092040891261427713,"palletCode":"PAL-DROP", + "warehouseId":2092040869757231105,"locationId":2092040891076878337, + "status":"IDLE","fbaWarehouseCode":null,"version":1}} + """, MediaType.APPLICATION_JSON)); + + WarehouseResourceGateway.WarehousePalletReference result = + gateway.ensureDropshipPallet("2092040041967063041", 2092040869757231105L, "DROP-1"); + + assertThat(result.palletId()).isEqualTo(2092040891261427713L); + server.verify(); + } +} diff --git a/scripts/admin-test-env-modules/phase4-overseas-client-services.mjs b/scripts/admin-test-env-modules/phase4-overseas-client-services.mjs index e887bc8bf..380254e5d 100644 --- a/scripts/admin-test-env-modules/phase4-overseas-client-services.mjs +++ b/scripts/admin-test-env-modules/phase4-overseas-client-services.mjs @@ -154,9 +154,9 @@ async function verifyTransfer(context, token, orders) { const created = await merchant(context, token, 'POST', '客户创建仓储转运申请', TRANSFER, body) const transferNo = id(created.data?.transferNo) context.assert(MODULE, '仓储转运申请进入合法待审核状态且绑定本轮来源订单', created.response, - Boolean(transferNo) && created.data?.status === 'PENDING_REVIEW' + Boolean(transferNo) && created.data?.orderStatus === 'PENDING_REVIEW' && created.data?.sourceOrders?.some((item) => id(item?.lastlegOrderId) === id(order.row.id)), - `transferNo=${transferNo || 'missing'}, status=${created.data?.status || 'missing'}; ${trace(created.response)}`, OPTIONS) + `transferNo=${transferNo || 'missing'}, status=${created.data?.orderStatus || 'missing'}; ${trace(created.response)}`, OPTIONS) if (!transferNo) return false const replay = await merchant(context, token, 'POST', '客户仓储转运申请幂等重放', TRANSFER, body) context.assert(MODULE, '转运重放复用同一申请', replay.response, @@ -170,9 +170,9 @@ async function verifyTransfer(context, token, orders) { const detail = await merchant(context, token, 'GET', '客户查询自身仓储转运详情', `${TRANSFER}/${encodeURIComponent(transferNo)}`) context.assert(MODULE, '转运详情保持待审核且不产生出库履约事实', detail.response, - id(detail.data?.transferNo) === transferNo && detail.data?.status === 'PENDING_REVIEW' + id(detail.data?.transferNo) === transferNo && detail.data?.orderStatus === 'PENDING_REVIEW' && detail.data?.outboundAt == null && Array.isArray(detail.data?.allocations) && detail.data.allocations.length === 0, - `status=${detail.data?.status || 'missing'}, allocations=${detail.data?.allocations?.length ?? 'missing'}; ${trace(detail.response)}`, OPTIONS) + `status=${detail.data?.orderStatus || 'missing'}, allocations=${detail.data?.allocations?.length ?? 'missing'}; ${trace(detail.response)}`, OPTIONS) context.createdResources.phase4OverseasClientServices.transferNo = transferNo return true } diff --git a/scripts/admin-test-env-modules/phase4-overseas-inbound-operations.mjs b/scripts/admin-test-env-modules/phase4-overseas-inbound-operations.mjs index 87bc9f03e..a28ce8ee6 100644 --- a/scripts/admin-test-env-modules/phase4-overseas-inbound-operations.mjs +++ b/scripts/admin-test-env-modules/phase4-overseas-inbound-operations.mjs @@ -44,11 +44,11 @@ async function inboundAdminLifecycle(context) { const plan = await request(context, 'POST', '尾程入仓单转换为入仓计划', `${PLAN_BASE}/convert`, convertBody) const replay = await request(context, 'POST', '重复转换返回同一入仓计划', `${PLAN_BASE}/convert`, convertBody) context.assert(MODULE, '入仓计划转换天然幂等', null, - Boolean(plan?.plan?.planNo) && replay?.plan?.planNo === plan.plan.planNo, - `first=${plan?.plan?.planNo || 'missing'}, replay=${replay?.plan?.planNo || 'missing'}`, OPTIONS) - const planNo = plan?.plan?.planNo - const fbaLines = (plan?.lines || []).filter((line) => line?.destinationType === 'FBA' - && line?.fbaWarehouseCode && line?.destinationWarehouseId) + Boolean(plan?.planNo) && replay?.planNo === plan.planNo, + `first=${plan?.planNo || 'missing'}, replay=${replay?.planNo || 'missing'}`, OPTIONS) + const planNo = plan?.planNo + const fbaLines = (plan?.lines || []).filter((line) => line?.fbaWarehouseCode + && line?.destinationWarehouseId) context.assert(MODULE, 'FBA入仓计划包含可预约明细', null, Boolean(planNo) && fbaLines.length > 0, `planNo=${planNo || 'missing'}, fbaLines=${fbaLines.length}`, OPTIONS)