feat: close preload confirmation and loading flow

This commit is contained in:
2026-08-15 17:04:00 +08:00
parent 5b8e7d6989
commit a35794e918
34 changed files with 1194 additions and 512 deletions
@@ -17,7 +17,7 @@ paths:
- name: status
in: query
description: 预装状态
schema: {type: string, enum: [LOADING]}
schema: {type: string, enum: [EDITING, LOADING]}
- {$ref: '#/components/parameters/OptionalWarehouseId'}
- {$ref: '#/components/parameters/CreatedFrom'}
- {$ref: '#/components/parameters/CreatedTo'}
@@ -34,7 +34,7 @@ paths:
/api/platform/v1/first-leg/loading-plans/{planId}/transport:
patch:
summary: 修改预装运输信息
description: 仅 LOADING 状态允许修改集装箱号与航次;装柜中可以维护未拣货明细。
description: 已推送且仍为 EDITING 的预装清单可补录或修改集装箱号与航次;LOADING 阶段按稳定柜次身份规则维护,不能清空已创建 PDA 任务的柜号。
x-permission: platform:firstleg:preload:edit
parameters:
- {$ref: '#/components/parameters/PlanId'}
@@ -47,6 +47,17 @@ paths:
schema: {$ref: '#/components/schemas/TransportUpdateRequest'}
responses:
'200': {$ref: '#/components/responses/PreloadDetailResponse'}
/api/platform/v1/first-leg/loading-plans/{planId}/confirm:
post:
summary: 原子确认整份预装计划
description: 以 loadingPlanId 为唯一范围,原子确认全部已分配入库预装票据。要求计划已 push 且仍为 EDITING、真实集装箱号已录入、稳定 bridge 完整、真实订舱已关联并为 RELEASED;任一票不满足均不写入。成功后唯一创建待领取 PDA task,claim 后才推进 LOADING。同一 Idempotency-Key 与相同请求精确重放原响应,不同 Key 重复确认返回业务冲突。
x-permission: platform:firstleg:preload:edit
parameters: [{$ref: '#/components/parameters/PlanId'}, {$ref: '#/components/parameters/IdempotencyKey'}]
requestBody:
required: true
content: {application/json: {schema: {$ref: '#/components/schemas/ConfirmPreloadRequest'}}}
responses:
'200': {$ref: '#/components/responses/PreloadConfirmationResponse'}
/api/platform/v1/first-leg/loading-lists:
get:
summary: 分页查询装柜清单
@@ -175,6 +186,9 @@ components:
PreloadDetailResponse:
description: 预装清单详情查询或操作成功,也可能返回业务失败
content: {application/json: {schema: {$ref: '#/components/schemas/PreloadDetailEnvelope'}}}
PreloadConfirmationResponse:
description: 计划级预装确认成功、精确重放或业务失败
content: {application/json: {schema: {$ref: '#/components/schemas/PreloadConfirmationEnvelope'}}}
ConfirmedPageResponse:
description: 装柜清单分页查询成功或业务失败,按响应体 code 判断
content: {application/json: {schema: {$ref: '#/components/schemas/ConfirmedPageEnvelope'}}}
@@ -218,6 +232,14 @@ components:
data:
allOf: [{$ref: '#/components/schemas/PreloadDetail'}]
nullable: true
PreloadConfirmationEnvelope:
allOf:
- {$ref: '#/components/schemas/ApiEnvelope'}
- type: object
properties:
data:
allOf: [{$ref: '#/components/schemas/PreloadConfirmation'}]
nullable: true
ConfirmedPageEnvelope:
allOf:
- {$ref: '#/components/schemas/ApiEnvelope'}
@@ -268,26 +290,61 @@ components:
customerName: {type: string, nullable: true, description: 客户名称}
PreloadSummary:
type: object
required: [planId, containerBookingId, preloadNo, customers, status, skuCount, totalPackageCount, totalVolumeCbm, totalGrossWeightKg, createdAt, version]
required: [planId, containerBookingId, preloadNo, customers, status, skuCount, totalPackageCount, totalVolumeCbm, totalGrossWeightKg, createdAt, version, readiness]
properties:
planId: {$ref: '#/components/schemas/LongId'}
containerBookingId: {$ref: '#/components/schemas/LongId'}
preloadNo: {type: string, description: 预装单号}
containerNo: {type: string, nullable: true, description: 集装箱号}
internalContainerNo: {type: string, nullable: true, description: 内部柜号}
cabinetNo: {type: string, nullable: true, description: 稳定柜次号;不得与真实集装箱号混用}
customers: {type: array, description: 计划包含的客户, items: {$ref: '#/components/schemas/Customer'}}
warehouseId: {$ref: '#/components/schemas/NullableLongId'}
warehouseName: {type: string, nullable: true, description: 仓库名称}
vesselName: {type: string, nullable: true, description: 船名}
voyageNo: {type: string, nullable: true, description: 航次}
containerType: {type: string, nullable: true, description: 货柜类型}
status: {type: string, enum: [LOADING], description: 装柜状态}
status: {type: string, enum: [EDITING, LOADING], description: 装柜计划状态}
skuCount: {type: string, pattern: '^[0-9]+$', description: SKU 种类数}
totalPackageCount: {type: string, pattern: '^[0-9]+$', description: 总箱数}
totalVolumeCbm: {type: number, description: 总体积,单位立方米}
totalGrossWeightKg: {type: number, description: 总毛重,单位千克}
createdAt: {type: string, format: date-time, description: 创建时间}
version: {type: integer, format: int32, minimum: 0, description: 乐观锁版本}
readiness: {$ref: '#/components/schemas/PreloadReadiness'}
PreloadReadiness:
type: object
required: [preloadPushed, containerNoReady, preloadLinkCount, confirmedPreloadCount, confirmationStatus, canConfirm, readyForPda, blockingReasons]
properties:
preloadPushed: {type: boolean, description: 是否已完成 push-preload}
containerNoReady: {type: boolean, description: 是否已录入真实集装箱号 containerNo}
preloadLinkCount: {type: integer, format: int32, minimum: 0, description: 计划关联的入库预装票据数}
confirmedPreloadCount: {type: integer, format: int32, minimum: 0, description: 已确认预装票据数}
oceanBookingId: {$ref: '#/components/schemas/NullableLongId'}
oceanBookingStatus: {type: string, nullable: true, enum: [CONFIRMED, CHANGE_PENDING, RELEASED, CANCELLED], description: 真实订舱当前状态}
pdaTaskId: {$ref: '#/components/schemas/NullableLongId'}
pdaTaskStatus: {type: string, nullable: true, description: PDA task 当前状态}
confirmationStatus: {type: string, enum: [PENDING, PARTIALLY_CONFIRMED, CONFIRMED], description: 整份计划的预装确认状态}
canConfirm: {type: boolean, description: 当前是否可调用计划级确认接口}
readyForPda: {type: boolean, description: PDA 创建前置条件是否全部满足;task 已创建后仍为 true}
blockingReasons:
type: array
description: 阻止计划确认的稳定原因码
items: {type: string, enum: [PRELOAD_NOT_PUSHED, LOADING_PLAN_NOT_EDITING, CONTAINER_NO_MISSING, PRELOAD_LINK_MISSING, OCEAN_BOOKING_NOT_LINKED, OCEAN_BOOKING_NOT_RELEASED, PDA_TASK_ALREADY_CREATED, PRELOAD_ALREADY_CONFIRMED]}
ConfirmPreloadRequest:
type: object
required: [expectedVersion]
additionalProperties: false
properties:
expectedVersion: {type: integer, format: int32, minimum: 0, description: 当前装柜计划 version}
PreloadConfirmation:
type: object
required: [planId, containerBookingId, confirmationStatus, version, readiness]
properties:
planId: {$ref: '#/components/schemas/LongId'}
containerBookingId: {$ref: '#/components/schemas/LongId'}
confirmationStatus: {type: string, enum: [CONFIRMED]}
version: {type: integer, format: int32, minimum: 0, description: 确认后的装柜计划 version}
readiness: {$ref: '#/components/schemas/PreloadReadiness'}
ConfirmedSummary:
type: object
required: [planId, containerBookingId, loadingListNo, status, totalPackageCount, totalGrossWeightKg, totalNetWeightKg, totalVolumeCbm, totalQuantity, createdAt, version]
@@ -298,7 +355,7 @@ components:
warehouseId: {$ref: '#/components/schemas/NullableLongId'}
warehouseName: {type: string, nullable: true, description: 仓库名称}
containerNo: {type: string, nullable: true, description: 集装箱号}
internalContainerNo: {type: string, nullable: true, description: 内部柜号}
cabinetNo: {type: string, nullable: true, description: 稳定柜次号}
status: {type: string, enum: [COMPLETED], description: 装柜清单状态}
totalPackageCount: {type: string, pattern: '^[0-9]+$', description: 总箱数}
totalGrossWeightKg: {type: number, description: 总毛重,单位千克}