feat: complete dropship palletization workflow
This commit is contained in:
@@ -1,54 +1,153 @@
|
||||
openapi: 3.0.3
|
||||
info:
|
||||
title: 一件代发 PDA 合托 API
|
||||
version: 1.0.0
|
||||
description: 测量完成后独立下发;不创建国内库存。PDA 扫箱唛识别 SKU,并按箱数合托。
|
||||
title: 一件代发国内清点组托 API
|
||||
version: 2.0.0
|
||||
description: 测量、计费后独立下发。箱码逐箱确认 SKU 实收数量;托盘码可先扫或后扫,封托后作为不可拆分柜单元。
|
||||
paths:
|
||||
/api/platform/v1/first-leg/pda-dropship/tasks/pending:
|
||||
get:
|
||||
summary: 查询待领取或本人已领取的一件代发合托任务
|
||||
responses: { '200': { description: OK } }
|
||||
summary: 查询待领取或本人已领取任务
|
||||
x-required-authority: platform:firstleg:pda:view
|
||||
responses: {'200': {description: OK}}
|
||||
/api/platform/v1/first-leg/pda-dropship/tasks/{taskId}:
|
||||
get:
|
||||
summary: 查询任务、托盘、入仓单、SKU 和箱数明细
|
||||
summary: 查询任务、已清点待绑箱及托盘结果
|
||||
x-required-authority: platform:firstleg:pda:view
|
||||
parameters: [{$ref: '#/components/parameters/TaskId'}, {$ref: '#/components/parameters/WarehouseId'}]
|
||||
responses: {'200': {description: OK}}
|
||||
/api/platform/v1/first-leg/pda-dropship/tasks/{taskId}/cartons/resolve:
|
||||
get:
|
||||
summary: 扫箱码解析入仓码、SKU 和应收数量,不返回全部未清点箱
|
||||
x-required-authority: platform:firstleg:pda:view
|
||||
parameters:
|
||||
- { name: taskId, in: path, required: true, schema: { type: integer, format: int64 } }
|
||||
- { name: warehouseId, in: query, required: true, schema: { type: integer, format: int64 } }
|
||||
responses: { '200': { description: OK } }
|
||||
- {$ref: '#/components/parameters/TaskId'}
|
||||
- {$ref: '#/components/parameters/WarehouseId'}
|
||||
- {name: boxCode, in: query, required: true, schema: {type: string, maxLength: 80}}
|
||||
responses: {'200': {description: OK}}
|
||||
/api/platform/v1/first-leg/pda-dropship/tasks/{taskId}/claim:
|
||||
post:
|
||||
summary: 领取合托任务
|
||||
parameters: [{ name: taskId, in: path, required: true, schema: { type: integer, format: int64 } }]
|
||||
responses: { '200': { description: OK } }
|
||||
/api/platform/v1/first-leg/pda-dropship/tasks/{taskId}/pallets/open:
|
||||
summary: 领取任务
|
||||
x-required-authority: platform:firstleg:pda:work
|
||||
parameters: [{$ref: '#/components/parameters/TaskId'}]
|
||||
requestBody: {required: true, content: {application/json: {schema: {$ref: '#/components/schemas/ClaimRequest'}}}}
|
||||
responses: {'200': {description: OK}}
|
||||
/api/platform/v1/first-leg/pda-dropship/tasks/{taskId}/cartons/count:
|
||||
post:
|
||||
summary: 开启一个现场托盘
|
||||
parameters: [{ name: taskId, in: path, required: true, schema: { type: integer, format: int64 } }]
|
||||
responses: { '200': { description: OK } }
|
||||
/api/platform/v1/first-leg/pda-dropship/tasks/{taskId}/pallets/{palletId}/scan:
|
||||
summary: 逐箱确认 SKU 实收数量,可同时绑定当前托盘
|
||||
description: palletNo 为空时进入 COUNTED_UNBOUND;不为空时幂等获取或创建 OPEN 托盘并绑定。数量不一致必须 ACCEPT_VARIANCE 且填写说明。
|
||||
x-required-authority: platform:firstleg:pda:work
|
||||
parameters: [{$ref: '#/components/parameters/TaskId'}]
|
||||
requestBody: {required: true, content: {application/json: {schema: {$ref: '#/components/schemas/CountCartonRequest'}}}}
|
||||
responses: {'200': {description: OK}}
|
||||
/api/platform/v1/first-leg/pda-dropship/tasks/{taskId}/pallets/bind-pending:
|
||||
post:
|
||||
summary: 扫箱唛识别 SKU 并填写上托箱数
|
||||
summary: 扫托盘码并把当前任务全部待绑箱绑定到该托盘
|
||||
x-required-authority: platform:firstleg:pda:work
|
||||
parameters: [{$ref: '#/components/parameters/TaskId'}]
|
||||
requestBody: {required: true, content: {application/json: {schema: {$ref: '#/components/schemas/BindPendingRequest'}}}}
|
||||
responses: {'200': {description: OK}}
|
||||
/api/platform/v1/first-leg/pda-dropship/tasks/{taskId}/cartons/{cartonId}/move:
|
||||
post:
|
||||
summary: 换托,targetPalletNo 为空时退回待绑区
|
||||
x-required-authority: platform:firstleg:pda:work
|
||||
parameters:
|
||||
- { name: taskId, in: path, required: true, schema: { type: integer, format: int64 } }
|
||||
- { name: palletId, in: path, required: true, schema: { type: integer, format: int64 } }
|
||||
responses: { '200': { description: OK } }
|
||||
- {$ref: '#/components/parameters/TaskId'}
|
||||
- {name: cartonId, in: path, required: true, schema: {type: integer, format: int64}}
|
||||
requestBody: {required: true, content: {application/json: {schema: {$ref: '#/components/schemas/MoveCartonRequest'}}}}
|
||||
responses: {'200': {description: OK}}
|
||||
/api/platform/v1/first-leg/pda-dropship/tasks/{taskId}/pallets/{palletId}/seal:
|
||||
post:
|
||||
summary: 完成合托并生成 DP 托盘号
|
||||
summary: 封托;禁止空托、待绑箱、版本冲突和重复归托
|
||||
x-required-authority: platform:firstleg:pda:work
|
||||
parameters:
|
||||
- { name: taskId, in: path, required: true, schema: { type: integer, format: int64 } }
|
||||
- { name: palletId, in: path, required: true, schema: { type: integer, format: int64 } }
|
||||
responses: { '200': { description: OK } }
|
||||
- {$ref: '#/components/parameters/TaskId'}
|
||||
- {name: palletId, in: path, required: true, schema: {type: integer, format: int64}}
|
||||
requestBody: {required: true, content: {application/json: {schema: {$ref: '#/components/schemas/SealPalletRequest'}}}}
|
||||
responses: {'200': {description: OK}}
|
||||
/api/platform/v1/first-leg/pda-dropship/inbound-orders/{inboundId}/pallets:
|
||||
get:
|
||||
summary: 入仓单查看绑定的一个或多个托盘及各自箱数
|
||||
parameters: [{ name: inboundId, in: path, required: true, schema: { type: integer, format: int64 } }]
|
||||
responses: { '200': { description: OK } }
|
||||
summary: Admin 查询入仓单权威托盘结果
|
||||
x-required-authority: firstleg:inbound:list
|
||||
responses: {'200': {description: OK}}
|
||||
/api/platform/v1/first-leg/pda-dropship/inbound-orders/{inboundId}/pallets/{palletId}/print:
|
||||
get:
|
||||
summary: 打印托盘号、入仓码和 SKU 箱数托盘唛
|
||||
parameters:
|
||||
- { name: inboundId, in: path, required: true, schema: { type: integer, format: int64 } }
|
||||
- { name: palletId, in: path, required: true, schema: { type: integer, format: int64 } }
|
||||
responses:
|
||||
'200': { description: PDF, content: { application/pdf: { schema: { type: string, format: binary } } } }
|
||||
summary: 打印托盘码、入仓码和 SKU 实收汇总
|
||||
x-required-authority: firstleg:inbound:list
|
||||
responses: {'200': {description: PDF}}
|
||||
components:
|
||||
parameters:
|
||||
TaskId: {name: taskId, in: path, required: true, schema: {type: integer, format: int64}}
|
||||
WarehouseId: {name: warehouseId, in: query, required: true, schema: {type: integer, format: int64}}
|
||||
schemas:
|
||||
Carton:
|
||||
type: object
|
||||
properties:
|
||||
cartonId: {type: integer, format: int64, nullable: true}
|
||||
boxCode: {type: string}
|
||||
inboundId: {type: integer, format: int64}
|
||||
inboundCode: {type: string}
|
||||
inboundDetailId: {type: integer, format: int64}
|
||||
skuCode: {type: string}
|
||||
cargoName: {type: string, nullable: true}
|
||||
expectedSkuQuantity: {type: integer, minimum: 1}
|
||||
actualSkuQuantity: {type: integer, minimum: 1, nullable: true}
|
||||
discrepancyStatus: {type: string, enum: [MATCH, ACCEPTED_VARIANCE], nullable: true}
|
||||
discrepancyRemark: {type: string, nullable: true}
|
||||
countStatus: {type: string, enum: [UNCOUNTED, COUNTED_UNBOUND, BOUND]}
|
||||
palletId: {type: integer, format: int64, nullable: true}
|
||||
palletNo: {$ref: '#/components/schemas/NullablePalletNo'}
|
||||
canCount: {type: boolean}
|
||||
blockReason: {type: string, nullable: true}
|
||||
Pallet:
|
||||
type: object
|
||||
properties:
|
||||
palletId: {type: integer, format: int64}
|
||||
palletNo: {$ref: '#/components/schemas/PalletNo'}
|
||||
status: {type: string, enum: [OPEN, SEALED]}
|
||||
cartonCount: {type: integer, minimum: 0}
|
||||
skuCount: {type: integer, minimum: 0}
|
||||
discrepancyCartons: {type: integer, minimum: 0}
|
||||
weightKg: {type: number, minimum: 0}
|
||||
volumeCbm: {type: number, minimum: 0}
|
||||
version: {type: integer, minimum: 1}
|
||||
items: {type: array, items: {type: object}}
|
||||
cartons: {type: array, items: {$ref: '#/components/schemas/Carton'}, description: 含稳定 cartonId,换托必须使用该 ID}
|
||||
sealedAt: {type: string, format: date-time, nullable: true}
|
||||
ClaimRequest:
|
||||
type: object
|
||||
required: [warehouseId]
|
||||
properties: {warehouseId: {type: integer, format: int64}}
|
||||
CountCartonRequest:
|
||||
type: object
|
||||
required: [warehouseId, boxCode, actualSkuQuantity, discrepancyAction, operationId]
|
||||
properties:
|
||||
warehouseId: {type: integer, format: int64}
|
||||
boxCode: {type: string, maxLength: 80}
|
||||
actualSkuQuantity: {type: integer, minimum: 1}
|
||||
discrepancyAction: {type: string, enum: [MATCH, ACCEPT_VARIANCE]}
|
||||
discrepancyRemark: {type: string, maxLength: 500, nullable: true}
|
||||
palletNo: {$ref: '#/components/schemas/NullablePalletNo'}
|
||||
operationId: {type: string, maxLength: 128}
|
||||
BindPendingRequest:
|
||||
type: object
|
||||
required: [warehouseId, palletNo, operationId]
|
||||
properties:
|
||||
warehouseId: {type: integer, format: int64}
|
||||
palletNo: {$ref: '#/components/schemas/PalletNo'}
|
||||
operationId: {type: string, maxLength: 128}
|
||||
MoveCartonRequest:
|
||||
type: object
|
||||
required: [warehouseId, operationId]
|
||||
properties:
|
||||
warehouseId: {type: integer, format: int64}
|
||||
targetPalletNo: {$ref: '#/components/schemas/NullablePalletNo'}
|
||||
operationId: {type: string, maxLength: 128}
|
||||
SealPalletRequest:
|
||||
type: object
|
||||
required: [warehouseId, expectedVersion, operationId]
|
||||
properties:
|
||||
warehouseId: {type: integer, format: int64}
|
||||
expectedVersion: {type: integer, minimum: 1}
|
||||
operationId: {type: string, maxLength: 128}
|
||||
PalletNo: {type: string, pattern: '^DP-[0-9]{6}-[0-9]{4}$'}
|
||||
NullablePalletNo: {type: string, pattern: '^DP-[0-9]{6}-[0-9]{4}$', nullable: true}
|
||||
|
||||
@@ -296,7 +296,7 @@ paths:
|
||||
post:
|
||||
summary: 按统一订单条件分页查询履约摘要(Order 内部)
|
||||
description: >-
|
||||
mainStatus 接受六态产品状态;WAIT_SPLIT 为入库完成后的唯一待分柜状态。
|
||||
mainStatus 接受七态产品状态;WAIT_PALLETIZE 为一件代发测量计费后的待清点组托状态,WAIT_SPLIT 为待分柜状态。
|
||||
计费与入库处理中状态在完成前仍归并为 WAIT_MEASURE,不提前开放分柜。
|
||||
security:
|
||||
- internalServiceToken: []
|
||||
@@ -1133,7 +1133,7 @@ paths:
|
||||
/api/platform/v1/inbounds/{inboundId}/measurements/approve:
|
||||
post:
|
||||
summary: 审核通过测量
|
||||
description: 需要 firstleg:inbound:measurement-review 权限。审核通过后立即进入 WAIT_SPLIT,并按该次测量数据尽力生成 CALCULATED 初算费用;价格未覆盖或初算异常只返回非阻断提示,不影响审核结果和待分柜状态。
|
||||
description: 需要 firstleg:inbound:measurement-review 权限。标准头程审核通过后进入 WAIT_SPLIT;一件代发进入 WAIT_PALLETIZE,完成逐箱清点和封托后再进入 WAIT_SPLIT。审核时按该次测量数据尽力生成 CALCULATED 初算费用;价格未覆盖或初算异常只返回非阻断提示。
|
||||
parameters:
|
||||
- {name: inboundId, in: path, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
|
||||
- {name: tenantId, in: query, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
|
||||
@@ -1150,7 +1150,7 @@ paths:
|
||||
expectedVersion: {type: integer, minimum: 0}
|
||||
reason: {type: string, maxLength: 1000}
|
||||
responses:
|
||||
'200': {description: 成功或业务失败,按响应体 code 判断;审核成功 data.processStatus 固定为 WAIT_SPLIT,initialPricingSucceeded 表示是否同时生成初算费用,初算失败时 feeStatus=UNPRICED 且主流程仍成功}
|
||||
'200': {description: 成功或业务失败,按响应体 code 判断;审核成功后标准头程 data.processStatus=WAIT_SPLIT,一件代发为 WAIT_PALLETIZE;initialPricingSucceeded 表示是否同时生成初算费用,未覆盖时 feeStatus=UNPRICED 且主流程仍成功}
|
||||
/api/platform/v1/inbounds/{inboundId}/measurements/submit:
|
||||
post:
|
||||
summary: 提交测量完成
|
||||
@@ -1164,7 +1164,7 @@ paths:
|
||||
/api/merchant/v1/first-leg/orders/{orderId}/inbound-billing:
|
||||
get:
|
||||
summary: 客户查询已完成入库结果和最新已发布费用
|
||||
description: 需要 merchant:order:view 权限;客户仅能按登录态客户范围查看。入库流程达到 WAIT_SPLIT 后,费用在 LOADING、LOADED、DELIVERED 仍持续可见;始终要求 measureReviewStatus=APPROVED、feeStatus=SENT 且存在 PUBLISHED 入库运费明细。latestFee.customerConfirmationStatus 表示客户是否已确认当前费用版本。
|
||||
description: 需要 merchant:order:view 权限;客户仅能按登录态客户范围查看。一件代发在 WAIT_PALLETIZE 清点组托阶段即可查看并确认已发布费用,之后在 WAIT_SPLIT、LOADING、LOADED、DELIVERED 持续可见;始终要求 measureReviewStatus=APPROVED、feeStatus=SENT 且存在 PUBLISHED 入库运费明细。
|
||||
parameters:
|
||||
- {name: orderId, in: path, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
|
||||
responses:
|
||||
@@ -1383,8 +1383,8 @@ components:
|
||||
invalidatedFeeId: {type: integer, format: int64, nullable: true}
|
||||
UnifiedMainStatus:
|
||||
type: string
|
||||
enum: [PENDING_REVIEW, WAIT_MEASURE, WAIT_SPLIT, LOADING, LOADED, DELIVERED]
|
||||
description: 六态产品主状态;WAIT_SPLIT 为入库完成后的唯一待分柜状态
|
||||
enum: [PENDING_REVIEW, WAIT_MEASURE, WAIT_PALLETIZE, WAIT_SPLIT, LOADING, LOADED, DELIVERED]
|
||||
description: 七态产品主状态;WAIT_PALLETIZE 仅表示一件代发待清点组托
|
||||
UnifiedInboundQuery:
|
||||
type: object
|
||||
properties:
|
||||
@@ -1393,7 +1393,7 @@ components:
|
||||
orderNo: {type: string, maxLength: 64, nullable: true}
|
||||
mainStatus:
|
||||
type: string
|
||||
enum: [PENDING_REVIEW, WAIT_MEASURE, WAIT_SPLIT, LOADING, LOADED, DELIVERED]
|
||||
enum: [PENDING_REVIEW, WAIT_MEASURE, WAIT_PALLETIZE, WAIT_SPLIT, LOADING, LOADED, DELIVERED]
|
||||
nullable: true
|
||||
description: WAIT_SPLIT 为唯一待分柜筛选值
|
||||
customerId: {type: integer, format: int64, nullable: true}
|
||||
@@ -1511,6 +1511,7 @@ components:
|
||||
deliveryWarehouseName: {type: string, nullable: true}
|
||||
businessType: {type: string, nullable: true}
|
||||
fulfillmentType: {type: string, enum: [STANDARD, ONE_CLICK_DROPSHIP], nullable: true}
|
||||
lxCode: {type: string, nullable: true, description: 一件代发线路或履约产品编码快照}
|
||||
channelCode: {type: string, nullable: true}
|
||||
channelName: {type: string, nullable: true}
|
||||
taxMode: {type: string, nullable: true}
|
||||
|
||||
@@ -170,104 +170,11 @@ paths:
|
||||
expectedVersion: {type: integer, minimum: 0}
|
||||
reason: {type: string, minLength: 1, maxLength: 500}
|
||||
responses: {'200': {description: 作废后柜级证据列表}}
|
||||
/api/platform/v1/first-leg/pda-loading/tasks/{taskId}/pallets:
|
||||
get:
|
||||
summary: 查询一件代发现场实际托盘、SKU汇总和逐箱明细
|
||||
parameters:
|
||||
- {$ref: '#/components/parameters/TaskId'}
|
||||
- {name: warehouseId, in: query, required: true, schema: {type: integer, format: int64, minimum: 1}}
|
||||
responses:
|
||||
'200':
|
||||
description: 当前任务未取消的现场托盘
|
||||
content: {application/json: {schema: {type: array, items: {$ref: '#/components/schemas/WorkPallet'}}}}
|
||||
/api/platform/v1/first-leg/pda-loading/tasks/{taskId}/pallets/open:
|
||||
post:
|
||||
summary: 为已领取任务开启一个一件代发现场托盘
|
||||
parameters: [{$ref: '#/components/parameters/TaskId'}]
|
||||
requestBody:
|
||||
required: true
|
||||
content: {application/json: {schema: {$ref: '#/components/schemas/OpenPalletRequest'}}}
|
||||
responses:
|
||||
'200': {description: 已开启托盘或相同operationId的幂等结果}
|
||||
/api/platform/v1/first-leg/pda-loading/tasks/{taskId}/pallets/{palletId}/cartons/scan:
|
||||
post:
|
||||
summary: 扫描一件代发箱唛上托;箱唛已在其他未封托托盘时按箱移托
|
||||
description: 本操作只记录实际箱到托关系,不推进既有拣货数量、订单状态或仓库资源结算。
|
||||
parameters: [{$ref: '#/components/parameters/TaskId'}, {$ref: '#/components/parameters/PalletId'}]
|
||||
requestBody:
|
||||
required: true
|
||||
content: {application/json: {schema: {$ref: '#/components/schemas/ScanCartonRequest'}}}
|
||||
responses:
|
||||
'200': {description: 包含最新SKU与箱唛汇总的目标托盘}
|
||||
/api/platform/v1/first-leg/pda-loading/tasks/{taskId}/pallets/{palletId}/seal:
|
||||
post:
|
||||
summary: 封托并校验现场上托箱数未超过既有PDA已提交拣货箱数
|
||||
parameters: [{$ref: '#/components/parameters/TaskId'}, {$ref: '#/components/parameters/PalletId'}]
|
||||
requestBody:
|
||||
required: true
|
||||
content: {application/json: {schema: {$ref: '#/components/schemas/SealPalletRequest'}}}
|
||||
responses:
|
||||
'200': {description: 已封托托盘或A0409数量/版本冲突}
|
||||
components:
|
||||
parameters:
|
||||
TaskId: {name: taskId, in: path, required: true, schema: {type: integer, format: int64, minimum: 1}}
|
||||
ItemId: {name: itemId, in: path, required: true, schema: {type: integer, format: int64, minimum: 1}}
|
||||
PalletId: {name: palletId, in: path, required: true, schema: {type: integer, format: int64, minimum: 1}}
|
||||
schemas:
|
||||
OpenPalletRequest:
|
||||
type: object
|
||||
required: [warehouseId, palletCode, operationId]
|
||||
properties:
|
||||
warehouseId: {type: integer, format: int64, minimum: 1}
|
||||
warehousePalletId: {type: integer, format: int64, minimum: 1, nullable: true}
|
||||
palletCode: {type: string, maxLength: 64}
|
||||
operationId: {type: string, maxLength: 128}
|
||||
ScanCartonRequest:
|
||||
type: object
|
||||
required: [warehouseId, boxCode, operationId]
|
||||
properties:
|
||||
warehouseId: {type: integer, format: int64, minimum: 1}
|
||||
boxCode: {type: string, maxLength: 80}
|
||||
operationId: {type: string, maxLength: 128}
|
||||
SealPalletRequest:
|
||||
type: object
|
||||
required: [warehouseId, expectedVersion, operationId]
|
||||
properties:
|
||||
warehouseId: {type: integer, format: int64, minimum: 1}
|
||||
expectedVersion: {type: integer, minimum: 0}
|
||||
operationId: {type: string, maxLength: 128}
|
||||
WorkPallet:
|
||||
type: object
|
||||
required: [id, palletCode, status, version, cartonCount, skuCount, customerCount, skus, cartons]
|
||||
properties:
|
||||
id: {type: integer, format: int64}
|
||||
palletCode: {type: string}
|
||||
warehousePalletId: {type: integer, format: int64, nullable: true}
|
||||
status: {type: string, enum: [OPEN, SEALED]}
|
||||
version: {type: integer, minimum: 0}
|
||||
cartonCount: {type: integer, minimum: 0}
|
||||
skuCount: {type: integer, minimum: 0}
|
||||
customerCount: {type: integer, minimum: 0}
|
||||
skus: {type: array, items: {$ref: '#/components/schemas/WorkPalletSku'}}
|
||||
cartons: {type: array, items: {$ref: '#/components/schemas/WorkPalletCarton'}}
|
||||
WorkPalletSku:
|
||||
type: object
|
||||
required: [skuCode, cartonCount, productQuantity]
|
||||
properties:
|
||||
skuCode: {type: string}
|
||||
cartonCount: {type: integer, minimum: 1}
|
||||
productQuantity: {type: integer, format: int64, minimum: 0}
|
||||
WorkPalletCarton:
|
||||
type: object
|
||||
required: [id, boxCode, skuCode, tenantId, inboundId, inboundDetailId]
|
||||
properties:
|
||||
id: {type: integer, format: int64}
|
||||
boxCode: {type: string}
|
||||
skuCode: {type: string}
|
||||
tenantId: {type: integer, format: int64}
|
||||
inboundId: {type: integer, format: int64}
|
||||
inboundDetailId: {type: integer, format: int64}
|
||||
unitsPerCarton: {type: integer, minimum: 1, nullable: true}
|
||||
Task:
|
||||
type: object
|
||||
required: [id, loadingPlanId, containerBookingId, inboundId, inboundVersion, loadingVersion, cabinetNo, sourceType, recordStatus, taskStatus, workflowStatus, version, items]
|
||||
|
||||
Reference in New Issue
Block a user