From 17d81b0b94565118a521df6a62fc2c139c70073e Mon Sep 17 00:00:00 2001 From: ouyangxq <775153912@qq.com> Date: Mon, 31 Aug 2026 15:38:18 +0800 Subject: [PATCH] feat(order): expose unified order channel code --- .../client/FirstlegUnifiedOrderClient.java | 2 +- .../order/dto/UnifiedOrderResponse.java | 2 +- .../service/UnifiedOrderQueryService.java | 6 ++--- .../src/main/resources/openapi/order-v1.yaml | 1 + .../UnifiedOrderApiContractTest.java | 6 ++++- .../service/UnifiedOrderQueryServiceTest.java | 23 +++++++++++++++++++ 6 files changed, 34 insertions(+), 6 deletions(-) diff --git a/order/src/main/java/com/baiyue/order/client/FirstlegUnifiedOrderClient.java b/order/src/main/java/com/baiyue/order/client/FirstlegUnifiedOrderClient.java index c8bb829bd..9e47bf2fb 100644 --- a/order/src/main/java/com/baiyue/order/client/FirstlegUnifiedOrderClient.java +++ b/order/src/main/java/com/baiyue/order/client/FirstlegUnifiedOrderClient.java @@ -45,7 +45,7 @@ public interface FirstlegUnifiedOrderClient { String processStatus, String orderStatusSnapshot, String measureReviewStatus, Integer version, Long customerId, String customerName, Long warehouseId, String warehouseName, - Long deliveryWarehouseId, String deliveryWarehouseName, String channelName, + Long deliveryWarehouseId, String deliveryWarehouseName, String channelCode, String channelName, Integer totalPackageCount, String locationCodes, LocalDateTime expectedArrivalAt, LocalDateTime requestedPickupAt, String feeReviewStatus, String companyName, String businessType, String taxMode, String containerMode, diff --git a/order/src/main/java/com/baiyue/order/dto/UnifiedOrderResponse.java b/order/src/main/java/com/baiyue/order/dto/UnifiedOrderResponse.java index 93e5ae5f0..4aded5a9c 100644 --- a/order/src/main/java/com/baiyue/order/dto/UnifiedOrderResponse.java +++ b/order/src/main/java/com/baiyue/order/dto/UnifiedOrderResponse.java @@ -15,7 +15,7 @@ public final class UnifiedOrderResponse { Long orderId, Long tenantId, String orderNo, String mainStatus, String nextAction, OrderRelationSummary relation, OrderStatus internalOrderStatus, - Long customerId, String customerName, String channelName, + Long customerId, String customerName, String channelCode, String channelName, Long receivingWarehouseId, String receivingWarehouseName, Long destinationWarehouseId, String destinationWarehouseName, Long inboundId, Integer inboundVersion, String inboundCode, LocalDate expectedShipDate, diff --git a/order/src/main/java/com/baiyue/order/service/UnifiedOrderQueryService.java b/order/src/main/java/com/baiyue/order/service/UnifiedOrderQueryService.java index d0bd0e2f7..60449bbd2 100644 --- a/order/src/main/java/com/baiyue/order/service/UnifiedOrderQueryService.java +++ b/order/src/main/java/com/baiyue/order/service/UnifiedOrderQueryService.java @@ -267,7 +267,7 @@ public class UnifiedOrderQueryService { order.getStatus() == OrderStatus.SUBMITTED ? "APPROVE_ORDER" : null, relation(order, childCounts), order.getStatus(), order.getCustomerId(), order.getCustomerName(), - order.getChannelName(), order.getReceivingWarehouseId(), order.getReceivingWarehouseName(), + order.getChannelCode(), order.getChannelName(), order.getReceivingWarehouseId(), order.getReceivingWarehouseName(), order.getDestinationWarehouseId(), order.getDestinationWarehouseName(), null, null, order.getInboundCode(), order.getExpectedShipDate(), totalPackageCount(cargo), null, null, grossWeightKg(cargo), volumeCbm(cargo), @@ -283,7 +283,7 @@ public class UnifiedOrderQueryService { return new UnifiedOrderResponse.Row(order.getId(), order.getTenantId(), order.getOrderNo(), summary.mainStatus(), summary.nextAction(), relation(order, childCounts), order.getStatus(), order.getCustomerId(), order.getCustomerName(), - order.getChannelName(), order.getReceivingWarehouseId(), order.getReceivingWarehouseName(), + order.getChannelCode(), order.getChannelName(), order.getReceivingWarehouseId(), order.getReceivingWarehouseName(), order.getDestinationWarehouseId(), order.getDestinationWarehouseName(), inbound.id(), inbound.version(), inbound.inboundCode(), order.getExpectedShipDate(), inbound.totalPackageCount() != null ? inbound.totalPackageCount() : totalPackageCount(cargo), null, inbound.locationCodes(), inbound.actualGrossWeightKg() != null ? inbound.actualGrossWeightKg() : grossWeightKg(cargo), @@ -307,7 +307,7 @@ public class UnifiedOrderQueryService { return new UnifiedOrderResponse.Row(inbound.orderId(), inbound.tenantId(), inbound.orderNo(), summary.mainStatus(), summary.nextAction(), relation(order, childCounts), parseOrderStatus(inbound.orderStatusSnapshot()), - inbound.customerId(), inbound.customerName(), inbound.channelName(), inbound.warehouseId(), + inbound.customerId(), inbound.customerName(), inbound.channelCode(), inbound.channelName(), inbound.warehouseId(), inbound.warehouseName(), inbound.deliveryWarehouseId(), inbound.deliveryWarehouseName(), inbound.id(), inbound.version(), inbound.inboundCode(), null, inbound.totalPackageCount() != null ? inbound.totalPackageCount() : totalPackageCount(cargo), diff --git a/order/src/main/resources/openapi/order-v1.yaml b/order/src/main/resources/openapi/order-v1.yaml index b3211da15..bd025c9bc 100644 --- a/order/src/main/resources/openapi/order-v1.yaml +++ b/order/src/main/resources/openapi/order-v1.yaml @@ -477,6 +477,7 @@ components: internalOrderStatus: {type: string, enum: [DRAFT, SUBMITTED, APPROVED, ACCEPTED, REJECTED, CANCELLED, PROCESSING, COMPLETED], nullable: true} customerId: {type: integer, format: int64, nullable: true} customerName: {type: string, nullable: true} + channelCode: {type: string, nullable: true, description: 稳定物流渠道编码,仅供业务校验;直接来自当前 Order 或 Firstleg 权威快照,不由 channelName 推导} channelName: {type: string, nullable: true} receivingWarehouseId: {type: integer, format: int64, nullable: true} receivingWarehouseName: {type: string, nullable: true} diff --git a/order/src/test/java/com/baiyue/order/controller/UnifiedOrderApiContractTest.java b/order/src/test/java/com/baiyue/order/controller/UnifiedOrderApiContractTest.java index bc4453c07..213fc233f 100644 --- a/order/src/test/java/com/baiyue/order/controller/UnifiedOrderApiContractTest.java +++ b/order/src/test/java/com/baiyue/order/controller/UnifiedOrderApiContractTest.java @@ -52,7 +52,7 @@ class UnifiedOrderApiContractTest { Map row = stringMap(schemas.get("UnifiedOrderRow")); assertThat(stringMap(row.get("properties"))).containsKeys( - "orderId", "mainStatus", "inboundId", "inboundVersion", "measurement", "preload", + "orderId", "mainStatus", "channelCode", "inboundId", "inboundVersion", "measurement", "preload", "loading", "delivery", "transport", "customerRemark", "latestInternalNote", "expectedArrivalAt", "requestedPickupAt", "feeReviewStatus", "companyName", "businessType", "pickupMethod", "taxMode", "containerMode", "customsInspection", "destinationType", "destinationCode", @@ -62,6 +62,8 @@ class UnifiedOrderApiContractTest { Map inboundCode = stringMap(stringMap(row.get("properties")).get("inboundCode")); assertThat(inboundCode).containsEntry("nullable", true); assertThat(inboundCode.get("description").toString()).contains("不得回退"); + Map channelCode = stringMap(stringMap(row.get("properties")).get("channelCode")); + assertThat(channelCode.get("description").toString()).contains("不由 channelName 推导"); Map coLoadGroup = stringMap(schemas.get("UnifiedCoLoadGroupSummary")); assertThat(stringMap(coLoadGroup.get("properties"))) .containsOnlyKeys("status", "memberCount", "memberInboundCodes"); @@ -79,6 +81,8 @@ class UnifiedOrderApiContractTest { Method page = FirstlegUnifiedOrderClient.class.getMethod( "page", String.class, FirstlegUnifiedOrderClient.Query.class); assertThat(page.getAnnotation(PostMapping.class).value()).containsExactly("/query"); + assertThat(List.of(FirstlegUnifiedOrderClient.Inbound.class.getRecordComponents()).stream() + .map(component -> component.getName())).contains("channelCode", "channelName"); } @Test diff --git a/order/src/test/java/com/baiyue/order/service/UnifiedOrderQueryServiceTest.java b/order/src/test/java/com/baiyue/order/service/UnifiedOrderQueryServiceTest.java index a3ef21449..18baf4d9b 100644 --- a/order/src/test/java/com/baiyue/order/service/UnifiedOrderQueryServiceTest.java +++ b/order/src/test/java/com/baiyue/order/service/UnifiedOrderQueryServiceTest.java @@ -72,6 +72,7 @@ class UnifiedOrderQueryServiceTest { assertThat(row.mainStatus()).isEqualTo("PENDING_REVIEW"); assertThat(row.nextAction()).isEqualTo("APPROVE_ORDER"); assertThat(row.inboundCode()).isEqualTo("RK-77"); + assertThat(row.channelCode()).isEqualTo("MATSON"); assertThat(row.inboundId()).isNull(); assertThat(row.customerRemark()).isEqualTo("客户要求提货前联系"); assertThat(row.latestInternalNote()).isEqualTo("客服已确认提货时间"); @@ -243,6 +244,7 @@ class UnifiedOrderQueryServiceTest { UnifiedOrderQuery query = query("PENDING_REVIEW"); OrderEntity order = order(OrderStatus.SUBMITTED); order.setInboundCode(null); + order.setChannelCode(null); when(orders.unifiedPage(eq(10001L), eq(query), eq(List.of(OrderStatus.SUBMITTED)))) .thenReturn(new PageResult<>(List.of(order), 1, 20, 1, 1)); @@ -250,9 +252,27 @@ class UnifiedOrderQueryServiceTest { assertThat(row.orderId()).isEqualTo(77L); assertThat(row.orderNo()).isEqualTo("FL-77"); assertThat(row.inboundCode()).isNull(); + assertThat(row.channelName()).isEqualTo("美森"); + assertThat(row.channelCode()).isNull(); }); } + @Test + void orderDrivenPageUsesOrderChannelCodeWithoutFirstlegOrNameFallback() { + UnifiedOrderQuery query = query(null); + OrderEntity order = order(OrderStatus.APPROVED); + order.setChannelCode("ORDER-SNAPSHOT"); + var summary = summary("LOADING", null); + when(summary.inbound().channelCode()).thenReturn("FIRSTLEG-SNAPSHOT"); + when(orders.unifiedPage(eq(10001L), eq(query), any())) + .thenReturn(new PageResult<>(List.of(order), 1, 20, 1, 1)); + when(firstleg.summaries(eq("internal-token"), any())) + .thenReturn(ApiResponse.success(List.of(summary))); + + assertThat(service.page(10001L, query).records()).singleElement() + .extracting(UnifiedOrderResponse.Row::channelCode).isEqualTo("ORDER-SNAPSHOT"); + } + @Test void platformPageAggregatesColoadStatusAndMemberInboundCodes() { UnifiedOrderQuery query = query("PENDING_REVIEW"); @@ -425,6 +445,7 @@ class UnifiedOrderQueryServiceTest { assertThat(row.loading().loadingVersion()).isEqualTo(3); assertThat(row.loading().pickingVersion()).isEqualTo(3); assertThat(row.inboundCode()).isEqualTo("RK-77"); + assertThat(row.channelCode()).isEqualTo("MATSON"); assertThat(row.recommendedPalletType()).isNull(); assertThat(row.locationCodes()).isEqualTo("A0-01, B2-03"); assertThat(row.companyName()).isEqualTo("测试客户有限公司"); @@ -603,6 +624,7 @@ class UnifiedOrderQueryServiceTest { OrderEntity order = new OrderEntity(); order.setId(77L); order.setTenantId(10001L); order.setOrderNo("FL-77"); order.setStatus(status); order.setCustomerId(30001L); order.setCustomerName("测试客户"); + order.setChannelCode("MATSON"); order.setChannelName("美森"); order.setCreatedAt(LocalDateTime.of(2026, 8, 6, 10, 0)); return order; } @@ -625,6 +647,7 @@ class UnifiedOrderQueryServiceTest { when(inbound.deliveryWarehouseId()).thenReturn(22L); when(inbound.deliveryWarehouseName()).thenReturn("ONT8"); when(inbound.channelName()).thenReturn("美森"); + when(inbound.channelCode()).thenReturn("MATSON"); when(inbound.totalPackageCount()).thenReturn(10); when(inbound.locationCodes()).thenReturn("A0-01, B2-03"); when(inbound.companyName()).thenReturn("测试客户有限公司");