From b000b056d1d5d938f37cc7dd2eeea846335c16a2 Mon Sep 17 00:00:00 2001 From: ouyangxq <775153912@qq.com> Date: Mon, 5 Oct 2026 01:06:11 +0800 Subject: [PATCH] feat(orders): expose customer-owned loaded transport facts --- .../dto/CustomerTransportFragment.java | 17 ++++ .../firstleg/dto/UnifiedInboundDetail.java | 3 +- .../mapper/UnifiedInboundTransportMapper.java | 23 +++++ .../UnifiedInboundReadRepository.java | 18 ++++ .../service/UnifiedInboundQueryService.java | 5 +- .../main/resources/openapi/firstleg-v1.yaml | 24 +++++ .../UnifiedInboundOpenApiContractTest.java | 15 ++++ ...tomerTransportFragmentPersistenceTest.java | 88 +++++++++++++++++++ .../UnifiedInboundQueryServiceTest.java | 22 +++++ .../client/FirstlegUnifiedOrderClient.java | 6 +- .../order/dto/UnifiedOrderResponse.java | 8 +- .../service/UnifiedOrderQueryService.java | 8 +- .../src/main/resources/openapi/order-v1.yaml | 24 +++++ .../UnifiedOrderApiContractTest.java | 15 ++++ .../service/UnifiedOrderQueryServiceTest.java | 19 +++- 15 files changed, 286 insertions(+), 9 deletions(-) create mode 100644 firstleg/src/main/java/com/baiyue/firstleg/dto/CustomerTransportFragment.java create mode 100644 firstleg/src/test/java/com/baiyue/firstleg/repository/CustomerTransportFragmentPersistenceTest.java diff --git a/firstleg/src/main/java/com/baiyue/firstleg/dto/CustomerTransportFragment.java b/firstleg/src/main/java/com/baiyue/firstleg/dto/CustomerTransportFragment.java new file mode 100644 index 000000000..e5914c7a7 --- /dev/null +++ b/firstleg/src/main/java/com/baiyue/firstleg/dto/CustomerTransportFragment.java @@ -0,0 +1,17 @@ +package com.baiyue.firstleg.dto; + +import java.time.LocalDateTime; +import java.util.List; + +/** Customer-safe, read-only transport facts for one actually loaded inbound/container fragment. */ +public record CustomerTransportFragment(String inboundCode, String cabinetNo, String containerNo, + List nodes) { + public record Node(String standardNode, Integer nodeSequence, String providerCode, + LocalDateTime estimatedAt, LocalDateTime actualAt, + String locationCode, String locationName) {} + + public record Row(Long inboundId, Long containerBookingId, String inboundCode, String cabinetNo, + String containerNo, String standardNode, Integer nodeSequence, String providerCode, + LocalDateTime estimatedAt, LocalDateTime actualAt, + String locationCode, String locationName) {} +} diff --git a/firstleg/src/main/java/com/baiyue/firstleg/dto/UnifiedInboundDetail.java b/firstleg/src/main/java/com/baiyue/firstleg/dto/UnifiedInboundDetail.java index e50938cac..c306ff6dd 100644 --- a/firstleg/src/main/java/com/baiyue/firstleg/dto/UnifiedInboundDetail.java +++ b/firstleg/src/main/java/com/baiyue/firstleg/dto/UnifiedInboundDetail.java @@ -6,7 +6,8 @@ import java.util.List; /** Detail payload for the product-level order detail. */ public record UnifiedInboundDetail( UnifiedInboundSummary summary, - List timeline + List timeline, + List transportFragments ) { public record TimelineEvent(String source, String eventType, String fromStatus, String toStatus, String action, String remark, Long operatorId, String operatorName, diff --git a/firstleg/src/main/java/com/baiyue/firstleg/mapper/UnifiedInboundTransportMapper.java b/firstleg/src/main/java/com/baiyue/firstleg/mapper/UnifiedInboundTransportMapper.java index c90eb6763..e7b4c7583 100644 --- a/firstleg/src/main/java/com/baiyue/firstleg/mapper/UnifiedInboundTransportMapper.java +++ b/firstleg/src/main/java/com/baiyue/firstleg/mapper/UnifiedInboundTransportMapper.java @@ -10,6 +10,29 @@ import java.util.List; /** 统一订单按当前有效装柜明细批量读取柜次船期。 */ @Mapper public interface UnifiedInboundTransportMapper { + @Select(""" + SELECT owned.inbound_id, owned.container_booking_id, owned.inbound_code, + b.cabinet_no, b.container_no, n.standard_node, n.node_sequence, n.provider_code, + n.estimated_at, n.actual_at, n.location_code, n.location_name + FROM ( + SELECT DISTINCT o.id AS inbound_id, p.container_booking_id, o.inbound_code + FROM fl_inbound_order o + JOIN fl_loading_plan_item i ON i.inbound_id=o.id AND i.account_id=o.tenant_id + JOIN fl_loading_plan p ON p.id=i.loading_plan_id AND p.plan_status='COMPLETED' + JOIN fl_loading_pick_task t ON t.loading_plan_id=p.id AND t.task_status='COMPLETED' + JOIN fl_loading_pick_item picked ON picked.pick_task_id=t.id + AND picked.loading_plan_item_id=i.id + WHERE o.tenant_id=#{tenantId} AND o.order_id=#{orderId} AND o.deleted=0 + AND i.deleted=0 AND picked.item_status IN ('PICKED','PARTIAL') + AND picked.picked_package_count>0 + ) owned + JOIN fl_container_booking b ON b.id=owned.container_booking_id + LEFT JOIN fl_carrier_schedule_node_fact n ON n.container_booking_id=owned.container_booking_id + ORDER BY owned.inbound_id, owned.container_booking_id, n.node_sequence, n.id + """) + List findCustomerTransportNodes( + @Param("tenantId") long tenantId, @Param("orderId") long orderId); + @Select("""