Files
baiyue-firstleg/lastleg-service/src/main/resources/openapi/overseas-business-v1.yaml
T

1186 lines
72 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
openapi: 3.0.3
info:
title: Lastleg Overseas Business API
version: 1.0.0
paths:
/api/pda/v1/last-leg/receiving-containers/candidates:
get:
summary: 查询当前客户待签收柜号
description: 权限 lastleg:pda:operate;仅 PLATFORM WAREHOUSE_PICKER 可用;仅返回已单调消费 PICKUP_READY(80) 或更高实际船节点、状态为 RECEIVING_AVAILABLE 的柜,不接收 customerId。
security: [{ bearerAuth: [] }]
responses: { '200': { description: 柜号候选及箱数进度, content: { application/json: { schema: { $ref: '#/components/schemas/ReceivingCandidateListApiResponse' } } } }, '403': { description: 缺少 PDA 操作权限 } }
/api/pda/v1/last-leg/receiving-containers/warehouse-profile:
get:
summary: 查询当前PDA账号绑定的海外仓主档
description: 权限 lastleg:pda:operate;仓库ID只取Token,名称与编码由共享仓库主档实时解析,不接收warehouseId参数。
security: [{ bearerAuth: [] }]
responses: { '200': { description: 当前绑定仓库中文名称与编码, content: { application/json: { schema: { $ref: '#/components/schemas/ReceivingWarehouseProfileApiResponse' } } } }, '403': { description: 账号未绑定有效海外仓 } }
/api/pda/v1/last-leg/receiving-containers/{containerNo}:
get:
summary: 查询待签收柜号详情
description: 权限 lastleg:pda:operate;按柜号唯一解析客户并返回柜内全部入仓码、目的类型、目的仓、托数和实收进度。
security: [{ bearerAuth: [] }]
parameters: [{ name: containerNo, in: path, required: true, schema: { type: string } }]
responses: { '200': { description: 柜号详情, content: { application/json: { schema: { $ref: '#/components/schemas/ReceivingSessionApiResponse' } } } }, '409': { description: 当前账号已锁定其他柜号 } }
/api/pda/v1/last-leg/receiving-containers/{containerNo}/prepare:
post:
summary: 选择当前待签收柜号
description: 权限 lastleg:pda:operate;仅 RECEIVING_AVAILABLE 柜可建立 WAIT_SIGN 会话,并以平台操作账号、柜号全局双唯一键防止切柜或多人同时处理。
security: [{ bearerAuth: [] }]
parameters: [{ name: containerNo, in: path, required: true, schema: { type: string } }]
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/ReceivingAction' } } } }
responses: { '200': { description: 当前柜会话, content: { application/json: { schema: { $ref: '#/components/schemas/ReceivingSessionApiResponse' } } } }, '409': { description: 账号或柜号已有未完成会话 } }
/api/pda/v1/last-leg/receiving-containers/current/unload-photos/files:
post:
summary: 上传当前柜签收照片
description: 权限 lastleg:pda:operate;multipart 文件归属当前 WAIT_SIGN 会话。
security: [{ bearerAuth: [] }]
requestBody: { required: true, content: { multipart/form-data: { schema: { type: object, required: [file], properties: { file: { type: string, format: binary } } } } } }
responses: { '200': { description: 文件标识, content: { application/json: { schema: { $ref: '#/components/schemas/ReceivingPhotoApiResponse' } } } }, '409': { description: 当前柜已签收 } }
/api/pda/v1/last-leg/receiving-containers/current/unload-photos/files/{fileId}/download:
get:
summary: 下载当前柜签收照片
description: 权限 lastleg:pda:operate;仅允许下载当前会话已签收角色绑定的照片。
security: [{ bearerAuth: [] }]
parameters:
- { name: fileId, in: path, required: true, schema: { type: string, pattern: '^[1-9][0-9]{0,18}$' } }
responses:
'200':
description: 签收照片字节流;Content-Type 透传文件类型,缺失时为 application/octet-stream;Content-Disposition 为 inline;Cache-Control 为 no-store。
headers:
Content-Disposition: { schema: { type: string }, description: inline 文件名 }
Cache-Control: { schema: { type: string, example: no-store } }
content:
image/jpeg: { schema: { type: string, format: binary } }
image/png: { schema: { type: string, format: binary } }
application/octet-stream: { schema: { type: string, format: binary } }
'403': { description: fileId 未绑定到当前操作员的当前柜会话三类签收照片 }
'404': { description: 当前柜会话或照片不存在 }
/api/pda/v1/last-leg/receiving-containers/current/sign:
post:
summary: 签收当前柜
description: 权限 lastleg:pda:operate;精确校验车牌、封签、开门三类照片各且仅 1 张及文件归属后由 WAIT_SIGN 推进 SIGNED;重拍由调用端在签收前替换对应槽位。
security: [{ bearerAuth: [] }]
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/ReceivingSign' } } } }
responses: { '200': { description: 已签收会话, content: { application/json: { schema: { $ref: '#/components/schemas/ReceivingSessionApiResponse' } } } }, '409': { description: 状态或照片校验失败 } }
/api/pda/v1/last-leg/receiving-containers/current:
get:
summary: 恢复当前账号已签柜
description: 权限 lastleg:pda:operate;返回 WAIT_SIGN、SIGNED 或 RECEIVING 当前柜,不依赖 planNo。
security: [{ bearerAuth: [] }]
responses: { '200': { description: 当前柜完整进度, content: { application/json: { schema: { $ref: '#/components/schemas/ReceivingSessionApiResponse' } } } }, '404': { description: 无当前柜 } }
/api/pda/v1/last-leg/receiving-containers/current/cartons/resolve:
post:
summary: 解析当前柜箱唛
description: 权限 lastleg:pda:operate;FBA 从完整 cartonMark 的第一个 # 前提取固定入仓码,并精确匹配当前锁定柜唯一 FBA line;不要求逐箱 manifest,不校验 SKU 或箱序号。OVERSEAS 必须命中真实 manifest。两者均不返回 SKU,也不登记收货。
security: [{ bearerAuth: [] }]
requestBody: { required: true, content: { application/json: { schema: { type: object, required: [cartonMark], properties: { cartonMark: { type: string } } } } } }
responses: { '200': { description: 箱唛与入仓码信息, content: { application/json: { schema: { $ref: '#/components/schemas/ReceivingCartonResolvedApiResponse' } } } }, '404': { description: 入仓码未命中当前柜,或 OVERSEAS 箱码未命中真实 manifest }, '409': { description: 缺少 #、空入仓码前缀、跨柜或当前柜多重命中 } }
/api/pda/v1/last-leg/receiving-containers/current/pallets/resolve:
post:
summary: 解析当前柜实物托盘码
description: 权限 lastleg:pda:operate;托盘固定从 Warehouse Overseas 公共资源作用域解析并校验实际仓与目的仓。
security: [{ bearerAuth: [] }]
requestBody: { required: true, content: { application/json: { schema: { type: object, required: [palletCode, inboundCode], properties: { palletCode: { type: string }, inboundCode: { type: string } } } } } }
responses: { '200': { description: 可用托盘与目的匹配结果, content: { application/json: { schema: { $ref: '#/components/schemas/ReceivingPalletResolvedApiResponse' } } } }, '409': { description: 仓库、目的仓或托盘状态不符 } }
/api/pda/v1/last-leg/receiving-containers/current/receipts/bulk:
post:
summary: FBA 入仓码按箱数收货
description: 权限 lastleg:pda:operate;只允许 destinationType=FBA,OVERSEAS 在服务端硬拒绝;服务端按当前入仓码所属计划的 line.id ASC 和冻结 SKU 明细顺序拆分箱数并记录真实 SKU 收货;不接收 SKU、customerId、planNo、allocationId、warehouseId、locationId。
security: [{ bearerAuth: [] }]
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/ReceivingBulk' } } } }
responses: { '200': { description: 本次与累计实收进度, content: { application/json: { schema: { $ref: '#/components/schemas/ReceivingReceiptApiResponse' } } } }, '409': { description: 海外仓批量、超收或托盘不匹配 } }
/api/pda/v1/last-leg/receiving-containers/current/receipts/carton:
post:
summary: 海外仓入仓码逐箱收货
description: 权限 lastleg:pda:operate;只允许 destinationType=OVERSEAS,拒绝跨柜、重复箱和不匹配托盘。
security: [{ bearerAuth: [] }]
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/ReceivingCarton' } } } }
responses: { '200': { description: 本次与累计实收进度, content: { application/json: { schema: { $ref: '#/components/schemas/ReceivingReceiptApiResponse' } } } }, '409': { description: FBA逐箱、跨柜、重复箱或托盘不匹配 } }
/api/pda/v1/last-leg/receiving-containers/current/complete:
post:
summary: 完成当前柜收货并入库存
description: 权限 lastleg:pda:operate;仅柜内每个入仓码实收总数精确相等后完成,库存、计划、尾程状态与卸柜 Outbox 同事务落地。
security: [{ bearerAuth: [] }]
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/ReceivingAction' } } } }
responses: { '200': { description: COMPLETED 柜号会话, content: { application/json: { schema: { $ref: '#/components/schemas/ReceivingSessionApiResponse' } } } }, '409': { description: 数量未核平或状态冲突 } }
/api/pda/v1/last-leg/inventory/resolve:
post:
summary: PDA按SKU、箱唛或入仓码扫码查询库存
description: 仅 WAREHOUSE_PICKER + lastleg:pda:operate;海外实际仓只取Token overseasWarehouseId,不接收客户或仓库参数。
security: [{ bearerAuth: [] }]
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/PdaWarehouseScan' } } } }
responses: { '200': { description: 同仓跨客户库存与物理仓位事实, content: { application/json: { schema: { $ref: '#/components/schemas/PdaInventoryScanApiResponse' } } } }, '404': { description: A0404:当前绑定仓无匹配库存 } }
/api/pda/v1/last-leg/locations/resolve:
post:
summary: PDA查询库位容量、状态与库存占用
description: 库位从Warehouse Overseas公共资源解析,并强制匹配Token绑定仓。
security: [{ bearerAuth: [] }]
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/PdaWarehouseScan' } } } }
responses: { '200': { description: 库位物理事实及Lastleg库存占用汇总, content: { application/json: { schema: { $ref: '#/components/schemas/PdaLocationApiResponse' } } } }, '404': { description: A0404:库位不存在或跨仓 } }
/api/pda/v1/last-leg/pallets/resolve:
post:
summary: PDA查询托盘、库位与绑定库存
description: 托盘从Warehouse Overseas公共资源解析;跨Token绑定仓返回A0409。
security: [{ bearerAuth: [] }]
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/PdaWarehouseScan' } } } }
responses: { '200': { description: 托盘物理事实及Lastleg绑定库存, content: { application/json: { schema: { $ref: '#/components/schemas/PdaPalletApiResponse' } } } }, '409': { description: A0409:托盘属于其他仓 } }
/api/pda/v1/last-leg/operations:
get:
summary: 查询当前PDA账号真实作业历史
description: 返回Token绑定仓内当前操作账号的柜号作业及盘点、移库、托盘、换标历史;不含出库或派送。
security: [{ bearerAuth: [] }]
parameters:
- { name: page, in: query, schema: { type: integer, minimum: 1, default: 1 } }
- { name: size, in: query, schema: { type: integer, minimum: 1, maximum: 200, default: 20 } }
- { name: operationType, in: query, schema: { type: string } }
responses: { '200': { description: 真实作业历史分页, content: { application/json: { schema: { $ref: '#/components/schemas/PdaOperationPageApiResponse' } } } } }
/api/platform/v1/last-leg/orders:
get:
summary: 分页查询尾程订单
description: 权限 platform:overseas-warehouse:order:list;平台管理员省略 customerId 时查询全部客户。
security: [{ bearerAuth: [] }]
parameters:
- { name: page, in: query, schema: { type: integer, minimum: 1, default: 1 } }
- { name: size, in: query, schema: { type: integer, minimum: 1, maximum: 200, default: 20 } }
- { name: orderNo, in: query, schema: { type: string } }
- { name: orderType, in: query, schema: { type: string, enum: [FIRST_LEG, RELABEL_APPLICATION, WAREHOUSE_TRANSFER, LOCAL_LOOSEBOARD, RETURN_RELABEL, ONE_CLICK_DROPSHIP] } }
- { name: currentStatus, in: query, schema: { type: string } }
- { name: inboundCode, in: query, schema: { type: string } }
- { name: sourceOrderNo, in: query, schema: { type: string } }
- { name: containerNo, in: query, schema: { type: string } }
- { name: warehouse, in: query, schema: { type: string } }
- { name: transferWarehouseCode, in: query, schema: { type: string } }
- { name: abnormal, in: query, schema: { type: boolean } }
- { name: detained, in: query, schema: { type: boolean } }
- { name: createdFrom, in: query, schema: { type: string, format: date-time } }
- { name: createdTo, in: query, schema: { type: string, format: date-time } }
responses: { '200': { description: 统一 ApiResponse 包装的尾程订单分页;列表行 destinationType 为 FBA 或 OVERSEAS } }
/api/platform/v1/last-leg/inbound-plans/convert:
post:
summary: 平台生成入库计划
description: 权限 platform:overseas-warehouse:inbound-order:create;必须同时传入真实 customerId 与 orderId,服务端按该客户和订单 ID 锁定归属,缺失 customerId 返回 A0400。
security: [{ bearerAuth: [] }]
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [customerId, orderId]
properties:
customerId: { type: string, pattern: '^[1-9][0-9]*$' }
orderId: { type: string, pattern: '^[1-9][0-9]*$' }
responses: { '200': { description: 统一 ApiResponse 包装的入库计划详情 } }
/api/platform/v1/last-leg/dispatches:
get:
summary: 分页查询排车单
description: 权限 platform:overseas-warehouse:inbound-order:list;平台跨客户分页查询,前端不传 customerId。
security: [{ bearerAuth: [] }]
parameters:
- { name: page, in: query, schema: { type: integer, minimum: 1, default: 1 } }
- { name: size, in: query, schema: { type: integer, minimum: 1, maximum: 200, default: 20 } }
- { name: dispatchNo, in: query, schema: { type: string } }
- { name: vehiclePlate, in: query, schema: { type: string } }
- { name: status, in: query, schema: { type: string } }
- { name: fbaAppointmentNo, in: query, schema: { type: string } }
responses:
'200': { description: 统一 ApiResponse 包装的排车单分页,records 元素为 DispatchResponse }
/api/platform/v1/last-leg/dispatches/{dispatchNo}:
get:
summary: 查询排车单详情
description: 权限 platform:overseas-warehouse:inbound-order:list;平台按全局排车单号定位记录,并使用记录自身客户范围查询明细,前端不传 customerId。
security: [{ bearerAuth: [] }]
parameters:
- { name: dispatchNo, in: path, required: true, schema: { type: string } }
responses:
'200': { description: 统一 ApiResponse 包装的 DispatchResponse }
'404': { description: 排车单不存在 }
'409': { description: 排车单号在不同客户下重复,无法唯一定位 }
/api/platform/v1/last-leg/dispatches/candidates:
get:
summary: 查询智能排车候选托盘
description: 权限 platform:overseas-warehouse:inbound-order:list;planIds 为空时平台跨客户查询全部可排托盘,传入时按所选入库计划解析客户范围;仅返回尚未被有效排车锁定的计划或已实收托盘,前端不传 customerId。
security: [{ bearerAuth: [] }]
parameters:
- name: planIds
in: query
required: false
description: 可选的入库计划 ID,逗号分隔;省略时平台查询全部客户候选。
schema: { type: array, minItems: 1, maxItems: 500, items: { type: integer, format: int64 } }
style: form
explode: false
- { name: orderNo, in: query, schema: { type: string } }
- { name: fbaWarehouseCode, in: query, schema: { type: string } }
- { name: sourceStage, in: query, schema: { type: string, enum: [PLAN, RECEIVED] } }
- { name: draftToken, in: query, schema: { type: string, maxLength: 64 }, description: 当前智能排车草稿标识;当前草稿已锁托盘仍可见 }
responses:
'200':
description: 统一 ApiResponse 包装的候选托盘数组
content: { application/json: { schema: { type: array, items: { $ref: '#/components/schemas/SmartDispatchCandidate' } } } }
/api/platform/v1/last-leg/dispatches/pre-arrange:
post:
summary: 创建智能预排车单
description: 权限 platform:overseas-warehouse:inbound-order:smart-dispatch;服务端根据所选托盘解析并校验唯一客户范围,锁定同一海外仓的托盘并创建 PENDING_DEPARTURE 排车单,前端不传 customerId;不开放编辑、取消、depart、PDA 出库或派送。
security: [{ bearerAuth: [] }]
requestBody:
required: true
content: { application/json: { schema: { $ref: '#/components/schemas/SmartDispatchPreArrange' } } }
responses:
'200': { description: 统一 ApiResponse 包装的预排车详情, content: { application/json: { schema: { $ref: '#/components/schemas/DispatchResponse' } } } }
/api/platform/v1/last-leg/dispatches/draft-locks/lock:
post:
summary: 将托盘移入智能排车草稿并立即锁定
description: 权限 platform:overseas-warehouse:inbound-order:smart-dispatch;草稿锁 30 分钟失效,与正式排车锁共享托盘排他约束。
security: [{ bearerAuth: [] }]
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/SmartDispatchDraftPallet' } } } }
responses: { '200': { description: 锁定成功 }, '409': { description: 托盘已被其他草稿或正式排车锁定 } }
/api/platform/v1/last-leg/dispatches/draft-locks/unlock:
post:
summary: 从智能排车草稿移除托盘并立即解锁
security: [{ bearerAuth: [] }]
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/SmartDispatchDraftPallet' } } } }
responses: { '200': { description: 解锁成功 }, '409': { description: 草稿锁不属于当前操作人 } }
/api/platform/v1/last-leg/dispatches/draft-locks/release:
post:
summary: 关闭智能排车草稿并释放草稿内全部托盘
security: [{ bearerAuth: [] }]
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/SmartDispatchDraftRelease' } } } }
responses: { '200': { description: 草稿锁已全部释放 } }
/api/platform/v1/last-leg/dispatches/drafts:
get:
summary: 查询当前操作人的有效智能排车草稿
description: 权限 platform:overseas-warehouse:inbound-order:smart-dispatch;只返回当前操作人未失效且未释放的草稿。
security: [{ bearerAuth: [] }]
responses:
'200': { description: 统一 ApiResponse 包装的智能排车草稿数组, content: { application/json: { schema: { type: array, items: { $ref: '#/components/schemas/SmartDispatchDraft' } } } } }
/api/platform/v1/last-leg/dispatches/drafts/snapshot:
post:
summary: 保存智能排车草稿布局快照
description: 权限 platform:overseas-warehouse:inbound-order:smart-dispatch;草稿仅归当前操作人。
security: [{ bearerAuth: [] }]
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/SmartDispatchDraftSnapshot' } } } }
responses: { '200': { description: 草稿快照保存成功 } }
/api/platform/v1/last-leg/dispatches/drafts/containers:
post:
summary: 在智能排车草稿中新增车厢
description: 权限 platform:overseas-warehouse:inbound-order:smart-dispatch;返回服务端生成的字符串 ID。
security: [{ bearerAuth: [] }]
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/SmartDispatchDraftContainerCreate' } } } }
responses: { '200': { description: 统一 ApiResponse 包装的草稿车厢, content: { application/json: { schema: { $ref: '#/components/schemas/SmartDispatchDraftContainer' } } } } }
/api/platform/v1/last-leg/dispatches/drafts/{draftToken}/containers/{containerId}:
delete:
summary: 删除智能排车草稿中的空车厢
description: 权限 platform:overseas-warehouse:inbound-order:smart-dispatch;仅允许当前操作人删除未绑定托盘的草稿车厢。
security: [{ bearerAuth: [] }]
parameters:
- { name: draftToken, in: path, required: true, schema: { type: string, maxLength: 64 } }
- { name: containerId, in: path, required: true, schema: { type: string } }
responses: { '200': { description: 空车厢删除成功 }, '409': { description: 车厢仍绑定托盘或草稿状态冲突 } }
/api/platform/v1/last-leg/overseas-procurements:
get:
summary: 分页查询海外采购订单
description: 权限 platform:overseas-business:purchase:list;customerId 为空时查询全部客户。
security: [{ bearerAuth: [] }]
parameters:
- { name: customerId, in: query, schema: { type: string } }
- { name: page, in: query, required: true, schema: { type: integer, minimum: 1 } }
- { name: size, in: query, required: true, schema: { type: integer, minimum: 1, maximum: 200 } }
- { name: orderNo, in: query, schema: { type: string } }
- { name: customerKeyword, in: query, schema: { type: string } }
- { name: purchaseCategory, in: query, schema: { type: string } }
- { name: productName, in: query, schema: { type: string } }
- { name: status, in: query, schema: { $ref: '#/components/schemas/ProcurementStatus' } }
- { name: purchaseWarehouseId, in: query, schema: { type: string } }
responses: { '200': { description: 统一 ApiResponse 包装的采购订单分页 } }
/api/platform/v1/last-leg/overseas-procurements/customer-options:
get:
summary: 查询已有采购订单的客户候选
description: 权限 platform:overseas-business:purchase:list;候选来自尾程库采购订单客户快照,不跨库查询 IAM。
security: [{ bearerAuth: [] }]
parameters:
- { name: keyword, in: query, schema: { type: string } }
- { name: limit, in: query, schema: { type: integer, minimum: 1, maximum: 200, default: 50 } }
responses:
'200':
description: 客户候选
content: { application/json: { schema: { $ref: '#/components/schemas/CustomerOptionResponse' } } }
/api/platform/v1/last-leg/overseas-procurements/warehouse-options:
get:
summary: 查询启用的海外合作采购仓候选
description: 权限 platform:overseas-business:purchase:list;复用服务端缓存目录,浏览器不访问国内内部 API。
security: [{ bearerAuth: [] }]
responses:
'200':
description: 采购仓候选
content: { application/json: { schema: { $ref: '#/components/schemas/WarehouseOptionResponse' } } }
/api/platform/v1/last-leg/overseas-procurements/{orderNo}:
parameters:
- { name: orderNo, in: path, required: true, schema: { type: string } }
- { name: customerId, in: query, required: true, schema: { type: string, pattern: '^[1-9][0-9]*$' } }
get:
summary: 查询海外采购订单详情及操作流水
description: 权限 platform:overseas-business:purchase:list。
security: [{ bearerAuth: [] }]
responses: { '200': { description: 统一 ApiResponse 包装的采购订单详情 } }
patch:
summary: 编辑海外采购订单
description: 权限 platform:overseas-business:purchase:edit;可选字段缺失表示不修改,显式 null 或空串表示清空。采购仓名称由 warehouse ID 对应候选快照决定。采购出库不属于本 API。
security: [{ bearerAuth: [] }]
requestBody:
required: true
content: { application/json: { schema: { $ref: '#/components/schemas/ProcurementUpdate' } } }
responses: { '200': { description: 统一 ApiResponse 包装的采购订单详情 }, '409': { description: 乐观锁冲突或状态不允许 } }
/api/platform/v1/last-leg/overseas-procurements/{orderNo}/review:
post:
summary: 审核海外采购订单
description: 权限 platform:overseas-business:purchase:review;同幂等键同请求重放成功,异请求、旧 version 或终态反向审核返回 A0409。
security: [{ bearerAuth: [] }]
parameters:
- { name: orderNo, in: path, required: true, schema: { type: string } }
- { name: customerId, in: query, required: true, schema: { type: string, pattern: '^[1-9][0-9]*$' } }
requestBody:
required: true
content: { application/json: { schema: { $ref: '#/components/schemas/ProcurementReview' } } }
responses: { '200': { description: 统一 ApiResponse 包装的采购订单详情 } }
/api/merchant/v1/last-leg/overseas-procurements:
post:
summary: 客户创建海外采购订单
description: 客户 ID 只取认证身份;新单固定进入 PENDING_REVIEW。
security: [{ bearerAuth: [] }]
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/ProcurementCreate' } } } }
responses: { '200': { description: 统一 ApiResponse 包装的采购订单详情 } }
get:
summary: 客户分页查询自己的海外采购订单
security: [{ bearerAuth: [] }]
responses: { '200': { description: 统一 ApiResponse 包装的采购订单分页 } }
/api/merchant/v1/last-leg/overseas-procurements/{orderNo}:
get:
summary: 客户查询自己的海外采购订单详情及流水
security: [{ bearerAuth: [] }]
parameters: [{ name: orderNo, in: path, required: true, schema: { type: string } }]
responses: { '200': { description: 统一 ApiResponse 包装的采购订单详情 } }
/api/platform/v1/last-leg/us-truck-orders:
get:
summary: 分页查询本土卡车订单
description: 权限 platform:overseas-business:truck:list。
security: [{ bearerAuth: [] }]
responses: { '200': { description: 统一 ApiResponse 包装的卡车订单分页 } }
post:
summary: 平台为指定客户创建本土卡车订单
description: 权限 platform:overseas-business:truck:create;customerId 必填且只作为可信服务端隔离键。
security: [{ bearerAuth: [] }]
parameters: [{ name: customerId, in: query, required: true, schema: { type: string, pattern: '^[1-9][0-9]*$' } }]
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/TruckCreate' } } } }
responses: { '200': { description: 统一 ApiResponse 包装的卡车订单详情 } }
/api/platform/v1/last-leg/us-truck-orders/{orderNo}:
parameters:
- { name: orderNo, in: path, required: true, schema: { type: string } }
- { name: customerId, in: query, required: true, schema: { type: string, pattern: '^[1-9][0-9]*$' } }
get:
summary: 查询本土卡车订单详情
description: 权限 platform:overseas-business:truck:list。
security: [{ bearerAuth: [] }]
responses: { '200': { description: 统一 ApiResponse 包装的卡车订单详情 } }
patch:
summary: 平台普通编辑本土卡车订单
description: 权限 platform:overseas-business:truck:edit;仅待审核订单可编辑,不能修改状态。
security: [{ bearerAuth: [] }]
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/TruckUpdate' } } } }
responses: { '200': { description: 统一 ApiResponse 包装的卡车订单详情 } }
/api/platform/v1/last-leg/us-truck-orders/{orderNo}/status:
patch:
summary: 取消未发车的本土卡车订单
description: 权限 platform:overseas-business:truck:status;该通用入口只接受 CANCELLED,正向状态必须使用具名命令,不能绕过实收、超托与分配事实。
security: [{ bearerAuth: [] }]
parameters:
- { name: orderNo, in: path, required: true, schema: { type: string } }
- { name: customerId, in: query, required: true, schema: { type: string, pattern: '^[1-9][0-9]*$' } }
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/TruckCancel' } } } }
responses: { '200': { description: 统一 ApiResponse 包装的卡车订单详情 }, '409': { description: 非法状态迁移 } }
/api/platform/v1/last-leg/us-truck-orders/{orderNo}/review:
parameters: &truckOrderTarget
- { name: orderNo, in: path, required: true, schema: { type: string } }
- { name: customerId, in: query, required: true, schema: { type: string, pattern: '^[1-9][0-9]*$' } }
post:
summary: 审核本土卡车订单
description: 权限 platform:overseas-business:truck:status;PENDING_REVIEW 审核通过进入 WAITING_INBOUND 并生成预期托盘;拒绝进入 REJECTED。幂等键异请求、旧 version 或非法跳转返回 A0409。
security: [{ bearerAuth: [] }]
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/TruckReview' } } } }
responses: { '200': { description: 卡车订单详情 }, '409': { description: 版本、状态或幂等冲突 } }
/api/platform/v1/last-leg/us-truck-orders/{orderNo}/receive-pallets:
post:
summary: 记录本土卡车订单实收托盘
description: 权限 platform:overseas-business:truck:status;幂等记录实收,不创建海外仓出库或派送单。
security: [{ bearerAuth: [] }]
parameters:
- { name: orderNo, in: path, required: true, schema: { type: string } }
- { name: customerId, in: query, required: true, schema: { type: string, pattern: '^[1-9][0-9]*$' } }
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/TruckReceivePallets' } } } }
responses: { '200': { description: 统一 ApiResponse 包装的卡车订单详情 } }
/api/platform/v1/last-leg/us-truck-orders/{orderNo}/review-pallet-overage:
parameters: *truckOrderTarget
post:
summary: 审核实收超出申报数的托盘
description: 权限 platform:overseas-business:truck:status;APPROVE 将超收托盘纳入本单并进入 WAITING_CONSOLIDATION;REJECT 标记超收托盘拒收并按原申报数继续。
security: [{ bearerAuth: [] }]
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/TruckReviewPalletOverage' } } } }
responses: { '200': { description: 卡车订单详情 }, '409': { description: 版本、状态或幂等冲突 } }
/api/platform/v1/last-leg/us-truck-orders/{orderNo}/allocate-pallets:
parameters: *truckOrderTarget
post:
summary: 分配已实收托盘到本土卡车行程
description: 权限 platform:overseas-business:truck:status;仅接收本单 RECEIVED 托盘 ID;部分分配进入 PARTIALLY_ALLOCATED,全部分配进入 ALLOCATED。不创建海外仓出库单或扣减库存。
security: [{ bearerAuth: [] }]
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/TruckAllocatePallets' } } } }
responses: { '200': { description: 卡车订单详情 }, '409': { description: 托盘归属、状态、版本或幂等冲突 } }
/api/platform/v1/last-leg/us-truck-orders/{orderNo}/prepare-dispatch:
parameters: *truckOrderTarget
post:
summary: 全部托盘分配后准备派车
description: 权限 platform:overseas-business:truck:status;旧 version、幂等键异请求或非 ALLOCATED 状态返回 A0409。
security: [{ bearerAuth: [] }]
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/TruckCommand' } } } }
responses: { '200': { description: 状态 PENDING_DISPATCH } }
/api/platform/v1/last-leg/us-truck-orders/{orderNo}/dispatch:
parameters: *truckOrderTarget
post:
summary: 确认本土卡车已派车
description: 权限 platform:overseas-business:truck:status;本土卡车单自身履约,不创建海外仓排车单、出库单或派送单。
security: [{ bearerAuth: [] }]
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/TruckCommand' } } } }
responses: { '200': { description: 状态 DISPATCHED } }
/api/platform/v1/last-leg/us-truck-orders/{orderNo}/start-transit:
parameters: *truckOrderTarget
post:
summary: 确认本土卡车开始运输
description: 权限 platform:overseas-business:truck:status;仅 DISPATCHED 可进入 IN_TRANSIT。
security: [{ bearerAuth: [] }]
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/TruckCommand' } } } }
responses: { '200': { description: 状态 IN_TRANSIT } }
/api/platform/v1/last-leg/us-truck-orders/{orderNo}/complete:
parameters: *truckOrderTarget
post:
summary: 完成本土卡车订单
description: 权限 platform:overseas-business:truck:status;仅 IN_TRANSIT 可进入不可逆 COMPLETED。
security: [{ bearerAuth: [] }]
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/TruckCommand' } } } }
responses: { '200': { description: 状态 COMPLETED } }
/api/platform/v1/last-leg/local-looseboard-orders:
get:
summary: 分页查询本土散板订单
description: 权限 platform:overseas-business:looseboard:list。
security: [{ bearerAuth: [] }]
responses: { '200': { description: 统一 ApiResponse 包装的散板订单分页 } }
post:
summary: 创建本土散板订单
description: 权限 platform:overseas-business:looseboard:create;独立稳定子域,不复用卡车端点。
security: [{ bearerAuth: [] }]
parameters: [{ name: customerId, in: query, required: true, schema: { type: string, pattern: '^[1-9][0-9]*$' } }]
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/LooseboardCreate' } } } }
responses: { '200': { description: 统一 ApiResponse 包装的散板订单详情 } }
/api/platform/v1/last-leg/local-looseboard-orders/{orderNo}:
parameters:
- { name: orderNo, in: path, required: true, schema: { type: string } }
- { name: customerId, in: query, required: true, schema: { type: string, pattern: '^[1-9][0-9]*$' } }
get:
summary: 查询本土散板订单详情及操作流水
description: 权限 platform:overseas-business:looseboard:list。
security: [{ bearerAuth: [] }]
responses: { '200': { description: 统一 ApiResponse 包装的散板订单详情 } }
put:
summary: 全量更新待接单的本土散板订单
description: 权限 platform:overseas-business:looseboard:edit;可空字段传 null 或空串即清空;状态由独立端点推进。
security: [{ bearerAuth: [] }]
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/LooseboardUpdate' } } } }
responses: { '200': { description: 统一 ApiResponse 包装的散板订单详情 }, '409': { description: 版本或状态冲突 } }
/api/platform/v1/last-leg/local-looseboard-orders/{orderNo}/status:
patch:
summary: 推进或取消本土散板订单
description: 权限 platform:overseas-business:looseboard:status;只允许 PENDING_ACCEPTANCE→DISPATCHED→IN_TRANSIT→COMPLETED,另建订单可进入 CANCELLED;幂等键异请求、旧 version、非法跳转或终态反向返回 A0409。
security: [{ bearerAuth: [] }]
parameters:
- { name: orderNo, in: path, required: true, schema: { type: string } }
- { name: customerId, in: query, required: true, schema: { type: string, pattern: '^[1-9][0-9]*$' } }
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/LooseboardStatusChange' } } } }
responses: { '200': { description: 统一 ApiResponse 包装的散板订单详情 }, '409': { description: 非法状态迁移 } }
/api/platform/v1/last-leg/relabel-applications:
get:
summary: 分页查询海外换标单
description: 权限 platform:overseas-warehouse:relabel-order:list;平台查询全部换标单,不接收 customerId。
security: [{ bearerAuth: [] }]
parameters:
- { name: page, in: query, schema: { type: integer, minimum: 1, default: 1 } }
- { name: size, in: query, schema: { type: integer, minimum: 1, maximum: 200, default: 20 } }
- { name: relabelNo, in: query, schema: { type: string, maxLength: 64 } }
- { name: customerOrderNo, in: query, schema: { type: string, maxLength: 128 } }
- { name: skuCode, in: query, schema: { type: string, maxLength: 128 } }
- { name: status, in: query, schema: { $ref: '#/components/schemas/RelabelStatus' } }
- { name: overseasWarehouseId, in: query, schema: { type: string, maxLength: 128 } }
- { name: createdFrom, in: query, schema: { type: string, format: date-time } }
- { name: createdTo, in: query, schema: { type: string, format: date-time } }
responses: { '200': { description: 统一 ApiResponse 包装的换标单分页 } }
post:
summary: 创建海外换标单
description: 权限 platform:overseas-warehouse:relabel-order:create;明细与换标文件按请求快照保存,使用 idempotencyKey 幂等。
security: [{ bearerAuth: [] }]
parameters:
- { name: customerId, in: query, required: true, schema: { type: string, pattern: '^[1-9][0-9]*$' } }
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/RelabelCreate' } } } }
responses: { '200': { description: 统一 ApiResponse 包装的换标单详情 }, '409': { description: 幂等键冲突 } }
/api/platform/v1/last-leg/relabel-applications/{relabelNo}:
get:
summary: 查询海外换标单详情
description: 权限 platform:overseas-warehouse:relabel-order:list。
security: [{ bearerAuth: [] }]
parameters:
- { name: relabelNo, in: path, required: true, schema: { type: string, maxLength: 64 } }
responses: { '200': { description: 统一 ApiResponse 包装的换标单详情 }, '404': { description: 换标单不存在或不属于当前客户 } }
/api/platform/v1/last-leg/relabel-applications/{relabelNo}/status:
put:
summary: 变更海外换标单状态
description: 权限 platform:overseas-warehouse:relabel-order:status;状态按 PENDING_PROCESSING→PROCESSING→COMPLETED/REJECTED/CANCELLED 流转。
security: [{ bearerAuth: [] }]
parameters:
- { name: relabelNo, in: path, required: true, schema: { type: string, maxLength: 64 } }
requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/RelabelStatusChange' } } } }
responses: { '200': { description: 统一 ApiResponse 包装的换标单详情 }, '409': { description: 非法状态迁移或关联尾程单缺失 } }
components:
schemas:
PdaWarehouseScan:
type: object
required: [code]
properties: { code: { type: string, minLength: 1, maxLength: 128 } }
PdaInventoryItem:
type: object
required: [customerId, balanceId, positionId, inboundCode, palletId, palletCode, availablePackages, holdPackages, receivingPackages, status, version]
properties:
customerId: { type: string }
customerName: { type: string, nullable: true }
balanceId: { type: integer, format: int64 }
positionId: { type: integer, format: int64 }
skuCode: { type: string, nullable: true }
productName: { type: string, nullable: true }
inboundCode: { type: string }
cartonMark: { type: string, nullable: true }
palletId: { type: integer, format: int64 }
palletCode: { type: string }
locationId: { type: integer, format: int64, nullable: true }
locationCode: { type: string, nullable: true }
availablePackages: { type: integer, format: int64, minimum: 0 }
holdPackages: { type: integer, format: int64, minimum: 0 }
receivingPackages: { type: integer, format: int64, minimum: 0 }
status: { type: string }
version: { type: integer, format: int64, minimum: 0 }
PdaInventoryScan:
type: object
required: [queryCode, items]
properties:
queryCode: { type: string }
items: { type: array, items: { $ref: '#/components/schemas/PdaInventoryItem' } }
PdaLocation:
type: object
required: [locationId, locationCode, locationType, status, occupiedPackages, inventoryPositionCount]
properties:
locationId: { type: integer, format: int64 }
locationCode: { type: string }
locationType: { type: string }
maxLoadKg: { type: number, nullable: true }
status: { type: string }
occupiedPackages: { type: integer, format: int64, minimum: 0 }
inventoryPositionCount: { type: integer, minimum: 0 }
PdaPallet:
type: object
required: [palletId, palletCode, status, version, locationId, locationCode, occupiedPackages, inventoryPositionCount, inventory]
properties:
palletId: { type: integer, format: int64 }
palletCode: { type: string }
status: { type: string }
version: { type: integer, minimum: 0 }
locationId: { type: integer, format: int64 }
locationCode: { type: string }
occupiedPackages: { type: integer, format: int64, minimum: 0 }
inventoryPositionCount: { type: integer, minimum: 0 }
inventory: { type: array, items: { $ref: '#/components/schemas/PdaInventoryItem' } }
PdaOperation:
type: object
required: [operationId, operationType, businessKey, status, occurredAt]
properties:
operationId: { type: integer, format: int64 }
operationType: { type: string }
businessKey: { type: string }
status: { type: string }
summary: { type: string, nullable: true }
customerId: { type: string, nullable: true }
occurredAt: { type: string, format: date-time }
PdaInventoryScanApiResponse:
allOf:
- { $ref: '#/components/schemas/ReceivingApiResponseBase' }
- type: object
properties: { data: { $ref: '#/components/schemas/PdaInventoryScan' } }
PdaLocationApiResponse:
allOf:
- { $ref: '#/components/schemas/ReceivingApiResponseBase' }
- type: object
properties: { data: { $ref: '#/components/schemas/PdaLocation' } }
PdaPalletApiResponse:
allOf:
- { $ref: '#/components/schemas/ReceivingApiResponseBase' }
- type: object
properties: { data: { $ref: '#/components/schemas/PdaPallet' } }
PdaOperationPageApiResponse:
allOf:
- { $ref: '#/components/schemas/ReceivingApiResponseBase' }
- type: object
properties:
data:
type: object
required: [records, page, size, total, pages]
properties:
records: { type: array, items: { $ref: '#/components/schemas/PdaOperation' } }
page: { type: integer }
size: { type: integer }
total: { type: integer, format: int64 }
pages: { type: integer, format: int64 }
ReceivingAction:
type: object
required: [idempotencyKey]
properties: { idempotencyKey: { type: string, minLength: 1, maxLength: 255 } }
ReceivingSign:
type: object
required: [photos, idempotencyKey]
properties:
photos: { type: array, minItems: 3, maxItems: 3, items: { $ref: '#/components/schemas/ReceivingSignedPhoto' } }
idempotencyKey: { type: string, minLength: 1, maxLength: 255 }
ReceivingSignedPhoto:
type: object
required: [role, fileId]
properties:
role: { type: string, enum: [LICENSE_PLATE, CONTAINER_SEAL, DOOR_OPEN] }
fileId: { type: string, pattern: '^[1-9][0-9]{0,18}$', description: Snowflake file ID kept as a decimal string }
ReceivingSignedSessionPhoto:
type: object
required: [role, fileId, downloadPath]
properties:
role: { type: string, enum: [LICENSE_PLATE, CONTAINER_SEAL, DOOR_OPEN] }
fileId: { type: string, pattern: '^[1-9][0-9]{0,18}$', description: Snowflake file ID kept as a decimal string }
downloadPath: { type: string, description: 用于会话恢复时直接下载签收照片 }
ReceivingBulk:
type: object
required: [inboundCode, palletCode, packageCount, idempotencyKey]
properties:
inboundCode: { type: string, minLength: 1 }
palletCode: { type: string, minLength: 1 }
packageCount: { type: integer, minimum: 1 }
idempotencyKey: { type: string, minLength: 1, maxLength: 255 }
ReceivingCarton:
type: object
required: [cartonMark, palletCode, idempotencyKey]
properties:
cartonMark: { type: string, minLength: 1 }
palletCode: { type: string, minLength: 1 }
idempotencyKey: { type: string, minLength: 1, maxLength: 255 }
ReceivingApiResponseBase:
type: object
required: [code, message, timestamp]
properties:
code: { type: string, example: '200' }
message: { type: string }
requestId: { type: string, nullable: true }
traceId: { type: string, nullable: true }
timestamp: { type: string, format: date-time }
ReceivingInbound:
type: object
required: [inboundCode, destinationType, plannedPalletCount, totalPackages, receivedPackages, pendingPackages]
properties:
inboundCode: { type: string }
destinationType: { type: string, enum: [FBA, OVERSEAS] }
overseasWarehouseId: { type: string, nullable: true, description: 实际海外收货仓ID;与FBA或其他业务目的仓ID严格区分 }
overseasWarehouseName: { type: string, nullable: true, description: 实际海外收货仓名称快照 }
destinationWarehouseId: { type: string, nullable: true }
destinationWarehouseCode: { type: string, nullable: true }
destinationWarehouseName: { type: string, nullable: true }
fbaWarehouseCode: { type: string, nullable: true }
plannedPalletCount: { type: integer }
totalPackages: { type: integer }
receivedPackages: { type: integer }
pendingPackages: { type: integer }
ReceivingWarehouseProfile:
type: object
required: [warehouseId, warehouseCode, warehouseName]
properties:
warehouseId: { type: string, pattern: '^\d+$' }
warehouseCode: { type: string }
warehouseName: { type: string, description: 国内Warehouse Service主档维护的当前中文名称 }
ReceivingCandidate:
type: object
required: [containerNo, status, planCount, inboundCodeCount, destinationCodes, plannedPalletCount, totalPackages, receivedPackages, currentAccount]
properties:
containerNo: { type: string }
status: { type: string, enum: [WAIT_SIGN, SIGNED, RECEIVING, COMPLETED] }
planCount: { type: integer }
inboundCodeCount: { type: integer }
destinationCodes: { type: array, uniqueItems: true, items: { type: string } }
plannedPalletCount: { type: integer }
totalPackages: { type: integer }
receivedPackages: { type: integer }
currentAccount: { type: boolean }
ReceivingSession:
type: object
required: [containerNo, overseasWarehouseId, overseasWarehouseName, status, version, photos, totalPackages, receivedPackages, pendingPackages, inbounds]
properties:
containerNo: { type: string }
overseasWarehouseId: { type: string, pattern: '^\d+$', description: PDA Token绑定并在认领柜号时冻结的共享实际海外收货仓ID }
overseasWarehouseName: { type: string, description: Warehouse Overseas服务校验后的共享实际海外收货仓名称快照 }
status: { type: string, enum: [WAIT_SIGN, SIGNED, RECEIVING, COMPLETED] }
operatorName: { type: string, nullable: true }
version: { type: integer }
photos: { type: array, maxItems: 3, items: { $ref: '#/components/schemas/ReceivingSignedSessionPhoto' } }
preparedAt: { type: string, format: date-time, nullable: true }
signedAt: { type: string, format: date-time, nullable: true }
receivingAt: { type: string, format: date-time, nullable: true }
completedAt: { type: string, format: date-time, nullable: true }
totalPackages: { type: integer }
receivedPackages: { type: integer }
pendingPackages: { type: integer }
inbounds: { type: array, items: { $ref: '#/components/schemas/ReceivingInbound' } }
ReceivingPhoto:
type: object
required: [fileId, fileName, contentType, sizeBytes]
properties:
fileId: { type: string, pattern: '^[1-9][0-9]{0,18}$', description: Snowflake file ID kept as a decimal string }
fileName: { type: string }
contentType: { type: string }
sizeBytes: { type: integer, format: int64 }
ReceivingCartonResolved:
allOf:
- { $ref: '#/components/schemas/ReceivingInbound' }
- type: object
required: [cartonMark]
properties:
cartonMark: { type: string }
ReceivingPalletResolved:
type: object
required: [palletCode, warehouseId, status, inboundCode, destinationType, compatible]
properties:
palletCode: { type: string }
warehouseId: { type: integer, format: int64 }
status: { type: string }
fbaWarehouseCode: { type: string, nullable: true }
inboundCode: { type: string }
destinationType: { type: string, enum: [FBA, OVERSEAS] }
compatible: { type: boolean }
ReceivingReceipt:
type: object
required: [result, containerNo, inboundCode, destinationType, palletCode, acceptedPackages, receivedPackages, pendingPackages, sessionStatus]
properties:
result: { type: string }
containerNo: { type: string }
inboundCode: { type: string }
destinationType: { type: string, enum: [FBA, OVERSEAS] }
palletCode: { type: string }
acceptedPackages: { type: integer }
receivedPackages: { type: integer }
pendingPackages: { type: integer }
sessionStatus: { type: string, enum: [SIGNED, RECEIVING] }
ReceivingCandidateListApiResponse:
allOf:
- { $ref: '#/components/schemas/ReceivingApiResponseBase' }
- type: object
required: [data]
properties: { data: { type: array, items: { $ref: '#/components/schemas/ReceivingCandidate' } } }
ReceivingWarehouseProfileApiResponse:
allOf:
- { $ref: '#/components/schemas/ReceivingApiResponseBase' }
- type: object
required: [data]
properties: { data: { $ref: '#/components/schemas/ReceivingWarehouseProfile' } }
ReceivingSessionApiResponse:
allOf:
- { $ref: '#/components/schemas/ReceivingApiResponseBase' }
- type: object
required: [data]
properties: { data: { $ref: '#/components/schemas/ReceivingSession' } }
ReceivingPhotoApiResponse:
allOf:
- { $ref: '#/components/schemas/ReceivingApiResponseBase' }
- type: object
required: [data]
properties: { data: { $ref: '#/components/schemas/ReceivingPhoto' } }
ReceivingCartonResolvedApiResponse:
allOf:
- { $ref: '#/components/schemas/ReceivingApiResponseBase' }
- type: object
required: [data]
properties: { data: { $ref: '#/components/schemas/ReceivingCartonResolved' } }
ReceivingPalletResolvedApiResponse:
allOf:
- { $ref: '#/components/schemas/ReceivingApiResponseBase' }
- type: object
required: [data]
properties: { data: { $ref: '#/components/schemas/ReceivingPalletResolved' } }
ReceivingReceiptApiResponse:
allOf:
- { $ref: '#/components/schemas/ReceivingApiResponseBase' }
- type: object
required: [data]
properties: { data: { $ref: '#/components/schemas/ReceivingReceipt' } }
SmartDispatchCandidate:
type: object
properties:
planId: { type: string }
planPalletId: { type: string }
warehousePalletId: { type: string, nullable: true }
orderId: { type: string }
customerId: { type: string }
customerName: { type: string, nullable: true }
planNo: { type: string, nullable: true }
orderType: { type: string, nullable: true }
volumeWeightKg: { type: number, nullable: true }
containerNo: { type: string, nullable: true }
appointmentAt: { type: string, format: date-time, nullable: true }
expectedLoadingAt: { type: string, format: date-time, nullable: true }
overseasWarehouseId: { type: string }
overseasWarehouseName: { type: string }
orderNo: { type: string }
orderRefs: { type: string }
inboundCode: { type: string }
palletNo: { type: string }
destinationWarehouseId: { type: string }
destinationWarehouseCode: { type: string }
destinationWarehouseName: { type: string }
fbaWarehouseCode: { type: string }
packageCount: { type: integer }
volumeCbm: { type: number }
sourceStage: { type: string, enum: [PLAN, RECEIVED] }
cartonMarks: { type: string, nullable: true, description: 该托盘箱号,逗号分隔 }
SmartDispatchPreArrange:
type: object
required: [planPalletIds]
properties:
planPalletIds: { type: array, minItems: 1, maxItems: 500, uniqueItems: true, items: { type: string } }
route: { type: string, nullable: true, maxLength: 255 }
fbaAppointmentNo: { type: string, nullable: true, maxLength: 64 }
fbaAppointmentStatus: { type: string, nullable: true, maxLength: 32, default: PENDING }
vehicleAppointmentStatus: { type: string, nullable: true, maxLength: 32, default: PENDING }
draftToken: { type: string, nullable: true, maxLength: 64, description: 拖入托盘时使用的智能排车草稿标识 }
SmartDispatchDraftPallet:
type: object
required: [planPalletId, draftToken]
properties:
planPalletId: { type: string }
draftToken: { type: string, minLength: 1, maxLength: 64 }
draftContainerId: { type: string, nullable: true, description: 托盘所在草稿车厢ID }
SmartDispatchDraftRelease:
type: object
required: [draftToken]
properties:
draftToken: { type: string, minLength: 1, maxLength: 64 }
SmartDispatchDraftSnapshot:
type: object
required: [draftToken, planIds, containersJson]
properties:
draftToken: { type: string, minLength: 1, maxLength: 64 }
planIds: { type: array, minItems: 1, maxItems: 500, uniqueItems: true, items: { type: string } }
containersJson: { type: string, minLength: 1, maxLength: 20000 }
SmartDispatchDraftContainerCreate:
type: object
required: [draftToken, capacity]
properties:
draftToken: { type: string, minLength: 1, maxLength: 64 }
capacity: { type: integer, minimum: 1, maximum: 500 }
SmartDispatchDraft:
type: object
required: [draftToken, containers]
properties:
draftToken: { type: string }
planIdsJson: { type: string, nullable: true }
containersJson: { type: string, nullable: true }
containers: { type: array, items: { $ref: '#/components/schemas/SmartDispatchDraftContainer' } }
SmartDispatchDraftContainer:
type: object
required: [id, capacity, palletIds]
properties:
id: { type: string }
capacity: { type: integer }
palletIds: { type: array, items: { type: string } }
DispatchResponse:
type: object
properties:
id: { type: string }
dispatchNo: { type: string }
vehiclePlate: { type: string, nullable: true }
driverName: { type: string, nullable: true }
driverPhone: { type: string, nullable: true }
carrierName: { type: string, nullable: true }
orderNos: { type: string }
route: { type: string, nullable: true }
overseasWarehouseId: { type: string }
overseasWarehouseName: { type: string }
departAt: { type: string, format: date-time, nullable: true }
fbaAppointmentNo: { type: string, nullable: true }
fbaAppointmentStatus: { type: string }
vehicleAppointmentStatus: { type: string }
estimatedArrivalAt: { type: string, format: date-time, nullable: true }
status: { type: string, description: 预排新建固定为 PENDING_DEPARTURE;查询可返回历史排车状态 }
itemCount: { type: integer }
palletCount: { type: integer }
packageCount: { type: integer }
pickedPackageCount: { type: integer }
shippedPackageCount: { type: integer }
remainingPackageCount: { type: integer }
partialCompletionReason: { type: string, nullable: true }
createdAt: { type: string, format: date-time }
items: { type: array, items: { $ref: '#/components/schemas/DispatchItem' } }
DispatchItem:
type: object
properties:
id: { type: string }
planPalletId: { type: string }
warehousePalletId: { type: string, nullable: true }
palletNo: { type: string }
overseasWarehouseId: { type: string }
overseasWarehouseName: { type: string }
orderNo: { type: string }
orderRefs: { type: string }
inboundCode: { type: string }
destinationWarehouseCode: { type: string }
destinationWarehouseName: { type: string }
fbaWarehouseCode: { type: string }
packageCount: { type: integer }
volumeCbm: { type: number }
sourceStage: { type: string, enum: [PLAN, RECEIVED] }
RelabelStatus: { type: string, enum: [PENDING_PROCESSING, PROCESSING, COMPLETED, REJECTED, CANCELLED] }
RelabelCreate:
type: object
required: [customerOrderNo, overseasWarehouseId, labelDeadline, contactName, contactPhone, idempotencyKey, items]
properties:
customerOrderNo: { type: string, maxLength: 128 }
overseasWarehouseId: { type: string, maxLength: 128 }
labelDeadline: { type: string, format: date-time }
contactName: { type: string, maxLength: 128 }
contactPhone: { type: string, maxLength: 64 }
remark: { type: string, nullable: true, maxLength: 1000 }
idempotencyKey: { type: string, maxLength: 255 }
items: { type: array, minItems: 1, maxItems: 500, items: { $ref: '#/components/schemas/RelabelItem' } }
RelabelItem:
type: object
required: [skuCode, productNameZh, totalPackageCount, notifiedPackageCount, shipmentNo, newSkuCode]
properties:
skuCode: { type: string, maxLength: 128 }
productImageFileId: { type: string, nullable: true, maxLength: 128 }
productImageFileName: { type: string, nullable: true, maxLength: 255 }
productImageUrl: { type: string, nullable: true, maxLength: 1000 }
productNameZh: { type: string, maxLength: 255 }
totalPackageCount: { type: integer, minimum: 1 }
notifiedPackageCount: { type: integer, minimum: 1 }
shipmentNo: { type: string, maxLength: 128 }
trackingCode: { type: string, nullable: true, maxLength: 255 }
newSkuCode: { type: string, maxLength: 128 }
labelRequirement: { type: string, nullable: true, maxLength: 1000 }
relabelFileId: { type: string, nullable: true, maxLength: 128 }
relabelFileName: { type: string, nullable: true, maxLength: 255 }
relabelFileUrl: { type: string, nullable: true, maxLength: 1000 }
RelabelStatusChange:
type: object
required: [status]
properties:
status: { $ref: '#/components/schemas/RelabelStatus' }
remark: { type: string, nullable: true, maxLength: 1000 }
ProcurementStatus: { type: string, enum: [PENDING_REVIEW, APPROVED, REJECTED] }
ProcurementReview:
type: object
required: [version, decision, idempotencyKey]
properties:
version: { type: integer, format: int64, minimum: 0 }
decision: { type: string, enum: [APPROVE, REJECT] }
idempotencyKey: { type: string, minLength: 1, maxLength: 255 }
remark: { type: string, nullable: true, maxLength: 1000 }
ProcurementCreate:
type: object
required: [purchaseCategory, productName, purchaseQuantity, contactName, contactPhone, idempotencyKey]
properties:
customerName: { type: string, nullable: true, maxLength: 255 }
purchaseCategory: { type: string, maxLength: 128 }
productName: { type: string, maxLength: 255 }
productSpecification: { type: string, nullable: true, maxLength: 500 }
productUrl: { type: string, nullable: true, maxLength: 2000 }
purchaseQuantity: { type: integer, format: int64, minimum: 1 }
budgetUnitPrice: { type: number, nullable: true, minimum: 0 }
currency: { type: string, minLength: 3, maxLength: 3, default: USD }
receivingAddress: { type: string, nullable: true, maxLength: 1000 }
contactName: { type: string, maxLength: 128 }
contactPhone: { type: string, maxLength: 64 }
remark: { type: string, nullable: true, maxLength: 1000 }
idempotencyKey: { type: string, maxLength: 255 }
NullableTextPatch: { type: string, nullable: true, description: 缺失不修改;null 或空串清空 }
ProcurementUpdate:
type: object
required: [version]
properties:
version: { type: integer, format: int64, minimum: 0 }
purchaseCategory: { type: string, maxLength: 128 }
productName: { type: string, maxLength: 255 }
productSpecification: { $ref: '#/components/schemas/NullableTextPatch' }
productUrl: { $ref: '#/components/schemas/NullableTextPatch' }
inboundQuantity: { type: integer, format: int64, minimum: 0 }
purchaseWarehouseId: { $ref: '#/components/schemas/NullableTextPatch' }
purchaseWarehouseName: { $ref: '#/components/schemas/NullableTextPatch' }
domesticCarrier: { $ref: '#/components/schemas/NullableTextPatch' }
domesticTrackingNo: { $ref: '#/components/schemas/NullableTextPatch' }
overseasCarrier: { $ref: '#/components/schemas/NullableTextPatch' }
overseasTrackingNo: { $ref: '#/components/schemas/NullableTextPatch' }
estimatedArrivalAt: { type: string, format: date-time, nullable: true, description: 缺失不修改;null 或空串清空 }
remark: { $ref: '#/components/schemas/NullableTextPatch' }
CustomerOptionResponse:
type: object
properties:
code: { type: string, enum: ['200'] }
data: { type: array, items: { type: object, properties: { customerId: { type: string }, customerName: { type: string } } } }
WarehouseOptionResponse:
type: object
properties:
code: { type: string, enum: ['200'] }
data: { type: array, items: { type: object, properties: { warehouseId: { type: string }, warehouseCode: { type: string }, warehouseName: { type: string }, countryCode: { type: string } } } }
TruckStatus: { type: string, enum: [PENDING_REVIEW, WAITING_INBOUND, RECEIVING, WAITING_CONSOLIDATION, PALLET_OVERAGE_REVIEW, PARTIALLY_ALLOCATED, ALLOCATED, PENDING_DISPATCH, DISPATCHED, IN_TRANSIT, COMPLETED, REJECTED, CANCELLED] }
TruckReview:
type: object
required: [version, decision, idempotencyKey]
properties:
version: { type: integer, format: int64, minimum: 0 }
decision: { type: string, enum: [APPROVE, REJECT] }
idempotencyKey: { type: string, minLength: 1, maxLength: 255 }
remark: { type: string, nullable: true, maxLength: 1000 }
TruckCancel:
type: object
required: [version, status, idempotencyKey]
properties:
version: { type: integer, format: int64, minimum: 0 }
status: { type: string, enum: [CANCELLED] }
idempotencyKey: { type: string, minLength: 1, maxLength: 255 }
remark: { type: string, nullable: true, maxLength: 1000 }
TruckReceivePallets:
type: object
required: [version, actualPalletCount, idempotencyKey]
properties:
version: { type: integer, format: int64, minimum: 0 }
actualPalletCount: { type: integer, minimum: 1 }
packageCount: { type: integer, nullable: true, minimum: 0 }
palletPackageCounts: { type: array, maxItems: 500, items: { type: integer, minimum: 0 } }
idempotencyKey: { type: string, minLength: 1, maxLength: 255 }
remark: { type: string, nullable: true, maxLength: 1000 }
TruckReviewPalletOverage:
allOf: [{ $ref: '#/components/schemas/TruckReview' }]
TruckAllocatePallets:
type: object
required: [version, palletIds, idempotencyKey]
properties:
version: { type: integer, format: int64, minimum: 0 }
palletIds: { type: array, minItems: 1, maxItems: 500, uniqueItems: true, items: { type: integer, format: int64, minimum: 1 } }
idempotencyKey: { type: string, minLength: 1, maxLength: 255 }
remark: { type: string, nullable: true, maxLength: 1000 }
TruckCommand:
type: object
required: [version, idempotencyKey]
properties:
version: { type: integer, format: int64, minimum: 0 }
idempotencyKey: { type: string, minLength: 1, maxLength: 255 }
remark: { type: string, nullable: true, maxLength: 1000 }
TruckCreate:
type: object
required: [origin, destination, palletCount, totalWeightKg, totalVolumeCbm, contactName, contactInfo, requestedDate, idempotencyKey]
properties:
transportType: { type: string, enum: [PORT_PICKUP, WAREHOUSE_TO_WAREHOUSE, WAREHOUSE_TO_DOOR] }
origin: { type: string, maxLength: 255 }
originAddress: { type: string, nullable: true, maxLength: 500 }
destination: { type: string, maxLength: 255 }
destinationAddress: { type: string, nullable: true, maxLength: 500 }
containerType: { type: string, nullable: true, maxLength: 32 }
palletCount: { type: integer, minimum: 1 }
packageCount: { type: integer, nullable: true, minimum: 0 }
totalWeightKg: { type: number, minimum: 0 }
totalVolumeCbm: { type: number, minimum: 0 }
budgetAmount: { type: number, nullable: true, minimum: 0 }
currency: { type: string, minLength: 3, maxLength: 3, default: USD }
contactName: { type: string, maxLength: 128 }
contactInfo: { type: string, maxLength: 128 }
requestedDate: { type: string, format: date }
remark: { type: string, nullable: true, maxLength: 1000 }
idempotencyKey: { type: string, maxLength: 255 }
TruckUpdate:
type: object
required: [version]
properties:
version: { type: integer, format: int64, minimum: 0 }
transportType: { type: string, enum: [PORT_PICKUP, WAREHOUSE_TO_WAREHOUSE, WAREHOUSE_TO_DOOR] }
origin: { type: string, maxLength: 255 }
originAddress: { type: string, nullable: true, maxLength: 500 }
destination: { type: string, maxLength: 255 }
destinationAddress: { type: string, nullable: true, maxLength: 500 }
containerType: { type: string, nullable: true, maxLength: 32 }
palletCount: { type: integer, minimum: 1 }
packageCount: { type: integer, minimum: 0 }
totalWeightKg: { type: number, minimum: 0 }
totalVolumeCbm: { type: number, minimum: 0 }
budgetAmount: { type: number, nullable: true, minimum: 0 }
currency: { type: string, minLength: 3, maxLength: 3 }
contactName: { type: string, maxLength: 128 }
contactInfo: { type: string, maxLength: 128 }
requestedDate: { type: string, format: date }
remark: { type: string, nullable: true, maxLength: 1000 }
LooseboardStatus: { type: string, enum: [PENDING_ACCEPTANCE, DISPATCHED, IN_TRANSIT, COMPLETED, CANCELLED] }
LooseboardStatusChange:
type: object
required: [version, status, idempotencyKey]
properties:
version: { type: integer, format: int64, minimum: 0 }
status: { $ref: '#/components/schemas/LooseboardStatus' }
idempotencyKey: { type: string, minLength: 1, maxLength: 255 }
remark: { type: string, nullable: true, maxLength: 1000 }
LooseboardCreate:
type: object
required: [transportMode, palletRequired, transportType, origin, destination, packageCount, totalWeightKg, totalVolumeCbm, idempotencyKey]
properties:
transportMode: { type: string, enum: [SHARED_TRUCK, PRIORITY_CONSOLIDATION] }
palletRequired: { type: string, enum: [YES, NO] }
transportType: { type: string, enum: [PORT_PICKUP, WAREHOUSE_TO_WAREHOUSE, WAREHOUSE_TO_DOOR] }
origin: { type: string, maxLength: 255 }
originAddress: { type: string, nullable: true, maxLength: 500 }
destination: { type: string, maxLength: 255 }
destinationAddress: { type: string, nullable: true, maxLength: 500 }
containerType: { type: string, nullable: true, maxLength: 32 }
packageCount: { type: integer, minimum: 0 }
totalWeightKg: { type: number, minimum: 0 }
totalVolumeCbm: { type: number, minimum: 0 }
budgetAmount: { type: number, nullable: true, minimum: 0 }
currency: { type: string, minLength: 3, maxLength: 3, default: USD }
contactName: { type: string, nullable: true, maxLength: 128 }
contactInfo: { type: string, nullable: true, maxLength: 128 }
requestedDate: { type: string, format: date, nullable: true }
remark: { type: string, nullable: true, maxLength: 1000 }
idempotencyKey: { type: string, maxLength: 255 }
LooseboardUpdate:
type: object
required: [version, transportMode, palletRequired, transportType, origin, destination, packageCount, totalWeightKg, totalVolumeCbm]
properties:
version: { type: integer, format: int64, minimum: 0 }
transportMode: { type: string, enum: [SHARED_TRUCK, PRIORITY_CONSOLIDATION] }
palletRequired: { type: string, enum: [YES, NO] }
transportType: { type: string, enum: [PORT_PICKUP, WAREHOUSE_TO_WAREHOUSE, WAREHOUSE_TO_DOOR] }
origin: { type: string, maxLength: 255 }
originAddress: { type: string, nullable: true, maxLength: 500 }
destination: { type: string, maxLength: 255 }
destinationAddress: { type: string, nullable: true, maxLength: 500 }
containerType: { type: string, nullable: true, maxLength: 32 }
packageCount: { type: integer, minimum: 0 }
totalWeightKg: { type: number, minimum: 0 }
totalVolumeCbm: { type: number, minimum: 0 }
budgetAmount: { type: number, nullable: true, minimum: 0 }
currency: { type: string, minLength: 3, maxLength: 3, default: USD }
contactName: { type: string, nullable: true, maxLength: 128 }
contactInfo: { type: string, nullable: true, maxLength: 128 }
requestedDate: { type: string, format: date, nullable: true }
remark: { type: string, nullable: true, maxLength: 1000 }
securitySchemes:
bearerAuth: { type: http, scheme: bearer, bearerFormat: JWT }