Files
baiyue-firstleg/firstleg/src/main/resources/openapi/firstleg-v1.yaml
T

2013 lines
113 KiB
YAML
Raw Normal View History

2026-07-31 14:57:09 +08:00
openapi: 3.0.3
info:
title: 柏悦头程履约 API
2026-08-01 10:17:20 +08:00
description: 业务成功和失败均使用 HTTP 200;仅响应体 code 为字符串 "200" 时表示成功,其他 code 表示失败。
2026-07-31 14:57:09 +08:00
version: 1.1.0
security:
- bearerAuth: []
paths:
2026-08-13 17:13:58 +08:00
/api/merchant/v1/first-leg/inbounds/{inboundId}/carton-label-pdf:
post:
summary: 客户端生成本客户入库单箱唛 PDF
parameters:
- {name: inboundId, in: path, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
- {name: cartonIndex, in: query, required: false, schema: {type: array, items: {type: integer, minimum: 1}}}
responses:
'200': {description: PDF 文件}
'403': {description: 非客户端身份、无订单查看权限或入库单不属于当前客户}
/api/merchant/v1/first-leg/orders/{orderId}/carton-label-pdf:
post:
summary: 客户端按订单生成本客户草稿或正式订单箱唛 PDF
description: 后端按登录客户和 orderId 查找真实预入库单;不要求客户端先取得 inboundId。
parameters:
- {name: orderId, in: path, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
- {name: cartonIndex, in: query, required: false, schema: {type: array, items: {type: integer, minimum: 1}}}
responses:
'200': {description: PDF 文件}
'403': {description: 非客户端身份、无订单查看权限或订单不属于当前客户}
'404': {description: 订单尚未生成预入库单}
2026-08-07 19:23:40 +08:00
/internal/firstleg/v1/customer-dimension-configs/defaults:
post:
2026-08-07 20:07:30 +08:00
summary: 幂等初始化客户四箱规默认配置
description: 原子创建 SMALL、MEDIUM、LARGE、EXTRA_LARGE 四行;同一客户和 initializationKey 重试稳定返回 createdByThisInitialization=true,configId 为 SMALL 行 ID。
2026-08-07 19:23:40 +08:00
security:
- internalServiceToken: []
requestBody:
required: true
content:
application/json:
schema: {$ref: '#/components/schemas/CustomerDimensionConfigInitializeRequest'}
responses:
'200': {description: 成功或业务失败,data 返回 configId 和 createdByThisInitialization}
delete:
2026-08-07 20:07:30 +08:00
summary: 补偿删除本次新建且尚未修改的四箱规默认配置
description: 仅当四行均匹配 initializationKey、默认尺寸、默认2cm和version=0时整组物理删除,不会部分删除。
2026-08-07 19:23:40 +08:00
security:
- internalServiceToken: []
parameters:
- {name: tenantId, in: query, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
- {name: initializationKey, in: query, required: true, schema: {type: string, minLength: 1, maxLength: 128}}
responses:
'200': {description: 幂等补偿完成}
2026-08-14 16:06:27 +08:00
/internal/firstleg/v1/pricing/channels/validate:
post:
2026-08-18 11:41:10 +08:00
summary: 校验订单渠道并按需返回进仓编码前缀
description: 仅供订单服务调用;AUTO 模式要求并返回编码前缀,LEGACY_MANUAL 模式仅校验渠道可用性。
2026-08-14 16:06:27 +08:00
security:
- internalServiceToken: []
requestBody:
required: true
content:
application/json:
schema:
type: object
2026-08-18 11:41:10 +08:00
required: [tenantId, originWarehouseId, channelCode, destinationType, requireInboundCodePrefix]
2026-08-14 16:06:27 +08:00
properties:
tenantId: {type: string, pattern: '^[1-9][0-9]*$'}
originWarehouseId: {type: string, pattern: '^[1-9][0-9]*$'}
channelCode: {type: string, minLength: 1, maxLength: 64}
destinationType: {type: string, enum: [FBA, OVERSEAS, PRIVATE]}
2026-08-18 11:41:10 +08:00
requireInboundCodePrefix: {type: boolean}
2026-08-14 16:06:27 +08:00
responses:
2026-08-18 11:41:10 +08:00
'200': {description: 成功时 data 返回 channelCode;requireInboundCodePrefix=true 时同时返回 inboundCodePrefix}
2026-08-19 09:42:07 +08:00
/internal/firstleg/v1/inbounds/{inboundId}/fees/{feeId}/source-snapshot:
get:
summary: Finance 按入库费用来源版本精确回查不可变快照
description: sourceVersion 必填;只返回 sourceFeeId 与该版本精确匹配的已发布费用,不回退到其他版本。
security:
- internalServiceToken: []
parameters:
- {name: inboundId, in: path, required: true, schema: {type: integer, format: int64, minimum: 1}}
- {name: feeId, in: path, required: true, schema: {type: integer, format: int64, minimum: 1}}
- {name: sourceVersion, in: query, required: true, schema: {type: integer, minimum: 1}}
responses:
'200': {description: 成功时 data 为 FinanceFeeSourceSnapshot;不存在精确版本时返回业务错误}
/internal/firstleg/v1/containers/{containerId}/fees/{feeId}/source-snapshot:
get:
summary: Finance 按柜次费用来源版本精确回查不可变快照
description: sourceVersion 必填;只返回 sourceFeeId 与该版本精确匹配的已发布费用,不回退到当前可变版本。
security:
- internalServiceToken: []
parameters:
- {name: containerId, in: path, required: true, schema: {type: integer, format: int64, minimum: 1}}
- {name: feeId, in: path, required: true, schema: {type: integer, format: int64, minimum: 1}}
- {name: sourceVersion, in: query, required: true, schema: {type: integer, minimum: 1}}
responses:
'200': {description: 成功时 data 为 FinanceFeeSourceSnapshot;不存在精确版本时返回业务错误}
2026-08-20 09:43:31 +08:00
/internal/firstleg/v1/fee-sources/commands/void:
post:
summary: Finance 发起 Firstleg 业务费用作废
description: >-
Finance 只发起命令,不修改或伪造业务费用状态。Firstleg 按 sourceType、sourceFeeId、sourceVersion、
customerId 和所属入库单/柜次精确校验,原子作废业务费用并写入 FIRSTLEG_FEE_VOIDED Outbox;
Finance 后续仅消费该事件同步本地费用池。相同幂等键与请求哈希安全重放,异参重放返回冲突。
security:
- internalServiceToken: []
parameters:
- {name: Idempotency-Key, in: header, required: true, schema: {type: string, minLength: 1, maxLength: 128}}
- {name: X-Request-Hash, in: header, required: true, schema: {type: string, pattern: '^[0-9a-f]{64}$'}}
requestBody:
required: true
content:
application/json:
schema: {$ref: '#/components/schemas/FinanceFeeSourceVoidCommand'}
responses:
'200': {description: 成功时 data 为 FinanceFeeSourceCommandResult;业务失败仍按统一响应 code 返回}
2026-08-07 19:23:40 +08:00
/api/platform/v1/first-leg/customer-dimension-config:
get:
2026-08-07 20:07:30 +08:00
summary: 查询客户固定四箱规尺寸配置
description: 需要 firstleg:dimension-config:view 权限;按 SMALL、MEDIUM、LARGE、EXTRA_LARGE 固定顺序返回;规则用于实测尺寸归档和计费体积加权,不包含价格。
2026-08-07 19:23:40 +08:00
parameters:
- {name: tenantId, in: query, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
responses:
2026-08-07 20:07:30 +08:00
'200': {description: 成功时 data 为 CustomerDimensionConfigGroupResponse}
2026-08-07 19:23:40 +08:00
'403': {description: 无查询权限}
put:
2026-08-07 20:07:30 +08:00
summary: 整组编辑客户固定四箱规尺寸配置
description: 需要 firstleg:dimension-config:edit 权限;请求必须恰好包含四种固定 boxType,四行逐行乐观锁并在同一事务原子保存。
2026-08-07 19:23:40 +08:00
parameters:
- {name: tenantId, in: query, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
requestBody:
required: true
content:
application/json:
schema: {$ref: '#/components/schemas/CustomerDimensionConfigUpdateRequest'}
responses:
2026-08-07 20:07:30 +08:00
'200': {description: 成功时 data 为更新后的 CustomerDimensionConfigGroupResponse}
2026-08-07 19:23:40 +08:00
'403': {description: 无编辑权限}
2026-08-07 10:45:09 +08:00
/internal/firstleg/v1/inbounds/order-approved:
post:
summary: 订单审核通过后幂等创建入库单
2026-08-07 14:46:55 +08:00
description: 仅供订单服务调用;入仓码由订单提交时生成,Firstleg 必须原样沿用。
2026-08-07 10:45:09 +08:00
security:
- internalServiceToken: []
requestBody:
required: true
content:
application/json:
schema: {$ref: '#/components/schemas/OrderApprovedInboundCommand'}
responses:
'200': {description: 成功或业务失败;相同客户和订单重放返回已有入库单 ID}
2026-08-12 14:08:29 +08:00
/internal/firstleg/v1/inbounds/unified-orders/query:
post:
summary: 按统一订单条件分页查询履约摘要(Order 内部)
description: >-
2026-08-13 14:37:51 +08:00
mainStatus 接受六态产品状态;WAIT_SPLIT 为入库完成后的唯一待分柜状态。
2026-08-13 09:49:55 +08:00
计费与入库处理中状态在完成前仍归并为 WAIT_MEASURE,不提前开放分柜。
2026-08-12 14:08:29 +08:00
security:
- internalServiceToken: []
requestBody:
required: true
content:
application/json:
schema: {$ref: '#/components/schemas/UnifiedInboundQuery'}
responses:
'200':
description: 成功或业务失败,按响应体 code 判断
content:
application/json:
schema: {$ref: '#/components/schemas/UnifiedInboundPageEnvelope'}
/internal/firstleg/v1/inbounds/unified-orders/summaries:
post:
summary: 按订单 ID 批量查询统一履约摘要(Order 内部)
security:
- internalServiceToken: []
requestBody:
required: true
content:
application/json:
schema: {$ref: '#/components/schemas/UnifiedInboundBatchRequest'}
responses:
'200':
description: 成功或业务失败,按响应体 code 判断
content:
application/json:
schema: {$ref: '#/components/schemas/UnifiedInboundListEnvelope'}
/internal/firstleg/v1/inbounds/unified-orders/detail:
post:
summary: 按订单 ID 查询统一履约详情(Order 内部)
2026-08-13 14:37:51 +08:00
description: 时间线保留 Firstleg 内部 fromStatus/toStatus;summary.mainStatus 使用六态产品状态。
2026-08-12 14:08:29 +08:00
security:
- internalServiceToken: []
requestBody:
required: true
content:
application/json:
schema: {$ref: '#/components/schemas/UnifiedInboundDetailRequest'}
responses:
'200':
description: 成功或业务失败;找不到对应入库单时 data 为 null
content:
application/json:
schema: {$ref: '#/components/schemas/UnifiedInboundDetailEnvelope'}
2026-07-31 14:57:09 +08:00
/api/platform/v1/first-leg/tasks:
get:
summary: 分页查询履约任务
description: 需要 platform:firstleg:task:list 权限
parameters:
- $ref: '#/components/parameters/TenantId'
- $ref: '#/components/parameters/Page'
- $ref: '#/components/parameters/Size'
- {name: keyword, in: query, schema: {type: string, maxLength: 64}}
- {name: status, in: query, schema: {type: string, enum: [PENDING_ASSIGNMENT, ASSIGNED, PROCESSING, COMPLETED, CANCELLED]}}
- {name: assigneeId, in: query, schema: {type: integer, format: int64}}
responses:
2026-08-01 10:17:20 +08:00
'200': {description: 成功或业务失败,按响应体 code 判断}
2026-07-31 14:57:09 +08:00
'403': {description: 无查询权限}
/api/platform/v1/first-leg/tasks/{taskId}:
get:
summary: 查询履约任务详情
description: 需要 platform:firstleg:task:view 权限
parameters:
- $ref: '#/components/parameters/TenantId'
- $ref: '#/components/parameters/TaskId'
responses:
2026-08-01 10:17:20 +08:00
'200': {description: 成功或业务失败,按响应体 code 判断}
2026-07-31 14:57:09 +08:00
'403': {description: 无查看权限}
/api/platform/v1/first-leg/tasks/by-order/{orderId}:
get:
summary: 按订单查询履约任务
description: 需要 platform:firstleg:task:view 权限
parameters:
- $ref: '#/components/parameters/TenantId'
- {name: orderId, in: path, required: true, schema: {type: integer, format: int64}}
responses:
2026-08-01 10:17:20 +08:00
'200': {description: 成功或业务失败,按响应体 code 判断}
2026-07-31 14:57:09 +08:00
'403': {description: 无查看权限}
/api/platform/v1/first-leg/tasks/{taskId}/assignment-history:
get:
summary: 分页查询任务分配历史
description: 需要 platform:firstleg:assignment:history 权限
parameters:
- $ref: '#/components/parameters/TenantId'
- $ref: '#/components/parameters/TaskId'
- $ref: '#/components/parameters/Page'
- $ref: '#/components/parameters/Size'
responses:
2026-08-01 10:17:20 +08:00
'200': {description: 成功或业务失败,按响应体 code 判断}
2026-07-31 14:57:09 +08:00
'403': {description: 无历史查看权限}
/api/platform/v1/first-leg/tasks/{taskId}/assignment:
post:
summary: 分配或改派履约任务
description: 需要 platform:firstleg:assignment:assign 权限
parameters:
- $ref: '#/components/parameters/TenantId'
- $ref: '#/components/parameters/TaskId'
requestBody:
required: true
content:
application/json:
schema: {$ref: '#/components/schemas/AssignRequest'}
responses:
2026-08-01 10:17:20 +08:00
'200': {description: 成功或业务失败,按响应体 code 判断}
2026-07-31 14:57:09 +08:00
'403': {description: 无分配权限}
2026-08-06 15:48:21 +08:00
/api/platform/v1/containers:
get:
summary: 分页查询平台货柜
description: 需要 platform:firstleg:container:list 权限;货柜为平台级数据,不传 tenant/account
parameters:
- {$ref: '#/components/parameters/Page'}
- {$ref: '#/components/parameters/Size'}
- {name: keyword, in: query, schema: {type: string, maxLength: 128}}
2026-08-14 12:50:37 +08:00
- {name: customerId, in: query, description: 仅返回包含该客户货物的柜次, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
2026-08-06 15:48:21 +08:00
- {name: containerNo, in: query, schema: {type: string, maxLength: 64}}
- {name: cabinetNo, in: query, schema: {type: string, maxLength: 64}}
- {name: warehouseId, in: query, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
2026-08-11 14:24:05 +08:00
- {name: status, in: query, schema: {type: string, enum: [WAIT_LOADING, EDITING, LOADING, COMPLETED]}}
2026-08-06 15:48:21 +08:00
responses:
'200':
description: 成功或业务失败,按响应体 code 判断
content:
application/json:
schema: {$ref: '#/components/schemas/ContainerBookingPageEnvelope'}
'403': {description: 无货柜查询权限}
post:
summary: 新增内部模拟柜
description: 需要 platform:firstleg:container:create 权限;服务端生成稳定 containerBookingId/cabinetNo,不要求真实柜号或订舱
2026-08-06 15:48:21 +08:00
requestBody:
required: true
content:
application/json:
schema: {$ref: '#/components/schemas/ContainerSimulationCreateRequest'}
2026-08-06 15:48:21 +08:00
responses:
'200': {description: 成功或重复号、参数校验等业务失败}
'403': {description: 无新增按钮权限}
/api/platform/v1/containers/{id}/ocean-booking-link:
post:
summary: 将内部模拟柜关联到已发布订舱需求
description: 需要 platform:firstleg:container:edit;请求指定 RELEASED oceanBookingId 和未满配 requirementId,containerNo 可空。首次关联允许 WAIT_LOADING 或已有预排货的 EDITING 模拟柜,保留原 containerBookingId/cabinetNo/loadingPlanId/items,原子写入订舱、运输和范围快照并创建 allocation;提柜后由拖车链调用柜次服务原子补录真实柜号。若关联请求已提供 containerNo,服务端仍规范化并校验 ISO 6346 结构、设备类别、校验位和全局唯一性。存在跨仓、跨渠道、柜型规格不一致、超量、重复柜号、PDA、有效装柜证据、业务单证或 LOADING/COMPLETED 等事实时拒绝。
parameters: [{$ref: '#/components/parameters/ContainerBookingId'}]
requestBody: {required: true, content: {application/json: {schema: {$ref: '#/components/schemas/ContainerOceanBookingLinkRequest'}}}}
2026-08-18 16:39:39 +08:00
responses: {'200': {description: 关联后的同一模拟柜 containerBookingId/cabinetNo;列表仍只有这一条 ACTIVE 操作身份}}
2026-08-06 15:48:21 +08:00
/api/platform/v1/containers/{id}:
get:
summary: 查询平台货柜详情
2026-08-13 11:57:33 +08:00
description: 需要 platform:firstleg:container:list 权限
2026-08-06 15:48:21 +08:00
parameters:
- {$ref: '#/components/parameters/ContainerBookingId'}
responses:
'200': {description: 成功或货柜不存在}
'403': {description: 无货柜查询权限}
put:
summary: 草稿阶段编辑货柜基础资料
description: 需要 platform:firstleg:container:edit 权限;仅待装柜或计划为 EDITING 时允许;请求不包含 containerNo/cabinetNo,不形成真实柜号或内部柜次号写入口
2026-08-06 15:48:21 +08:00
parameters:
- {$ref: '#/components/parameters/ContainerBookingId'}
requestBody:
required: true
content:
application/json:
schema: {$ref: '#/components/schemas/ContainerFullUpdateRequest'}
responses:
'200': {description: 成功或状态、版本、重复号冲突}
'403': {description: 无货柜编辑权限}
2026-08-12 20:36:11 +08:00
/api/platform/v1/containers/{id}/clearance:
get:
summary: 查询货柜目的港清关资料
2026-08-12 20:36:50 +08:00
description: 需要 platform:firstleg:customs:manage 权限
2026-08-12 20:36:11 +08:00
parameters: [{$ref: '#/components/parameters/ContainerBookingId'}]
responses: {'200': {description: 成功或货柜不存在}}
/api/platform/v1/containers/{id}/clearance/document:
post:
summary: 上传或替换货柜目的港清关资料
2026-08-12 20:36:50 +08:00
description: 需要 platform:firstleg:customs:manage 权限,fileId 必须严格绑定当前货柜
2026-08-12 20:36:11 +08:00
parameters: [{$ref: '#/components/parameters/ContainerBookingId'}, {$ref: '#/components/parameters/IdempotencyKey'}]
requestBody:
required: true
content: {application/json: {schema: {$ref: '#/components/schemas/ContainerDocumentAttachRequest'}}}
responses: {'200': {description: 成功、文件归属不匹配或版本冲突}}
/api/platform/v1/containers/{id}/clearance/document/{fileId}/download:
get:
summary: 下载货柜目的港清关附件
description: 需要 platform:firstleg:customs:manage 权限;服务端校验当前 DESTINATION_CLEARANCE fileId 及 File 业务归属,完成态仍可下载,响应禁止缓存
parameters:
- {$ref: '#/components/parameters/ContainerBookingId'}
- {name: fileId, in: path, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
responses:
'200': {description: 附件二进制内容,包含 Content-Disposition 与 Cache-Control no-store}
'404': {description: 当前附件不存在或归属不匹配}
2026-08-13 09:49:55 +08:00
/api/platform/v1/containers/{id}/clearance/document/upload:
post:
summary: 直接选择文件上传或替换货柜目的港清关资料
description: Firstleg 使用内部服务令牌上传 File,浏览器不得传递 fileId 或内部令牌;旧 JSON document 接口仅兼容存量调用。
parameters: [{$ref: '#/components/parameters/ContainerBookingId'}, {$ref: '#/components/parameters/IdempotencyKey'}]
requestBody:
required: true
content:
multipart/form-data:
schema: {$ref: '#/components/schemas/ContainerDocumentUploadRequest'}
responses: {'200': {description: 成功、文件上传失败或版本冲突}}
2026-08-12 20:36:11 +08:00
/api/platform/v1/containers/{id}/clearance/complete:
post:
summary: 点击完成目的港清关
2026-08-12 20:36:50 +08:00
description: 需要 platform:firstleg:customs:manage 权限
2026-08-12 20:36:11 +08:00
parameters: [{$ref: '#/components/parameters/ContainerBookingId'}, {$ref: '#/components/parameters/IdempotencyKey'}]
requestBody:
required: true
content: {application/json: {schema: {$ref: '#/components/schemas/ContainerDocumentCompleteRequest'}}}
responses: {'200': {description: 成功、未上传资料或版本冲突}}
2026-08-06 15:48:21 +08:00
/api/platform/v1/first-leg/smart-loading/plans/by-booking/{bookingId}:
get:
summary: 按货柜恢复智能装柜草稿
description: 需要 platform:firstleg:smart-loading:list 权限;仅返回 EDITING 草稿
parameters:
- {name: bookingId, in: path, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
responses:
'200': {description: 成功、草稿不存在或计划已进入预装流程}
'403': {description: 无智能装柜查询权限}
2026-08-12 18:20:11 +08:00
/api/platform/v1/first-leg/smart-loading/candidates:
get:
summary: Query same-channel smart-loading candidates
parameters:
- {name: bookingId, in: query, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
- {name: warehouseId, in: query, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
responses: {'200': {description: Candidates filtered by the server to the booking channel}}
/api/platform/v1/first-leg/smart-loading/channels:
get:
summary: 查询当前仓库智能装柜渠道目录及统计
description: >-
需要 platform:firstleg:smart-loading:list 权限。渠道目录只来自平台当前唯一 ACTIVE 价格版本中
对该国内仓存在 ACTIVE 价格行的渠道;候选入仓码数、可用箱数及可编排柜次数由 Firstleg 当前事实聚合。
零候选或零可用柜次的有效渠道仍返回,Admin 可展示空态;实际分配仍由服务端重新校验仓库、渠道和资格。
parameters:
- {name: warehouseId, in: query, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
responses:
'200':
description: 成功;无 ACTIVE 价格版本时 data 为空数组
content:
application/json:
schema:
type: object
properties:
code: {type: string}
message: {type: string}
data: {type: array, items: {$ref: '#/components/schemas/SmartLoadingChannelSummary'}}
'403': {description: 无智能装柜查询权限}
2026-08-21 17:07:34 +08:00
/api/platform/v1/first-leg/smart-loading/inbound-candidates:
get:
summary: 按入仓码查询智能装柜候选
description: >-
需要 platform:firstleg:smart-loading:list 权限。每个入库单/入仓码只返回一行;
平均单箱毛重、净重按整票实测重量除以总箱数,平均单箱体积按剩余规格数量加权。
这些数据用于数量级计划,不表示具体箱号已核验归属。
parameters:
- {name: bookingId, in: query, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
- {name: warehouseId, in: query, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
responses: {'200': {description: 成功,data 为入仓码级候选列表}}
2026-08-30 17:02:19 +08:00
/api/platform/v1/first-leg/loading-associations/summary:
get:
summary: 查询入仓片段的装柜与国内PDA关联摘要
description: >-
需要 platform:firstleg:smart-loading:list 权限。inboundId 与 inboundCode 必须且只能提供一个;
inboundCode 是订单当前有效入仓片段业务号。响应优先提供 orderNo、loadingPlanNo、cabinetNo/containerNo、
loadingStatus、pdaTaskStatus 与 coLoadGroupNo 供页面展示;loadingPlanId、containerBookingId、taskId、
coLoadGroupId 和 items[].itemId 仅为技术关联,不得替代业务号作为UI主标识。
parameters:
- {name: inboundId, in: query, required: false, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
- {name: inboundCode, in: query, required: false, schema: {type: string, minLength: 1, maxLength: 40}}
responses:
'200':
description: 成功或业务失败;未进入装柜时仍返回 inboundId/inboundCode,其余关联字段为空
content:
application/json:
schema:
type: object
required: [code, message, data]
properties:
code: {type: string, example: '200'}
message: {type: string}
data: {$ref: '#/components/schemas/LoadingAssociationSummary'}
2026-08-06 15:48:21 +08:00
/api/platform/v1/first-leg/smart-loading/plans/{planId}:
get:
summary: 查询智能装柜草稿详情
description: 需要 platform:firstleg:smart-loading:list 权限;返回草稿及当前未删除明细
parameters:
- {name: planId, in: path, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
responses:
'200': {description: 成功、计划不存在或计划已进入预装流程}
'403': {description: 无智能装柜查询权限}
2026-08-17 15:41:42 +08:00
/api/platform/v1/first-leg/smart-loading/plans/{planId}/assignments:
post:
summary: 向预装计划新增入库单明细
description: >-
EDITING 或 LOADING 且 PDA task 尚未完成时可用。服务端按 planId 锁定同一 PDA task,
校验仓库、渠道、客户范围、可用箱数、容积和限重后原子新增/累加明细;LOADING 时同步到原 taskId,
递增 planVersion、taskVersion,原 inventorySnapshotToken 随即失效。与 PDA batch/final complete 并发时,
锁顺序为 PDA task 行锁 -> plan 乐观锁;仅先取得任务锁且持有匹配版本的一方成功,另一方返回 A0409。
PDA 应重新 GET task detail 与 inventory snapshot,Admin 应重新 GET SmartLoadingPlan。新增项沿用原 taskId、
loadingPlanId、containerBookingId 和 inbound identity;已全拣任务会因新增 PENDING item 从 AWAITING_REVIEW
回到 IN_PROGRESS,已有证据不删除,但 final complete 门禁撤回。
parameters:
- {name: planId, in: path, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
requestBody:
required: true
content: {application/json: {schema: {$ref: '#/components/schemas/SmartLoadingAssignRequest'}}}
responses:
'200': {description: 成功或业务失败,data 为最新 SmartLoadingPlan}
2026-08-21 17:07:34 +08:00
/api/platform/v1/first-leg/smart-loading/plans/{planId}/inbound-assignments:
post:
summary: 按入仓码分配计划装柜箱数
description: >-
需要 platform:firstleg:smart-loading:assign 权限。操作员只选择某个入仓码的本次计划箱数;
服务端在单一事务内按剩余规格箱数比例生成内部规格快照,用于体积估算及兼容 PDA/拆单。
只记录数量计划,具体实装箱号归属为 UNVERIFIED,不得将内部比例分摊宣称为现场箱号事实。
parameters:
- {name: planId, in: path, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
requestBody:
required: true
content: {application/json: {schema: {$ref: '#/components/schemas/SmartLoadingInboundAssignRequest'}}}
responses:
'200': {description: 成功或业务失败,data 为最新 SmartLoadingPlan}
2026-08-17 15:41:42 +08:00
/api/platform/v1/first-leg/smart-loading/plans/{planId}/items/{itemId}:
patch:
summary: 调整预装计划明细箱数
description: >-
EDITING/LOADING 均可;packageCount 不得小于已拣 pickedPackageCount。成功递增 plan、计划明细和现有 PDA task 版本,
原 inventorySnapshotToken 失效。PDA task 已完成或并发版本变化返回 A0409,事务零写入;调用方须刷新
SmartLoadingPlan,PDA 在下一次写入前须刷新 task detail 与 inventory snapshot。
parameters:
- {name: planId, in: path, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
- {name: itemId, in: path, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
requestBody:
required: true
content: {application/json: {schema: {$ref: '#/components/schemas/SmartLoadingAdjustRequest'}}}
responses:
'200': {description: 成功或业务失败,data 为最新 SmartLoadingPlan}
delete:
summary: 删除未拣预装计划明细
description: >-
仅 pickedPackageCount=0 且计划/PDA task 未最终完成时允许。成功递增 plan 和 task 版本并使原库存快照失效;
已拣、COMPLETED 或并发版本变化返回 A0409,事务零写入。PDA final complete 与本操作使用相同 task 行锁,
因而只允许一个事务成功;失败方刷新计划、task detail 与 inventory snapshot 后再决定后续操作。
parameters:
- {name: planId, in: path, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
- {name: itemId, in: path, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
requestBody:
required: true
content: {application/json: {schema: {$ref: '#/components/schemas/SmartLoadingDeleteRequest'}}}
responses:
'200': {description: 成功或业务失败,data 为最新 SmartLoadingPlan}
2026-08-18 16:03:42 +08:00
/api/platform/v1/first-leg/smart-loading/plans/{planId}/items/{itemId}/warehouse-remark:
patch:
summary: 修改装柜明细仓库备注
2026-08-18 16:39:39 +08:00
description: >-
需要 platform:firstleg:preload:edit 权限。EDITING/LOADING 可修改或清空 warehouseRemark;
COMPLETED、计划/明细版本冲突返回 A0409 且事务零写入,写入历史且与 PDA final complete 使用同一并发门禁。
成功响应中的 version 是递增后的 planVersion,items[].version 是递增后的 itemVersion;调用方同时使用
canEdit、items[].canAdjust/canRemove 与自身权限决定操作可用性。数量调整或动态增量不会覆盖已有 warehouseRemark。
2026-08-18 16:03:42 +08:00
parameters:
- {name: planId, in: path, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
- {name: itemId, in: path, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
requestBody:
required: true
content: {application/json: {schema: {$ref: '#/components/schemas/SmartLoadingWarehouseRemarkRequest'}}}
responses:
'200': {description: 成功或业务失败,data 为最新 SmartLoadingPlan}
2026-08-04 10:07:45 +08:00
/openapi/v1/inbound-measurements:
post:
2026-08-04 12:23:46 +08:00
summary: 提交一条第三方箱规测量结果和一张图片
2026-08-04 10:07:45 +08:00
description: >-
2026-08-04 12:23:46 +08:00
data 中的 inboundCode 匹配入库单,inboundDetailId 必须匹配该入库单关联订单中的已有货物明细;
每次只保存一条箱规明细和一张图片,不审核、不计费、不入库,也不改变入库单状态。
2026-08-08 10:18:29 +08:00
首轮联调可由服务端配置 signature-required=false:此时只强制固定 X-App-Key 和
Idempotency-Key,X-Timestamp、X-Nonce、X-Signature 可不传;恢复签名后按下述规则计算。
2026-08-04 10:07:45 +08:00
签名串依次为 METHOD、原始 PATH、X-Timestamp、X-Nonce、Idempotency-Key、
2026-08-04 12:23:46 +08:00
签名body的 SHA-256 小写十六进制,六部分使用 LF(\n)连接且末尾不追加换行。
签名body = data原始UTF-8文本 + LF + image文件内容SHA-256小写十六进制。
2026-08-04 10:07:45 +08:00
三层语义:Nonce 防短时重放;Idempotency-Key 标识一次 HTTP 写操作;
2026-08-07 14:46:55 +08:00
appKey + eventNo 标识第三方业务事件。多台设备可共用同一 appKey/secret,
但 deviceCode、eventNo 和 Idempotency-Key 必须由调用方生成全局唯一值,
不得仅在单台设备内从 1 开始递增。
2026-08-04 10:07:45 +08:00
security:
- measurementAppKey: []
measurementTimestamp: []
measurementNonce: []
measurementSignature: []
parameters:
- {$ref: '#/components/parameters/XTimestamp'}
- {$ref: '#/components/parameters/XNonce'}
- {$ref: '#/components/parameters/IdempotencyKey'}
requestBody:
required: true
content:
2026-08-08 10:31:44 +08:00
application/json:
schema:
type: object
required: [boxCode, length, width, height, machineNo, picture]
2026-08-08 10:31:44 +08:00
properties:
2026-08-14 14:50:39 +08:00
boxCode: {type: string, maxLength: 128, example: 'ZBYHK2608140001#4-1'}
shipment_id: {type: string, maxLength: 64, example: 'FBA19L5KMY2CU000002', description: '可选;设备从Amazon FBA箱标实际扫描得到,有则原样上传;系统只保存,不生成且不覆盖客户下单值'}
2026-08-08 10:31:44 +08:00
length: {type: number, format: decimal, minimum: 0.001}
width: {type: number, format: decimal, minimum: 0.001}
height: {type: number, format: decimal, minimum: 0.001}
machineNo: {type: string, maxLength: 64}
measuredAt: {type: string, format: date-time, nullable: true}
picture: {type: string, description: 'data:image/jpeg;base64,...'}
2026-08-04 12:23:46 +08:00
multipart/form-data:
schema:
type: object
required: [data, image]
properties:
data:
type: string
description: InboundMeasurementCallbackRequest 的原始UTF-8 JSON文本
image:
type: string
format: binary
description: 当前测量明细唯一对应图片,JPG/PNG/BMP且不超过5MB
2026-08-04 10:07:45 +08:00
responses:
2026-08-08 12:01:45 +08:00
'200':
description: JSON 墨家协议在正式箱码匹配或未匹配联调收件成功时均返回 code=200;data.matched 区分结果。其他业务失败按 code 判断。
content:
application/json:
schema: {$ref: '#/components/schemas/MojiaMeasurementUploadEnvelope'}
2026-08-04 10:07:45 +08:00
'413': {description: 请求体超过网关限制}
'415': {description: Content-Type 不支持}
/openapi/v1/inbound-measurements/events/{eventNo}:
get:
summary: 查询第三方测量事件状态
2026-08-08 10:18:29 +08:00
description: >-
signature-required=false 时只需固定 X-App-Key;恢复签名后,GET 签名串的
Idempotency-Key 行为空字符串,body 摘要为空字节 SHA-256。
2026-08-04 10:07:45 +08:00
security:
- measurementAppKey: []
measurementTimestamp: []
measurementNonce: []
measurementSignature: []
parameters:
- name: eventNo
in: path
required: true
schema: {type: string, pattern: '^[A-Za-z0-9._:-]{1,128}$'}
- {$ref: '#/components/parameters/XTimestamp'}
- {$ref: '#/components/parameters/XNonce'}
responses:
'200': {description: 成功或业务失败,按响应体字符串 code 判断}
/api/platform/inbounds:
get:
summary: 分页查询入库单
2026-08-05 09:11:26 +08:00
description: 需要 platform:firstleg:inbound:list 权限;默认查询全部企业,可选 tenantId 筛选;仅使用 V2 四个页签
2026-08-04 10:07:45 +08:00
parameters:
2026-08-05 09:11:26 +08:00
- {name: tenantId, in: query, required: false, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
2026-08-13 14:37:51 +08:00
- {name: tab, in: query, schema: {type: string, enum: [WAIT_MEASURE, WAIT_REVIEW, WAIT_FEE_SEND, WAIT_SPLIT]}}
2026-08-04 10:07:45 +08:00
responses:
2026-08-05 09:11:26 +08:00
'200':
2026-08-05 16:26:10 +08:00
description: 成功或业务失败,按响应体 code 判断;每条记录携带后续客户隔离操作所需的 tenantId,该字段当前表示客户 ID
2026-08-05 09:11:26 +08:00
content:
application/json:
schema: {$ref: '#/components/schemas/InboundOrderPageEnvelope'}
2026-08-04 10:07:45 +08:00
'403': {description: 无查询权限}
/api/platform/inbounds/{inboundId}:
get:
summary: 查询入库单详情
description: 需要 platform:firstleg:inbound:view 权限
parameters:
- {name: tenantId, in: query, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
- {name: inboundId, in: path, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
responses:
'200': {description: 成功或业务失败,按响应体 code 判断}
'403': {description: 无查看权限}
2026-08-07 17:36:02 +08:00
/api/platform/inbounds/{inboundId}/carton-label-pdf:
post:
summary: 生成或补打入仓箱唛 PDF
description: 需要 platform:firstleg:inbound:view 权限;首次打印冻结整单箱号,重复打印和部分补打复用原映射。
parameters:
- {name: tenantId, in: query, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
- {name: inboundId, in: path, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
- name: cartonIndex
in: query
required: false
style: form
explode: true
schema: {type: array, items: {type: integer, minimum: 1}}
description: 不传时打印整单;可重复传入以部分补打指定箱下标。
responses:
'200':
description: 成功返回 PDF;业务失败返回统一 JSON 响应,调用方必须按 Content-Type 区分。
content:
application/pdf: {schema: {type: string, format: binary}}
application/json:
schema:
type: object
required: [code, message]
properties:
code: {type: string}
message: {type: string}
requestId: {type: string, nullable: true}
traceId: {type: string, nullable: true}
'403': {description: 无查看权限}
2026-08-17 17:49:03 +08:00
/api/platform/v1/first-leg/inbounds/{inboundId}/measurement:
get:
summary: 查询入库测量详情
description: >-
需要 platform:firstleg:inbound:measure:view 权限。尺寸测量图片只随 items 返回,
由稳定的 item.id(measurementItemId)与 intelligentImageFileId 关联;称重图片只随
weightResults 返回,由稳定的 weightResult.id 与 fileId 关联,并携带确认状态及服务端确认的
grossWeightKg/netWeightKg。两类证据不得合并为无明细归属的统一图片列表。
2026-08-18 11:32:55 +08:00
actualGrossWeightKg 是服务端确认后的实测毛重,actualNetWeightKg 是扣除托盘皮重后的货物净重;
两者语义独立,消费者不得互相回退,也不得根据图片或 OCR 值自行重算。
2026-08-17 17:49:03 +08:00
parameters:
- {name: tenantId, in: query, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
- {name: inboundId, in: path, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
responses:
'200':
description: 成功或业务失败,按响应体 code 判断
content:
application/json:
schema: {$ref: '#/components/schemas/InboundMeasurementDetailEnvelope'}
'403': {description: 无入库测量查看权限}
2026-08-18 11:32:55 +08:00
/api/platform/v1/first-leg/inbounds/{inboundId}/measurement/draft:
put:
summary: 保存测量草稿
description: >-
原单据号码、申报毛重和申报体积由服务端从客户订单生成快照,客户端不得提交覆盖;
actualGoodsName 默认使用客户货物品名汇总,但允许测量人员修正。
parameters:
- {name: tenantId, in: query, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
- {name: inboundId, in: path, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
requestBody:
required: true
content:
application/json:
schema: {$ref: '#/components/schemas/InboundMeasurementSaveDraftRequest'}
responses:
'200': {description: 成功或业务失败,按响应体 code 判断}
'403': {description: 无测量编辑权限}
2026-08-07 18:03:56 +08:00
/api/platform/v1/first-leg/inbounds/{inboundId}/measurement/carton-scans:
post:
summary: 平台模拟单箱设备扫描
description: >-
需要 platform:firstleg:inbound:measure:edit 权限;仅用于平台联调和代设备录入,
复用正式单箱覆盖规则,不代表最终第三方设备协议或鉴权方式。
parameters:
- {name: tenantId, in: query, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
- {name: inboundId, in: path, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
2026-08-12 14:37:45 +08:00
requestBody:
required: true
content:
multipart/form-data:
schema:
type: object
required: [data, image]
properties:
data:
type: object
required: [boxCode, length, width, height, machineNo, measuredAt]
properties:
boxCode: {type: string, maxLength: 128}
length: {type: number, format: double, minimum: 0.001}
width: {type: number, format: double, minimum: 0.001}
height: {type: number, format: double, minimum: 0.001}
machineNo: {type: string, maxLength: 64}
measuredAt: {type: string, format: date-time}
image: {type: string, format: binary}
responses:
'200': {description: 成功或业务失败,按响应体 code 判断}
'403': {description: 无测量编辑权限}
/api/platform/v1/first-leg/inbounds/{inboundId}/measurement/manual-cartons:
post:
summary: 平台人工录入单箱测量
description: >-
2026-08-12 14:56:57 +08:00
需要 platform:firstleg:inbound:measure:manual-entry 权限;人工录入独立记录为 MANUAL/PLATFORM,
2026-08-12 14:37:45 +08:00
复用正式单箱绑定、图片、计算和覆盖规则,不影响设备扫描入口。
parameters:
- {name: tenantId, in: query, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
- {name: inboundId, in: path, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
2026-08-07 18:03:56 +08:00
requestBody:
required: true
content:
multipart/form-data:
schema:
type: object
required: [data, image]
properties:
data:
type: object
required: [boxCode, length, width, height, machineNo, measuredAt]
properties:
boxCode: {type: string, maxLength: 128}
length: {type: number, format: double, minimum: 0.001}
width: {type: number, format: double, minimum: 0.001}
height: {type: number, format: double, minimum: 0.001}
machineNo: {type: string, maxLength: 64}
measuredAt: {type: string, format: date-time}
image: {type: string, format: binary}
responses:
'200': {description: 成功或业务失败,按响应体 code 判断}
'403': {description: 无测量编辑权限}
2026-08-14 17:37:59 +08:00
/api/platform/v1/first-leg/inbounds/{inboundId}/weight-pallet-options:
get:
summary: 查询称重可选托盘快照
description: >-
2026-08-27 11:07:57 +08:00
需要入库测量查看或称重编辑权限。Firstleg 按入库单 warehouseId 分页查询 Warehouse 当前称重托盘候选;
Warehouse 校验平台公共作用域、启用国内仓、同仓归属和当前未删除资格。托盘可复用,不按预占或占用过滤,Admin 不需要 platform:pallet:list。
2026-08-14 17:37:59 +08:00
parameters:
- {name: tenantId, in: query, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
- {name: inboundId, in: path, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
2026-08-27 11:07:57 +08:00
- {name: page, in: query, required: false, schema: {type: integer, format: int64, minimum: 1, default: 1}}
- {name: size, in: query, required: false, schema: {type: integer, format: int64, minimum: 1, maximum: 100, default: 20}}
- {name: keyword, in: query, required: false, description: 匹配托盘编码或类型, schema: {type: string, maxLength: 50}}
2026-08-14 17:37:59 +08:00
responses:
'200':
description: 成功或业务失败,按响应体 code 判断
content:
application/json:
schema:
type: object
properties:
code: {type: string}
message: {type: string}
2026-08-27 11:09:51 +08:00
data: {$ref: '#/components/schemas/WeightPalletOptionPage'}
2026-08-14 17:37:59 +08:00
'403': {description: 无入库测量查看或称重编辑权限}
/api/platform/v1/first-leg/inbounds/{inboundId}/weight-results:
post:
summary: 登记称重图片 OCR 毛重结果
description: >-
需要称重编辑权限。请求必须绑定 palletId;Firstleg 按入库单 warehouseId 读取 Warehouse
权威快照并固化托盘编码、类型、容量和皮重,不信任前端托盘快照。
parameters:
- {name: tenantId, in: query, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
- {name: inboundId, in: path, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
requestBody:
required: true
content:
application/json:
schema: {$ref: '#/components/schemas/CreateWeightResultRequest'}
responses:
'200':
description: 成功或业务失败,按响应体 code 判断
content:
application/json:
schema:
type: object
properties:
code: {type: string}
message: {type: string}
data: {$ref: '#/components/schemas/InboundWeightResult'}
'403': {description: 无称重编辑权限}
2026-08-07 18:44:51 +08:00
/api/platform/v1/first-leg/inbounds/{inboundId}/weight-results/{resultId}/confirm:
post:
summary: 确认 OCR 重量
description: >-
需要 platform:firstleg:inbound:weight:confirm 权限;携带人工修改字段时还需要
platform:firstleg:inbound:weight:edit 权限。修改与确认在同一事务内完成,保留 OCR 原值,
2026-08-14 17:37:59 +08:00
分别写入 CORRECT 和 CONFIRM 修订记录。输入表示含托盘毛重;服务端统一换算为 KG,
使用创建时固化的托盘皮重计算 netWeightKg,且毛重必须大于皮重。
2026-08-18 11:32:55 +08:00
入库单 actualGrossWeightKg 为实测毛重;actualNetWeightKg 为扣除托盘皮重后的货物净重,两者不得混用。
2026-08-07 18:44:51 +08:00
parameters:
- {name: tenantId, in: query, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
- {name: inboundId, in: path, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
- {name: resultId, in: path, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
requestBody:
required: true
content:
application/json:
schema: {$ref: '#/components/schemas/ConfirmWeightResultRequest'}
responses:
2026-08-14 17:37:59 +08:00
'200':
description: 成功或业务失败,按响应体 code 判断
content:
application/json:
schema:
type: object
properties:
code: {type: string}
message: {type: string}
data: {$ref: '#/components/schemas/InboundWeightResult'}
2026-08-07 18:44:51 +08:00
'403': {description: 无确认权限,或修改重量时无编辑权限}
2026-08-07 20:07:30 +08:00
/api/platform/v1/first-leg/inbounds/{inboundId}/weight-results/{resultId}:
2026-08-14 17:37:59 +08:00
put:
summary: 人工修正 OCR 毛重
description: >-
需要称重编辑权限。修正值仍表示含托盘毛重;保留 OCR 原值,已确认结果修正后立即移出净重汇总并回到待确认。
parameters:
- {name: tenantId, in: query, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
- {name: inboundId, in: path, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
- {name: resultId, in: path, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
requestBody:
required: true
content:
application/json:
schema: {$ref: '#/components/schemas/CorrectWeightResultRequest'}
responses:
'200':
description: 成功或业务失败,按响应体 code 判断
content:
application/json:
schema:
type: object
properties:
code: {type: string}
message: {type: string}
data: {$ref: '#/components/schemas/InboundWeightResult'}
'403': {description: 无称重编辑权限}
2026-08-07 20:07:30 +08:00
delete:
summary: 删除称重图片及重量结果
description: >-
需要 platform:firstleg:inbound:weight:edit 权限;仅允许在可编辑的测量状态删除。
2026-08-18 11:32:55 +08:00
删除已确认图片后由生产者分别重算剩余确认称重的毛重、净重;消费端不得用净重填充毛重。
2026-08-07 20:07:30 +08:00
parameters:
- {name: tenantId, in: query, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
- {name: version, in: query, required: true, schema: {type: integer, format: int32, minimum: 0}}
- {name: inboundId, in: path, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
- {name: resultId, in: path, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
responses:
'200': {description: 成功或业务失败,按响应体 code 判断}
'403': {description: 无重量编辑权限}
2026-08-04 10:07:45 +08:00
/api/platform/v1/inbounds/{inboundId}/measurements/approve:
post:
summary: 审核通过测量
2026-08-14 14:26:56 +08:00
description: 需要 firstleg:inbound:measurement-review 权限。审核通过后立即进入 WAIT_SPLIT,并按该次测量数据尽力生成 CALCULATED 初算费用;价格未覆盖或初算异常只返回非阻断提示,不影响审核结果和待分柜状态。
2026-08-04 10:07:45 +08:00
parameters:
- {name: inboundId, in: path, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
2026-08-13 17:14:46 +08:00
- {name: tenantId, in: query, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
2026-08-04 10:07:45 +08:00
- {name: Idempotency-Key, in: header, required: true, schema: {type: string}}
2026-08-13 17:14:46 +08:00
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [measurementId, expectedVersion]
properties:
measurementId: {type: string, pattern: '^[1-9][0-9]*$'}
expectedVersion: {type: integer, minimum: 0}
reason: {type: string, maxLength: 1000}
2026-08-04 10:07:45 +08:00
responses:
2026-08-14 14:26:56 +08:00
'200': {description: 成功或业务失败,按响应体 code 判断;审核成功 data.processStatus 固定为 WAIT_SPLIT,initialPricingSucceeded 表示是否同时生成初算费用,初算失败时 feeStatus=UNPRICED 且主流程仍成功}
2026-08-04 10:07:45 +08:00
/api/platform/v1/inbounds/{inboundId}/measurements/submit:
post:
summary: 提交测量完成
description: 测量提交后立即按总体积拆分普通托盘、分配并确认占用库位,再进入客服待审核;无普通空闲位时共享 A0。
parameters:
- {name: tenantId, in: query, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
- {name: inboundId, in: path, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
responses:
'200': {description: 成功时 processStatus=MEASURE_PENDING、measureReviewStatus=PENDING,且库位已 OCCUPIED}
'403': {description: 无测量提交权限}
/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 入库运费明细,不需要客户确认费用。CONFIRMED 只表示发送前确认完成,尚未生成可对客发布明细。
2026-08-04 10:07:45 +08:00
parameters:
- {name: orderId, in: path, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
responses:
2026-08-05 20:32:43 +08:00
'200':
description: 成功;publishedFeeDetail 是后台和客户共同读取的同一条已发布入库运费明细,latestFee 仅为兼容保留的计费快照
content:
application/json:
schema: {$ref: '#/components/schemas/MerchantInboundBillingEnvelope'}
2026-08-05 16:26:10 +08:00
'403': {description: 非当前客户或无订单查看权限}
2026-08-18 17:40:32 +08:00
/api/platform/v1/loading-plans/{loadingPlanId}/fee-details/{feeId}/adjust:
post:
summary: 调整已审核柜次费用的日期和金额
description: >-
仅 ACTIVE、APPROVED 且 sourceVersion 匹配的费用可调整。成功后 sourceVersion 加一并重新进入
2026-08-20 18:02:20 +08:00
PENDING;费用方向、费用项目、供应商、结算方式、已付快照、币种和备注保持原快照。业务字段需要变化时,
2026-08-18 17:40:32 +08:00
必须作废原费用并新增。同一 expectedSourceVersion、businessDate、amount 的原样重试只读返回已生成的
PENDING 版本;旧版本异参、已作废或非已审核状态返回 A0409 且零写入。
parameters:
- {name: accountId, in: query, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
- {name: loadingPlanId, in: path, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
- {name: feeId, in: path, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
requestBody:
required: true
content:
application/json:
schema: {$ref: '#/components/schemas/ContainerFeeAdjustRequest'}
responses:
'200': {description: 成功时 data 为调整后柜次费用;业务冲突通过响应体 A0409 返回}
'403': {description: 无 firstleg:inbound:fee-detail:edit 权限}
2026-07-31 14:57:09 +08:00
components:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
2026-08-04 10:07:45 +08:00
measurementAppKey:
type: apiKey
in: header
name: X-App-Key
description: 分配给测量服务商的应用标识
measurementTimestamp:
type: apiKey
in: header
name: X-Timestamp
description: Unix 毫秒时间戳
measurementNonce:
type: apiKey
in: header
name: X-Nonce
description: 每次请求唯一的随机串
measurementSignature:
type: apiKey
in: header
name: X-Signature
description: HMAC-SHA256 小写十六进制签名
2026-08-07 10:45:09 +08:00
internalServiceToken:
type: apiKey
in: header
name: X-Internal-Service-Token
2026-07-31 14:57:09 +08:00
parameters:
2026-08-04 10:07:45 +08:00
XTimestamp:
name: X-Timestamp
in: header
required: true
schema: {type: string, pattern: '^[0-9]{13}$', example: '1785551400000'}
XNonce:
name: X-Nonce
in: header
required: true
schema: {type: string, minLength: 1, maxLength: 128}
IdempotencyKey:
name: Idempotency-Key
in: header
required: true
schema: {type: string, minLength: 1, maxLength: 128}
2026-07-31 14:57:09 +08:00
TenantId:
name: tenantId
in: query
required: true
schema: {type: integer, format: int64, minimum: 1}
TaskId:
name: taskId
in: path
required: true
schema: {type: integer, format: int64}
Page:
name: page
in: query
schema: {type: integer, format: int64, minimum: 1, default: 1}
Size:
name: size
in: query
schema: {type: integer, format: int64, minimum: 1, maximum: 200, default: 20}
2026-08-06 15:48:21 +08:00
ContainerBookingId:
name: id
in: path
required: true
schema: {type: string, pattern: '^[1-9][0-9]*$'}
2026-07-31 14:57:09 +08:00
schemas:
2026-08-12 14:08:29 +08:00
UnifiedMainStatus:
type: string
2026-08-13 14:37:51 +08:00
enum: [PENDING_REVIEW, WAIT_MEASURE, WAIT_SPLIT, LOADING, LOADED, DELIVERED]
description: 六态产品主状态;WAIT_SPLIT 为入库完成后的唯一待分柜状态
2026-08-12 14:08:29 +08:00
UnifiedInboundQuery:
type: object
properties:
tenantId: {type: integer, format: int64, nullable: true}
keyword: {type: string, maxLength: 64, nullable: true}
orderNo: {type: string, maxLength: 64, nullable: true}
mainStatus:
type: string
2026-08-13 14:37:51 +08:00
enum: [PENDING_REVIEW, WAIT_MEASURE, WAIT_SPLIT, LOADING, LOADED, DELIVERED]
2026-08-12 14:08:29 +08:00
nullable: true
2026-08-13 14:37:51 +08:00
description: WAIT_SPLIT 为唯一待分柜筛选值
2026-08-12 14:08:29 +08:00
customerId: {type: integer, format: int64, nullable: true}
receivingWarehouseId: {type: integer, format: int64, nullable: true}
destinationWarehouseId: {type: integer, format: int64, nullable: true}
inboundCode: {type: string, maxLength: 64, nullable: true}
internalOrderStatus: {type: string, maxLength: 32, nullable: true}
expectedArrivalDate: {type: string, format: date, nullable: true}
feeReviewStatus: {type: string, maxLength: 32, nullable: true}
channelName: {type: string, maxLength: 128, nullable: true}
cabinetNo: {type: string, maxLength: 64, nullable: true}
sailingDate: {type: string, format: date, nullable: true}
loaded: {type: boolean, nullable: true}
fullContainer: {type: boolean, nullable: true}
measurementReviewStatus: {type: string, maxLength: 32, nullable: true}
candidateOrderIds: {type: array, nullable: true, items: {type: integer, format: int64}}
createdFrom: {type: string, format: date-time, nullable: true}
createdTo: {type: string, format: date-time, nullable: true}
page: {type: integer, format: int64, minimum: 1, default: 1}
size: {type: integer, format: int64, minimum: 1, maximum: 200, default: 20}
UnifiedInboundBatchRequest:
type: object
required: [orderIds]
properties:
tenantId: {type: integer, format: int64, nullable: true}
orderIds:
type: array
minItems: 1
maxItems: 200
items: {type: integer, format: int64, minimum: 1}
UnifiedInboundDetailRequest:
type: object
required: [tenantId, orderId]
properties:
tenantId: {type: integer, format: int64, minimum: 1}
orderId: {type: integer, format: int64, minimum: 1}
UnifiedInboundPageEnvelope:
type: object
properties:
code: {type: string, example: '200'}
message: {type: string}
data:
type: object
properties:
records: {type: array, items: {$ref: '#/components/schemas/UnifiedInboundSummary'}}
page: {type: integer, format: int64, minimum: 1}
size: {type: integer, format: int64, minimum: 1}
total: {type: integer, format: int64, minimum: 0}
pages: {type: integer, format: int64, minimum: 0}
UnifiedInboundListEnvelope:
type: object
properties:
code: {type: string, example: '200'}
message: {type: string}
data: {type: array, items: {$ref: '#/components/schemas/UnifiedInboundSummary'}}
UnifiedInboundDetailEnvelope:
type: object
properties:
code: {type: string, example: '200'}
message: {type: string}
data:
allOf: [{$ref: '#/components/schemas/UnifiedInboundDetail'}]
nullable: true
UnifiedInboundDetail:
type: object
properties:
summary: {$ref: '#/components/schemas/UnifiedInboundSummary'}
timeline:
type: array
items:
type: object
properties:
source: {type: string}
eventType: {type: string}
fromStatus: {type: string, nullable: true}
toStatus: {type: string, nullable: true}
action: {type: string, nullable: true}
remark: {type: string, nullable: true}
operatorId: {type: integer, format: int64, nullable: true}
operatorName: {type: string, nullable: true}
occurredAt: {type: string, format: date-time, nullable: true}
UnifiedInboundSummary:
type: object
properties:
inbound: {$ref: '#/components/schemas/UnifiedInboundOrderSummary'}
mainStatus: {$ref: '#/components/schemas/UnifiedMainStatus'}
nextAction: {type: string, nullable: true}
preload: {$ref: '#/components/schemas/UnifiedPreloadSummary'}
loading: {$ref: '#/components/schemas/UnifiedLoadingSummary'}
delivery: {$ref: '#/components/schemas/UnifiedDeliverySummary'}
UnifiedInboundOrderSummary:
type: object
description: InboundOrderSummary 的内部统一订单投影
properties:
id: {type: integer, format: int64}
tenantId: {type: integer, format: int64}
orderId: {type: integer, format: int64, nullable: true}
orderNo: {type: string, nullable: true}
inboundCode: {type: string, nullable: true}
2026-09-01 13:41:00 +08:00
processStatus: {type: string, nullable: true, description: Firstleg 内部状态;一件代发测量后先进入 WAIT_PALLETIZE,合托完成再进入 WAIT_SPLIT}
2026-08-12 14:08:29 +08:00
orderStatusSnapshot: {type: string, nullable: true}
measureReviewStatus: {type: string, nullable: true}
feeStatus: {type: string, nullable: true}
feeReviewStatus: {type: string, nullable: true}
notificationStatus: {type: string, nullable: true}
version: {type: integer, nullable: true}
expectedArrivalAt: {type: string, format: date-time, nullable: true}
customerId: {type: integer, format: int64, nullable: true}
customerName: {type: string, nullable: true}
companyId: {type: integer, format: int64, nullable: true}
companyName: {type: string, nullable: true}
warehouseId: {type: integer, format: int64, nullable: true}
warehouseName: {type: string, nullable: true}
deliveryWarehouseId: {type: integer, format: int64, nullable: true}
deliveryWarehouseName: {type: string, nullable: true}
businessType: {type: string, nullable: true}
fulfillmentType: {type: string, enum: [STANDARD, ONE_CLICK_DROPSHIP], nullable: true}
2026-08-12 14:08:29 +08:00
channelCode: {type: string, nullable: true}
channelName: {type: string, nullable: true}
taxMode: {type: string, nullable: true}
pricingTaxMode: {type: string, nullable: true}
containerMode: {type: string, nullable: true}
customsInspection: {type: boolean, nullable: true}
destinationType: {type: string, nullable: true}
destinationWarehouseId: {type: integer, format: int64, nullable: true}
destinationCode: {type: string, nullable: true}
destinationName: {type: string, nullable: true}
holdFlag: {type: boolean, nullable: true}
currentHoldReason: {type: string, nullable: true}
totalPackageCount: {type: integer, nullable: true}
locationCodes: {type: string, nullable: true}
2026-08-18 11:32:55 +08:00
actualGrossWeightKg: {type: number, nullable: true, multipleOf: 0.001, description: 服务端确认后的实测毛重 KG;只读取 fl_inbound_order.actual_gross_weight_kg,不以净重回退}
actualNetWeightKg: {type: number, nullable: true, multipleOf: 0.001, description: 服务端确认后的货物净重 KG;只读取 fl_inbound_order.actual_net_weight_kg,不以毛重回退}
2026-08-12 14:08:29 +08:00
actualVolumeCbm: {type: number, nullable: true}
volumeWeightKg: {type: number, nullable: true}
chargeableWeightKg: {type: number, nullable: true}
chargeableVolumeCbm: {type: number, nullable: true}
palletCount: {type: integer, nullable: true}
measureCompletedAt: {type: string, format: date-time, nullable: true}
inboundedAt: {type: string, format: date-time, nullable: true}
expressCompanyCode: {type: string, nullable: true}
expressCompanyName: {type: string, nullable: true}
containerNo: {type: string, nullable: true}
cabinetNo: {type: string, nullable: true}
vesselName: {type: string, nullable: true}
voyageNo: {type: string, nullable: true}
2026-08-18 11:32:55 +08:00
estimatedSailingAt: {type: string, format: date-time, nullable: true, description: 当前关联柜次预计开船时间}
actualSailingAt: {type: string, format: date-time, nullable: true, description: 当前关联柜次实际开船时间}
estimatedPortArrivalAt: {type: string, format: date-time, nullable: true, description: 当前关联柜次预计到港时间}
actualPortArrivalAt: {type: string, format: date-time, nullable: true, description: 当前关联柜次实际到港时间}
2026-08-12 14:08:29 +08:00
expressTrackingNo: {type: string, nullable: true}
2026-08-17 19:51:54 +08:00
pickupMethod: {type: string, enum: [SELF_EXPRESS, PICKUP, SELF_TRUCK], nullable: true}
requestedPickupAt: {type: string, format: date-time, nullable: true, description: 客户要求平台上门提货的预约时间}
2026-08-17 19:13:08 +08:00
createdByName: {type: string, nullable: true}
2026-08-12 14:08:29 +08:00
createdAt: {type: string, format: date-time, nullable: true}
updatedAt: {type: string, format: date-time, nullable: true}
UnifiedPreloadSummary:
type: object
nullable: true
properties:
status: {type: string, nullable: true}
version: {type: integer, nullable: true}
itemCount: {type: integer, nullable: true}
updatedAt: {type: string, format: date-time, nullable: true}
UnifiedLoadingSummary:
type: object
nullable: true
properties:
status: {type: string, nullable: true}
loadingVersion: {type: integer, nullable: true, description: 当前为 pickingVersion 兼容别名}
pickingVersion: {type: integer, nullable: true}
expectedCount: {type: integer, nullable: true}
pickedCount: {type: integer, nullable: true}
evidenceCount: {type: integer, nullable: true}
sealNo: {type: string, nullable: true}
updatedAt: {type: string, format: date-time, nullable: true}
UnifiedDeliverySummary:
type: object
nullable: true
properties:
status: {type: string, nullable: true}
completedAt: {type: string, format: date-time, nullable: true}
trackingNo: {type: string, nullable: true}
2026-08-08 12:01:45 +08:00
MojiaMeasurementUploadEnvelope:
type: object
properties:
code: {type: string, example: '200'}
message: {type: string, example: success}
data: {$ref: '#/components/schemas/MojiaMeasurementUploadResponse'}
MojiaMeasurementUploadResponse:
type: object
required: [accepted, matched, boxCode, created]
properties:
accepted: {type: boolean, example: true}
matched: {type: boolean, description: true 表示已写入正式箱级测量;false 表示已写入联调收件箱等待排查}
receiptId: {type: string, nullable: true, description: matched=false 时返回的联调收件记录ID}
measurementId: {type: string, nullable: true}
itemId: {type: string, nullable: true}
boxCode: {type: string}
imageFileId: {type: string, nullable: true}
created: {type: boolean}
2026-08-07 19:23:40 +08:00
CustomerDimensionConfigUpdateRequest:
type: object
2026-08-07 20:07:30 +08:00
required: [rules]
2026-08-07 19:23:40 +08:00
properties:
2026-08-07 20:07:30 +08:00
rules:
type: array
minItems: 4
maxItems: 4
description: 必须恰好包含 SMALL、MEDIUM、LARGE、EXTRA_LARGE 各一行
items: {$ref: '#/components/schemas/CustomerDimensionConfigRuleUpdateRequest'}
CustomerDimensionConfigRuleUpdateRequest:
type: object
required: [boxType, innerLengthCm, innerWidthCm, innerHeightCm, edgeAdditionCm, version]
properties:
boxType: {type: string, enum: [SMALL, MEDIUM, LARGE, EXTRA_LARGE]}
innerLengthCm: {type: number, minimum: 0.001, multipleOf: 0.001}
innerWidthCm: {type: number, minimum: 0.001, multipleOf: 0.001}
innerHeightCm: {type: number, minimum: 0.001, multipleOf: 0.001}
2026-08-07 19:23:40 +08:00
edgeAdditionCm:
type: number
minimum: 0.001
maximum: 100
multipleOf: 0.001
2026-08-07 20:07:30 +08:00
description: 箱规长、宽、高三个方向分别使用的每侧加宽厘米数
2026-08-07 19:23:40 +08:00
example: 2.000
remark: {type: string, maxLength: 500, nullable: true}
version: {type: integer, minimum: 0, description: 乐观锁版本号}
2026-08-07 20:07:30 +08:00
CustomerDimensionConfigGroupResponse:
2026-08-07 19:23:40 +08:00
type: object
2026-08-07 20:07:30 +08:00
required: [tenantId, rules]
properties:
tenantId: {type: string, pattern: '^[1-9][0-9]*$'}
rules:
type: array
minItems: 4
maxItems: 4
items: {$ref: '#/components/schemas/CustomerDimensionConfigRuleResponse'}
CustomerDimensionConfigRuleResponse:
type: object
required: [id, boxType, boxTypeName, innerLengthCm, innerWidthCm, innerHeightCm, edgeAdditionCm, outerLengthCm, outerWidthCm, outerHeightCm, volumeCbm, version]
2026-08-07 19:23:40 +08:00
properties:
id: {type: string, pattern: '^[1-9][0-9]*$'}
2026-08-07 20:07:30 +08:00
boxType: {type: string, enum: [SMALL, MEDIUM, LARGE, EXTRA_LARGE]}
boxTypeName: {type: string, enum: [小箱, 中箱, 大箱, 特大箱]}
innerLengthCm: {type: number, minimum: 0.001, multipleOf: 0.001}
innerWidthCm: {type: number, minimum: 0.001, multipleOf: 0.001}
innerHeightCm: {type: number, minimum: 0.001, multipleOf: 0.001}
2026-08-07 19:23:40 +08:00
edgeAdditionCm: {type: number, minimum: 0.001, maximum: 100, example: 2.000}
2026-08-07 20:07:30 +08:00
outerLengthCm: {type: number, minimum: 0.001, description: innerLengthCm + edgeAdditionCm * 2}
outerWidthCm: {type: number, minimum: 0.001, description: innerWidthCm + edgeAdditionCm * 2}
outerHeightCm: {type: number, minimum: 0.001, description: innerHeightCm + edgeAdditionCm * 2}
volumeCbm: {type: number, multipleOf: 0.001, description: 使用未舍入外径完整计算后四舍五入保留3位}
2026-08-07 19:23:40 +08:00
remark: {type: string, nullable: true}
version: {type: integer, minimum: 0}
createdAt: {type: string, format: date-time, nullable: true}
updatedAt: {type: string, format: date-time, nullable: true}
CustomerDimensionConfigInitializeRequest:
type: object
required: [tenantId, operatorId, initializationKey]
properties:
tenantId: {type: string, pattern: '^[1-9][0-9]*$'}
operatorId: {type: string, pattern: '^[0-9]+$'}
initializationKey: {type: string, minLength: 1, maxLength: 128}
CustomerDimensionConfigInitializeResponse:
type: object
required: [configId, createdByThisInitialization]
properties:
configId: {type: string, pattern: '^[1-9][0-9]*$'}
createdByThisInitialization: {type: boolean}
2026-08-14 17:37:59 +08:00
WeightPalletSnapshot:
type: object
required: [palletId, palletCode, palletType, capacityCbm, tareWeightKg]
properties:
palletId: {type: string, pattern: '^[1-9][0-9]*$'}
palletCode: {type: string}
palletType: {type: string}
capacityCbm: {type: number, format: double, minimum: 0.0001}
tareWeightKg: {type: number, format: double, minimum: 0, multipleOf: 0.001}
2026-08-27 11:09:51 +08:00
WeightPalletOptionPage:
2026-08-27 11:07:57 +08:00
type: object
required: [records, page, size, total, pages]
properties:
records:
type: array
maxItems: 100
items: {$ref: '#/components/schemas/WeightPalletSnapshot'}
page: {oneOf: [{type: integer, format: int64, minimum: 1}, {type: string, pattern: '^[1-9][0-9]*$'}]}
size: {oneOf: [{type: integer, format: int64, minimum: 1, maximum: 100}, {type: string, pattern: '^(?:[1-9]|[1-9][0-9]|100)$'}]}
total: {oneOf: [{type: integer, format: int64, minimum: 0}, {type: string, pattern: '^(?:0|[1-9][0-9]*)$'}]}
pages: {oneOf: [{type: integer, format: int64, minimum: 0}, {type: string, pattern: '^(?:0|[1-9][0-9]*)$'}]}
2026-08-14 17:37:59 +08:00
CreateWeightResultRequest:
type: object
required: [fileId, palletId]
properties:
fileId: {type: string, pattern: '^[1-9][0-9]*$'}
palletId: {type: string, pattern: '^[1-9][0-9]*$'}
ocrProvider: {type: string, maxLength: 64, nullable: true}
ocrRawText: {type: string, maxLength: 1000, nullable: true}
ocrWeightValue: {type: number, format: double, minimum: 0, nullable: true, description: OCR 原始含托盘毛重}
ocrWeightUnit: {type: string, maxLength: 8, nullable: true}
confidence: {type: number, format: double, minimum: 0, maximum: 1, nullable: true}
CorrectWeightResultRequest:
type: object
required: [version, adjustedWeightValue, adjustedWeightUnit, adjustmentReason]
properties:
version: {type: integer, minimum: 0}
adjustedWeightValue: {type: number, format: double, minimum: 0.001, description: 人工修正后的含托盘毛重}
adjustedWeightUnit: {type: string, enum: [KG, LB]}
adjustmentReason: {type: string, minLength: 1, maxLength: 500}
InboundWeightResult:
type: object
required: [id, fileId, palletId, palletCode, palletType, palletCapacityCbm, palletTareWeightKg, recognitionStatus, version]
properties:
id: {type: string, pattern: '^[1-9][0-9]*$'}
fileId: {type: string, pattern: '^[1-9][0-9]*$'}
palletId: {type: string, pattern: '^[1-9][0-9]*$'}
palletCode: {type: string}
palletType: {type: string}
palletCapacityCbm: {type: number, format: double, minimum: 0.0001}
palletTareWeightKg: {type: number, format: double, minimum: 0, multipleOf: 0.001}
ocrProvider: {type: string, nullable: true}
ocrRawText: {type: string, nullable: true}
ocrWeightValue: {type: number, format: double, nullable: true, description: OCR 原始含托盘毛重}
ocrWeightUnit: {type: string, nullable: true}
confidence: {type: number, format: double, nullable: true}
grossWeightKg: {type: number, format: double, nullable: true, multipleOf: 0.001, description: 确认时标准化的含托盘毛重 KG}
adjustedWeightValue: {type: number, format: double, nullable: true, description: 人工修正后的含托盘毛重}
adjustedWeightUnit: {type: string, nullable: true}
netWeightKg: {type: number, format: double, nullable: true, multipleOf: 0.001, description: grossWeightKg - palletTareWeightKg}
recognitionStatus: {type: string, enum: [PENDING, PENDING_CONFIRM, NEEDS_MANUAL, CONFIRMED]}
adjustmentReason: {type: string, nullable: true}
adjustedBy: {type: string, nullable: true}
adjustedAt: {type: string, format: date-time, nullable: true}
confirmedBy: {type: string, nullable: true}
confirmedAt: {type: string, format: date-time, nullable: true}
version: {type: integer, minimum: 0}
2026-08-17 17:49:03 +08:00
InboundMeasurementItem:
type: object
description: >-
单条尺寸测量明细。id 是稳定 measurementItemId;intelligentImageFileId 仅表示该明细的
尺寸测量原图,不得与 weightResults.fileId 混用。
required: [id]
properties:
id: {type: string, pattern: '^[1-9][0-9]*$', description: 稳定 measurementItemId}
inboundDetailId: {type: string, pattern: '^[1-9][0-9]*$', nullable: true}
itemNo: {type: string, nullable: true}
boxSpecification: {type: string, nullable: true}
packageCount: {type: integer, nullable: true}
lengthCm: {type: number, format: double, nullable: true}
widthCm: {type: number, format: double, nullable: true}
heightCm: {type: number, format: double, nullable: true}
girthCm: {type: number, format: double, nullable: true}
unitVolumeCbm: {type: number, format: double, nullable: true}
totalVolumeCbm: {type: number, format: double, nullable: true}
volumeWeightKg: {type: number, format: double, nullable: true}
intelligentImageFileId:
type: string
pattern: '^[1-9][0-9]*$'
nullable: true
description: 当前尺寸测量明细的 File 文件 ID;图片类型固定为 DIMENSION
overLimitWarning: {type: string, nullable: true}
outerLengthCm: {type: number, format: double, nullable: true}
outerWidthCm: {type: number, format: double, nullable: true}
outerHeightCm: {type: number, format: double, nullable: true}
remark: {type: string, nullable: true}
boxCode: {type: string, nullable: true}
scannedShipmentId: {type: string, nullable: true}
confirmedPackageCount: {type: integer, nullable: true}
machineNo: {type: string, nullable: true}
deviceMeasuredAt: {type: string, format: date-time, nullable: true}
updatedAt: {type: string, format: date-time, nullable: true}
InboundMeasurementDetail:
type: object
description: >-
入库测量权威详情。尺寸证据天然归属 items,称重证据天然归属 weightResults,响应不提供统一 images。
required: [inboundId, inboundVersion, items, weightResults]
properties:
inboundId: {type: string, pattern: '^[1-9][0-9]*$'}
inboundCode: {type: string, nullable: true}
companyName: {type: string, nullable: true}
channelCode: {type: string, nullable: true}
channelName: {type: string, nullable: true}
processStatus: {type: string, nullable: true}
measureReviewStatus: {type: string, nullable: true}
recommendedPalletType: {type: string, nullable: true}
reviewReason: {type: string, nullable: true}
reviewerId: {type: string, pattern: '^[1-9][0-9]*$', nullable: true}
reviewerName: {type: string, nullable: true}
measurementId: {type: string, pattern: '^[1-9][0-9]*$', nullable: true}
sourceType: {type: string, nullable: true}
measurementStatus: {type: string, nullable: true}
inboundVersion: {type: integer, minimum: 0}
version: {type: integer, minimum: 0, nullable: true}
2026-08-18 11:32:55 +08:00
originalDocumentNo: {type: string, nullable: true, description: 客户订单 referenceId 的服务端快照;旧空快照按订单事实回退}
originalGrossWeightKg: {type: number, format: double, nullable: true, description: 客户订单有效货物行 grossWeightKg 合计的服务端快照}
originalVolumeCbm: {type: number, format: double, nullable: true, description: 客户订单有效货物行 volumeCbm 合计的服务端快照}
2026-08-17 17:49:03 +08:00
originalPackageCount: {type: integer, nullable: true}
actualPackageCount: {type: integer, nullable: true}
actualGrossWeightKg:
type: number
format: double
nullable: true
multipleOf: 0.001
2026-08-18 11:32:55 +08:00
description: 全部 CONFIRMED 称重结果 grossWeightKg 之和,含托盘毛重 KG;无确认结果时为空
actualNetWeightKg:
type: number
format: double
nullable: true
multipleOf: 0.001
description: 全部 CONFIRMED 称重结果 netWeightKg 之和,扣除托盘皮重后的货物净重 KG;无确认结果时为空,审核与计费以此为准
2026-08-17 17:49:03 +08:00
actualVolumeCbm: {type: number, format: double, nullable: true}
volumeWeightKg: {type: number, format: double, nullable: true}
2026-08-18 11:32:55 +08:00
actualGoodsName: {type: string, nullable: true, description: 默认由客户货物品名去重汇总,测量阶段允许人工修正}
2026-08-17 17:49:03 +08:00
items:
type: array
description: DIMENSION 尺寸测量明细及其图片证据
items: {$ref: '#/components/schemas/InboundMeasurementItem'}
weightResults:
type: array
description: WEIGHT 称重结果及其图片、确认状态和服务端重量事实
items: {$ref: '#/components/schemas/InboundWeightResult'}
2026-08-18 11:32:55 +08:00
InboundMeasurementSaveDraftRequest:
type: object
required: [version, items]
additionalProperties: false
properties:
measurementId: {type: string, pattern: '^[1-9][0-9]*$', nullable: true}
version: {type: integer, minimum: 0}
actualGoodsName: {type: string, maxLength: 255, nullable: true}
items:
type: array
minItems: 1
maxItems: 500
items: {$ref: '#/components/schemas/InboundMeasurementItemRequest'}
InboundMeasurementItemRequest:
type: object
2026-08-18 15:43:58 +08:00
required: [inboundDetailId, itemNo, boxSpecification, packageCount, lengthCm, widthCm, heightCm]
2026-08-18 11:32:55 +08:00
additionalProperties: false
properties:
inboundDetailId: {type: string, pattern: '^[1-9][0-9]*$'}
itemNo: {type: string, minLength: 1, maxLength: 32}
boxSpecification: {type: string, minLength: 1, maxLength: 64}
packageCount: {type: integer, minimum: 1, maximum: 1000000}
lengthCm: {type: number, minimum: 0.001}
widthCm: {type: number, minimum: 0.001}
heightCm: {type: number, minimum: 0.001}
intelligentImageFileId: {type: string, pattern: '^[1-9][0-9]*$', nullable: true}
overLimitWarning: {type: string, maxLength: 500, nullable: true}
outerLengthCm: {type: number, minimum: 0, nullable: true}
outerWidthCm: {type: number, minimum: 0, nullable: true}
outerHeightCm: {type: number, minimum: 0, nullable: true}
remark: {type: string, maxLength: 500, nullable: true}
2026-08-17 17:49:03 +08:00
InboundMeasurementDetailEnvelope:
type: object
required: [code, message]
properties:
code: {type: string, example: '200'}
message: {type: string}
data: {$ref: '#/components/schemas/InboundMeasurementDetail'}
requestId: {type: string, nullable: true}
traceId: {type: string, nullable: true}
2026-08-07 18:44:51 +08:00
ConfirmWeightResultRequest:
type: object
required: [version]
2026-08-14 17:37:59 +08:00
description: 人工修改字段表示含托盘毛重且必须同时提供;全部省略时直接确认现有 OCR 或已修正毛重。
2026-08-07 18:44:51 +08:00
properties:
version: {type: integer, minimum: 0}
adjustedWeightValue: {type: number, format: double, minimum: 0.001, nullable: true}
adjustedWeightUnit: {type: string, enum: [KG, LB], nullable: true}
adjustmentReason: {type: string, minLength: 1, maxLength: 500, nullable: true}
2026-08-07 10:45:09 +08:00
OrderApprovedInboundCommand:
type: object
required: [tenantId, orderId, inboundCode, customerName, warehouseId, fulfillmentType]
2026-08-07 10:45:09 +08:00
properties:
tenantId: {type: string, pattern: '^[1-9][0-9]*$', description: 当前客户隔离 ID}
orderId: {type: string, pattern: '^[1-9][0-9]*$'}
orderNo: {type: string, nullable: true}
2026-08-14 14:50:39 +08:00
inboundCode: {type: string, minLength: 1, maxLength: 40, example: ZBYHK2608140001}
2026-08-07 10:45:09 +08:00
customerId: {type: string, pattern: '^[1-9][0-9]*$', nullable: true}
customerName: {type: string, minLength: 1}
warehouseId: {type: string, pattern: '^[1-9][0-9]*$'}
warehouseName: {type: string, nullable: true}
deliveryWarehouseId: {type: string, pattern: '^[1-9][0-9]*$', nullable: true}
deliveryWarehouseName: {type: string, nullable: true}
expectedArrivalAt: {type: string, format: date-time, nullable: true}
businessType: {type: string, nullable: true}
fulfillmentType: {type: string, enum: [STANDARD, ONE_CLICK_DROPSHIP], description: 独立履约类型;不得复用计费 businessType}
2026-08-07 10:45:09 +08:00
channelCode: {type: string, nullable: true}
channelName: {type: string, nullable: true}
2026-08-07 14:46:55 +08:00
carrierId: {type: string, pattern: '^[1-9][0-9]*$', nullable: true, description: 历史兼容的内部运输供应商快照}
2026-08-07 10:45:09 +08:00
carrierName: {type: string, nullable: true}
taxMode: {type: string, nullable: true}
2026-08-07 14:46:55 +08:00
pricingTaxMode: {type: string, enum: [TAX_INCLUDED, TAX_EXCLUDED], nullable: true, description: 报价包税维度;独立于订单taxMode}
2026-08-07 10:45:09 +08:00
containerMode: {type: string, nullable: true}
customsInspection: {type: boolean, nullable: true}
destinationType: {type: string, nullable: true}
destinationWarehouseId: {type: string, pattern: '^[1-9][0-9]*$', nullable: true}
destinationCode: {type: string, nullable: true}
destinationName: {type: string, nullable: true}
publicRemark: {type: string, nullable: true}
expressCompanyName: {type: string, nullable: true}
expressTrackingNo: {type: string, nullable: true}
2026-08-06 15:48:21 +08:00
ContainerBookingPageEnvelope:
type: object
properties:
code: {type: string, example: '200'}
message: {type: string}
data:
type: object
properties:
records: {type: array, items: {$ref: '#/components/schemas/ContainerBooking'}}
page: {type: string, pattern: '^[1-9][0-9]*$'}
size: {type: string, pattern: '^[1-9][0-9]*$'}
total: {type: string, pattern: '^[0-9]+$'}
pages: {type: string, pattern: '^[0-9]+$'}
ContainerBooking:
type: object
2026-08-17 19:51:54 +08:00
required: [id, bookingNo, cabinetNo, sourceType, recordStatus, warehouseId, warehouseName, containerType, capacityCbm, maxWeightKg, planStatus, exceptionActive, destinationClearanceDocumentStatus, customsDeclarationDocumentStatus, deliveryOrderDocumentStatus, pickupOrderDocumentStatus, version]
2026-08-06 15:48:21 +08:00
properties:
id: {type: string, pattern: '^[1-9][0-9]*$'}
planId: {type: string, pattern: '^[1-9][0-9]*$', nullable: true, description: 关联智能装柜计划ID;未创建计划时为空}
2026-08-19 09:14:30 +08:00
planNo: {type: string, nullable: true, pattern: '^LP-[0-9]{6}-[0-9]{4}$', example: LP-260818-0001, description: 预装与确认装柜清单共用的稳定编号;未创建计划时为空}
bookingNo: {type: string, pattern: '^CB-[0-9]{6}-[0-9]{4}$', example: CB-260818-0001, description: 平台内部货柜登记号}
2026-08-06 15:48:21 +08:00
containerNo: {type: string, maxLength: 64, nullable: true}
2026-08-19 09:14:30 +08:00
cabinetNo: {type: string, pattern: '^CAB-[0-9]{6}-[0-9]{4}$', example: CAB-260818-0001, description: 平台稳定柜次号}
2026-08-17 13:24:48 +08:00
sourceType: {type: string, enum: [SIMULATION, OCEAN_BOOKING], description: SIMULATION 为内部模拟柜;OCEAN_BOOKING 为订舱登记直接生成的真实柜}
recordStatus: {type: string, enum: [ACTIVE, MERGED], description: 正常列表和详情仅返回 ACTIVE;真实订舱柜被模拟柜消费后变为 MERGED 且不再作为可操作柜返回}
mergedIntoContainerBookingId: {type: string, pattern: '^[1-9][0-9]*$', nullable: true, description: MERGED 源真实柜指向保留的模拟柜稳定 containerBookingId;ACTIVE 时为空}
2026-08-12 17:29:30 +08:00
channelCode: {type: string, maxLength: 64, nullable: true, description: Missing legacy snapshots are blocked from loading until explicitly backfilled}
channelName: {type: string, maxLength: 128, nullable: true}
oceanBookingId: {type: string, pattern: '^[1-9][0-9]*$', nullable: true}
oceanBookingRequirementId: {type: string, pattern: '^[1-9][0-9]*$', nullable: true}
2026-08-06 15:48:21 +08:00
warehouseId: {type: string, pattern: '^[1-9][0-9]*$'}
warehouseName: {type: string, maxLength: 128}
billOfLadingNo: {type: string, maxLength: 128, nullable: true}
vesselName: {type: string, maxLength: 128, nullable: true}
voyageNo: {type: string, maxLength: 64, nullable: true}
2026-08-17 12:31:24 +08:00
containerType: {type: string, enum: [20GP, 40GP, 40HC, 40NR, 45HC], description: 平台固定柜型}
2026-08-06 15:48:21 +08:00
shippingCompanyId: {type: string, nullable: true}
shippingCompanyName: {type: string, maxLength: 128, nullable: true}
departurePortCode: {type: string, maxLength: 32, nullable: true}
departurePortName: {type: string, maxLength: 128, nullable: true}
destinationPortCode: {type: string, maxLength: 32, nullable: true}
destinationPortName: {type: string, maxLength: 128, nullable: true}
destinationWarehouseCode: {type: string, maxLength: 64, nullable: true}
destinationWarehouseName: {type: string, maxLength: 128, nullable: true}
2026-08-17 12:31:24 +08:00
capacityCbm: {type: number, exclusiveMinimum: true, minimum: 0, description: 必须等于柜型固定容量}
maxWeightKg: {type: number, exclusiveMinimum: true, minimum: 0, description: 必须等于柜型固定限重}
2026-08-15 11:12:19 +08:00
terminalTruckingCompanyId: {type: string, pattern: '^[1-9][0-9]*$', nullable: true, description: ACTIVE Warehouse Supplier ID validated as TRUCKING}
terminalTruckingCompany: {type: string, maxLength: 128, nullable: true, description: Server-frozen Warehouse supplier name snapshot}
2026-08-06 15:48:21 +08:00
loadingAt: {type: string, format: date-time, nullable: true}
estimatedSailingAt: {type: string, format: date-time, nullable: true}
actualSailingAt: {type: string, format: date-time, nullable: true}
estimatedPortArrivalAt: {type: string, format: date-time, nullable: true}
actualPortArrivalAt: {type: string, format: date-time, nullable: true}
estimatedWarehouseArrivalAt: {type: string, format: date-time, nullable: true}
actualWarehouseArrivalAt: {type: string, format: date-time, nullable: true}
2026-08-20 15:20:05 +08:00
unloadingCompletedAt: {type: string, format: date-time, nullable: true, description: 海外仓卸柜完成时间}
unloadingPhotoUploadedAt: {type: string, format: date-time, nullable: true, description: 海外仓卸柜照片上传成功时间}
estimatedEmptyReportedAt: {type: string, format: date-time, nullable: true, description: 预计报空时间,由卸柜照片上传成功时间加两天计算}
actualEmptyReportedAt: {type: string, format: date-time, nullable: true, description: 实际报空时间}
emptyReportSourceVersion: {type: string, pattern: '^[1-9][0-9]*$', nullable: true, description: 海外货柜事件聚合版本}
2026-08-11 14:24:05 +08:00
planStatus: {type: string, enum: [WAIT_LOADING, EDITING, LOADING, COMPLETED]}
2026-08-17 19:51:54 +08:00
exceptionActive: {type: boolean, description: 最新异常历史动作是否为 MARK}
destinationClearanceDocumentStatus: {$ref: '#/components/schemas/ContainerDocumentStatus'}
customsDeclarationDocumentStatus: {$ref: '#/components/schemas/ContainerDocumentStatus'}
deliveryOrderDocumentStatus: {$ref: '#/components/schemas/ContainerDocumentStatus'}
pickupOrderDocumentStatus: {$ref: '#/components/schemas/ContainerDocumentStatus'}
2026-08-06 15:48:21 +08:00
version: {type: integer, minimum: 0}
2026-08-17 19:51:54 +08:00
ContainerDocumentStatus:
type: string
enum: [MISSING, UPLOADED, COMPLETED]
description: 单证聚合状态;DO/PU 无完成动作,因此只返回 MISSING 或 UPLOADED
2026-08-06 15:48:21 +08:00
ContainerSaveRequest:
type: object
2026-08-19 09:42:07 +08:00
required: [warehouseId, warehouseName, containerType, capacityCbm, maxWeightKg]
2026-08-06 15:48:21 +08:00
properties:
containerNo: {type: string, maxLength: 64, nullable: true}
warehouseId: {type: string, pattern: '^[1-9][0-9]*$'}
warehouseName: {type: string, maxLength: 128}
billOfLadingNo: {type: string, maxLength: 128, nullable: true}
vesselName: {type: string, maxLength: 128, nullable: true}
voyageNo: {type: string, maxLength: 64, nullable: true}
2026-08-17 12:31:24 +08:00
containerType: {type: string, enum: [20GP, 40GP, 40HC, 40NR, 45HC], description: 平台固定柜型}
2026-08-06 15:48:21 +08:00
shippingCompanyId: {type: string, pattern: '^[1-9][0-9]*$', nullable: true}
shippingCompanyName: {type: string, maxLength: 128, nullable: true}
departurePortCode: {type: string, maxLength: 32, nullable: true}
departurePortName: {type: string, maxLength: 128, nullable: true}
destinationPortCode: {type: string, maxLength: 32, nullable: true}
destinationPortName: {type: string, maxLength: 128, nullable: true}
destinationWarehouseCode: {type: string, maxLength: 64, nullable: true}
destinationWarehouseName: {type: string, maxLength: 128, nullable: true}
2026-08-17 12:31:24 +08:00
capacityCbm: {type: number, exclusiveMinimum: true, minimum: 0, description: 必须等于柜型固定容量}
maxWeightKg: {type: number, exclusiveMinimum: true, minimum: 0, description: 必须等于柜型固定限重}
2026-08-15 11:12:19 +08:00
terminalTruckingCompanyId: {type: string, pattern: '^[1-9][0-9]*$', nullable: true, description: ACTIVE Warehouse Supplier ID validated as TRUCKING}
terminalTruckingCompany: {type: string, maxLength: 128, nullable: true, description: Optional consistency hint; persisted name always comes from Warehouse and cannot replace the ID}
2026-08-06 15:48:21 +08:00
loadingAt: {type: string, format: date-time, nullable: true}
estimatedSailingAt: {type: string, format: date-time, nullable: true}
actualSailingAt: {type: string, format: date-time, nullable: true}
estimatedPortArrivalAt: {type: string, format: date-time, nullable: true}
actualPortArrivalAt: {type: string, format: date-time, nullable: true}
estimatedWarehouseArrivalAt: {type: string, format: date-time, nullable: true}
actualWarehouseArrivalAt: {type: string, format: date-time, nullable: true}
ContainerFullUpdateRequest:
type: object
required: [version, data]
properties:
version: {type: integer, minimum: 0}
data: {$ref: '#/components/schemas/ContainerSaveRequest'}
2026-08-17 15:41:42 +08:00
SmartLoadingAssignRequest:
type: object
required: [inboundId, inboundDetailId, packageCount, expectedVersion, operationId]
properties:
inboundId: {type: string, pattern: '^[1-9][0-9]*$'}
inboundDetailId: {type: string, pattern: '^[1-9][0-9]*$'}
packageCount: {type: integer, minimum: 1}
expectedVersion: {type: integer, minimum: 0, description: 当前 planVersion}
operationId: {type: string, minLength: 1, maxLength: 128}
2026-08-21 17:07:34 +08:00
SmartLoadingInboundAssignRequest:
type: object
required: [inboundId, packageCount, expectedVersion, operationId]
properties:
inboundId: {type: string, pattern: '^[1-9][0-9]*$'}
packageCount: {type: integer, minimum: 1, description: 该入仓码本次计划装柜总箱数}
expectedVersion: {type: integer, minimum: 0, description: 当前 planVersion}
operationId: {type: string, minLength: 1, maxLength: 128}
2026-08-17 15:41:42 +08:00
SmartLoadingAdjustRequest:
type: object
required: [packageCount, expectedPlanVersion, expectedItemVersion, operationId]
properties:
packageCount: {type: integer, minimum: 1, description: 不得小于响应中的 minPackageCount}
expectedPlanVersion: {type: integer, minimum: 0}
expectedItemVersion: {type: integer, minimum: 0}
operationId: {type: string, minLength: 1, maxLength: 128}
SmartLoadingDeleteRequest:
type: object
required: [expectedPlanVersion, expectedItemVersion, operationId]
properties:
expectedPlanVersion: {type: integer, minimum: 0}
expectedItemVersion: {type: integer, minimum: 0}
operationId: {type: string, minLength: 1, maxLength: 128}
2026-08-18 16:03:42 +08:00
SmartLoadingWarehouseRemarkRequest:
type: object
required: [expectedPlanVersion, expectedItemVersion, operationId]
properties:
warehouseRemark: {type: string, nullable: true, maxLength: 1000, description: 仓库备注;null/空字符串均表示清空}
expectedPlanVersion: {type: integer, minimum: 0}
expectedItemVersion: {type: integer, minimum: 0}
operationId: {type: string, minLength: 1, maxLength: 128}
2026-08-30 17:02:19 +08:00
LoadingAssociationSummary:
type: object
required: [inboundId, inboundCode, orderNo, items]
properties:
inboundId: {type: string, pattern: '^[1-9][0-9]*$', description: 入仓片段内部技术ID}
inboundCode: {type: string, minLength: 1, maxLength: 40, description: 订单当前入仓片段业务号,UI主展示}
orderNo: {type: string, nullable: true, description: 订单业务号,UI主展示}
loadingPlanId: {type: string, pattern: '^[1-9][0-9]*$', nullable: true, description: 装柜计划技术关联ID}
loadingPlanNo: {type: string, nullable: true, pattern: '^LP-[0-9]{6}-[0-9]{4}$', description: 装柜计划业务号,UI主展示}
containerBookingId: {type: string, pattern: '^[1-9][0-9]*$', nullable: true, description: 柜次技术关联ID}
cabinetNo: {type: string, nullable: true, description: 稳定柜次业务号,UI主展示}
containerNo: {type: string, nullable: true, description: 真实集装箱号,UI主展示}
loadingStatus: {type: string, enum: [EDITING, LOADING, COMPLETED], nullable: true}
taskId: {type: string, pattern: '^[1-9][0-9]*$', nullable: true, description: 国内PDA任务技术关联ID}
pdaTaskStatus: {type: string, enum: [UNASSIGNED, IN_PROGRESS, AWAITING_REVIEW, PROCESSING, COMPLETION_FAILED, COMPLETED], nullable: true, description: 国内PDA任务业务状态}
coLoadGroupId: {type: string, pattern: '^[1-9][0-9]*$', nullable: true, description: 同柜不可拆组技术关联ID}
coLoadGroupNo: {type: string, nullable: true, description: 同柜不可拆组业务号,UI主展示}
items:
type: array
description: 装柜明细技术关联;不作为UI主展示
items:
type: object
required: [itemId]
properties:
itemId: {type: string, pattern: '^[1-9][0-9]*$'}
SmartLoadingChannelSummary:
type: object
additionalProperties: false
required: [channelCode, channelName, candidateInboundCount, availablePackageCount, availableContainerCount]
properties:
channelCode: {type: string, minLength: 1, maxLength: 64}
channelName: {type: string, minLength: 1, maxLength: 128}
candidateInboundCount: {type: integer, format: int64, minimum: 0, description: 当前可分配的唯一入仓码数量}
availablePackageCount: {type: integer, format: int64, minimum: 0, description: 当前候选规格剩余可分配箱数合计}
availableContainerCount: {type: integer, format: int64, minimum: 0, description: 当前 WAIT_LOADING、EDITING 或 LOADING 可编排柜次数量}
2026-08-17 15:41:42 +08:00
SmartLoadingPlan:
type: object
required: [id, planNo, status, bookingId, version, canAssign, canEdit, finalCompletionStatus, items]
properties:
id: {type: string}
2026-08-19 09:14:30 +08:00
planNo: {type: string, pattern: '^LP-[0-9]{6}-[0-9]{4}$', example: LP-260818-0001, description: 预装与确认装柜清单共用的稳定编号}
2026-08-17 15:41:42 +08:00
status: {type: string, enum: [EDITING, LOADING, COMPLETED]}
bookingId: {type: string}
containerNo: {type: string, nullable: true}
voyageNo: {type: string, nullable: true}
version: {type: integer, minimum: 0, description: planVersion,写请求使用此值}
canAssign: {type: boolean}
canEdit: {type: boolean}
blockedReason: {type: string, nullable: true}
finalCompletionStatus: {type: string, enum: [NOT_STARTED, IN_PROGRESS, COMPLETED], description: IN_PROGRESS 表示 final complete 门禁尚未通过;增量新增 PENDING item 会保持或恢复此值,COMPLETED 后 canAssign/canEdit 均为 false}
pdaTaskId: {type: string, nullable: true}
pdaTaskStatus: {type: string, nullable: true, enum: [LOADING, COMPLETED], description: LOADING task 在增量后保持原 taskId;COMPLETED 永久拒绝增量}
pdaTaskVersion: {type: integer, minimum: 0, nullable: true, description: 服务端同步后最新 taskVersion;Admin 写操作不提交该值}
items:
type: array
items: {$ref: '#/components/schemas/SmartLoadingPlanItem'}
SmartLoadingPlanItem:
type: object
required: [id, packageCount, version, pickedPackageCount, minPackageCount, canAdjust, canRemove]
properties:
id: {type: string}
inboundId: {type: string}
inboundDetailId: {type: string}
orderNo: {type: string, nullable: true}
inboundCode: {type: string, nullable: true}
customerName: {type: string, nullable: true}
2026-08-18 16:03:42 +08:00
customerRemark: {type: string, nullable: true, readOnly: true, description: 来源为订单 customerRemark}
internalRemark: {type: string, nullable: true, readOnly: true, description: 来源为订单最新内部备注,不使用 cargoRemark}
warehouseRemark: {type: string, nullable: true, description: 仓库人员逐条维护,可在 EDITING/LOADING 修改}
2026-08-17 15:41:42 +08:00
packageCount: {type: integer, minimum: 1}
version: {type: integer, minimum: 0, description: itemVersion,调整/删除写请求使用此值}
pickedPackageCount: {type: integer, minimum: 0}
minPackageCount: {type: integer, minimum: 1}
canAdjust: {type: boolean}
canRemove: {type: boolean}
2026-08-12 20:36:11 +08:00
ContainerDocumentAttachRequest:
type: object
required: [fileId, expectedVersion]
properties:
fileId: {type: string, pattern: '^[1-9][0-9]*$'}
expectedVersion: {type: integer, minimum: 0}
operationReason: {type: string, maxLength: 500, nullable: true}
ContainerDocumentCompleteRequest:
type: object
required: [expectedVersion]
properties:
expectedVersion: {type: integer, minimum: 0}
operationReason: {type: string, maxLength: 500, nullable: true}
2026-08-13 09:49:55 +08:00
ContainerDocumentUploadRequest:
type: object
required: [file, expectedVersion]
additionalProperties: false
properties:
file: {type: string, format: binary, description: 用户直接选择的清关资料}
expectedVersion: {type: integer, minimum: 0, description: 当前文档乐观锁版本,首次上传为 0}
operationReason: {type: string, maxLength: 500, nullable: true}
2026-08-05 20:32:43 +08:00
MerchantInboundBillingEnvelope:
type: object
properties:
code: {type: string, example: '200'}
message: {type: string}
data:
type: object
properties:
inbound: {type: object, description: 入库单详情}
measurementSummary: {type: object, description: 测量汇总}
measurementItems: {type: array, items: {type: object}}
weightResults: {type: array, items: {type: object}}
measurementImages: {type: array, items: {type: object}}
weightImages: {type: array, items: {type: object}}
billingBasis: {type: object, description: 计费依据}
latestFee: {type: object, nullable: true, description: 兼容保留的最新计费快照}
publishedFeeDetail:
allOf:
- {$ref: '#/components/schemas/PublishedFreightFeeDetail'}
nullable: true
description: 后台与客户共用的已发布FBA头程运费应收明细
PublishedFreightFeeDetail:
type: object
description: 审核发布后绑定入库单的FBA头程运费应收明细
properties:
id: {type: integer, format: int64, description: 入库费用明细ID}
inboundId: {type: integer, format: int64}
inboundCode: {type: string}
sourceFeeId: {type: integer, format: int64, description: 来源计费快照ID}
sourceFeeVersion: {type: integer}
sourceFeeNo: {type: string}
direction: {type: string, enum: [RECEIVABLE]}
businessDate: {type: string, format: date}
customerId: {type: integer, format: int64}
customerName: {type: string}
invoiceTitle: {type: string, nullable: true}
channelCode: {type: string, nullable: true}
channelName: {type: string, nullable: true}
destinationCode: {type: string, nullable: true}
destinationName: {type: string, nullable: true}
packageCount: {type: integer, nullable: true}
actualGrossWeightKg: {type: number, format: double, nullable: true}
actualVolumeCbm: {type: number, format: double, nullable: true}
volumeWeightKg: {type: number, format: double, nullable: true}
chargeableWeightKg: {type: number, format: double, nullable: true}
chargeableVolumeCbm: {type: number, format: double, nullable: true}
chargeableQuantity: {type: number, format: double}
chargeUnit: {type: string, enum: [KG, CBM]}
feeTypeName: {type: string, example: FBA头程运费}
unitPrice: {type: number, format: double}
currency: {type: string, example: CNY}
amount: {type: number, format: double, description: 客户应收金额}
reviewStatus: {type: string, enum: [APPROVED]}
publicationStatus: {type: string, enum: [PUBLISHED]}
publishedAt: {type: string, format: date-time}
inboundedAt: {type: string, format: date-time, nullable: true}
2026-08-05 09:11:26 +08:00
InboundOrderPageEnvelope:
type: object
properties:
code: {type: string, example: '200'}
message: {type: string}
data: {$ref: '#/components/schemas/InboundOrderPage'}
InboundOrderPage:
type: object
properties:
records:
type: array
items: {$ref: '#/components/schemas/InboundOrderSummary'}
page: {type: integer, minimum: 1}
size: {type: integer, minimum: 1}
total: {type: integer, format: int64, minimum: 0}
pages: {type: integer, format: int64, minimum: 0}
InboundOrderSummary:
type: object
required: [id, tenantId]
properties:
id: {type: string, pattern: '^[1-9][0-9]*$'}
2026-08-05 16:26:10 +08:00
tenantId: {type: string, pattern: '^[1-9][0-9]*$', description: 记录所属客户 ID;字段名为历史兼容,用于详情和处理接口的客户隔离}
2026-08-05 09:11:26 +08:00
orderId: {type: string, nullable: true}
orderNo: {type: string, nullable: true}
inboundCode: {type: string, nullable: true}
processStatus: {type: string}
customerId: {type: string, nullable: true}
companyId: {type: string, nullable: true}
2026-08-07 14:46:55 +08:00
taxMode: {type: string, nullable: true, description: 订单报关方式快照}
pricingTaxMode: {type: string, enum: [TAX_INCLUDED, TAX_EXCLUDED], nullable: true, description: 下单时选择的报价包税维度快照}
2026-08-17 19:13:08 +08:00
expectedArrivalAt: {type: string, format: date-time, nullable: true}
customerName: {type: string, nullable: true}
companyName: {type: string, nullable: true}
warehouseId: {type: string, nullable: true}
warehouseName: {type: string, nullable: true}
deliveryWarehouseId: {type: string, nullable: true}
deliveryWarehouseName: {type: string, nullable: true}
businessType: {type: string, nullable: true}
fulfillmentType: {type: string, enum: [STANDARD, ONE_CLICK_DROPSHIP], nullable: true}
2026-08-17 19:13:08 +08:00
channelCode: {type: string, nullable: true}
channelName: {type: string, nullable: true}
containerMode: {type: string, nullable: true}
customsInspection: {type: boolean, nullable: true}
destinationType: {type: string, nullable: true}
destinationWarehouseId: {type: string, nullable: true}
destinationCode: {type: string, nullable: true}
destinationName: {type: string, nullable: true}
totalPackageCount: {type: integer, nullable: true}
actualGrossWeightKg: {type: number, nullable: true}
actualNetWeightKg: {type: number, nullable: true}
actualVolumeCbm: {type: number, nullable: true}
volumeWeightKg: {type: number, nullable: true}
chargeableWeightKg: {type: number, nullable: true}
chargeableVolumeCbm: {type: number, nullable: true}
palletCount: {type: integer, nullable: true}
locationCodes: {type: string, nullable: true}
measureCompletedAt: {type: string, format: date-time, nullable: true}
inboundedAt: {type: string, format: date-time, nullable: true}
expressCompanyName: {type: string, nullable: true}
expressTrackingNo: {type: string, nullable: true}
createdAt: {type: string, format: date-time, nullable: true}
updatedAt: {type: string, format: date-time, nullable: true}
2026-08-04 10:07:45 +08:00
InboundMeasurementCallbackRequest:
type: object
2026-08-04 12:23:46 +08:00
required: [eventNo, externalDetailNo, warehouseCode, inboundCode, inboundDetailId, deviceCode, measuredAt, boxSpecification, packageCount, lengthCm, widthCm, heightCm]
2026-08-04 10:07:45 +08:00
properties:
eventNo: {type: string, maxLength: 128, pattern: '^[A-Za-z0-9._:-]+$', example: M202608010001}
2026-08-04 12:23:46 +08:00
externalDetailNo: {type: string, maxLength: 128, pattern: '^[A-Za-z0-9._:-]+$', example: BOX-20260801-0001}
2026-08-04 10:07:45 +08:00
warehouseCode: {type: string, maxLength: 50, example: CN-YW-01}
2026-08-14 14:50:39 +08:00
inboundCode: {type: string, maxLength: 40, example: ZBYHK2608140001}
2026-08-04 12:23:46 +08:00
inboundDetailId: {type: string, example: '190000000000000001', description: 柏悦订单货物明细ID}
2026-08-04 10:07:45 +08:00
deviceCode: {type: string, maxLength: 64, example: DEVICE-01}
measuredAt: {type: string, format: date-time, example: '2026-08-01T10:30:00+08:00'}
2026-08-04 12:23:46 +08:00
boxSpecification: {type: string, maxLength: 64, example: '40x30x47cm'}
2026-08-04 10:07:45 +08:00
lengthCm: {type: number, exclusiveMinimum: true, minimum: 0, example: 50.20}
widthCm: {type: number, exclusiveMinimum: true, minimum: 0, example: 40.10}
heightCm: {type: number, exclusiveMinimum: true, minimum: 0, example: 30.00}
2026-08-04 12:23:46 +08:00
packageCount: {type: integer, minimum: 1, maximum: 1000000, example: 50}
remark: {type: string, maxLength: 500, nullable: true}
2026-08-04 10:07:45 +08:00
InboundMeasurementEventResponse:
type: object
properties:
eventNo: {type: string}
inboundCode: {type: string}
2026-08-04 12:23:46 +08:00
inboundDetailId: {type: string}
measurementId: {type: string}
measurementItemId: {type: string}
imageFileId: {type: string}
2026-08-04 10:07:45 +08:00
accepted: {type: boolean}
status: {type: string, enum: [RECEIVED]}
receivedAt: {type: string, format: date-time}
2026-07-31 14:57:09 +08:00
AssignRequest:
type: object
required: [assigneeId, assigneeName]
properties:
assigneeId: {type: integer, format: int64}
assigneeName: {type: string, maxLength: 64}
reason: {type: string, maxLength: 500}
ContainerSimulationCreateRequest:
type: object
required: [channelCode, warehouseId, containerType, capacityCbm, maxWeightKg]
properties:
channelCode: {type: string, maxLength: 64, description: 当前 ACTIVE 价格簿中的真实物流渠道}
warehouseId: {type: integer, format: int64, minimum: 1}
2026-08-17 12:31:24 +08:00
containerType: {type: string, enum: [20GP, 40GP, 40HC, 40NR, 45HC], description: 与订舱共用的平台固定柜型}
capacityCbm: {type: number, minimum: 0, exclusiveMinimum: true, description: 必须等于柜型固定容量}
maxWeightKg: {type: number, minimum: 0, exclusiveMinimum: true, description: 必须等于柜型固定限重}
ContainerOceanBookingLinkRequest:
type: object
required: [oceanBookingId, requirementId, expectedVersion]
properties:
2026-08-18 15:43:58 +08:00
oceanBookingId: {type: integer, format: int64, minimum: 1, description: RELEASED订舱ID}
requirementId: {type: integer, format: int64, minimum: 1, description: 未满配的订舱柜型需求ID}
containerNo: {type: string, nullable: true, maxLength: 64, description: 可选;港口提柜后可由拖车链另行原子补录。非空时服务端移除格式空白、转大写并校验ISO 6346结构、设备类别、校验位和全局唯一性}
expectedVersion: {type: integer, minimum: 0}
2026-08-18 17:40:32 +08:00
ContainerFeeAdjustRequest:
type: object
additionalProperties: false
required: [expectedSourceVersion, businessDate, amount]
properties:
expectedSourceVersion: {type: integer, minimum: 1}
businessDate: {type: string, format: date}
amount: {type: number, minimum: 0}
2026-08-19 09:42:07 +08:00
FinanceFeeSourceSnapshot:
type: object
description: Finance 消费的版本化费用来源快照;supplierCategory 为空表示仅约束供应商 ACTIVE,非空才约束明确类别。
required: [tenantId, sourceType, feeId, feeVersion, customerId, customerName, feeItemName, direction, businessDate, currency, totalAmount, reviewStatus, publicationStatus, sourceHash, snapshotVersion]
properties:
tenantId: {type: integer, format: int64}
sourceType: {type: string, enum: [INBOUND_FEE, CONTAINER_FEE]}
feeId: {type: integer, format: int64}
feeVersion: {type: integer, minimum: 1}
inboundId: {type: integer, format: int64, nullable: true}
inboundCode: {type: string, nullable: true}
orderId: {type: integer, format: int64, nullable: true}
containerId: {type: integer, format: int64, nullable: true}
containerBookingId: {type: integer, format: int64, nullable: true}
containerNo: {type: string, nullable: true}
customerId: {type: integer, format: int64}
customerName: {type: string}
supplierId: {type: integer, format: int64, nullable: true}
supplierName: {type: string, nullable: true}
supplierCategory: {type: string, enum: [BOOKING, CUSTOMS, TRUCKING, CERTIFICATE], nullable: true, description: PAYABLE供应商类别约束;为空时仅要求供应商ACTIVE}
2026-08-20 18:02:20 +08:00
settlementMode: {type: string, enum: [ON_ACCOUNT, DIRECT_PAID], nullable: true, description: 仅PAYABLE;ON_ACCOUNT可进入AP,DIRECT_PAID仅计成本且禁止进入AP}
paidAt: {type: string, format: date-time, nullable: true}
paymentMethod: {type: string, enum: [ONLINE, BANK_TRANSFER, CASH, OTHER], nullable: true}
paymentReferenceNo: {type: string, nullable: true}
paymentVoucherFileIds: {type: array, nullable: true, items: {type: integer, format: int64}}
2026-08-19 09:42:07 +08:00
feeItemId: {type: integer, format: int64, nullable: true}
feeItemCode: {type: string, nullable: true}
feeItemName: {type: string}
direction: {type: string, enum: [RECEIVABLE, PAYABLE]}
businessDate: {type: string, format: date}
currency: {type: string, enum: [CNY]}
totalAmount: {type: number, minimum: 0}
reviewStatus: {type: string, enum: [APPROVED]}
publicationStatus: {type: string, enum: [PUBLISHED]}
publishedAt: {type: string, format: date-time, nullable: true}
chargeableQuantity: {type: number, nullable: true}
chargeUnit: {type: string, nullable: true}
actualGrossWeightKg: {type: number, nullable: true}
actualVolumeCbm: {type: number, nullable: true}
sourceHash: {type: string}
snapshotVersion: {type: integer, minimum: 1}
2026-08-20 09:43:31 +08:00
FinanceFeeSourceVoidCommand:
type: object
additionalProperties: false
required: [sourceType, sourceFeeId, sourceVersion, customerId, operatorId, operatorName, reason]
properties:
sourceType: {type: string, enum: [INBOUND_FEE, CONTAINER_FEE]}
sourceFeeId: {type: integer, format: int64, minimum: 1}
sourceVersion: {type: integer, minimum: 1}
customerId: {type: integer, format: int64, minimum: 1}
inboundId: {type: integer, format: int64, minimum: 1, nullable: true, description: INBOUND_FEE必填且containerId必须为空}
containerId: {type: integer, format: int64, minimum: 1, nullable: true, description: CONTAINER_FEE必填且inboundId必须为空}
operatorId: {type: integer, format: int64, minimum: 1}
operatorName: {type: string, minLength: 1, maxLength: 64}
reason: {type: string, minLength: 1, maxLength: 500}
FinanceFeeSourceCommandResult:
type: object
required: [sourceType, sourceFeeId, sourceVersion, status, replayed]
properties:
sourceType: {type: string, enum: [INBOUND_FEE, CONTAINER_FEE]}
sourceFeeId: {type: integer, format: int64}
sourceVersion: {type: integer}
status: {type: string, enum: [VOIDED]}
replayed: {type: boolean}