feat(order): expose cargo shipment binding

This commit is contained in:
2026-09-08 17:17:57 +08:00
parent 2e60f2cd77
commit e597bebafd
3 changed files with 53 additions and 3 deletions
@@ -75,7 +75,7 @@ public class InternalOrderCargoController {
return ApiResponse.success(orders.findCargoInheritedByOrder(tenantId, orderId).stream() return ApiResponse.success(orders.findCargoInheritedByOrder(tenantId, orderId).stream()
.map(cargo -> new CargoLabelBinding(cargo.getId(), orderId, cargo.getItemNo(), .map(cargo -> new CargoLabelBinding(cargo.getId(), orderId, cargo.getItemNo(),
cargo.getCargoName(), cargo.getSkuNo(), cargo.getPackageCount(), cargo.getLengthCm(), cargo.getCargoName(), cargo.getSkuNo(), cargo.getPackageCount(), cargo.getLengthCm(),
cargo.getWidthCm(), cargo.getHeightCm())) cargo.getWidthCm(), cargo.getHeightCm(), cargo.getShipmentId()))
.toList()); .toList());
} }
@@ -156,11 +156,12 @@ public class InternalOrderCargoController {
public record CargoLabelBinding(Long cargoId, Long orderId, Integer itemNo, String cargoName, public record CargoLabelBinding(Long cargoId, Long orderId, Integer itemNo, String cargoName,
String skuNo, Integer packageCount, java.math.BigDecimal lengthCm, String skuNo, Integer packageCount, java.math.BigDecimal lengthCm,
java.math.BigDecimal widthCm, java.math.BigDecimal heightCm) { java.math.BigDecimal widthCm, java.math.BigDecimal heightCm,
String shipmentId) {
public CargoLabelBinding(Long cargoId, Long orderId, Integer itemNo, String cargoName, public CargoLabelBinding(Long cargoId, Long orderId, Integer itemNo, String cargoName,
Integer packageCount, java.math.BigDecimal lengthCm, Integer packageCount, java.math.BigDecimal lengthCm,
java.math.BigDecimal widthCm, java.math.BigDecimal heightCm) { java.math.BigDecimal widthCm, java.math.BigDecimal heightCm) {
this(cargoId, orderId, itemNo, cargoName, null, packageCount, lengthCm, widthCm, heightCm); this(cargoId, orderId, itemNo, cargoName, null, packageCount, lengthCm, widthCm, heightCm, null);
} }
} }
@@ -6,6 +6,28 @@ info:
security: security:
- bearerAuth: [] - bearerAuth: []
paths: paths:
/internal/order/v1/cargoes/{tenantId}/{orderId}:
get:
security: []
summary: Firstleg 批量读取订单货物绑定
description: >-
仅接受内部服务令牌。按 tenantId 与 orderId 严格限定订单范围,并按订单货物顺序一次返回全部货物;
cargoId 是 Firstleg inboundDetailId 的绑定键,shipmentId 仅取对应货物行快照,
不使用订单顶层货件号回退,也不提供逐货物查询替代本批量契约。
parameters:
- name: X-Internal-Service-Token
in: header
required: true
schema: {type: string}
- {name: tenantId, in: path, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
- {name: orderId, in: path, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
responses:
'200':
description: 当前订单范围内的货物绑定列表
content:
application/json:
schema: {$ref: '#/components/schemas/CargoLabelBindingListEnvelope'}
'403': {description: 内部服务令牌无效}
/internal/order/v1/pending-review-orders: /internal/order/v1/pending-review-orders:
get: get:
security: [] security: []
@@ -590,6 +612,29 @@ components:
scheme: bearer scheme: bearer
bearerFormat: JWT bearerFormat: JWT
schemas: schemas:
CargoLabelBindingListEnvelope:
type: object
required: [code, data]
properties:
code: {type: string, example: "200"}
message: {type: string, nullable: true}
data:
type: array
items: {$ref: '#/components/schemas/CargoLabelBinding'}
CargoLabelBinding:
type: object
required: [cargoId, orderId, itemNo, cargoName, packageCount]
properties:
cargoId: {type: string, pattern: '^[1-9][0-9]*$', description: Firstleg inboundDetailId 的绑定键}
orderId: {type: string, pattern: '^[1-9][0-9]*$'}
itemNo: {type: integer, minimum: 1}
cargoName: {type: string}
skuNo: {type: string, nullable: true}
packageCount: {type: integer, minimum: 1}
lengthCm: {type: number, nullable: true}
widthCm: {type: number, nullable: true}
heightCm: {type: number, nullable: true}
shipmentId: {type: string, nullable: true, description: 当前货物行的 FBA 货件号快照,不以订单级字段回退}
DomesticWarehouseOrderExportBatchRequest: DomesticWarehouseOrderExportBatchRequest:
type: object type: object
required: [taskId, tenantId, appCode, requestedBy, dispatchVersion, parameters, limit] required: [taskId, tenantId, appCode, requestedBy, dispatchVersion, parameters, limit]
@@ -89,6 +89,8 @@ class InternalOrderCargoControllerTest {
void listsCargoInRepositoryOrderForStableCartonAllocation() { void listsCargoInRepositoryOrderForStableCartonAllocation() {
OrderCargoEntity first = cargo(31L, 1, 3, "60", "40", "30"); OrderCargoEntity first = cargo(31L, 1, 3, "60", "40", "30");
OrderCargoEntity second = cargo(32L, 2, 2, "50", "30", "20"); OrderCargoEntity second = cargo(32L, 2, 2, "50", "30", "20");
first.setShipmentId("FBA-SHIPMENT-31");
second.setShipmentId("FBA-SHIPMENT-32");
when(orders.findCargoInheritedByOrder(11L, 21L)).thenReturn(List.of(first, second)); when(orders.findCargoInheritedByOrder(11L, 21L)).thenReturn(List.of(first, second));
var response = controller.listForCartonLabels("internal-token", 11L, 21L); var response = controller.listForCartonLabels("internal-token", 11L, 21L);
@@ -98,6 +100,8 @@ class InternalOrderCargoControllerTest {
.containsExactly(31L, 32L); .containsExactly(31L, 32L);
assertThat(response.data().get(0).packageCount()).isEqualTo(3); assertThat(response.data().get(0).packageCount()).isEqualTo(3);
assertThat(response.data().get(0).lengthCm()).isEqualByComparingTo("60"); assertThat(response.data().get(0).lengthCm()).isEqualByComparingTo("60");
assertThat(response.data()).extracting(InternalOrderCargoController.CargoLabelBinding::shipmentId)
.containsExactly("FBA-SHIPMENT-31", "FBA-SHIPMENT-32");
verify(orders).findCargoInheritedByOrder(11L, 21L); verify(orders).findCargoInheritedByOrder(11L, 21L);
} }