openapi: 3.0.3 info: title: Lastleg Overseas Business API description: 派送资料完整契约见同目录 delivery-documents-v1.yaml;派送列表/详情行返回 bolNo、documentSummary(三类状态与x/3),状态仍使用 version 和 allowedActions。 version: 1.0.0 paths: /api/platform/v1/last-leg/dispatches/capacity-demands: get: summary: 读取有效派送排车的内部散板余位需求 description: 仅平台内部capacity-offer:list或manage可读;返回运输摘要,不返回客户、司机私人资料。实时排除未勾选、取货、本土卡车、已发车、取消及已知满载排车;缺测余位明确未知。 operationId: listDispatchCapacityDemands security: [{ bearerAuth: [] }] parameters: - { name: page, in: query, schema: { type: integer, minimum: 1, default: 1 } } - { name: size, in: query, schema: { type: integer, minimum: 1, maximum: 100, default: 20 } } - { name: origin, in: query, schema: { type: string } } - { name: destination, in: query, schema: { type: string } } responses: '200': description: 统一业务响应,data为包含records、page、size、total和pages的分页结果。 content: application/json: schema: type: object properties: code: { type: string } data: type: object properties: records: { type: array, items: { $ref: '#/components/schemas/DispatchCapacityDemand' } } page: { oneOf: [{ type: string, pattern: '^[0-9]+$' }, { type: integer }] } size: { oneOf: [{ type: string, pattern: '^[0-9]+$' }, { type: integer }] } total: { oneOf: [{ type: string, pattern: '^[0-9]+$' }, { type: integer }] } pages: { oneOf: [{ type: string, pattern: '^[0-9]+$' }, { type: integer }] } /api/merchant/v1/last-leg/warehouse-transfers/{transferNo}/increase-forecast-cartons: post: summary: 测量完成前增加预报箱数并补充箱唛 description: 客户身份及transfer:create权限;仅外来货物待审核或待PDA测量可用,按原预报快照追加整单箱数,不绑定SKU,实际箱内SKU由PDA清点确定,原箱唛与件数不变。补箱及PDA完工锁定同一订单;成功后PDA刷新继续清点。 parameters: - {name: transferNo, in: path, required: true, schema: {type: string}} requestBody: required: true content: application/json: schema: type: object required: [expectedPackageCount, packageCount] properties: expectedPackageCount: {type: integer, minimum: 1, maximum: 5000, description: 修改前整单预报箱数} packageCount: {type: integer, minimum: 1, maximum: 5000, description: 增加后整单预报箱数} responses: '200': {description: 返回补箱后的转运详情,相同原快照和目标箱数重试不重复生成箱唛} /api/platform/v1/last-leg/warehouse-transfers/{transferNo}/increase-forecast-cartons: post: summary: 平台在测量完成前增加整单预报箱数 description: 平台身份及 platform:overseas-warehouse:warehouse-transfer:approve 权限;指定目标客户,沿用客户补箱的状态、并发及幂等规则,不改变SKU预报件数。 security: [{ bearerAuth: [] }] parameters: - { name: transferNo, in: path, required: true, schema: { type: string } } - { name: customerId, in: query, required: true, schema: { type: string } } requestBody: required: true content: application/json: schema: type: object required: [expectedPackageCount, packageCount] properties: expectedPackageCount: { type: integer, minimum: 1, maximum: 5000 } packageCount: { type: integer, minimum: 1, maximum: 5000 } responses: '200': { description: 补箱后的转运详情 } '409': { description: 已完成测量或原预报箱数过期 } /api/pda/v1/last-leg/warehouse-transfers/{transferNo}/carton-label: get: summary: PDA读取转运箱标签 description: 需要 lastleg:pda:operate 与 OVERSEAS_WAREHOUSE_PDA_OPERATOR;只可读取Token绑定仓的转运单标签,包含客户预报及后续补充预报的箱唛。 parameters: - {name: transferNo, in: path, required: true, schema: {type: string}} responses: '200': {description: 统一业务响应,成功data为包含printableHtml的箱标签} /api/pda/v1/last-leg/warehouse-transfers/{transferNo}/pallets/drafts: post: summary: 先创建转运签收托盘草稿 description: 仅绑定仓PDA可操作,提交幂等键创建空托盘草稿,再调用generate生成实物托盘号。不接收手工箱数、尺寸、体积和重量,箱子清点时按归属自动汇总。 parameters: - {name: transferNo, in: path, required: true, schema: {type: string}} requestBody: required: true content: application/json: schema: type: object required: [idempotencyKey] properties: palletId: {type: integer, format: int64, nullable: true} idempotencyKey: {type: string, maxLength: 255} responses: '200': {description: 统一业务响应,data为含空托盘草稿的转运详情} /api/pda/v1/last-leg/warehouse-transfers/{transferNo}/cartons/count: post: summary: 转运逐箱测量与清点 description: 仅限 lastleg:pda:operate 与 OVERSEAS_WAREHOUSE_PDA_OPERATOR,绑定仓由统一Token确定。先创建本单托盘号,每箱选择所属托盘,可包含多个本单预报SKU,逐项记录实点件数;同箱SKU不可重复,尺寸重量和实收箱数按实物箱计算一次,托盘体积重量由分配箱子汇总,全部实收箱子测量清点后才可完成打托入库,打托箱数与已清点实收箱数核平;短收箱保留未收到事实,额外箱须客户先增加预报箱数补生成箱唛;清点允许暂不填写差异原因,最终完成测量时仅SKU实收件数有差异才必填原因。事务锁定转运单;原键原载荷重试不重复写入,同键不同载荷拒绝,已确认事实不可覆盖。 parameters: - {name: transferNo, in: path, required: true, schema: {type: string}} requestBody: required: true content: application/json: schema: type: object required: [idempotencyKey, boxes, forecastPackageCount] properties: idempotencyKey: {type: string, maxLength: 255} forecastPackageCount: {type: integer, minimum: 1, description: 设备读取的预报箱数,补箱后旧快照须刷新} discrepancyReason: {type: string, maxLength: 1000, description: 清点阶段可选,最终完成测量时SKU实收件数有差异必填原因} boxes: type: array minItems: 1 maxItems: 5000 items: type: object required: [cartonMark, transferPalletId, length, width, height, weight, items] properties: cartonMark: {type: string, maxLength: 255, description: 必须为当前单预报中已存在的仓库唛头} transferItemId: {type: integer, format: int64, nullable: true, description: 箱子所属本单申报明细} transferPalletId: {type: integer, format: int64, description: 本单已生成的转运托盘事实ID,逐箱关联,托盘箱数体积重量由箱子汇总} length: {type: number, minimum: 0.01, description: 箱长厘米} width: {type: number, minimum: 0.01, description: 箱宽厘米} height: {type: number, minimum: 0.01, description: 箱高厘米} weight: {type: number, minimum: 0.01, description: 箱重千克} items: type: array minItems: 1 maxItems: 200 description: 本箱实际SKU明细,仅限本单预报SKU,同箱不可重复 items: type: object required: [skuCode, quantity] properties: skuCode: {type: string, maxLength: 255} quantity: {type: integer, minimum: 1, maximum: 2147483647, description: 本SKU箱内实点件数} responses: '200': {description: 统一业务响应,成功data为转运详情,cartons含逐箱尺寸重量、quantity合计件数、items逐SKU明细(transferItemId/skuCode/quantity)及清点操作人时间} /api/platform/v1/last-leg/inventory/balances/{balanceId}: get: summary: 查询单条库存余额详情 description: 仅平台且要求 lastleg:inventory:list;按 balanceId 直接查询非零库存余额,不依赖列表分页。可选 customerId 用于精确客户隔离,越权或不存在统一返回404。 security: [{ bearerAuth: [] }] parameters: - { in: path, name: balanceId, required: true, schema: { type: string, pattern: '^[1-9][0-9]*$', description: 长整型ID按字符串传输 } } - { in: query, name: customerId, required: false, schema: { type: string } } responses: '200': { description: 单条库存余额, content: { application/json: { schema: { $ref: '#/components/schemas/InventoryBalanceApiResponse' } } } } '403': { description: 非平台身份或缺少库存查看权限 } '404': { description: 库存余额不存在、已归零或不属于指定客户 } /api/platform/v1/last-leg/inventory/inbound-code-relationships/{inboundCode}: get: summary: 按入仓码查询海外关系摘要 description: 仅平台且要求 lastleg:inventory:list;不接收customerId,不跨国内数据库查询,未命中返回found=false和空关系。 security: [{ bearerAuth: [] }] parameters: - { in: path, name: inboundCode, required: true, schema: { type: string, minLength: 1, maxLength: 128 } } responses: '200': { description: 海外订单、计划、收货、托盘和库存业务关系, content: { application/json: { schema: { $ref: '#/components/schemas/InboundCodeRelationshipApiResponse' } } } } '403': { description: 非平台身份或缺少库存查看权限 } '409': { description: 入仓码跨客户或快照关系不一致 } /api/pda/v1/last-leg/receiving-containers/candidates: get: summary: 查询当前仓待签收柜号 description: 权限 lastleg:pda:operate;仅 PLATFORM OVERSEAS_WAREHOUSE_PDA_OPERATOR 可用;按来源柜跨客户聚合,仅返回已单调消费 PICKUP_READY(80) 或更高实际船节点、状态为 RECEIVING_AVAILABLE 的柜,不接收 customerId。 security: [{ bearerAuth: [] }] responses: { '200': { description: 柜号候选及箱数进度, content: { application/json: { schema: { $ref: '#/components/schemas/ReceivingCandidateListApiResponse' } } } }, '403': { description: 缺少 PDA 操作权限 } } /api/pda/v1/last-leg/receiving-containers/warehouse-profile: get: summary: 查询当前PDA账号绑定的海外仓主档 description: 权限 lastleg:pda:operate;仓库ID只取Token,名称与编码由共享仓库主档实时解析,不接收warehouseId参数。 security: [{ bearerAuth: [] }] responses: { '200': { description: 当前绑定仓库中文名称与编码, content: { application/json: { schema: { $ref: '#/components/schemas/ReceivingWarehouseProfileApiResponse' } } } }, '403': { description: 账号未绑定有效海外仓 } } /api/pda/v1/last-leg/receiving-containers/{containerNo}: get: summary: 查询待签收柜号详情 description: 权限 lastleg:pda:operate;sourceContainerBookingId 与真实集装箱号共同锁定本次柜次,允许物理集装箱号在不同柜次重复使用;按来源柜返回跨客户的全部入仓码、目的类型、目的仓、托数和实收进度。 security: [{ bearerAuth: [] }] parameters: - { name: containerNo, in: path, required: true, schema: { type: string } } - { name: sourceContainerBookingId, in: query, required: true, schema: { type: string, minLength: 1, maxLength: 128 } } responses: { '200': { description: 柜号详情, content: { application/json: { schema: { $ref: '#/components/schemas/ReceivingSessionApiResponse' } } } }, '409': { description: 当前账号已锁定其他柜号 } } /api/pda/v1/last-leg/receiving-containers/{containerNo}/prepare: post: summary: 选择当前待签收柜号 description: 权限 lastleg:pda:operate;sourceContainerBookingId 与真实集装箱号共同锁定本次柜次;仅 RECEIVING_AVAILABLE 柜可建立 WAIT_SIGN 会话,并以平台操作账号、当前作业柜全局双唯一键防止切柜或多人同时处理。 security: [{ bearerAuth: [] }] parameters: - { name: containerNo, in: path, required: true, schema: { type: string } } - { name: sourceContainerBookingId, in: query, required: true, schema: { type: string, minLength: 1, maxLength: 128 } } requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/ReceivingAction' } } } } responses: { '200': { description: 当前柜会话, content: { application/json: { schema: { $ref: '#/components/schemas/ReceivingSessionApiResponse' } } } }, '409': { description: 账号或柜号已有未完成会话 } } /api/pda/v1/last-leg/receiving-containers/current/unload-photos/files: post: summary: 上传当前柜签收照片 description: 权限 lastleg:pda:operate;multipart 文件归属当前 WAIT_SIGN 会话。 security: [{ bearerAuth: [] }] requestBody: { required: true, content: { multipart/form-data: { schema: { type: object, required: [file], properties: { file: { type: string, format: binary } } } } } } responses: { '200': { description: 文件标识, content: { application/json: { schema: { $ref: '#/components/schemas/ReceivingPhotoApiResponse' } } } }, '409': { description: 当前柜已签收 } } /api/pda/v1/last-leg/receiving-containers/current/unload-photos/files/{fileId}/download: get: summary: 下载当前柜签收照片 description: 权限 lastleg:pda:operate;仅允许下载当前会话已签收角色绑定的照片。 security: [{ bearerAuth: [] }] parameters: - { name: fileId, in: path, required: true, schema: { type: string, pattern: '^[1-9][0-9]{0,18}$' } } responses: '200': description: 签收照片字节流;Content-Type 透传文件类型,缺失时为 application/octet-stream;Content-Disposition 为 inline;Cache-Control 为 no-store。 headers: Content-Disposition: { schema: { type: string }, description: inline 文件名 } Cache-Control: { schema: { type: string, example: no-store } } content: image/jpeg: { schema: { type: string, format: binary } } image/png: { schema: { type: string, format: binary } } application/octet-stream: { schema: { type: string, format: binary } } '403': { description: fileId 未绑定到当前操作员的当前柜会话三类签收照片 } '404': { description: 当前柜会话或照片不存在 } /api/pda/v1/last-leg/receiving-containers/{containerNo}/unload-photos/files/{fileId}/download: get: summary: 按柜号下载卸柜签收照片 description: 权限 lastleg:pda:operate;按当前 PDA 绑定仓和柜号读取历史或当前柜的签收照片,不要求存在未完成接柜会话。 security: [{ bearerAuth: [] }] parameters: - { name: containerNo, in: path, required: true, schema: { type: string } } - { name: fileId, in: path, required: true, schema: { type: string, pattern: '^[1-9][0-9]{0,18}$' } } responses: '200': { description: 签收照片字节流, content: { image/jpeg: { schema: { type: string, format: binary } }, image/png: { schema: { type: string, format: binary } } } } '404': { description: 当前仓没有该柜或照片不存在 } /api/pda/v1/last-leg/receiving-containers/current/domestic-loading-photos/{evidenceType}/content: get: summary: 查看当前柜国内装柜照片 description: 权限 lastleg:pda:operate;只按当前操作员已锁定的物理柜读取国内装柜完成快照,不返回客户或内部文件ID,加载失败不改变拆柜状态。 security: [{ bearerAuth: [] }] parameters: - { name: evidenceType, in: path, required: true, schema: { type: string, enum: [PHOTO_STEP_1, PHOTO_STEP_2, PHOTO_STEP_3, PHOTO_STEP_4, SEAL] } } responses: '200': description: 国内装柜照片字节流;禁止缓存。 content: image/jpeg: { schema: { type: string, format: binary } } image/png: { schema: { type: string, format: binary } } application/octet-stream: { schema: { type: string, format: binary } } '404': { description: 当前柜或指定类型照片不存在 } '503': { description: 国内照片服务暂不可用 } /api/pda/v1/last-leg/receiving-containers/{containerNo}/domestic-loading-photos/{evidenceType}/content: get: summary: 按柜号查看国内装柜照片 description: 权限 lastleg:pda:operate;按当前 PDA 绑定仓和柜号读取历史或当前柜的国内装柜照片,不要求存在未完成接柜会话。 security: [{ bearerAuth: [] }] parameters: - { name: containerNo, in: path, required: true, schema: { type: string } } - { name: evidenceType, in: path, required: true, schema: { type: string, enum: [PHOTO_STEP_1, PHOTO_STEP_2, PHOTO_STEP_3, PHOTO_STEP_4, SEAL] } } responses: '200': { description: 国内装柜照片字节流, content: { image/jpeg: { schema: { type: string, format: binary } }, image/png: { schema: { type: string, format: binary } } } } '404': { description: 当前仓没有该柜或指定类型照片不存在 } /api/pda/v1/last-leg/receiving-containers/current/sign: post: summary: 签收当前柜 description: 权限 lastleg:pda:operate;精确校验车牌、封签、开门三类照片各且仅 1 张及文件归属后由 WAIT_SIGN 推进 SIGNED;重拍由调用端在签收前替换对应槽位。 security: [{ bearerAuth: [] }] requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/ReceivingSign' } } } } responses: { '200': { description: 已签收会话, content: { application/json: { schema: { $ref: '#/components/schemas/ReceivingSessionApiResponse' } } } }, '409': { description: 状态或照片校验失败 } } /api/pda/v1/last-leg/receiving-containers/current: get: summary: 恢复当前账号已签柜 description: 权限 lastleg:pda:operate;返回 WAIT_SIGN、SIGNED 或 RECEIVING 当前柜,不依赖 planNo。 security: [{ bearerAuth: [] }] responses: { '200': { description: 当前柜完整进度, content: { application/json: { schema: { $ref: '#/components/schemas/ReceivingSessionApiResponse' } } } }, '404': { description: 无当前柜 } } /api/pda/v1/last-leg/receiving-containers/current/cartons/resolve: post: summary: 解析当前柜箱唛 description: 权限 lastleg:pda:operate;一件代发扫描 DP 或任一箱码解析整托并校验跨客户完整清单;普通 FBA 扫任一箱码后按当前柜+FBA目的仓聚合所有入仓码;海外仓中转仍逐箱解析。响应不返回客户信息。 security: [{ bearerAuth: [] }] requestBody: { required: true, content: { application/json: { schema: { type: object, required: [cartonMark], properties: { cartonMark: { type: string } } } } } } responses: { '200': { description: 箱唛与入仓码信息, content: { application/json: { schema: { $ref: '#/components/schemas/ReceivingCartonResolvedApiResponse' } } } }, '404': { description: 入仓码未命中当前柜,或 OVERSEAS 箱码未命中真实 manifest }, '409': { description: '缺少 #、空入仓码前缀、跨柜或当前柜多重命中' } } /api/pda/v1/last-leg/receiving-containers/current/pallets/resolve: post: summary: 解析当前柜实物托盘码 description: 权限 lastleg:pda:operate;普通 FBA 只解析当前柜该 FBA 目的仓已经生成的“柜号-FBA仓-序号”托盘,返回版本与该托现场累计箱数。 security: [{ bearerAuth: [] }] requestBody: { required: true, content: { application/json: { schema: { type: object, required: [palletCode, inboundCode], properties: { palletCode: { type: string }, inboundCode: { type: string } } } } } } responses: { '200': { description: 可用托盘与目的匹配结果, content: { application/json: { schema: { $ref: '#/components/schemas/ReceivingPalletResolvedApiResponse' } } } }, '409': { description: 仓库、目的仓或托盘状态不符 } } /api/pda/v1/last-leg/receiving-containers/current/receipts/bulk: post: summary: FBA 入仓码按箱数收货 description: 权限 lastleg:pda:operate;只允许普通 FBA。packageCount 是该托现场累计箱数,单托最多 66 箱;服务端按当前柜+FBA目的仓稳定分摊到全部关联入仓码;超出计划但未超出单托上限的部分只记差异,不生成可用库存。 security: [{ bearerAuth: [] }] requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/ReceivingBulk' } } } } responses: { '200': { description: 本次与累计实收进度,超收返回 DIFFERENCE_RECORDED, content: { application/json: { schema: { $ref: '#/components/schemas/ReceivingReceiptApiResponse' } } } }, '409': { description: 非普通FBA、累计数回退、单托超过66箱、版本变化或托盘不匹配 } } /api/pda/v1/last-leg/receiving-containers/current/receipts/carton: post: summary: 海外仓入仓码逐箱收货 description: 权限 lastleg:pda:operate;只允许 destinationType=OVERSEAS,单托最多 66 箱,拒绝跨柜、重复箱和不匹配托盘。 security: [{ bearerAuth: [] }] requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/ReceivingCarton' } } } } responses: { '200': { description: 本次与累计实收进度, content: { application/json: { schema: { $ref: '#/components/schemas/ReceivingReceiptApiResponse' } } } }, '409': { description: FBA逐箱、跨柜、重复箱或托盘不匹配 } } /api/pda/v1/last-leg/receiving-containers/current/receipts/pallet: post: summary: 一件代发按完整来源托盘收货 description: 权限 lastleg:pda:operate;只允许 ONE_CLICK_DROPSHIP,扫描 DP 或该托任一箱码,一次接收跨客户完整 DP;单托最多 66 箱,所有客户事件分片清单一致且齐全后才允许收货。 security: [{ bearerAuth: [] }] requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/ReceivingWholePallet' } } } } responses: { '200': { description: 本次与累计实收进度, content: { application/json: { schema: { $ref: '#/components/schemas/ReceivingReceiptApiResponse' } } } }, '404': { description: 来源托盘不属于当前柜 }, '409': { description: 非一件代发、来源托盘重复或已操作 } } /api/pda/v1/last-leg/receiving-containers/current/complete: post: summary: 完成当前柜收货并入库存 description: 权限 lastleg:pda:operate;无差异时正常入库;allowDifference=true 时允许短少或超收现场结束,差异计划进入 PENDING_RECONCILIATION 且不生成客户可用库存。 security: [{ bearerAuth: [] }] requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/ReceivingComplete' } } } } responses: { '200': { description: COMPLETED 或 COMPLETED_WITH_DIFFERENCE 柜号会话, content: { application/json: { schema: { $ref: '#/components/schemas/ReceivingSessionApiResponse' } } } }, '409': { description: 未确认差异或状态冲突 } } /api/pda/v1/last-leg/inventory/resolve: post: summary: PDA按SKU、箱唛或入仓码扫码查询库存 description: 仅 OVERSEAS_WAREHOUSE_PDA_OPERATOR + lastleg:pda:operate;海外实际仓只取Token overseasWarehouseId,不接收客户或仓库参数。 security: [{ bearerAuth: [] }] requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/PdaWarehouseScan' } } } } responses: { '200': { description: 同仓跨客户库存与物理仓位事实, content: { application/json: { schema: { $ref: '#/components/schemas/PdaInventoryScanApiResponse' } } } }, '404': { description: A0404:当前绑定仓无匹配库存 } } /api/pda/v1/last-leg/locations/resolve: post: summary: PDA查询库位容量、状态与库存占用 description: 库位从Warehouse Overseas公共资源解析,并强制匹配Token绑定仓。 security: [{ bearerAuth: [] }] requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/PdaWarehouseScan' } } } } responses: { '200': { description: 库位物理事实及Lastleg库存占用汇总, content: { application/json: { schema: { $ref: '#/components/schemas/PdaLocationApiResponse' } } } }, '404': { description: A0404:库位不存在或跨仓 } } /api/pda/v1/last-leg/pallets/resolve: post: summary: PDA查询托盘、库位与绑定库存 description: 托盘从Warehouse Overseas公共资源解析;跨Token绑定仓返回A0409。 security: [{ bearerAuth: [] }] requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/PdaWarehouseScan' } } } } responses: { '200': { description: 托盘物理事实及Lastleg绑定库存, content: { application/json: { schema: { $ref: '#/components/schemas/PdaPalletApiResponse' } } } }, '409': { description: A0409:托盘属于其他仓 } } /api/pda/v1/last-leg/operations: get: summary: 查询当前PDA账号真实作业历史 description: 返回Token绑定仓内当前操作账号的柜号作业及盘点、移库、托盘、换标历史;不含出库或派送。 security: [{ bearerAuth: [] }] parameters: - { name: page, in: query, schema: { type: integer, minimum: 1, default: 1 } } - { name: size, in: query, schema: { type: integer, minimum: 1, maximum: 200, default: 20 } } - { name: operationType, in: query, schema: { type: string } } responses: { '200': { description: 真实作业历史分页, content: { application/json: { schema: { $ref: '#/components/schemas/PdaOperationPageApiResponse' } } } } } /api/platform/v1/last-leg/orders: get: summary: 分页查询尾程订单 description: 权限 platform:overseas-warehouse:last-mile-order:list;平台管理员省略 customerId 时查询全部客户。containerNode 来自稳定 sourceContainerBookingId 对应的柜级船节点门禁;grossWeightKg/netWeightKg 由头程冻结货物明细聚合。businessSource 返回 businessType、label、businessOrderNo、externalBookingNo;商业类型优先取同客户同尾程单的池来源桥,独立散板取自身来源单号,普通转运不推断为散板。orderType 保留履约类型;无关联单号为空。 security: [{ bearerAuth: [] }] parameters: - { name: businessType, in: query, description: 商业类型;本土散板同时覆盖独立和池来源,仓储转运排除已关联散板或卡车商业单, schema: { type: string, maxLength: 64 } } - { name: businessOrderNo, in: query, description: 正式关联商业单号包含匹配,不解析备注, schema: { type: string, maxLength: 128 } } - { name: externalBookingNo, in: query, description: 正式外接预订号包含匹配,不解析备注, schema: { type: string, maxLength: 128 } } - { name: sailingStage, in: query, description: '可选开船阶段。仅匹配头程订单类型 FIRST_LEG;未传不限制类型。按实际柜级节点序号>=40判断开船后;人工节点覆盖后仅按该票 ACTUAL_DEPARTURE 非空判断,不回退柜级。无实际开船事实归开船前。', schema: { type: string, enum: [BEFORE_DEPARTURE, AFTER_DEPARTURE] } } - { name: page, in: query, schema: { type: integer, minimum: 1, default: 1 } } - { name: size, in: query, schema: { type: integer, minimum: 1, maximum: 200, default: 20 } } - { name: orderNo, in: query, schema: { type: string } } - { name: orderType, in: query, schema: { type: string, enum: [FIRST_LEG, RELABEL_APPLICATION, WAREHOUSE_TRANSFER, LOCAL_LOOSEBOARD, RETURN_RELABEL, ONE_CLICK_DROPSHIP, CARGO_DISCARD] } } - { name: currentStatus, in: query, schema: { type: string } } - { name: inboundCode, in: query, schema: { type: string } } - { name: sourceOrderNo, in: query, schema: { type: string } } - { name: containerNo, in: query, schema: { type: string } } - { name: warehouse, in: query, description: 按尾程订单冻结的海外接柜仓名称或编码进行大小写无关的包含匹配, schema: { type: string } } - { name: transferWarehouseCode, in: query, schema: { type: string } } - { name: abnormal, in: query, schema: { type: boolean } } - { name: detained, in: query, schema: { type: boolean } } - { name: createdFrom, in: query, schema: { type: string, format: date-time } } - { name: createdTo, in: query, schema: { type: string, format: date-time } } responses: { '200': { description: 统一 ApiResponse 包装的尾程订单分页;每行 relabelApplications 数组按创建时间返回所有换标子单的 relabelNo、status、quantity、createdAt,旧标量字段只代表最近一张;列表行 destinationType 为 FBA 或 OVERSEAS;inboundCode 仅返回真实来源入仓码,无入仓关系的换标申请和本土散板为空 } } /api/platform/v1/last-leg/orders/{id}: get: summary: 查询尾程订单详情 x-return-order-number: RETURN_RELABEL 类型的 order.orderNo 与来源退货单 returnNo 相同;创建时使用同一 RT 单号,退货关联快照 lastlegOrderNo 同步保存该号。 description: 权限 platform:overseas-warehouse:last-mile-order:list;返回订单、货物、状态历史、费用明细和操作记录。订单中的 containerNode 来自稳定 sourceContainerBookingId 对应的柜级船节点门禁;grossWeightKg/netWeightKg 由头程冻结货物明细聚合。businessSource 返回 businessType、label、businessOrderNo、externalBookingNo;商业类型优先取同客户同尾程单的池来源桥,独立散板取自身来源单号,普通转运不推断为散板。orderType 保留履约类型;无关联单号为空。 security: [{ bearerAuth: [] }] parameters: - { name: id, in: path, required: true, schema: { type: integer, format: int64 } } - { name: customerId, in: query, required: false, schema: { type: string, pattern: '^[1-9][0-9]*$' } } responses: '200': { description: 统一 ApiResponse 包装的尾程订单详情;order.relabelApplications 返回所有换标子单的独立状态和本次数量。RETURN_RELABEL 订单另返回 returnReceipt,其结构与退货单详情相同,按订单真实客户与 sourceOrderNo 读取签收汇总和 cartons 箱内签收清点快照;其他类型 returnReceipt 为 null } '404': { description: 尾程订单不存在或不属于查询客户 } /api/platform/v1/last-leg/orders/{id}/relabel-review: put: summary: 在尾程订单工作台审核客户直接创建的贴标单 description: 权限 platform:overseas-warehouse:last-mile-order:edit;仅 RELABEL_APPLICATION + PENDING_REVIEW 可审核。通过进入 WAIT_RELABEL,驳回必须填写原因并保持 REJECTED 供客户修改后重提。 security: [{ bearerAuth: [] }] parameters: - { name: id, in: path, required: true, schema: { type: integer, format: int64 } } - { name: customerId, in: query, required: false, schema: { type: string, pattern: '^[1-9][0-9]*$' } } requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/RelabelStatusChange' } } } } responses: { '200': { description: 审核后的贴标单详情 }, '400': { description: 驳回原因缺失或决定非法 }, '409': { description: 非直接贴标单、审核入口错误或状态冲突 } } /api/platform/v1/last-leg/orders/{id}/fees: post: summary: 新增尾程订单费用 description: 权限 platform:overseas-warehouse:last-mile-order:edit;在订单客户范围内创建统一费用来源并提交财务审核。 security: [{ bearerAuth: [] }] parameters: - { name: id, in: path, required: true, schema: { type: integer, format: int64 } } - { name: customerId, in: query, required: false, schema: { type: string, pattern: '^[1-9][0-9]*$' } } - { name: Idempotency-Key, in: header, required: true, schema: { type: string, minLength: 1, maxLength: 128 } } requestBody: required: true content: { application/json: { schema: { $ref: '#/components/schemas/LastMileFeeCreate' } } } responses: '200': { description: 新增后的费用明细, content: { application/json: { schema: { $ref: '#/components/schemas/LastMileFeeApiResponse' } } } } '404': { description: 尾程订单不存在或不属于操作客户 } /api/platform/v1/last-leg/orders/{id}/hold: put: summary: 设置或解除尾程订单暂扣 description: 权限 platform:overseas-warehouse:last-mile-order:edit;使用订单版本和 Idempotency-Key 原子写入计费标记、原因及不可变历史。仅完成入库且尚未进入出库流程的订单允许新增暂扣;解除暂扣不受该状态限制。暂扣只作用于当前票并仅阻断排车和出库,不影响入库计划或同柜其他订单。 security: [{ bearerAuth: [] }] parameters: - { name: id, in: path, required: true, schema: { type: integer, format: int64 } } - { name: customerId, in: query, required: false, schema: { type: string, pattern: '^[1-9][0-9]*$' } } - { name: Idempotency-Key, in: header, required: true, schema: { type: string, minLength: 1, maxLength: 128 } } requestBody: required: true content: application/json: schema: { $ref: '#/components/schemas/LastlegOrderHoldRequest' } responses: '200': { description: 暂扣状态已更新, content: { application/json: { schema: { type: object, properties: { code: { type: string }, data: { $ref: '#/components/schemas/LastlegOrderHoldResponse' } } } } } } '409': { description: 版本冲突、幂等键冲突、重复状态、尚未完成入库或订单已进入出库流程 } /api/platform/v1/last-leg/orders/{id}/manual-nodes: get: summary: 查询尾程订单人工展示节点 description: 权限 platform:overseas-warehouse:last-mile-order:list;人工覆盖开启后返回完整且固定顺序的8行快照,行值允许为空。 security: [{ bearerAuth: [] }] parameters: - { name: id, in: path, required: true, schema: { type: integer, format: int64 } } - { name: customerId, in: query, required: false, schema: { type: string, pattern: '^[1-9][0-9]*$' } } responses: { '200': { description: 完整人工展示节点快照 } } put: summary: 永久启用并保存尾程订单人工展示节点 description: 权限 platform:overseas-warehouse:last-mile-order:edit;提交完整8行快照且至少一个时间非空,使用订单版本和 Idempotency-Key;保存后 nodeSource 永久为 MANUAL,不回写柜节点,也不提供清除或恢复继承接口。 security: [{ bearerAuth: [] }] parameters: - { name: id, in: path, required: true, schema: { type: integer, format: int64 } } - { name: customerId, in: query, required: false, schema: { type: string, pattern: '^[1-9][0-9]*$' } } - { name: Idempotency-Key, in: header, required: true, schema: { type: string, minLength: 1, maxLength: 128 } } requestBody: required: true content: { application/json: { schema: { $ref: '#/components/schemas/LastlegOrderManualNodesRequest' } } } responses: '200': { description: 更新后的完整8行人工展示节点快照 } '409': { description: 订单版本或幂等键冲突 } /api/platform/v1/last-leg/orders/{id}/pallet-merge-required: put: summary: 设置尾程订单合托标记 description: 权限 platform:overseas-warehouse:last-mile-order:edit;标记后 PDA 扫描本单箱唛时返回合托提示;实际完成合托后不可取消。 security: [{ bearerAuth: [] }] parameters: - { name: id, in: path, required: true, schema: { type: integer, format: int64 } } - { name: customerId, in: query, required: false, schema: { type: string, pattern: '^[1-9][0-9]*$' } } requestBody: required: true content: application/json: schema: type: object required: [palletMergeRequired] properties: { palletMergeRequired: { type: boolean } } responses: { '200': { description: 合托标记已更新 }, '409': { description: 已完成实际合托,不能修改标记 } } /api/platform/v1/last-leg/orders/pallet-merge-required/batch: put: summary: 批量设置同组合托标记 description: 权限 platform:overseas-warehouse:last-mile-order:edit;所选订单按同一合托批次原子标记或取消。 security: [{ bearerAuth: [] }] requestBody: required: true content: application/json: schema: type: object required: [orderIds, palletMergeRequired] properties: orderIds: { type: array, minItems: 1, uniqueItems: true, items: { type: integer, format: int64 } } palletMergeRequired: { type: boolean } responses: { '200': { description: 批量合托标记已更新 } } /api/platform/v1/last-leg/orders/container-summaries: get: summary: 分页查询柜级入库计划进度 description: 权限 platform:overseas-warehouse:last-mile-order:list;平台跨客户按稳定 sourceContainerBookingId 服务端聚合,不受订单分页影响,返回全部稳定来源柜;全部入仓码均已生成有效独立计划的柜仍保留,供柜级接柜仓查询与修改,生成计划动作由 allPlansReady/pendingPlanCount 控制。containerNo 只返回装柜完成事件携带并规范化冻结的真实集装箱号,不从 cabinetNo、订单号或内部 ID 推导。plannedArrivalAt 取 ll_order.estimated_warehouse_at,可由装柜完成事件初始化,并在入库计划生成前由平台按整柜人工修正;按该时间升序、null 最后、稳定柜 ID 升序。 security: [{ bearerAuth: [] }] parameters: - { name: page, in: query, schema: { type: integer, minimum: 1, default: 1 } } - { name: size, in: query, schema: { type: integer, minimum: 1, maximum: 200, default: 20 } } - { name: containerNo, in: query, schema: { type: string } } - { name: createdFrom, in: query, schema: { type: string, format: date-time } } - { name: createdTo, in: query, schema: { type: string, format: date-time } } responses: '200': description: 统一 ApiResponse 包装的柜级摘要分页 content: application/json: schema: type: object properties: code: { type: string, enum: ['200'] } data: type: object properties: page: { type: integer, format: int64 } size: { type: integer, format: int64 } total: { type: integer, format: int64 } pages: { type: integer, format: int64 } records: type: array items: { $ref: '#/components/schemas/ContainerPlanProgressSummary' } /api/platform/v1/last-leg/orders/container-summaries/{sourceContainerBookingId}: get: summary: 查询柜级入库计划进度详情 description: 权限 platform:overseas-warehouse:last-mile-order:list;按稳定柜 ID 返回柜内全部尾程订单、入仓码及各自计划状态,不受订单分页截断。 security: [{ bearerAuth: [] }] parameters: - { name: sourceContainerBookingId, in: path, required: true, schema: { type: string, minLength: 1, maxLength: 128 } } responses: '200': description: 统一 ApiResponse 包装的柜级进度详情 content: application/json: schema: type: object properties: code: { type: string, enum: ['200'] } data: { $ref: '#/components/schemas/ContainerPlanProgressDetail' } '404': { description: 稳定柜 ID 不存在 } /api/platform/v1/last-leg/orders/container-summaries/{sourceContainerBookingId}/receiving-warehouse: put: summary: 修改整柜海外接柜仓 description: 权限 platform:overseas-warehouse:last-mile-order:edit;目标必须为国内 Warehouse Service 有效 OVERSEAS 仓。使用柜级版本和 Idempotency-Key,事务内原子同步柜内全部尾程订单及已有入库计划;海外PDA一旦建立接柜会话即永久锁定。 security: [{ bearerAuth: [] }] parameters: - { name: sourceContainerBookingId, in: path, required: true, schema: { type: string, minLength: 1, maxLength: 128 } } - { name: Idempotency-Key, in: header, required: true, schema: { type: string, minLength: 1, maxLength: 255 } } requestBody: required: true content: application/json: schema: { $ref: '#/components/schemas/ChangeReceivingWarehouseRequest' } responses: '200': description: 更新后的柜级摘要 content: application/json: schema: type: object properties: code: { type: string, enum: ['200'] } data: { $ref: '#/components/schemas/ContainerPlanProgressSummary' } '400': { description: 请求无效或目标不是有效 OVERSEAS 仓 } '409': { description: 版本冲突、幂等键冲突或PDA接柜会话已建立 } /api/platform/v1/last-leg/orders/container-arrival-times/query: post: summary: 批量查询整柜预计与实际到仓时间 description: 权限 platform:overseas-warehouse:last-mile-order:list;预计到仓取整柜人工冻结值,实际到仓取海外 PDA 首次开始收货时间。 security: [{ bearerAuth: [] }] requestBody: required: true content: application/json: schema: { $ref: '#/components/schemas/ContainerArrivalTimeQuery' } responses: '200': description: 柜级到仓时间列表 content: application/json: schema: type: object properties: code: { type: string, enum: ['200'] } data: type: array items: { $ref: '#/components/schemas/ContainerArrivalTimeView' } /api/platform/v1/last-leg/orders/container-summaries/{sourceContainerBookingId}/expected-arrival: put: summary: 修改整柜预计到仓时间 description: 权限 platform:overseas-warehouse:last-mile-order:edit;使用柜级时间版本与 Idempotency-Key,在入库计划生成前原子更新柜内全部尾程订单。 security: [{ bearerAuth: [] }] parameters: - { name: sourceContainerBookingId, in: path, required: true, schema: { type: string } } - { name: Idempotency-Key, in: header, required: true, schema: { type: string, minLength: 1, maxLength: 255 } } requestBody: required: true content: application/json: schema: { $ref: '#/components/schemas/ChangeExpectedWarehouseArrivalRequest' } responses: '200': description: 更新后的柜级到仓时间 content: application/json: schema: type: object properties: code: { type: string, enum: ['200'] } data: { $ref: '#/components/schemas/ContainerArrivalTimeView' } '409': { description: 已生成入库计划、版本冲突或幂等键冲突 } /api/platform/v1/last-leg/orders/{id}/destination: put: summary: 将单票尾程订单转入 FBA 目的仓 description: 权限 platform:overseas-warehouse:last-mile-order:edit;目标必须来自国内 Warehouse Service 平台公共 ACTIVE FBA 主档,warehouseId/warehouseCode/warehouseName 必须与权威记录一致。实际海外收货仓、普通国内中转仓、停用仓或伪造字段均返回 A0400“所选FBA仓不存在或已停用”。 security: [{ bearerAuth: [] }] parameters: - { name: id, in: path, required: true, schema: { type: string, pattern: '^[1-9][0-9]*$' } } - { name: customerId, in: query, required: false, schema: { type: string, pattern: '^[1-9][0-9]*$' } } requestBody: required: true content: application/json: schema: { $ref: '#/components/schemas/FbaTransferDestination' } responses: '200': { description: 统一 ApiResponse 包装的更新订单数 } '400': { description: 所选FBA仓不存在、已停用、类型错误或字段不一致 } '503': { description: 国内FBA仓权威主数据暂不可用,写入失败关闭 } /api/platform/v1/last-leg/orders/destination: put: summary: 批量将尾程订单转入 FBA 目的仓 description: 权限 platform:overseas-warehouse:last-mile-order:edit;一次校验国内 Warehouse Service 权威 FBA 主档后,在 Lastleg 事务内更新所选订单及冻结明细。目标仓必须为平台公共 ACTIVE FBA 且 ID/编码/名称完全一致。 security: [{ bearerAuth: [] }] parameters: - { name: customerId, in: query, required: false, schema: { type: string, pattern: '^[1-9][0-9]*$' } } requestBody: required: true content: application/json: schema: { $ref: '#/components/schemas/FbaBatchTransferDestination' } responses: '200': { description: 统一 ApiResponse 包装的更新订单数 } '400': { description: 所选FBA仓不存在、已停用、类型错误或字段不一致 } '503': { description: 国内FBA仓权威主数据暂不可用,写入失败关闭 } /api/platform/v1/last-leg/inbound-plans: get: summary: 平台分页查询海外入库订单 description: 权限 platform:overseas-warehouse:inbound-order:list;overseasWarehouseCode/overseasWarehouseName 只取尾程订单预分配接柜仓事实,并按入库计划冻结接柜仓ID从海外仓权威目录解析;warehouseCode/warehouseName 仍表示目的仓。 security: [{ bearerAuth: [] }] parameters: - { name: customerId, in: query, required: false, schema: { type: string, pattern: '^[1-9][0-9]*$' } } - { name: page, in: query, schema: { type: integer, minimum: 1, default: 1 } } - { name: size, in: query, schema: { type: integer, minimum: 1, maximum: 200, default: 20 } } - { name: planNo, in: query, schema: { type: string } } - { name: inboundCode, in: query, schema: { type: string } } - { name: lxCode, in: query, schema: { type: string } } - { name: status, in: query, schema: { type: string } } - { name: overseasWarehouseId, in: query, schema: { type: string } } - { name: destinationWarehouseCode, in: query, schema: { type: string } } - { name: warehouse, in: query, schema: { type: string } } - { name: fbaWarehouseCode, in: query, schema: { type: string } } - { name: appointmentStatus, in: query, schema: { type: string, enum: [UNAPPOINTED, PENDING, SUCCESS, FAILED, CANCELLED, MULTIPLE] } } - { name: dispatchStatus, in: query, schema: { type: string, enum: [UNSCHEDULED, SCHEDULED] } } - { name: createdFrom, in: query, schema: { type: string, format: date-time } } - { name: createdTo, in: query, schema: { type: string, format: date-time } } responses: { '200': { description: 平台入库订单分页, content: { application/json: { schema: { $ref: '#/components/schemas/InboundPlanPageResponse' } } } } } /api/platform/v1/last-leg/inbound-plans/{planNo}: get: summary: 平台查询海外入库订单详情 description: 权限 platform:overseas-warehouse:inbound-order:list;详情中的 overseasWarehouseCode/overseasWarehouseName 只取当前计划来源尾程订单的预分配接柜仓事实。 security: [{ bearerAuth: [] }] parameters: - { name: planNo, in: path, required: true, schema: { type: string } } - { name: customerId, in: query, required: false, schema: { type: string, pattern: '^[1-9][0-9]*$' } } responses: '200': { description: 平台入库订单详情, content: { application/json: { schema: { $ref: '#/components/schemas/InboundPlanDetailResponse' } } } } '404': { description: 入库订单不存在或不属于指定客户 } /api/platform/v1/last-leg/inbound-plans/{planNo}/confirm-shortage: post: summary: 确认FBA入库短少并按实收入库 description: 权限 platform:overseas-warehouse:inbound-order:edit;仅平台指定客户操作。仅支持同柜次同目的仓收货组单票、冻结申报单SKU;多SKU或跨票合收不能按自动分摊确认。PENDING_RECONCILIATION且0<实收<应收时,核对版本及逐SKU实收,保留原应收和现场收货时间,按实收写入库存并进入PARTIAL_INBOUND,同事务交接原预排并移除明确零实收托盘的排车明细、占用和预约分配。操作原因与操作人写入收货操作记录;不重复发布卸柜事件。超收、SKU不一致、客户不匹配和陈旧版本拒绝;相同请求键重放不会重复入库。 security: [{ bearerAuth: [] }] parameters: - { name: planNo, in: path, required: true, schema: { type: string } } - { name: Idempotency-Key, in: header, required: true, schema: { type: string, minLength: 1, maxLength: 128 } } requestBody: required: true content: application/json: schema: type: object required: [customerId, version, expectedPackageCount, receivedPackageCount, reason] properties: customerId: { type: string, pattern: '^[1-9][0-9]*$' } version: { type: integer, minimum: 0 } expectedPackageCount: { type: integer, minimum: 1 } receivedPackageCount: { type: integer, minimum: 1 } reason: { type: string, minLength: 1, maxLength: 200 } responses: '200': { description: ApiResponse包装的收货任务结果,status为PARTIAL_INBOUND } '403': { description: 非平台身份或无入库编辑权限 } '404': { description: 入库单不存在或客户不匹配 } '409': { description: 版本、状态、实收数量、SKU或幂等键冲突 } /api/platform/v1/last-leg/inbound-plans/manual: post: summary: 平台按单票手工生成入库计划 description: 权限 platform:overseas-warehouse:inbound-order:create;按 customerId 与 orderId 锁定单票,校验订单版本、状态、真实入仓码、客户归属及有效公共接柜仓。暂扣只限制排车和出库,不阻断入库计划。预计到仓日期由服务端锁定读取来源柜全部订单的 estimatedWarehouseAt,缺失或同柜不一致时拒绝生成,不接受调用方提交。一次只生成当前票的独立计划,不改变同柜其他订单;命令原子且幂等。 security: [{ bearerAuth: [] }] parameters: - { name: Idempotency-Key, in: header, required: true, schema: { type: string, minLength: 1, maxLength: 128 } } requestBody: required: true content: application/json: schema: { $ref: '#/components/schemas/ManualInboundPlanRequest' } responses: '200': { description: 统一 ApiResponse 包装的入库计划详情 } '400': { description: 客户、入仓码、仓库主数据或请求字段无效 } '409': { description: 订单版本、状态、柜级预计到仓时间、重复计划或幂等键冲突 } /api/platform/v1/last-leg/inbound-plans/convert-container: post: summary: 按整柜批量生成剩余入库计划 description: 权限 platform:overseas-warehouse:inbound-order:create;调用方必须先取柜级预览并原样回传 snapshotVersion/snapshotHash。服务端以 sourceContainerBookingId 建立唯一 Saga 命令,先向海外仓资源服务按票、按托盘批量预留真实 palletId/palletCode/locationId/resourceLockId,再在一个本地事务中锁整柜并为每票生成独立计划,最后确认资源批次。本地任一票失败时整柜回滚并补偿资源;本地已提交但远端确认失败时重放只重试确认。同柜不同 Idempotency-Key 也不会产生第二批资源。 security: [{ bearerAuth: [] }] parameters: - { name: Idempotency-Key, in: header, required: true, schema: { type: string, minLength: 1, maxLength: 128 } } requestBody: required: true content: application/json: schema: type: object required: [sourceContainerBookingId, snapshotVersion, snapshotHash] properties: sourceContainerBookingId: { type: string, minLength: 1, maxLength: 128 } snapshotVersion: { type: integer, format: int64, minimum: 0 } snapshotHash: { type: string, pattern: '^[0-9a-f]{64}$' } responses: { '200': { description: 统一 ApiResponse 包装的入库计划数组 } } /api/platform/v1/last-leg/inbound-plans/container-preview: get: summary: 预览按柜生成入库计划 description: 权限 platform:overseas-warehouse:inbound-order:list;按稳定 sourceContainerBookingId 返回不受订单分页影响的全柜事实。分组固定为 FBA、一件代发、私人地址,FBA 按目的仓编码/名称/ID 稳定排序;托数及 readiness/blockers 只由服务端计算。确认时必须原样回传 snapshotVersion 与 snapshotHash,服务端仍会锁柜重算。 security: [{ bearerAuth: [] }] parameters: - { name: sourceContainerBookingId, in: query, required: true, schema: { type: string, minLength: 1, maxLength: 128 } } responses: '200': { description: 柜级入库计划转换预览, content: { application/json: { schema: { $ref: '#/components/schemas/ContainerInboundPlanPreviewApiResponse' } } } } '404': { description: 来源柜没有尾程订单 } /api/platform/v1/last-leg/dispatches: get: summary: 分页查询五阶段整车及全量筛选统计 description: 权限 platform:overseas-warehouse:dispatch:list。客户仅为平台可选明细筛选,整车主单无客户头部;取消不是第六阶段。 security: - bearerAuth: [] responses: '200': description: 统一ApiResponse;业务失败通过code返回,不能仅凭HTTP200判断成功。 content: application/json: schema: type: object properties: code: type: string message: type: string requestId: type: string nullable: true traceId: type: string nullable: true timestamp: type: string format: date-time data: allOf: - $ref: '#/components/schemas/DispatchPage' nullable: true parameters: - name: page in: query schema: type: integer minimum: 1 - name: size in: query schema: type: integer minimum: 1 maximum: 200 - name: dispatchNo in: query schema: type: string - name: vehiclePlate in: query schema: type: string - name: warehouseId in: query schema: type: string - name: customerId in: query schema: type: string - name: fbaAppointmentNo in: query schema: type: string - name: status in: query schema: $ref: '#/components/schemas/DispatchStatusFilter' - name: stage in: query schema: $ref: '#/components/schemas/DispatchStage' - name: beforeLoadingSection in: query schema: $ref: '#/components/schemas/DispatchBeforeLoadingSection' - name: reviewStatus in: query schema: $ref: '#/components/schemas/DispatchReviewStatus' post: summary: 新建一趟整车排车 description: 权限 platform:overseas-warehouse:dispatch:create。 security: - bearerAuth: [] responses: '200': description: 统一ApiResponse;业务失败通过code返回,不能仅凭HTTP200判断成功。 content: application/json: schema: type: object properties: code: type: string message: type: string requestId: type: string nullable: true traceId: type: string nullable: true timestamp: type: string format: date-time data: allOf: - $ref: '#/components/schemas/DispatchCommandResult' nullable: true requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/DispatchCreate' /api/platform/v1/last-leg/dispatches/{dispatchNo}: get: summary: 读取四块排车详情 description: 权限 platform:overseas-warehouse:dispatch:list。 security: - bearerAuth: [] responses: '200': description: 统一ApiResponse;业务失败通过code返回,不能仅凭HTTP200判断成功。 content: application/json: schema: type: object properties: code: type: string message: type: string requestId: type: string nullable: true traceId: type: string nullable: true timestamp: type: string format: date-time data: allOf: - $ref: '#/components/schemas/DispatchDetail' nullable: true put: summary: 按当前整车版本维护资源及计划 description: 权限 platform:overseas-warehouse:dispatch:edit。更改影响审核依据时使两级审核失效;不手改阶段和实际发车时间。 security: - bearerAuth: [] responses: '200': description: 统一ApiResponse;业务失败通过code返回,不能仅凭HTTP200判断成功。 content: application/json: schema: type: object properties: code: type: string message: type: string requestId: type: string nullable: true traceId: type: string nullable: true timestamp: type: string format: date-time data: allOf: - $ref: '#/components/schemas/DispatchCommandResult' nullable: true requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/DispatchUpdate' parameters: - name: dispatchNo in: path required: true schema: type: string /api/platform/v1/last-leg/dispatches/{dispatchNo}/prints/bol: get: summary: 生成排车 BOL PDF description: 权限 platform:overseas-warehouse:dispatch:list;服务端按目的地与预约号归集BOL,同目的地同预约号跨客户合并,不同预约号分别生成BOL并独立分页;无预约号也能打印且预约栏留空,同目的地空号合并。本次仍返回包含各份BOL的一个固定A4 PDF,浏览器不直接访问内部打印服务,打印不改变货物客户归属。 security: [{ bearerAuth: [] }] parameters: [{ name: dispatchNo, in: path, required: true, schema: { type: string } }] responses: '200': description: BOL PDF headers: Content-Disposition: { schema: { type: string } } X-Print-Page-Count: { schema: { type: integer, minimum: 1 } } content: { application/pdf: { schema: { type: string, format: binary } } } '404': { description: 排车单不存在 } '422': { description: 排车单没有可打印的 BOL 明细 } /api/platform/v1/last-leg/dispatches/candidates: get: summary: 分页读取真实候选及来源版本 description: 权限 platform:overseas-warehouse:dispatch:list。数据库按客户、订单、托盘和来源身份稳定排序分页;总数与当前页来自同一只读快照。selectionGroup仍包含完整同托及整申请来源,可包含页外成员;选取时服务端再次权威解析,不以当前页充当完整组。 security: - bearerAuth: [] responses: '200': description: 统一ApiResponse;业务失败通过code返回,不能仅凭HTTP200判断成功。 content: application/json: schema: type: object properties: code: type: string message: type: string requestId: type: string nullable: true traceId: type: string nullable: true timestamp: type: string format: date-time data: allOf: - $ref: '#/components/schemas/DispatchCandidateList' nullable: true parameters: - name: warehouseId in: query description: 可选真实起运仓;未指定时按 warehouseTab 跨仓分页浏览,草稿及建单仍要求同一起运仓。 required: false schema: type: string - name: planIds in: query schema: type: array items: type: string style: form explode: true - name: orderNo in: query schema: type: string - name: destinationWarehouseCode in: query schema: type: string - name: sourceStage in: query schema: type: string - name: draftToken in: query schema: type: string - name: page in: query schema: type: integer minimum: 1 default: 1 - name: size in: query schema: type: integer minimum: 1 maximum: 50 default: 20 - name: warehouseTab in: query description: 对起运仓名称和编码的服务端页签筛选,在统计和分页前生效。 schema: type: string enum: [ALL, LAX, NYC] default: ALL /api/platform/v1/last-leg/dispatches/drafts/pre-arrange: post: summary: 将所有非空容器原子转换为整车 description: 权限 platform:overseas-warehouse:dispatch:create。本人草稿、单仓;一容器一整车,保留多客户和多目的地。原键重放返回原结果,任一组失败全批回滚。 security: - bearerAuth: [] responses: '200': description: 统一ApiResponse;业务失败通过code返回,不能仅凭HTTP200判断成功。 content: application/json: schema: type: object properties: code: type: string message: type: string requestId: type: string nullable: true traceId: type: string nullable: true timestamp: type: string format: date-time data: allOf: - $ref: '#/components/schemas/DispatchConvertedDraft' nullable: true requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/DispatchConvertDraft' /api/platform/v1/last-leg/dispatches/draft-locks/lock: post: summary: 核对来源版本后锁入本草稿容器 description: 权限 platform:overseas-warehouse:dispatch:create。本人草稿、单仓;一容器一整车,保留多客户和多目的地。原键重放返回原结果,任一组失败全批回滚。 security: - bearerAuth: [] responses: '200': description: 统一ApiResponse;业务失败通过code返回,不能仅凭HTTP200判断成功。 content: application/json: schema: type: object properties: code: type: string message: type: string requestId: type: string nullable: true traceId: type: string nullable: true timestamp: type: string format: date-time data: allOf: - $ref: '#/components/schemas/DispatchDraft' nullable: true requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/DispatchDraftSelection' /api/platform/v1/last-leg/dispatches/draft-locks/unlock: post: summary: 解除本草稿本容器原来源占用 description: 权限 platform:overseas-warehouse:dispatch:create。本人草稿、单仓;一容器一整车,保留多客户和多目的地。原键重放返回原结果,任一组失败全批回滚。 security: - bearerAuth: [] responses: '200': description: 统一ApiResponse;业务失败通过code返回,不能仅凭HTTP200判断成功。 content: application/json: schema: type: object properties: code: type: string message: type: string requestId: type: string nullable: true traceId: type: string nullable: true timestamp: type: string format: date-time data: allOf: - $ref: '#/components/schemas/DispatchDraft' nullable: true requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/DispatchDraftSelection' /api/platform/v1/last-leg/dispatches/draft-locks/release: post: summary: 按拥有者和版本释放草稿 description: 权限 platform:overseas-warehouse:dispatch:create。本人草稿、单仓;一容器一整车,保留多客户和多目的地。原键重放返回原结果,任一组失败全批回滚。 security: - bearerAuth: [] responses: '200': description: 统一ApiResponse;业务失败通过code返回,不能仅凭HTTP200判断成功。 content: application/json: schema: type: object properties: code: type: string message: type: string requestId: type: string nullable: true traceId: type: string nullable: true timestamp: type: string format: date-time data: allOf: - $ref: '#/components/schemas/DispatchDraft' nullable: true requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/DispatchDraftRelease' /api/platform/v1/last-leg/dispatches/drafts: get: summary: 查询本人未失效的服务器草稿 description: 权限 platform:overseas-warehouse:dispatch:list。 security: - bearerAuth: [] responses: '200': description: 统一ApiResponse;业务失败通过code返回,不能仅凭HTTP200判断成功。 content: application/json: schema: type: object properties: code: type: string message: type: string requestId: type: string nullable: true traceId: type: string nullable: true timestamp: type: string format: date-time data: allOf: - type: array items: $ref: '#/components/schemas/DispatchDraft' nullable: true post: summary: 持久幂等创建服务器草稿 description: 权限 platform:overseas-warehouse:dispatch:create。 security: - bearerAuth: [] responses: '200': description: 统一ApiResponse;业务失败通过code返回,不能仅凭HTTP200判断成功。 content: application/json: schema: type: object properties: code: type: string message: type: string requestId: type: string nullable: true traceId: type: string nullable: true timestamp: type: string format: date-time data: allOf: - $ref: '#/components/schemas/DispatchDraft' nullable: true requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/DispatchCreateDraft' /api/platform/v1/last-leg/dispatches/drafts/snapshot: post: summary: 保存本草稿已锁定来源的布局 description: 权限 platform:overseas-warehouse:dispatch:create。本人草稿、单仓;一容器一整车,保留多客户和多目的地。原键重放返回原结果,任一组失败全批回滚。 security: - bearerAuth: [] responses: '200': description: 统一ApiResponse;业务失败通过code返回,不能仅凭HTTP200判断成功。 content: application/json: schema: type: object properties: code: type: string message: type: string requestId: type: string nullable: true traceId: type: string nullable: true timestamp: type: string format: date-time data: allOf: - $ref: '#/components/schemas/DispatchDraft' nullable: true requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/DispatchDraftSnapshot' /api/platform/v1/last-leg/dispatches/drafts/containers: post: summary: 按草稿版本新增装车容器 description: 权限 platform:overseas-warehouse:dispatch:create。本人草稿、单仓;一容器一整车,保留多客户和多目的地。原键重放返回原结果,任一组失败全批回滚。 security: - bearerAuth: [] responses: '200': description: 统一ApiResponse;业务失败通过code返回,不能仅凭HTTP200判断成功。 content: application/json: schema: type: object properties: code: type: string message: type: string requestId: type: string nullable: true traceId: type: string nullable: true timestamp: type: string format: date-time data: allOf: - $ref: '#/components/schemas/DispatchDraft' nullable: true requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/DispatchCreateContainer' /api/platform/v1/last-leg/dispatches/drafts/{draftToken}/containers/{containerId}: delete: summary: 按版本移除本人草稿的空容器 description: 权限 platform:overseas-warehouse:dispatch:create。容器非空时拒绝;DELETE也须提交原版本和幂等请求体。 security: - bearerAuth: [] responses: '200': description: 统一ApiResponse;业务失败通过code返回,不能仅凭HTTP200判断成功。 content: application/json: schema: type: object properties: code: type: string message: type: string requestId: type: string nullable: true traceId: type: string nullable: true timestamp: type: string format: date-time data: allOf: - $ref: '#/components/schemas/DispatchDraft' nullable: true requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/DispatchReasonCommand' parameters: - name: draftToken in: path required: true schema: type: string - name: containerId in: path required: true schema: type: string /api/platform/v1/last-leg/dispatches/{dispatchNo}/external-freight: get: summary: 读取各客户目的地外接运费组 description: 权限 platform:overseas-warehouse:dispatch:list。 security: - bearerAuth: [] responses: '200': description: 统一ApiResponse;业务失败通过code返回,不能仅凭HTTP200判断成功。 content: application/json: schema: type: object properties: code: type: string message: type: string requestId: type: string nullable: true traceId: type: string nullable: true timestamp: type: string format: date-time data: allOf: - type: array items: $ref: '#/components/schemas/DispatchPreviewGroup' nullable: true parameters: - name: dispatchNo in: path required: true schema: type: string /api/platform/v1/last-leg/dispatches/{dispatchNo}/items: post: summary: 按真实来源版本向整车加货 description: 权限 platform:overseas-warehouse:dispatch:edit。 security: - bearerAuth: [] responses: '200': description: 统一ApiResponse;业务失败通过code返回,不能仅凭HTTP200判断成功。 content: application/json: schema: type: object properties: code: type: string message: type: string requestId: type: string nullable: true traceId: type: string nullable: true timestamp: type: string format: date-time data: allOf: - $ref: '#/components/schemas/DispatchCommandResult' nullable: true requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/DispatchAddCargo' get: summary: 读取真实明细及逐项移除资格 description: 权限 platform:overseas-warehouse:dispatch:list。 security: - bearerAuth: [] responses: '200': description: 统一ApiResponse;业务失败通过code返回,不能仅凭HTTP200判断成功。 content: application/json: schema: type: object properties: code: type: string message: type: string requestId: type: string nullable: true traceId: type: string nullable: true timestamp: type: string format: date-time data: allOf: - $ref: '#/components/schemas/DispatchItems' nullable: true parameters: - name: dispatchNo in: path required: true schema: type: string /api/platform/v1/last-leg/dispatches/{dispatchNo}/items/{itemId}/remove: post: summary: 移除本车未扫码的真实明细 description: 权限 platform:overseas-warehouse:dispatch:edit。 security: - bearerAuth: [] responses: '200': description: 统一ApiResponse;业务失败通过code返回,不能仅凭HTTP200判断成功。 content: application/json: schema: type: object properties: code: type: string message: type: string requestId: type: string nullable: true traceId: type: string nullable: true timestamp: type: string format: date-time data: allOf: - $ref: '#/components/schemas/DispatchCommandResult' nullable: true requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/DispatchReasonCommand' parameters: - name: dispatchNo in: path required: true schema: type: string - name: itemId in: path required: true schema: type: string pattern: ^[1-9][0-9]*$ /api/platform/v1/last-leg/dispatches/{dispatchNo}/cancel: post: summary: 按版本和原命令键取消排车 description: 权限 platform:overseas-warehouse:dispatch:cancel。 security: - bearerAuth: [] responses: '200': description: 统一ApiResponse;业务失败通过code返回,不能仅凭HTTP200判断成功。 content: application/json: schema: type: object properties: code: type: string message: type: string requestId: type: string nullable: true traceId: type: string nullable: true timestamp: type: string format: date-time data: allOf: - $ref: '#/components/schemas/DispatchCommandResult' nullable: true requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/DispatchReasonCommand' parameters: - name: dispatchNo in: path required: true schema: type: string /api/platform/v1/last-leg/dispatches/{dispatchNo}/submit-review: post: summary: 提交两级审核 description: 权限 platform:overseas-warehouse:dispatch:edit。 security: - bearerAuth: [] responses: '200': description: 统一ApiResponse;业务失败通过code返回,不能仅凭HTTP200判断成功。 content: application/json: schema: type: object properties: code: type: string message: type: string requestId: type: string nullable: true traceId: type: string nullable: true timestamp: type: string format: date-time data: allOf: - $ref: '#/components/schemas/DispatchCommandResult' nullable: true requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/DispatchSubmitReview' parameters: - name: dispatchNo in: path required: true schema: type: string /api/platform/v1/last-leg/dispatches/{dispatchNo}/dispatch-review: post: summary: 调度审核 description: 权限 platform:fleet:trip:dispatch-review。 security: - bearerAuth: [] responses: '200': description: 统一ApiResponse;业务失败通过code返回,不能仅凭HTTP200判断成功。 content: application/json: schema: type: object properties: code: type: string message: type: string requestId: type: string nullable: true traceId: type: string nullable: true timestamp: type: string format: date-time data: allOf: - $ref: '#/components/schemas/DispatchCommandResult' nullable: true requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/DispatchReviewCommand' parameters: - name: dispatchNo in: path required: true schema: type: string /api/platform/v1/last-leg/dispatches/{dispatchNo}/loading-review: post: summary: 理货员审核 description: 权限 platform:fleet:trip:loading-review。 security: - bearerAuth: [] responses: '200': description: 统一ApiResponse;业务失败通过code返回,不能仅凭HTTP200判断成功。 content: application/json: schema: type: object properties: code: type: string message: type: string requestId: type: string nullable: true traceId: type: string nullable: true timestamp: type: string format: date-time data: allOf: - $ref: '#/components/schemas/DispatchCommandResult' nullable: true requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/DispatchReviewCommand' parameters: - name: dispatchNo in: path required: true schema: type: string /api/platform/v1/last-leg/dispatches/{dispatchNo}/return-to-review: post: summary: 零真实扫码退回装车前重审 description: 权限 platform:overseas-warehouse:dispatch:edit。 security: - bearerAuth: [] responses: '200': description: 统一ApiResponse;业务失败通过code返回,不能仅凭HTTP200判断成功。 content: application/json: schema: type: object properties: code: type: string message: type: string requestId: type: string nullable: true traceId: type: string nullable: true timestamp: type: string format: date-time data: allOf: - $ref: '#/components/schemas/DispatchCommandResult' nullable: true requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/DispatchReturnToReview' parameters: - name: dispatchNo in: path required: true schema: type: string /api/platform/v1/last-leg/dispatches/{dispatchNo}/exceptions: post: summary: 登记派送异常 description: 权限 platform:overseas-warehouse:dispatch:edit;仅有效仓库派送单DELIVERING可登记,保存后阶段不变,不产生退货、签收或库存变化。原键重试恢复原结果。 security: - bearerAuth: [] responses: '200': description: 统一ApiResponse;业务失败通过code返回,不能仅凭HTTP200判断成功。 content: application/json: schema: type: object properties: code: type: string message: type: string requestId: type: string nullable: true traceId: type: string nullable: true timestamp: type: string format: date-time data: allOf: - $ref: '#/components/schemas/DispatchCommandResult' nullable: true requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/DispatchMarkException' parameters: - name: dispatchNo in: path required: true schema: type: string /api/platform/v1/last-leg/dispatches/{dispatchNo}/loading-complete: post: summary: 确认装车完成,资料齐全时自动进入派送中 description: 权限 platform:overseas-warehouse:dispatch:loading-complete。 装车中可通过loading-documents同步保存五张装车照片。原请求保存实载确认;成功action为LOADING_COMPLETE,资料已齐时stage为DELIVERING,未齐时为AFTER_LOADING,result保留真实Loaded装车证据。装车确认与资料齐全两项均完成时自动生成派送并发车;触发该次推进的装车确认或最后一次绑定与派送同事务回滚,先前已保存照片保留。重试装车原键保持原最终阶段结果,当前阶段另行读取。 security: - bearerAuth: [] responses: '200': description: 统一ApiResponse;业务失败通过code返回,不能仅凭HTTP200判断成功。 content: application/json: schema: type: object properties: code: type: string message: type: string requestId: type: string nullable: true traceId: type: string nullable: true timestamp: type: string format: date-time data: allOf: - $ref: '#/components/schemas/DispatchCommandResult' nullable: true requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/DispatchLoadingComplete' parameters: - name: dispatchNo in: path required: true schema: type: string /api/platform/v1/last-leg/dispatches/{dispatchNo}/appointment-allocations: parameters: - name: dispatchNo in: path required: true schema: type: string get: summary: 读取本车逐票正式预约选项及当前分配 description: 权限 platform:overseas-warehouse:dispatch:list。只读本车真实货物;已确认时段和覆盖来自正式收货预约。本车原占用不扣减本车可重分配量,其他有效车辆占用仍扣减。 security: - bearerAuth: [] responses: '200': description: 统一ApiResponse;业务失败通过code返回。 content: application/json: schema: type: object properties: code: {type: string} message: {type: string} data: $ref: '#/components/schemas/DispatchAppointmentAllocations' put: summary: 在原排车关联或调整正式预约分配 description: 权限 platform:overseas-warehouse:dispatch:edit。主单及原批次版本必填,0合法;每个触及实物必须按客户/来源/目的仓完整分配。仅装车前零真实扫码且无有效下游单据,成功增加主版本并使两级审核失效,不新建排车、不改变货物或库存。失败原子回滚;同键同载荷恢复原结果,同键异载荷拒绝。 security: - bearerAuth: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/DispatchAppointmentAllocationCommand' responses: '200': description: 统一ApiResponse;业务失败通过code返回。 content: application/json: schema: type: object properties: code: {type: string} message: {type: string} data: $ref: '#/components/schemas/DispatchCommandResult' /api/platform/v1/last-leg/dispatches/{dispatchNo}/route: get: summary: 读取实际起点与既有卸货站序 description: 权限 platform:overseas-warehouse:dispatch:list。 security: - bearerAuth: [] responses: '200': description: 统一ApiResponse;业务失败通过code返回,不能仅凭HTTP200判断成功。 content: application/json: schema: type: object properties: code: type: string message: type: string requestId: type: string nullable: true traceId: type: string nullable: true timestamp: type: string format: date-time data: allOf: - $ref: '#/components/schemas/DispatchRoute' nullable: true put: summary: 调整既有全部目的地卸货顺序 description: 权限 platform:overseas-warehouse:dispatch:edit。 security: - bearerAuth: [] responses: '200': description: 统一ApiResponse;业务失败通过code返回,不能仅凭HTTP200判断成功。 content: application/json: schema: type: object properties: code: type: string message: type: string requestId: type: string nullable: true traceId: type: string nullable: true timestamp: type: string format: date-time data: allOf: - $ref: '#/components/schemas/DispatchCommandResult' nullable: true requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/DispatchRouteCommand' parameters: - name: dispatchNo in: path required: true schema: type: string /api/platform/v1/last-leg/dispatches/{dispatchNo}/loading: get: summary: 读取真实拣货及实际测量依据 description: 权限 platform:overseas-warehouse:dispatch:list。 security: - bearerAuth: [] responses: '200': description: 统一ApiResponse;业务失败通过code返回,不能仅凭HTTP200判断成功。 content: application/json: schema: type: object properties: code: type: string message: type: string requestId: type: string nullable: true traceId: type: string nullable: true timestamp: type: string format: date-time data: allOf: - $ref: '#/components/schemas/DispatchLoadingPreview' nullable: true parameters: - name: dispatchNo in: path required: true schema: type: string /api/platform/v1/last-leg/dispatches/{dispatchNo}/commands/{idempotencyKey}: get: summary: 恢复本人原动作不可变结果 description: 权限 原动作当前独立权限。必须为原操作者;服务端按持久动作重新核对权限,列表权限不授予他人命令读取。 security: - bearerAuth: [] responses: '200': description: 统一ApiResponse;业务失败通过code返回,不能仅凭HTTP200判断成功。 content: application/json: schema: type: object properties: code: type: string message: type: string requestId: type: string nullable: true traceId: type: string nullable: true timestamp: type: string format: date-time data: allOf: - $ref: '#/components/schemas/DispatchCommandResult' nullable: true parameters: - name: dispatchNo in: path required: true schema: type: string - name: idempotencyKey in: path required: true schema: type: string /api/platform/v1/last-leg/dispatches/{dispatchNo}/evidence/{kind}: post: summary: 上传本趟车辆或司机证据 description: 客服阶段使用 platform:overseas-warehouse:dispatch:edit;调度待审/理货待审分别使用 platform:fleet:trip:dispatch-review / platform:fleet:trip:loading-review,无需维护车辆权限。VEHICLE和DRIVER支持PDF/JPG/PNG,DRIVER_PHOTO和EXCEPTION仅JPG/PNG;EXCEPTION仅派送中使用排车edit权限,引用随异常登记保存。非空且不超过10MiB;平台、本车、类型复合归属。审核补充附件随ReviewCommand保存,不修改资源,不重启审核。 security: - bearerAuth: [] responses: '200': description: 统一ApiResponse;业务失败通过code返回,不能仅凭HTTP200判断成功。 content: application/json: schema: type: object properties: code: type: string message: type: string requestId: type: string nullable: true traceId: type: string nullable: true timestamp: type: string format: date-time data: allOf: - $ref: '#/components/schemas/DispatchEvidenceFile' nullable: true requestBody: required: true content: multipart/form-data: schema: type: object required: - file properties: file: type: string format: binary parameters: - name: dispatchNo in: path required: true schema: type: string - name: kind in: path required: true schema: type: string enum: - VEHICLE - DRIVER - DRIVER_PHOTO - EXCEPTION /api/platform/v1/last-leg/dispatches/{dispatchNo}/evidence/{kind}/{fileId}: get: summary: 读取本车证据元数据 description: 权限 platform:overseas-warehouse:dispatch:list。 security: - bearerAuth: [] responses: '200': description: 统一ApiResponse;业务失败通过code返回,不能仅凭HTTP200判断成功。 content: application/json: schema: type: object properties: code: type: string message: type: string requestId: type: string nullable: true traceId: type: string nullable: true timestamp: type: string format: date-time data: allOf: - $ref: '#/components/schemas/DispatchEvidenceFile' nullable: true parameters: - name: dispatchNo in: path required: true schema: type: string - name: kind in: path required: true schema: type: string enum: - VEHICLE - DRIVER - DRIVER_PHOTO - EXCEPTION - name: fileId in: path required: true schema: type: string pattern: ^[1-9][0-9]*$ /api/platform/v1/last-leg/dispatches/{dispatchNo}/evidence/{kind}/{fileId}/content: get: summary: 鉴权读取本车证据内容 description: 权限 platform:overseas-warehouse:dispatch:list;每次核对本车类型归属,inline且no-store;错误JSON不能当文件。 security: - bearerAuth: [] responses: '200': description: PDF或图片内容;业务失败仍可能为统一JSON错误。 content: application/pdf: schema: type: string format: binary image/jpeg: schema: type: string format: binary image/png: schema: type: string format: binary parameters: - name: dispatchNo in: path required: true schema: type: string - name: kind in: path required: true schema: type: string enum: - VEHICLE - DRIVER - DRIVER_PHOTO - EXCEPTION - name: fileId in: path required: true schema: type: string pattern: ^[1-9][0-9]*$ /api/platform/v1/last-leg/outbound-orders: get: summary: 分页查询出库单 description: 权限 platform:overseas-warehouse:outbound:list;customerId 仅为可选平台筛选条件。 security: [{ bearerAuth: [] }] parameters: - { name: customerId, in: query, required: false, schema: { type: string, pattern: '^[1-9][0-9]*$' } } - { name: page, in: query, schema: { type: integer, minimum: 1, default: 1 } } - { name: size, in: query, schema: { type: integer, minimum: 1, maximum: 200, default: 20 } } - { name: documentNo, in: query, schema: { type: string } } - { name: warehouseId, in: query, schema: { type: string } } - { name: status, in: query, schema: { type: string } } responses: { '200': { description: 出库单分页 } } /api/platform/v1/last-leg/outbound-orders/return: post: summary: 按包裹或箱标签创建整实物退货出库单 description: 权限 platform:overseas-warehouse:outbound:create;以包裹或箱为最小单位,cartonMarks为实际标签码,PARCEL可包含多个SKU,整包裹/箱或整托出库。新签收和新合箱须先扫码确认贴标。部分包裹及部分箱均须通过合箱生成独立新标签箱后才能出库。提交skuCode、quantity或非空items直接拒绝,不修改库存。来源合箱占用或尚未清点时拒绝,PDA按实物标签扣全部内容,同键重放不重复扣减。 security: [{ bearerAuth: [] }] parameters: [{ name: customerId, in: query, required: true, schema: { type: string } }] requestBody: required: true content: application/json: schema: type: object required: [recipient, overseasWarehouseId, returnNo, cartonMarks, idempotencyKey] properties: recipient: { type: string, maxLength: 1000 } overseasWarehouseId: { type: string, maxLength: 128 } returnNo: { type: string, maxLength: 128 } cartonMarks: { type: array, minItems: 1, maxItems: 200, uniqueItems: true, items: { type: string, maxLength: 128 } } unitType: { type: string, enum: [BOX, PALLET], nullable: true } remark: { type: string, maxLength: 1000, nullable: true } idempotencyKey: { type: string, maxLength: 255 } responses: { '200': { description: 退货出库PDA任务 }, '400': { description: 数量或请求格式错误 }, '409': { description: 来源占用、库存或幂等冲突 } } /api/platform/v1/last-leg/outbound-orders/one-click-dropship: post: summary: 创建一件代发出库单 description: 权限 platform:overseas-warehouse:outbound:create;因尚无既有业务单号可解析归属,平台必须显式传 customerId。 security: [{ bearerAuth: [] }] parameters: [{ name: customerId, in: query, required: true, schema: { type: string, pattern: '^[1-9][0-9]*$' } }] requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/OneClickOutboundCreate' } } } } responses: { '200': { description: 一件代发出库 PDA 任务 }, '409': { description: 库存或幂等冲突 } } /api/platform/v1/last-leg/outbound-orders/one-click-dropship/candidates: get: summary: 查询一件代发出库候选库存 description: 权限 platform:overseas-warehouse:outbound:create;仅平台身份可查询,customerId 为可选客户筛选条件,未传时跨客户查询,可按海外仓筛选。仅返回 ACTIVE 一件代发档案、OCCUPIED 正可用库存、AVAILABLE 箱唛与 SKU 余额共同覆盖且未被排车、转仓或待执行出库占用的维度。创建命令仍必须指定唯一客户并再次校验客户与仓库,不信任前端候选快照。 security: [{ bearerAuth: [] }] parameters: - { name: customerId, in: query, required: false, schema: { type: string, pattern: '^[1-9][0-9]*$' } } - { name: warehouseId, in: query, required: false, schema: { type: string } } responses: '200': description: 最多 500 条一件代发出库候选;单次 SQL 返回,不逐行补查 content: { application/json: { schema: { type: array, items: { $ref: '#/components/schemas/OneClickOutboundCandidate' } } } } /api/platform/v1/last-leg/outbound-orders/{outboundNo}: get: summary: 查询出库单详情 description: 权限 platform:overseas-warehouse:outbound:list;只按全局唯一 outboundNo 定位并从记录解析客户范围,不接收 customerId。 security: [{ bearerAuth: [] }] parameters: [{ name: outboundNo, in: path, required: true, schema: { type: string } }] responses: { '200': { description: '出库单、出库托盘及关联 deliveries 派送单数组;一件代发等独立出库时数组为空,排车转派送按目的FBA仓返回一项或多项;pallets[].palletNo 为 Warehouse 权威实物托盘码' }, '404': { description: 出库单不存在 } } /api/platform/v1/last-leg/outbound-orders/{outboundNo}/cancel: post: summary: 取消未执行出库单 description: 权限 platform:overseas-warehouse:outbound:cancel;操作人取认证身份,只按全局唯一outboundNo解析客户,不接收customerId。关联排车按dispatch→outbound顺序锁定,已拣货/发车拒绝,仍绑定车次时须先解除;取消出库不自动取消原排车占用,后续在排车列表取消。当前已审核有效的DELIVERY_FEE应收按原来源版本申请作废,装车/买约/应付等其他费用保留核对,物流取消不代表账务作废成功。取消原因完整保存在派送操作记录,重复取消幂等成功。 security: [{ bearerAuth: [] }] parameters: [{ name: outboundNo, in: path, required: true, schema: { type: string } }] requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/OutboundCancel' } } } } responses: { '200': { description: 取消成功或已取消 }, '404': { description: 出库单不存在 }, '409': { description: 出库已开始执行 } } /api/platform/v1/last-leg/delivery-orders: get: summary: 分页查询平台派送单 description: 权限 platform:overseas-warehouse:delivery:list;customerId 仅为可选平台筛选条件。同一排车按目的FBA仓显示为不同派送单,每行返回目的仓快照和服务端计算的 allowedActions,页面不得自行推导状态门禁;完成动作不再由人工触发。 security: [{ bearerAuth: [] }] responses: { '200': { description: 派送单分页, content: { application/json: { schema: { $ref: '#/components/schemas/DeliveryOrderPageResponse' } } } } } /api/platform/v1/last-leg/delivery-orders/{deliveryNo}: get: summary: 查询平台派送单详情 description: 权限 platform:overseas-warehouse:delivery:list;列表权限包含详情只读;order.allowedActions 为当前可执行动作。 security: [{ bearerAuth: [] }] parameters: [{ name: deliveryNo, in: path, required: true, schema: { type: string } }] responses: { '200': { description: '派送单详情,SKU与BOL打印数据只包含当前派送单目的FBA仓;fees附reviewStatus、sourceStatus、voidStatus(NOT_REQUESTED/PENDING_FINANCE/FINANCE_ATTENTION/CONFIRMED),不得把待财务确认或待处理显示为已作废。feeCoverage为可空的原费用服务覆盖确认快照,只包含当前派送所属货物、引用的原费用版本及服务、确认人和时间;不代表新增收费或原费用已付款。', content: { application/json: { schema: { $ref: '#/components/schemas/DeliveryOrderDetailResponse' } } } }, '404': { description: 派送单不存在 } } /api/platform/v1/last-leg/exception-orders: get: summary: 分页查询异常订单 description: 权限 platform:overseas-warehouse:exception-order:list。 security: [{ bearerAuth: [] }] responses: { '200': { description: 异常订单分页 } } post: summary: 创建异常订单 description: 权限 platform:overseas-warehouse:exception-order:create。 security: [{ bearerAuth: [] }] requestBody: { required: true, content: { application/json: { schema: { type: object } } } } responses: { '200': { description: 已创建异常订单 } } /api/platform/v1/last-leg/exception-orders/{exceptionNo}: get: summary: 查询异常订单详情与冻结退回明细 description: 权限 platform:overseas-warehouse:exception-order:list;返回 version 和服务端 allowedActions。returnReceipts 保留当前异常全部实收批次及按冻结退回凭据关联的重派排车/派送,包括已耗尽库存;每批及每次重派分别返回数量,不能把候选库存或可变尾程当前单号当历史关联。 security: [{ bearerAuth: [] }] parameters: [{ name: exceptionNo, in: path, required: true, schema: { type: string } }] responses: { '200': { description: 异常订单详情, content: { application/json: { schema: { $ref: '#/components/schemas/ExceptionOrderDetailResponse' } } } }, '404': { description: 异常订单不存在 } } /api/platform/v1/last-leg/exception-orders/{exceptionNo}/start-processing: post: summary: 开始处理异常订单 description: 权限 platform:overseas-warehouse:exception-order:process;仅 PENDING→PROCESSING,同版本与同幂等请求可重放。 security: [{ bearerAuth: [] }] parameters: [{ name: exceptionNo, in: path, required: true, schema: { type: string } }] requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/ExceptionStartProcessing' } } } } responses: { '200': { description: 异常处理命令结果 }, '409': { description: 版本、状态或幂等冲突 } } /api/platform/v1/last-leg/exception-orders/{exceptionNo}/evidence: post: summary: 上传异常处理证据 description: 权限 platform:overseas-warehouse:exception-order:process;文件按当前客户和异常订单绑定为 OVERSEAS_EXCEPTION_EVIDENCE。 security: [{ bearerAuth: [] }] parameters: [{ name: exceptionNo, in: path, required: true, schema: { type: string } }] requestBody: required: true content: multipart/form-data: schema: { type: object, required: [file], properties: { file: { type: string, format: binary } } } responses: { '200': { description: 异常处理证据元数据 }, '400': { description: 文件或归属无效 } } /api/platform/v1/last-leg/exception-orders/{exceptionNo}/complete: post: summary: 完成异常处理并原子恢复退回库存 description: 权限 platform:overseas-warehouse:exception-order:process;退回海外仓支持分批实收,每批使用新幂等键及当前版本,累计不得超过批准量。普通库存 RETURN_STOCK_IN 或原箱不可变回仓凭据成功落账后累计实收,未收齐保留 PROCESSING,批准量收齐才转 COMPLETED。详情 returnSources 只返回剩余可收数量。派送仅在累计实际退回覆盖整单实发数量时写 RETURNED 和 RETURN_COMPLETED;非海外仓异常结案不证明货物交接完成。原 signedAt 保留,车次及资源不由工单关闭释放。 security: [{ bearerAuth: [] }] parameters: [{ name: exceptionNo, in: path, required: true, schema: { type: string } }] requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/ExceptionComplete' } } } } responses: { '200': { description: 异常处理与库存恢复结果 }, '409': { description: 版本、状态、归属、数量或幂等冲突 } } /api/platform/v1/last-leg/exception-orders/{exceptionNo}/cancel: post: summary: 取消未处理异常订单 description: 权限 platform:overseas-warehouse:exception-order:process;仅 PENDING→CANCELLED,已有实收禁止取消。退回单按创建时冻结的派送及关联尾程状态原子恢复,保留原签收事实;缺少冻结状态或当前状态已变化时拒绝猜测恢复。 security: [{ bearerAuth: [] }] parameters: [{ name: exceptionNo, in: path, required: true, schema: { type: string } }] requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/ExceptionCancel' } } } } responses: { '200': { description: 异常取消结果 }, '409': { description: 版本、状态或幂等冲突 } } /api/platform/v1/last-leg/exception-orders/resolve: get: summary: 解析异常订单关联关系 description: 权限 platform:overseas-warehouse:exception-order:list;属于列表页只读辅助接口。 security: [{ bearerAuth: [] }] responses: { '200': { description: 关联关系 } } /api/platform/v1/last-leg/delivery-orders/{deliveryNo}/return-inbound-options: get: summary: 查询派送退回候选主单 description: 权限 platform:overseas-warehouse:exception-order:list;每个候选以lastMileOrderId定位、lastMileOrderNo展示;inboundOrderId和inboundCode可空,换标主单不要求普通入仓单。返回按原出库拣货事实解析的 returnSources,页面不得自由填写 SKU 或猜测库存位置。每条来源返回outboundPalletItemId、inventoryPositionId、returnCartonId、cartonMark、palletNo、skuCode和maxReturnPackages;普通仓位与原箱互斥,箱码用于展示,内部标识仅作提交键。 security: [{ bearerAuth: [] }] parameters: [{ name: deliveryNo, in: path, required: true, schema: { type: string } }] responses: { '200': { description: 退回候选主单及真实出库来源 } } /api/platform/v1/last-leg/delivery-orders/{deliveryNo}/mark-return: post: summary: 将派送单标记为退回入仓 description: 权限 platform:overseas-warehouse:delivery:return;items 必须来自 return-inbound-options,服务端扣除历史实际退回量后冻结源出库明细与批准退回上限。同一派送同时只允许一个 PENDING/PROCESSING 退回异常,取消或完成后可为剩余货物新建;RETURN_PENDING 不允许绕过尚未完成的退回异常。 security: [{ bearerAuth: [] }] parameters: [{ name: deliveryNo, in: path, required: true, schema: { type: string } }] requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/DeliveryMarkReturn' } } } } responses: { '200': { description: 已创建退回异常单 } } /api/platform/v1/last-leg/delivery-orders/{deliveryNo}/status: put: summary: 更新派送状态 description: 权限 platform:overseas-warehouse:delivery:status。人工只允许实际出库后的 WAIT_DELIVERY→DELIVERING/REJECTED、DELIVERING→REJECTED;取消仅允许经未执行出库的聚合取消命令;DELIVERED 仅由签收资料保存成功自动触发,同状态幂等,终态不可倒退。 security: [{ bearerAuth: [] }] parameters: [{ name: deliveryNo, in: path, required: true, schema: { type: string } }] requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/DeliveryStatusChange' } } } } responses: { '200': { description: 更新后的派送状态 }, '409': { description: 非法状态迁移 } } /api/platform/v1/last-leg/customer-visits: get: summary: 分页查询客户回访 description: 权限 platform:overseas-warehouse:customer-visit:list。 security: [{ bearerAuth: [] }] responses: { '200': { description: 客户回访分页 } } /api/platform/v1/last-leg/customer-visits/{visitId}: get: summary: 查询客户回访详情 description: 权限 platform:overseas-warehouse:customer-visit:list;列表权限包含详情只读。 security: [{ bearerAuth: [] }] parameters: [{ name: visitId, in: path, required: true, schema: { type: integer, format: int64 } }] responses: { '200': { description: 客户回访详情 } } put: summary: 保存客户回访 description: 权限 platform:overseas-warehouse:customer-visit:edit。 security: [{ bearerAuth: [] }] parameters: [{ name: visitId, in: path, required: true, schema: { type: integer, format: int64 } }] requestBody: { required: true, content: { application/json: { schema: { type: object } } } } responses: { '200': { description: 已保存客户回访 } } /api/platform/v1/last-leg/customer-visits/{visitId}/attachments: post: summary: 上传客户回访附件 description: 权限 platform:overseas-warehouse:customer-visit:edit。 security: [{ bearerAuth: [] }] parameters: [{ name: visitId, in: path, required: true, schema: { type: integer, format: int64 } }] requestBody: { required: true, content: { multipart/form-data: { schema: { type: object } } } } responses: { '200': { description: 已上传附件 } } /api/platform/v1/last-leg/overseas-procurements: get: summary: 分页查询海外采购订单 description: 权限 platform:overseas-business:purchase:list;customerId 为空时查询全部客户。 security: [{ bearerAuth: [] }] parameters: - { name: customerId, in: query, schema: { type: string } } - { name: page, in: query, required: true, schema: { type: integer, minimum: 1 } } - { name: size, in: query, required: true, schema: { type: integer, minimum: 1, maximum: 200 } } - { name: orderNo, in: query, schema: { type: string } } - { name: customerKeyword, in: query, schema: { type: string } } - { name: purchaseCategory, in: query, schema: { type: string } } - { name: productName, in: query, schema: { type: string } } - { name: status, in: query, schema: { $ref: '#/components/schemas/ProcurementStatus' } } - { name: purchaseWarehouseId, in: query, schema: { type: string } } responses: { '200': { description: 统一 ApiResponse 包装的采购订单分页 } } /api/platform/v1/last-leg/overseas-procurements/customer-options: get: summary: 查询已有采购订单的客户候选 description: 权限 platform:overseas-business:purchase:list;候选来自尾程库采购订单客户快照,不跨库查询 IAM。 security: [{ bearerAuth: [] }] parameters: - { name: keyword, in: query, schema: { type: string } } - { name: limit, in: query, schema: { type: integer, minimum: 1, maximum: 200, default: 50 } } responses: '200': description: 客户候选 content: { application/json: { schema: { $ref: '#/components/schemas/CustomerOptionResponse' } } } /api/platform/v1/last-leg/overseas-procurements/warehouse-options: get: summary: 按采购方向查询有效公共起运收货仓候选 description: 权限 platform:overseas-business:purchase:list;海外采购取 OVERSEAS、ACTIVE、RECEIVING 公共仓,国内采购取 DOMESTIC、ACTIVE 公共仓,均以 Warehouse 为准。 parameters: - { name: procurementDirection, in: query, schema: { $ref: '#/components/schemas/ProcurementDirection' } } security: [{ bearerAuth: [] }] responses: '200': description: 采购仓候选 content: { application/json: { schema: { $ref: '#/components/schemas/WarehouseOptionResponse' } } } /api/platform/v1/last-leg/overseas-procurements/{orderNo}: parameters: - { name: orderNo, in: path, required: true, schema: { type: string } } - { name: customerId, in: query, required: true, schema: { type: string, pattern: '^[1-9][0-9]*$' } } get: summary: 查询海外采购订单详情及操作流水 description: 权限 platform:overseas-business:purchase:list。 security: [{ bearerAuth: [] }] responses: { '200': { description: 后台采购聚合详情及服务端操作资格, content: { application/json: { schema: { $ref: 'procurement-fulfillment-v1.yaml#/components/schemas/ProcurementPlatformResponse' } } } } } patch: summary: 编辑海外采购订单 description: 权限 platform:overseas-business:purchase:edit;仅编辑内部备注,字段缺失表示不修改,显式 null 或空串表示清空。商品、仓库、数量和运输字段由各履约节点维护,提交这些旧字段会被拒绝。 security: [{ bearerAuth: [] }] requestBody: required: true content: { application/json: { schema: { $ref: '#/components/schemas/ProcurementUpdate' } } } responses: { '200': { description: 统一 ApiResponse 包装的采购订单详情 }, '409': { description: 乐观锁冲突或状态不允许 } } /api/platform/v1/last-leg/overseas-procurements/{orderNo}/review: post: summary: 审核海外采购订单 description: 权限 platform:overseas-business:purchase:review;同幂等键同请求重放成功,异请求、旧 version 或终态反向审核返回 A0409。 security: [{ bearerAuth: [] }] parameters: - { name: orderNo, in: path, required: true, schema: { type: string } } - { name: customerId, in: query, required: true, schema: { type: string, pattern: '^[1-9][0-9]*$' } } requestBody: required: true content: { application/json: { schema: { $ref: '#/components/schemas/ProcurementReview' } } } responses: { '200': { description: 统一 ApiResponse 包装的采购订单详情 } } /api/platform/v1/last-leg/warehouse-transfers/{transferNo}/allocations: post: summary: 选择已有库存转运的真实来源 description: 权限lastleg:warehouse-transfer:manage;必须指定customerId。仅APPROVED原票选择精确来源位置和托盘,箱数等于原票箱数。needRelabel=true时按本票relabelBindings创建唯一关联换标并冻结所选数量,返回WAIT_RELABEL和relabelNo;客户完成作业复核确认后回到ALLOCATED,分配追随实际换标位置和新SKU。原idempotencyKey及原载荷重放不重复预留或建換标,同键异载荷冲突。 security: [{ bearerAuth: [] }] parameters: - { name: transferNo, in: path, required: true, schema: { type: string } } - { name: customerId, in: query, required: true, schema: { type: string } } requestBody: required: true content: application/json: schema: type: object required: [idempotencyKey, allocations] properties: idempotencyKey: { type: string, maxLength: 255 } allocations: type: array minItems: 1 items: type: object required: [inventoryPositionId, palletId, packageCount] properties: inventoryPositionId: { type: integer, format: int64 } palletId: { type: integer, format: int64 } packageCount: { type: integer, minimum: 1 } responses: '200': { description: 原转运详情;allocations内skuCode为锁定的实际发货SKU,换标后返回新SKU;不包括已被换标替换的历史分配 } '409': { description: 来源不可用或幂等载荷冲突 } /api/platform/v1/last-leg/warehouse-transfers/{transferNo}/receipts: post: summary: 已有库存转运逐来源在目标仓实收 description: 权限lastleg:warehouse-transfer:manage;必须指定customerId。只接收本票SHIPPED来源,服务端读取实际OVERSEAS/ACTIVE/RECEIVING仓、托盘及绑定库位、权威FBA主档并核对冻结目的仓。先持久化完整原请求,再占用资源;同转运同目标托盘的多来源共享一次ACTIVE资源锁。远端成功但本地事务失败时保留原命令,原键原载荷重试继续;新键或变更载荷不能绕过。库存、收货记录和最终换标费用结算命令同本地事务提交,成功重放不重复入账或占用,未知结果须先核对原命令。 security: [{ bearerAuth: [] }] parameters: - { name: transferNo, in: path, required: true, schema: { type: string } } - { name: customerId, in: query, required: true, schema: { type: string } } requestBody: required: true content: application/json: schema: type: object required: [sourceInventoryPositionId, destinationOverseasWarehouseId, destinationWarehouseCode, destinationPalletId, destinationPalletNo, idempotencyKey] properties: sourceInventoryPositionId: { type: integer, format: int64 } destinationOverseasWarehouseId: { type: string, maxLength: 128 } destinationOverseasWarehouseCode: { type: string, nullable: true, maxLength: 128 } destinationOverseasWarehouseName: { type: string, nullable: true, maxLength: 255 } destinationWarehouseId: { type: string, nullable: true, maxLength: 128 } destinationWarehouseCode: { type: string, maxLength: 128 } destinationWarehouseName: { type: string, nullable: true, maxLength: 255 } destinationPalletId: { type: integer, format: int64 } destinationPalletNo: { type: string, maxLength: 128 } batchNo: { type: string, nullable: true, maxLength: 128 } warehouseLocationId: { type: integer, format: int64, nullable: true, description: 未传时使用该实物托盘绑定库位 } warehouseLocationCode: { type: string, nullable: true, maxLength: 128 } idempotencyKey: { type: string, maxLength: 255 } remark: { type: string, nullable: true, maxLength: 1000 } responses: '200': { description: 原转运详情,部分来源PARTIALLY_RECEIVED、全部来源RECEIVED;receiptCommands包含真正COMPLETED的本次命令,原键原载荷返回持久结果, content: { application/json: { schema: { $ref: '#/components/schemas/WarehouseTransferDetailApiResponse' } } } } '409': { description: 原请求冲突、来源状态或目标资源归属不匹配;不得换键绕过 } '503': { description: 资源服务不可用,保留原收货命令待核对恢复 } /api/platform/v1/last-leg/warehouse-transfers/{transferNo}/outbound: post: summary: 已有库存转运实际出库 description: 权限lastleg:warehouse-transfer:manage;必须指定customerId。仅ALLOCATED可执行,需换标本票必须关联本尾程订单的唯一换标申请,实际作业复核及客户确认已完成。按当前分配的新SKU和位置发货并保留唯一SHIP流水,不以MIXED聚合值替代实际SKU。成功原命令重放不重复扣减。 security: [{ bearerAuth: [] }] parameters: - { name: transferNo, in: path, required: true, schema: { type: string } } - { name: customerId, in: query, required: true, schema: { type: string } } requestBody: required: true content: application/json: schema: type: object required: [idempotencyKey] properties: idempotencyKey: { type: string, maxLength: 255 } remark: { type: string, maxLength: 1000 } responses: '200': { description: 本票OUTBOUNDED事实或成功原命令重放 } '409': { description: 尚未完成本票换标客户确认或分配不完整 } /api/merchant/v1/last-leg/delivery-orders: get: summary: 客户分页查询自己的派送单 description: 权限 merchant:warehouse:delivery:list;客户范围只取认证 Token,不接收 customerId。 security: [{ bearerAuth: [] }] parameters: - { name: page, in: query, schema: { type: integer, minimum: 1, default: 1 } } - { name: size, in: query, schema: { type: integer, minimum: 1, maximum: 200, default: 20 } } - { name: documentNo, in: query, schema: { type: string } } - { name: warehouseId, in: query, schema: { type: string } } - { name: status, in: query, schema: { type: string } } - { name: dispatchNo, in: query, schema: { type: string } } - { name: waybillNo, in: query, schema: { type: string } } - { name: vehiclePlate, in: query, schema: { type: string } } - { name: driverName, in: query, schema: { type: string } } - { name: deliveryMethod, in: query, schema: { type: string } } - { name: plannedFrom, in: query, schema: { type: string, format: date-time } } - { name: plannedTo, in: query, schema: { type: string, format: date-time } } responses: { '200': { description: 当前客户派送单分页, content: { application/json: { schema: { $ref: '#/components/schemas/DeliveryOrderPageResponse' } } } }, '403': { description: 缺少客户派送查看权限 } } /api/merchant/v1/last-leg/delivery-orders/{deliveryNo}: get: summary: 客户查询自己的派送单详情 description: 权限 merchant:warehouse:delivery:list;列表权限包含详情只读,客户范围只取认证 Token,不接收 customerId。 security: [{ bearerAuth: [] }] parameters: [{ name: deliveryNo, in: path, required: true, schema: { type: string } }] responses: { '200': { description: 当前客户派送单详情, content: { application/json: { schema: { $ref: '#/components/schemas/DeliveryOrderDetailResponse' } } } }, '403': { description: 缺少客户派送查看权限 }, '404': { description: 当前客户下派送单不存在 } } /api/merchant/v1/last-leg/orders: get: summary: 客户分页查询自己的海外尾程订单 description: 权限 merchant:overseas-warehouse:last-mile-order:list;列表权限包含详情只读,客户范围只取认证 Token。 security: [{ bearerAuth: [] }] parameters: - { name: businessType, in: query, description: 商业类型;本土散板同时覆盖独立和池来源,仓储转运排除已关联散板或卡车商业单, schema: { type: string, maxLength: 64 } } - { name: businessOrderNo, in: query, description: 正式关联商业单号包含匹配,不解析备注, schema: { type: string, maxLength: 128 } } - { name: externalBookingNo, in: query, description: 正式外接预订号包含匹配,不解析备注, schema: { type: string, maxLength: 128 } } - { name: sailingStage, in: query, description: '可选开船阶段。仅匹配头程订单类型 FIRST_LEG;未传不限制类型。按实际柜级节点序号>=40判断开船后;人工节点覆盖后仅按该票 ACTUAL_DEPARTURE 非空判断,不回退柜级。无实际开船事实归开船前。', schema: { type: string, enum: [BEFORE_DEPARTURE, AFTER_DEPARTURE] } } responses: { '200': { description: 当前客户海外尾程订单分页 }, '403': { description: 缺少海外尾程订单查看权限 } } /api/merchant/v1/last-leg/orders/{id}: get: summary: 客户查询自己的海外尾程订单详情 description: 权限 merchant:overseas-warehouse:last-mile-order:list;不泄露其他客户订单。 security: [{ bearerAuth: [] }] parameters: [{ name: id, in: path, required: true, schema: { type: integer, format: int64 } }] responses: { '200': { description: 当前客户海外尾程订单详情 }, '403': { description: 缺少海外尾程订单查看权限 }, '404': { description: 当前客户下订单不存在 } } /api/merchant/v1/last-leg/warehouse-transfers: get: summary: 客户分页查询自己的仓储转运单 description: 权限 merchant:overseas-warehouse:transfer:list;列表权限包含详情只读;每行同时返回关联换标单号 relabelNo、换标申请流程状态 relabelStatus 与履约状态 relabelFulfillmentStatus。 security: [{ bearerAuth: [] }] responses: { '200': { description: 当前客户仓储转运单分页 }, '403': { description: 缺少仓储转运查看权限 } } post: summary: 客户创建仓储转运单 description: 选择已有库存入仓码时,deliveryMethod、deliveryAddress和estimatedArrivalAt不需要提交;服务端保存库存转运标记并清空预计入仓时间,目的去向仅FBA或PRIVATE。外来货物仍须填写入仓方式、地址和预计入仓时间。 权限 merchant:overseas-warehouse:transfer:create;客户范围只取认证 Token。货物 items[].quantity 为 SKU 申报件数(正整数),items[].packageCount 为预计箱数,整单 packageCount 等于明细预计箱数合计;件数与箱数独立,实际签收箱数和每箱件数以 PDA 清点事实为准,支持短收、超收并记录差异原因。目的去向可暂未确定(destinationType 为 NONE 或不传),允许保存草稿、编辑和提交;入库确认后可在出库时绑定 FBA 仓或私人仓,也可选择入库库存发起贴标申请出库;普通转运出库前必须补齐目的仓。 security: [{ bearerAuth: [] }] responses: { '200': { description: 创建后的仓储转运单 }, '403': { description: 缺少仓储转运创建权限 }, '409': { description: 幂等、库存或状态冲突 } } /api/merchant/v1/last-leg/warehouse-transfers/inventory-source-cartons: get: summary: 客户查询库存来源单据的原始箱明细 description: 权限 merchant:overseas-warehouse:transfer:create;客户取认证会话。按仓库及入仓码查询真实原单箱快照,返回箱号、SKU子明细、已记录的件数和原目的仓;不存在逐箱快照时返回空数组,不按箱数伪造箱号,不宣称原单箱当前均可用。 security: [{ bearerAuth: [] }] parameters: - { name: operatingWarehouseId, in: query, required: true, schema: { type: string } } - { name: inboundCode, in: query, required: true, schema: { type: string } } responses: { '200': { description: 原单箱明细数组,cartonMark/productNameZh/quantity/destinationWarehouseCode/destinationWarehouseName/items;quantity未记录为null }, '403': { description: 缺少创建权限 } } /api/merchant/v1/last-leg/warehouse-transfers/{transferNo}: get: summary: 客户查询自己的仓储转运单详情 description: 权限 merchant:overseas-warehouse:transfer:list;不泄露其他客户订单。 security: [{ bearerAuth: [] }] parameters: [{ name: transferNo, in: path, required: true, schema: { type: string } }] responses: { '200': { description: 当前客户仓储转运单详情,receiptCommands仅本客户本票;未知状态或损坏快照拒绝返回,不当作新请求, content: { application/json: { schema: { $ref: '#/components/schemas/WarehouseTransferDetailApiResponse' } } } }, '403': { description: 缺少仓储转运查看权限 }, '404': { description: 当前客户下转运单不存在 }, '409': { description: 持久实收命令状态、原请求或目标损坏,须核查原命令 } } /api/merchant/v1/last-leg/warehouse-transfers/{transferNo}/confirm-measurement: post: summary: 客户确认仓储转运实测数据 description: 权限 merchant:overseas-warehouse:transfer:confirm;仅当前客户满足状态门禁的转运单可确认。 security: [{ bearerAuth: [] }] parameters: [{ name: transferNo, in: path, required: true, schema: { type: string } }] responses: { '200': { description: 确认后的仓储转运单 }, '403': { description: 缺少实测确认权限 }, '409': { description: 状态或版本冲突 } } /api/merchant/v1/last-leg/cargo-discards: get: summary: 客户分页查询自己的货物废弃申请 description: 权限 merchant:overseas-warehouse:discard:list;列表权限包含详情和库存候选只读。 security: [{ bearerAuth: [] }] responses: { '200': { description: 当前客户货物废弃申请分页 }, '403': { description: 缺少货物废弃查看权限 } } post: summary: 客户创建货物废弃申请 description: 权限 merchant:overseas-warehouse:discard:create;客户范围只取认证 Token。 security: [{ bearerAuth: [] }] responses: { '200': { description: 创建后的货物废弃申请 }, '403': { description: 缺少货物废弃创建权限 }, '409': { description: 库存或状态冲突 } } /api/merchant/v1/last-leg/cargo-discards/inventory-candidates: get: summary: 查询当前客户可废弃库存候选 description: 权限 merchant:overseas-warehouse:discard:list;候选按认证客户隔离。 security: [{ bearerAuth: [] }] responses: { '200': { description: 可废弃库存候选 }, '403': { description: 缺少货物废弃查看权限 } } /api/merchant/v1/last-leg/cargo-discards/{discardNo}: get: summary: 客户查询自己的货物废弃申请详情 description: 权限 merchant:overseas-warehouse:discard:list;不泄露其他客户申请。 security: [{ bearerAuth: [] }] parameters: [{ name: discardNo, in: path, required: true, schema: { type: string } }] responses: { '200': { description: 当前客户货物废弃申请详情 }, '403': { description: 缺少货物废弃查看权限 }, '404': { description: 当前客户下申请不存在 } } /api/merchant/v1/last-leg/cargo-discards/{discardNo}/cancel: post: summary: 客户取消自己的货物废弃申请 description: 权限 merchant:overseas-warehouse:discard:cancel;仅满足状态门禁的申请可取消。 security: [{ bearerAuth: [] }] parameters: [{ name: discardNo, in: path, required: true, schema: { type: string } }] responses: { '200': { description: 取消后的货物废弃申请 }, '403': { description: 缺少货物废弃取消权限 }, '409': { description: 状态冲突 } } /api/merchant/v1/last-leg/overseas-procurements: post: summary: 客户创建海外采购订单 description: 权限 merchant:cross-border:procurement:create;客户 ID 只取认证身份且不接收 customerId;新单固定进入 PENDING_REVIEW。同幂等键同请求返回既有订单,异请求返回 A0409。 security: [{ bearerAuth: [] }] requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/ProcurementCreate' } } } } responses: { '200': { description: 采购订单详情, content: { application/json: { schema: { $ref: 'procurement-fulfillment-v1.yaml#/components/schemas/ProcurementCustomerResponse' } } } }, '409': { description: 幂等冲突 } } get: summary: 客户分页查询自己的海外采购订单 description: 权限 merchant:cross-border:procurement:list;客户范围只取认证 Token,不接收 customerId。 security: [{ bearerAuth: [] }] parameters: - { name: page, in: query, schema: { type: integer, minimum: 1, default: 1 } } - { name: size, in: query, schema: { type: integer, minimum: 1, maximum: 200, default: 20 } } - { name: orderNo, in: query, schema: { type: string } } - { name: purchaseCategory, in: query, schema: { type: string } } - { name: productName, in: query, schema: { type: string } } - { name: status, in: query, schema: { type: string } } - { name: purchaseWarehouseId, in: query, schema: { type: string } } - { name: createdFrom, in: query, schema: { type: string, format: date-time } } - { name: createdTo, in: query, schema: { type: string, format: date-time } } responses: { '200': { description: 当前客户采购订单分页, content: { application/json: { schema: { $ref: '#/components/schemas/ProcurementPageResponse' } } } } } /api/merchant/v1/last-leg/overseas-procurements/{orderNo}: get: summary: 客户查询自己的采购履约、箱明细、运单及费用 description: 权限 merchant:cross-border:procurement:list;列表权限包含详情只读,客户范围只取认证 Token。 security: [{ bearerAuth: [] }] parameters: [{ name: orderNo, in: path, required: true, schema: { type: string } }] responses: { '200': { description: 当前客户采购订单详情, content: { application/json: { schema: { $ref: 'procurement-fulfillment-v1.yaml#/components/schemas/ProcurementCustomerResponse' } } } }, '404': { description: 当前客户下订单不存在 } } /api/merchant/v1/last-leg/us-truck-orders: get: summary: 客户分页查询自己的美国本土卡订单 description: 权限 merchant:cross-border:domestic-trucking:list;客户范围只取认证 Token,不接收 customerId。 security: [{ bearerAuth: [] }] parameters: - { name: page, in: query, schema: { type: integer, minimum: 1, default: 1 } } - { name: size, in: query, schema: { type: integer, minimum: 1, maximum: 200, default: 20 } } - { name: orderNo, in: query, schema: { type: string } } - { name: routeKeyword, in: query, schema: { type: string } } - { name: status, in: query, schema: { $ref: '#/components/schemas/TruckStatus' } } - { name: vehicleType, in: query, schema: { type: string } } - { name: pickupFrom, in: query, schema: { type: string, format: date-time } } - { name: pickupTo, in: query, schema: { type: string, format: date-time } } responses: { '200': { description: 当前客户本土卡订单分页, content: { application/json: { schema: { $ref: '#/components/schemas/TruckPageResponse' } } } } } post: summary: 客户创建美国本土卡订单 description: 权限 merchant:cross-border:domestic-trucking:create;新单固定进入 PENDING_REVIEW,客户不能调用平台审核或状态推进端点。 security: [{ bearerAuth: [] }] requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/TruckCreate' } } } } responses: { '200': { description: 本土卡订单详情, content: { application/json: { schema: { $ref: '#/components/schemas/TruckDetailResponse' } } } }, '409': { description: 幂等冲突 } } /api/merchant/v1/last-leg/us-truck-orders/{orderNo}: parameters: [{ name: orderNo, in: path, required: true, schema: { type: string } }] get: summary: 客户查询自己的美国本土卡订单详情 description: 权限 merchant:cross-border:domestic-trucking:list;不泄露其他客户订单。 security: [{ bearerAuth: [] }] responses: { '200': { description: 当前客户本土卡订单详情, content: { application/json: { schema: { $ref: '#/components/schemas/TruckDetailResponse' } } } }, '404': { description: 当前客户下订单不存在 } } patch: summary: 客户编辑待审核的美国本土卡订单 description: 权限 merchant:cross-border:domestic-trucking:edit;仅 PENDING_REVIEW 可编辑,version 必填;不能修改状态。 security: [{ bearerAuth: [] }] requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/TruckUpdate' } } } } responses: { '200': { description: 更新后的订单详情, content: { application/json: { schema: { $ref: '#/components/schemas/TruckDetailResponse' } } } }, '409': { description: 版本或状态冲突 } } /api/merchant/v1/last-leg/local-looseboard-orders: get: summary: 客户分页查询自己的本土散板订单 description: 权限 merchant:cross-border:pallet-shipping:list;客户范围只取认证 Token,不接收 customerId。 security: [{ bearerAuth: [] }] parameters: - { name: page, in: query, schema: { type: integer, minimum: 1, default: 1 } } - { name: size, in: query, schema: { type: integer, minimum: 1, maximum: 200, default: 20 } } - { name: orderNo, in: query, schema: { type: string } } - { name: routeKeyword, in: query, schema: { type: string } } - { name: status, in: query, schema: { $ref: '#/components/schemas/LooseboardStatus' } } - { name: requestedFrom, in: query, schema: { type: string, format: date } } - { name: requestedTo, in: query, schema: { type: string, format: date } } responses: { '200': { description: 当前客户本土散板订单分页, content: { application/json: { schema: { $ref: '#/components/schemas/LooseboardPageResponse' } } } } } post: summary: 客户创建本土散板订单 description: 权限 merchant:cross-border:pallet-shipping:create;新单固定进入 PENDING_ACCEPTANCE,客户不能调用平台状态推进端点。 security: [{ bearerAuth: [] }] requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/LooseboardCreate' } } } } responses: { '200': { description: 本土散板订单详情, content: { application/json: { schema: { $ref: '#/components/schemas/LooseboardDetailResponse' } } } }, '409': { description: 幂等冲突 } } /api/merchant/v1/last-leg/local-looseboard-orders/{orderNo}: parameters: [{ name: orderNo, in: path, required: true, schema: { type: string } }] get: summary: 客户查询自己的本土散板订单详情 description: 权限 merchant:cross-border:pallet-shipping:list;不泄露其他客户订单。 security: [{ bearerAuth: [] }] responses: { '200': { description: 当前客户本土散板订单详情, content: { application/json: { schema: { $ref: '#/components/schemas/LooseboardDetailResponse' } } } }, '404': { description: 当前客户下订单不存在 } } put: summary: 客户编辑待接单的本土散板订单 description: 权限 merchant:cross-border:pallet-shipping:edit;仅 PENDING_ACCEPTANCE 可编辑,version 必填;不能修改状态。 security: [{ bearerAuth: [] }] requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/LooseboardUpdate' } } } } responses: { '200': { description: 更新后的订单详情, content: { application/json: { schema: { $ref: '#/components/schemas/LooseboardDetailResponse' } } } }, '409': { description: 版本或状态冲突 } } /api/merchant/v1/last-leg/inbound-plans: get: summary: 客户分页查询自己的海外入库订单 description: 权限 merchant:warehouse:inbound:list;客户范围只取认证 Token,不接收 customerId;overseasWarehouseCode/overseasWarehouseName 只取该客户尾程订单预分配接柜仓事实,warehouseCode/warehouseName 仍表示目的仓。 security: [{ bearerAuth: [] }] parameters: - { name: page, in: query, schema: { type: integer, minimum: 1, default: 1 } } - { name: size, in: query, schema: { type: integer, minimum: 1, maximum: 200, default: 20 } } - { name: planNo, in: query, schema: { type: string } } - { name: inboundCode, in: query, schema: { type: string } } - { name: status, in: query, schema: { type: string } } - { name: overseasWarehouseId, in: query, schema: { type: string } } - { name: destinationWarehouseCode, in: query, schema: { type: string } } - { name: appointmentStatus, in: query, schema: { type: string, enum: [UNAPPOINTED, PENDING, SUCCESS, FAILED, CANCELLED, MULTIPLE] } } - { name: dispatchStatus, in: query, schema: { type: string, enum: [UNSCHEDULED, SCHEDULED] } } - { name: createdFrom, in: query, schema: { type: string, format: date-time } } - { name: createdTo, in: query, schema: { type: string, format: date-time } } responses: { '200': { description: 当前客户入库订单分页, content: { application/json: { schema: { $ref: '#/components/schemas/InboundPlanPageResponse' } } } } } /api/merchant/v1/last-leg/inbound-plans/{planNo}: get: summary: 客户查询自己的海外入库订单详情 description: 权限 merchant:warehouse:inbound:list;列表权限包含详情只读,不接收 customerId;overseasWarehouseCode/overseasWarehouseName 只取该计划来源尾程订单的预分配接柜仓事实。 security: [{ bearerAuth: [] }] parameters: [{ name: planNo, in: path, required: true, schema: { type: string } }] responses: { '200': { description: 当前客户入库订单详情, content: { application/json: { schema: { $ref: '#/components/schemas/InboundPlanDetailResponse' } } } }, '404': { description: 当前客户下入库订单不存在 } } /api/platform/v1/last-leg/us-truck-orders: get: summary: 分页查询本土卡车订单 description: 权限 platform:overseas-business:truck:list。 security: [{ bearerAuth: [] }] responses: { '200': { description: 统一 ApiResponse 包装的卡车订单分页 } } post: summary: 平台为指定客户创建本土卡车订单 description: 权限 platform:overseas-business:truck:create;customerId 必填且只作为可信服务端隔离键。 security: [{ bearerAuth: [] }] parameters: [{ name: customerId, in: query, required: true, schema: { type: string, pattern: '^[1-9][0-9]*$' } }] requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/TruckCreate' } } } } responses: { '200': { description: 统一 ApiResponse 包装的卡车订单详情 } } /api/platform/v1/last-leg/us-truck-orders/{orderNo}: parameters: - { name: orderNo, in: path, required: true, schema: { type: string } } - { name: customerId, in: query, required: true, schema: { type: string, pattern: '^[1-9][0-9]*$' } } get: summary: 查询本土卡车订单详情 description: 权限 platform:overseas-business:truck:list。 security: [{ bearerAuth: [] }] responses: { '200': { description: 统一 ApiResponse 包装的卡车订单详情 } } patch: summary: 平台普通编辑本土卡车订单 description: 权限 platform:overseas-business:truck:edit;仅待审核订单可编辑,不能修改状态。 security: [{ bearerAuth: [] }] requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/TruckUpdate' } } } } responses: { '200': { description: 统一 ApiResponse 包装的卡车订单详情 } } /api/platform/v1/last-leg/us-truck-orders/{orderNo}/status: patch: summary: 取消未发车的本土卡车订单 description: 权限 platform:overseas-business:truck:status;该通用入口只接受 CANCELLED,正向状态必须使用具名命令,不能绕过实收、超托与分配事实。 security: [{ bearerAuth: [] }] parameters: - { name: orderNo, in: path, required: true, schema: { type: string } } - { name: customerId, in: query, required: true, schema: { type: string, pattern: '^[1-9][0-9]*$' } } requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/TruckCancel' } } } } responses: { '200': { description: 统一 ApiResponse 包装的卡车订单详情 }, '409': { description: 非法状态迁移 } } /api/platform/v1/last-leg/us-truck-orders/{orderNo}/review: parameters: &truckOrderTarget - { name: orderNo, in: path, required: true, schema: { type: string } } - { name: customerId, in: query, required: true, schema: { type: string, pattern: '^[1-9][0-9]*$' } } post: summary: 审核本土卡车订单 description: 权限 platform:overseas-business:truck:status;PENDING_REVIEW 审核通过进入 WAITING_INBOUND 并生成预期托盘;拒绝进入 REJECTED。幂等键异请求、旧 version 或非法跳转返回 A0409。 security: [{ bearerAuth: [] }] requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/TruckReview' } } } } responses: { '200': { description: 卡车订单详情 }, '409': { description: 版本、状态或幂等冲突 } } /api/platform/v1/last-leg/us-truck-orders/{orderNo}/receive-pallets: post: summary: 记录本土卡车订单实收托盘 description: 权限 platform:overseas-business:truck:status;幂等记录实收,不创建海外仓出库或派送单。 security: [{ bearerAuth: [] }] parameters: - { name: orderNo, in: path, required: true, schema: { type: string } } - { name: customerId, in: query, required: true, schema: { type: string, pattern: '^[1-9][0-9]*$' } } requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/TruckReceivePallets' } } } } responses: { '200': { description: 统一 ApiResponse 包装的卡车订单详情 } } /api/platform/v1/last-leg/us-truck-orders/{orderNo}/review-pallet-overage: parameters: *truckOrderTarget post: summary: 审核实收超出申报数的托盘 description: 权限 platform:overseas-business:truck:status;APPROVE 将超收托盘纳入本单并进入 WAITING_CONSOLIDATION;REJECT 标记超收托盘拒收并按原申报数继续。 security: [{ bearerAuth: [] }] requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/TruckReviewPalletOverage' } } } } responses: { '200': { description: 卡车订单详情 }, '409': { description: 版本、状态或幂等冲突 } } /api/platform/v1/last-leg/us-truck-orders/{orderNo}/allocate-pallets: parameters: *truckOrderTarget post: summary: 分配已实收托盘到本土卡车行程 description: 权限 platform:overseas-business:truck:status;仅接收本单 RECEIVED 托盘 ID;部分分配进入 PARTIALLY_ALLOCATED,全部分配进入 ALLOCATED。不创建海外仓出库单或扣减库存。 security: [{ bearerAuth: [] }] requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/TruckAllocatePallets' } } } } responses: { '200': { description: 卡车订单详情 }, '409': { description: 托盘归属、状态、版本或幂等冲突 } } /api/platform/v1/last-leg/us-truck-orders/{orderNo}/prepare-dispatch: parameters: *truckOrderTarget post: summary: 全部托盘分配后准备派车 description: 权限 platform:overseas-business:truck:status;旧 version、幂等键异请求或非 ALLOCATED 状态返回 A0409。 security: [{ bearerAuth: [] }] requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/TruckCommand' } } } } responses: { '200': { description: 状态 PENDING_DISPATCH } } /api/platform/v1/last-leg/us-truck-orders/{orderNo}/dispatch: parameters: *truckOrderTarget post: summary: 确认本土卡车已派车 description: 权限 platform:overseas-business:truck:status;本土卡车单自身履约,不创建海外仓排车单、出库单或派送单。 security: [{ bearerAuth: [] }] requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/TruckCommand' } } } } responses: { '200': { description: 状态 DISPATCHED } } /api/platform/v1/last-leg/us-truck-orders/{orderNo}/start-transit: parameters: *truckOrderTarget post: summary: 确认本土卡车开始运输 description: 权限 platform:overseas-business:truck:status;仅 DISPATCHED 可进入 IN_TRANSIT。 security: [{ bearerAuth: [] }] requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/TruckCommand' } } } } responses: { '200': { description: 状态 IN_TRANSIT } } /api/platform/v1/last-leg/us-truck-orders/{orderNo}/complete: parameters: *truckOrderTarget post: summary: 完成本土卡车订单 description: 权限 platform:overseas-business:truck:status;仅 IN_TRANSIT 可进入不可逆 COMPLETED。 security: [{ bearerAuth: [] }] requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/TruckCommand' } } } } responses: { '200': { description: 状态 COMPLETED } } /api/platform/v1/last-leg/local-looseboard-orders: get: summary: 分页查询本土散板订单 description: 权限 platform:overseas-business:looseboard:list。 security: [{ bearerAuth: [] }] responses: { '200': { description: 统一 ApiResponse 包装的散板订单分页 } } post: summary: 创建本土散板订单 description: 权限 platform:overseas-business:looseboard:create;独立稳定子域,不复用卡车端点。 security: [{ bearerAuth: [] }] parameters: [{ name: customerId, in: query, required: true, schema: { type: string, pattern: '^[1-9][0-9]*$' } }] requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/LooseboardCreate' } } } } responses: { '200': { description: 统一 ApiResponse 包装的散板订单详情 } } /api/platform/v1/last-leg/local-looseboard-orders/{orderNo}: parameters: - { name: orderNo, in: path, required: true, schema: { type: string } } - { name: customerId, in: query, required: true, schema: { type: string, pattern: '^[1-9][0-9]*$' } } get: summary: 查询本土散板订单详情及操作流水 description: 权限 platform:overseas-business:looseboard:list。 security: [{ bearerAuth: [] }] responses: { '200': { description: 统一 ApiResponse 包装的散板订单详情 } } put: summary: 全量更新待接单的本土散板订单 description: 权限 platform:overseas-business:looseboard:edit;可空字段传 null 或空串即清空;状态由独立端点推进。 security: [{ bearerAuth: [] }] requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/LooseboardUpdate' } } } } responses: { '200': { description: 统一 ApiResponse 包装的散板订单详情 }, '409': { description: 版本或状态冲突 } } /api/platform/v1/last-leg/local-looseboard-orders/{orderNo}/status: patch: summary: 推进或取消本土散板订单 description: 权限 platform:overseas-business:looseboard:status;只允许 PENDING_ACCEPTANCE→DISPATCHED→IN_TRANSIT→COMPLETED,另建订单可进入 CANCELLED;幂等键异请求、旧 version、非法跳转或终态反向返回 A0409。 security: [{ bearerAuth: [] }] parameters: - { name: orderNo, in: path, required: true, schema: { type: string } } - { name: customerId, in: query, required: true, schema: { type: string, pattern: '^[1-9][0-9]*$' } } requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/LooseboardStatusChange' } } } } responses: { '200': { description: 统一 ApiResponse 包装的散板订单详情 }, '409': { description: 非法状态迁移 } } /api/platform/v1/last-leg/relabel-applications: get: summary: 分页查询海外换标单 description: 权限 platform:overseas-warehouse:relabel-order:list;平台查询全部换标单,不接收 customerId。 security: [{ bearerAuth: [] }] parameters: - { name: page, in: query, schema: { type: integer, minimum: 1, default: 1 } } - { name: size, in: query, schema: { type: integer, minimum: 1, maximum: 200, default: 20 } } - { name: relabelNo, in: query, schema: { type: string, maxLength: 64 } } - { name: customerOrderNo, in: query, schema: { type: string, maxLength: 128 } } - { name: skuCode, in: query, schema: { type: string, maxLength: 128 } } - { name: status, in: query, schema: { $ref: '#/components/schemas/RelabelStatus' } } - { name: overseasWarehouseId, in: query, schema: { type: string, maxLength: 128 } } - { name: createdFrom, in: query, schema: { type: string, format: date-time } } - { name: createdTo, in: query, schema: { type: string, format: date-time } } responses: { '200': { description: 统一 ApiResponse 包装的换标单分页 } } post: summary: 创建海外换标单 description: 权限 platform:overseas-warehouse:relabel-order:create;明细与换标文件按请求快照保存,使用 idempotencyKey 幂等。 security: [{ bearerAuth: [] }] parameters: - { name: customerId, in: query, required: true, schema: { type: string, pattern: '^[1-9][0-9]*$' } } requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/RelabelCreate' } } } } responses: { '200': { description: 统一 ApiResponse 包装的换标单详情 }, '409': { description: 幂等键冲突 } } /api/platform/v1/last-leg/relabel-applications/{relabelNo}: get: summary: 查询海外换标单详情 description: 权限 platform:overseas-warehouse:relabel-order:list。 security: [{ bearerAuth: [] }] parameters: - { name: relabelNo, in: path, required: true, schema: { type: string, maxLength: 64 } } responses: { '200': { description: 统一 ApiResponse 包装的换标单详情 }, '404': { description: 换标单不存在或不属于当前客户 } } /api/platform/v1/last-leg/relabel-applications/{relabelNo}/status: put: summary: 变更海外换标单状态 description: 权限 platform:overseas-warehouse:relabel-order:status;待审核阶段只处理转运、退货等关联业务产生的换标单,客户直接创建的贴标单必须在尾程订单工作台审核。PDA复核通过后进入CUSTOMER_CONFIRM_PENDING,客户确认后进入READY_FOR_OUTBOUND。 security: [{ bearerAuth: [] }] parameters: - { name: relabelNo, in: path, required: true, schema: { type: string, maxLength: 64 } } requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/RelabelStatusChange' } } } } responses: { '200': { description: 统一 ApiResponse 包装的换标单详情 }, '409': { description: 非法状态迁移或关联尾程单缺失 } } /api/platform/v1/last-leg/relabel-applications/{relabelNo}/wallet-settlement/retry: post: summary: 重试失败的换标费用结算 description: 权限 platform:overseas-warehouse:relabel-order:status;仅允许已完成且资金状态为SETTLE_FAILED的换标单,使用新幂等键重新发送结算指令。 security: [{ bearerAuth: [] }] parameters: - { name: relabelNo, in: path, required: true, schema: { type: string, maxLength: 64 } } requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/WalletFreezeRetry' } } } } responses: { '200': { description: 结算重试已提交 }, '409': { description: 当前换标单不满足重试条件 } } /api/platform/v1/last-leg/relabel-applications/{relabelNo}/files: post: summary: 上传总换标PDF或明细换标PDF description: 权限 platform:overseas-warehouse:relabel-order:create。PENDING_REVIEW/PENDING_PROCESSING/PROCESSING/REJECTED 可替换,PDF内容且不超过10MiB。客户从申请单解析,ITEM必须属于该申请单同客户。成功保存File返回的资料元数据,旧资料不再允许通过当前绑定下载。 security: [{ bearerAuth: [] }] parameters: - { name: relabelNo, in: path, required: true, schema: { type: string } } - { name: scope, in: query, required: true, schema: { type: string, enum: [TOTAL, ITEM] } } - { name: itemId, in: query, description: ITEM必填,TOTAL不得传入, schema: { type: integer, format: int64, minimum: 1 } } requestBody: required: true content: multipart/form-data: schema: { type: object, required: [file], properties: { file: { type: string, format: binary } } } responses: '200': { description: 换标详情;application包含totalFileId/totalFileName/totalFileUrl,items包含relabelFileId/relabelFileName/relabelFileUrl。URL为受权下载路径,文件ID按字符串返回 } '400': { description: 非PDF、超限或资料范围无效 } '404': { description: 申请或明细不属于当前客户 } '409': { description: 换标状态不允许修改资料 } /api/platform/v1/last-leg/relabel-applications/{relabelNo}/files/{fileId}/download: get: summary: 读取当前绑定的换标PDF description: 权限 platform:overseas-warehouse:relabel-order:list;按申请单客户、资料类别、application.id或item.id及fileId精确授权。仅当前已保存资料可读,未绑定或替换的文件拒绝。响应Cache-Control为no-store。 security: [{ bearerAuth: [] }] parameters: - { name: relabelNo, in: path, required: true, schema: { type: string } } - { name: fileId, in: path, required: true, schema: { type: integer, format: int64, minimum: 1 } } - { name: scope, in: query, required: true, schema: { type: string, enum: [TOTAL, ITEM] } } - { name: itemId, in: query, schema: { type: integer, format: int64, minimum: 1 } } responses: '200': { description: PDF字节, content: { application/pdf: { schema: { type: string, format: binary } } } } '404': { description: 资料未绑定或归属不匹配 } /api/merchant/v1/last-leg/relabel-applications/inventory-candidates: get: summary: 查询客户可换标库存候选 description: 权限 merchant:overseas-warehouse:relabel:list;返回当前客户在指定海外中转仓仍有可用箱数的历史入仓库存,以及仓库合箱后生成的可用退货箱库存。候选按客户 Token 隔离,不接收 customerId;inboundCode 可按入仓码、退货单号或仓库唛头模糊筛选。 security: [{ bearerAuth: [] }] parameters: - { name: operationWarehouseId, in: query, required: true, schema: { type: string, maxLength: 128 } } - { name: inboundCode, in: query, required: false, schema: { type: string, maxLength: 128 } } responses: '200': { description: 可换标库存候选, content: { application/json: { schema: { type: object, properties: { code: { type: string, example: '200' }, data: { type: array, items: { $ref: '#/components/schemas/RelabelInventoryCandidate' } } } } } } } '403': { description: 缺少客户换标权限 } /api/merchant/v1/last-leg/relabel-applications: get: summary: 分页查询客户换标申请 description: 权限 merchant:overseas-warehouse:relabel:list;客户范围只取认证 Token,不接收 customerId。 security: [{ bearerAuth: [] }] parameters: - { name: page, in: query, schema: { type: integer, minimum: 1, default: 1 } } - { name: size, in: query, schema: { type: integer, minimum: 1, maximum: 200, default: 20 } } - { name: relabelNo, in: query, schema: { type: string, maxLength: 64 } } - { name: customerOrderNo, in: query, schema: { type: string, maxLength: 128 } } - { name: skuCode, in: query, schema: { type: string, maxLength: 128 } } - { name: status, in: query, schema: { $ref: '#/components/schemas/RelabelStatus' } } - { name: overseasWarehouseId, in: query, schema: { type: string, maxLength: 128 } } - { name: createdFrom, in: query, schema: { type: string, format: date-time } } - { name: createdTo, in: query, schema: { type: string, format: date-time } } responses: '200': { description: 客户换标申请分页, content: { application/json: { schema: { $ref: '#/components/schemas/RelabelMerchantPageResponse' } } } } post: summary: 创建客户换标申请 description: 权限 merchant:overseas-warehouse:relabel:create;申请创建即冻结对应库存。一张申请只能选择一种换标类型,所有 items.operationType 必须一致;不同类型混合提交返回业务参数错误且不冻结库存。SKU_LABEL 不要求派送方式;CARTON_LABEL/CARTON_AND_SKU 必须指定 TRUCK、EXPRESS、PICKUP、AMAZON_PICKUP 或 CUSTOMER_PICKUP。 security: [{ bearerAuth: [] }] requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/RelabelCreate' } } } } responses: '200': { description: 换标申请详情, content: { application/json: { schema: { $ref: '#/components/schemas/RelabelMerchantDetailResponse' } } } } '409': { description: 幂等键、库存或状态冲突 } /api/merchant/v1/last-leg/relabel-applications/historical-orders: get: summary: 查询贴标申请历史订单候选 description: 按海外仓和关键字查询客户历史尾程订单,并包含贴标出库单(RELABEL_OUTBOUND),供贴标申请订单下拉筛选。 security: [{ bearerAuth: [] }] parameters: - { name: operationWarehouseId, in: query, required: true, schema: { type: string, maxLength: 128 } } - { name: keyword, in: query, required: false, schema: { type: string, maxLength: 128 } } responses: '200': { description: 历史订单候选, content: { application/json: { schema: { type: object, properties: { code: { type: string, example: '200' }, data: { type: array, items: { $ref: '#/components/schemas/RelabelHistoricalOrder' } } } } } } } '403': { description: 缺少客户换标权限 } /api/merchant/v1/last-leg/relabel-applications/{relabelNo}: get: summary: 查询客户换标申请详情 description: 权限 merchant:overseas-warehouse:relabel:list;客户范围只取认证 Token。 security: [{ bearerAuth: [] }] parameters: [{ name: relabelNo, in: path, required: true, schema: { type: string, maxLength: 64 } }] responses: '200': { description: 换标申请详情, content: { application/json: { schema: { $ref: '#/components/schemas/RelabelMerchantDetailResponse' } } } } '404': { description: 申请不存在或不属于当前客户 } /api/merchant/v1/last-leg/relabel-applications/{relabelNo}/resubmit: put: summary: 修改并重新提交已驳回贴标单 description: 权限 merchant:overseas-warehouse:relabel:create;客户可先替换贴标资料,再修改截止时间、联系人、电话和备注并重新提交审核。重新冻结原库存和费用,直接贴标回到尾程订单审核,关联换标回到换标单审核。 security: [{ bearerAuth: [] }] parameters: [{ name: relabelNo, in: path, required: true, schema: { type: string, maxLength: 64 } }] requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/RelabelResubmit' } } } } responses: { '200': { description: 重新提交后的贴标单详情 }, '409': { description: 非驳回状态、库存已变化或费用尚未释放 } } /api/merchant/v1/last-leg/relabel-applications/{relabelNo}/shipping-label: post: summary: 上传换标快递面单 description: 权限 merchant:overseas-warehouse:relabel:files;仅 EXPRESS 且申请尚未客户确认时允许上传;审核驳回后可替换文件再重新提交,文件由服务端绑定到申请单。 security: [{ bearerAuth: [] }] parameters: [{ name: relabelNo, in: path, required: true, schema: { type: string, maxLength: 64 } }] requestBody: { required: true, content: { multipart/form-data: { schema: { type: object, required: [file], properties: { file: { type: string, format: binary } } } } } } responses: '200': { description: 更新后的换标详情, content: { application/json: { schema: { $ref: '#/components/schemas/RelabelMerchantDetailResponse' } } } } '400': { description: 文件类型或大小不合法 } '409': { description: 当前状态不允许上传 } /api/merchant/v1/last-leg/relabel-applications/{relabelNo}/files: post: summary: 上传客户换标总文件或明细文件 description: 权限 merchant:overseas-warehouse:relabel:files;文件只能绑定到当前客户的换标申请。 security: [{ bearerAuth: [] }] parameters: - { name: relabelNo, in: path, required: true, schema: { type: string, maxLength: 64 } } - { name: scope, in: query, required: true, schema: { type: string, enum: [CARTON_TOTAL, SKU_TOTAL, ITEM] } } - { name: itemId, in: query, required: false, schema: { type: integer, format: int64 } } requestBody: { required: true, content: { multipart/form-data: { schema: { type: object, required: [file], properties: { file: { type: string, format: binary } } } } } } responses: { '200': { description: 更新后的换标详情 }, '403': { description: 缺少换标文件维护权限 }, '409': { description: 状态或归属冲突 } } /api/merchant/v1/last-leg/relabel-applications/{relabelNo}/files/{fileId}/download: get: summary: 客户查看或下载申请已绑定的贴标文件 description: 权限 merchant:overseas-warehouse:relabel:list;按登录客户隔离,并校验总文件或明细文件归属。响应禁止缓存。 security: [{ bearerAuth: [] }] parameters: - { name: relabelNo, in: path, required: true, schema: { type: string } } - { name: fileId, in: path, required: true, schema: { type: integer, format: int64, minimum: 1 } } - { name: scope, in: query, required: true, schema: { type: string, enum: [TOTAL, CARTON_TOTAL, SKU_TOTAL, ITEM] } } - { name: itemId, in: query, required: false, schema: { type: integer, format: int64 } } responses: '200': { description: 贴标 PDF, content: { application/pdf: { schema: { type: string, format: binary } } } } '403': { description: 缺少客户查询权限 } '404': { description: 申请或文件不存在或不属于当前客户 } /api/platform/v1/last-leg/relabel-applications/{relabelNo}/shipping-label/{fileId}/download: get: summary: 平台查看客户上传的换标面单 description: 权限 platform:overseas-warehouse:relabel-order:list;校验平台身份及申请的面单绑定关系。 security: [{ bearerAuth: [] }] parameters: - { name: relabelNo, in: path, required: true, schema: { type: string } } - { name: fileId, in: path, required: true, schema: { type: integer, format: int64, minimum: 1 } } responses: '200': { description: 面单文件, content: { application/pdf: { schema: { type: string, format: binary } }, image/jpeg: { schema: { type: string, format: binary } }, image/png: { schema: { type: string, format: binary } } } } '404': { description: 文件未绑定当前申请 } /api/merchant/v1/last-leg/relabel-applications/{relabelNo}/shipping-label/{fileId}/download: get: summary: 下载换标快递面单 description: 权限 merchant:overseas-warehouse:relabel:list;仅允许下载当前申请已绑定的面单文件。 security: [{ bearerAuth: [] }] parameters: - { name: relabelNo, in: path, required: true, schema: { type: string, maxLength: 64 } } - { name: fileId, in: path, required: true, schema: { type: integer, format: int64, minimum: 1 } } responses: '200': { description: 面单文件, content: { application/pdf: { schema: { type: string, format: binary } }, image/jpeg: { schema: { type: string, format: binary } }, image/png: { schema: { type: string, format: binary } } } } '404': { description: 文件未绑定或不属于当前客户 } /api/merchant/v1/last-leg/relabel-applications/{relabelNo}/completion-photos/{fileId}/download: get: summary: 下载换标完成照片 description: 权限 merchant:overseas-warehouse:relabel:list;仅允许下载该申请 PDA 完工证据中的照片。 security: [{ bearerAuth: [] }] parameters: - { name: relabelNo, in: path, required: true, schema: { type: string, maxLength: 64 } } - { name: fileId, in: path, required: true, schema: { type: integer, format: int64, minimum: 1 } } responses: '200': { description: 完工照片, content: { image/jpeg: { schema: { type: string, format: binary } }, image/png: { schema: { type: string, format: binary } } } } '404': { description: 照片不存在或不属于当前客户 } /api/merchant/v1/last-leg/relabel-applications/{relabelNo}/confirm-completion: post: summary: 客户确认换标完成 description: 权限 merchant:overseas-warehouse:relabel:confirm;仅 CUSTOMER_CONFIRM_PENDING 可确认,确认前复验实际托盘绑定,仓库手动完工不豁免该门禁。普通库存箱唛换标必须绑定实际托盘;退货整箱 EXPRESS、PICKUP、AMAZON_PICKUP、CUSTOMER_PICKUP 可不组托但仍校验全箱 SKU 数量。只有平台卡车 TRUCK 进入 WAIT_PRE_DISPATCH;EXPRESS 与全部自提方式幂等生成 RELABEL_OUTBOUND 出库单和 PDA 出库任务,不进入预排车候选,直接预排请求也拒绝。已分配仓储转运保持原转运出库链,不生成独立出库。EXPRESS 且要求打印面单时必须先上传面单。 security: [{ bearerAuth: [] }] parameters: [{ name: relabelNo, in: path, required: true, schema: { type: string, maxLength: 64 } }] requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/RelabelCustomerConfirm' } } } } responses: '200': { description: 更新后的换标详情, content: { application/json: { schema: { $ref: '#/components/schemas/RelabelMerchantDetailResponse' } } } } '409': { description: 状态、面单、库存或幂等冲突 } /api/merchant/v1/last-leg/return-orders: get: summary: 客户分页查询退货签收订单 description: 权限 merchant:overseas-warehouse:return-order:list;客户范围只取认证 Token。可按退货单号、快递单号、SKU 和签收状态过滤;实收数量以仓库 PDA 签收为准。 security: [{ bearerAuth: [] }] parameters: - { name: page, in: query, schema: { type: integer, minimum: 1, default: 1 } } - { name: size, in: query, schema: { type: integer, minimum: 1, maximum: 200, default: 20 } } - { name: returnNo, in: query, schema: { type: string } } - { name: trackingNo, in: query, schema: { type: string } } - { name: skuCode, in: query, schema: { type: string } } - { name: status, in: query, schema: { type: string, enum: [PENDING_RECEIPT, PARTIALLY_RECEIVED, COMPLETED] } } responses: { '200': { description: 当前客户退货订单分页;每行 relabelApplications 返回所有换标子单的 relabelNo、status、quantity、createdAt,主单 status 仍表示退货签收状态 } } post: summary: 客户创建退货预报订单 description: 权限 merchant:overseas-warehouse:return-order:create;客户只预报不重复的 SKU 和预计数量,不要求提前知道快递单号;仓库 PDA 实收数量才是实际入库事实。系统退货编号由业务前缀和25位大写Base36完整随机UUID编码组成,退货单RT、签收单RR、批次RB、箱唛RC及退货主单RETU均独立生成,不编码内部ID、仓库或日期。幂等重放返回已保存的编号,不重新生成。 security: [{ bearerAuth: [] }] requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/ReturnOrderCreate' } } } } responses: { '200': { description: 创建后的退货订单详情 }, '409': { description: 幂等键冲突 } } /api/merchant/v1/last-leg/return-orders/{returnNo}: get: summary: 客户查询退货订单与签收批次 description: 权限 merchant:overseas-warehouse:return-order:list;返回各 SKU 的预报和实收数量,以及每次 PDA 签收产生的批次号和可选快递单号。cartons 数组包含 receiptNo、palletCode、cartonMark、countStatus、countedAt、items(skuCode、productNameZh、quantity、boxCount)。CONFIRMED 为签收或清点时不可变箱内快照;PENDING 的 items 为空,不返回预分配平均数;UNRECORDED 表示历史未留存箱内快照,不能以已变化库存冒充签收数量。包裹作为一个独立实物明细,保留同包裹全部SKU及可打印标签。 security: [{ bearerAuth: [] }] parameters: [{ name: returnNo, in: path, required: true, schema: { type: string } }] responses: { '200': { description: 当前客户退货订单详情 }, '404': { description: 当前客户下退货订单不存在 } } /api/merchant/v1/last-leg/return-orders/{returnNo}/photos/files/{fileId}/download: get: summary: 客户下载退货签收打托照片 description: 权限 merchant:overseas-warehouse:return-order:list;仅允许下载当前客户、当前退货单关联的签收照片,响应为原始文件且禁止缓存。 security: [{ bearerAuth: [] }] parameters: - { name: returnNo, in: path, required: true, schema: { type: string } } - { name: fileId, in: path, required: true, schema: { type: integer, format: int64 } } responses: '200': { description: 照片文件, content: { image/*: { schema: { type: string, format: binary } } } } '404': { description: 当前客户下退货单或关联照片不存在 } /api/merchant/v1/last-leg/return-orders/{returnNo}/relabel-candidates: get: summary: 查询退货单可转换标候选 description: 权限 merchant:overseas-warehouse:return-order:relabel;只返回当前客户退货单的可转换标明细。 security: [{ bearerAuth: [] }] parameters: [{ name: returnNo, in: path, required: true, schema: { type: string } }] responses: { '200': { description: 可转换标候选 }, '403': { description: 缺少退货转换标权限 }, '404': { description: 当前客户下退货单不存在 } } /api/merchant/v1/last-leg/return-orders/{returnNo}/relabel: post: summary: 将退货库存转换为换标申请 description: 权限 merchant:overseas-warehouse:return-order:relabel;只能处理当前客户且满足状态门禁的退货库存。 security: [{ bearerAuth: [] }] parameters: [{ name: returnNo, in: path, required: true, schema: { type: string } }] responses: { '200': { description: 创建后的换标申请 }, '403': { description: 缺少退货转换标权限 }, '409': { description: 状态、库存或幂等冲突 } } /api/pda/v1/last-leg/return-receipts/start: post: summary: PDA 以退件单号开始签收 description: 仓库先从包裹收件信息取得客户填写的退件单号。仅当前绑定仓的 PENDING_RECEIPT(待签收)和 PARTIALLY_RECEIVED(签收中)退货单可开始签收,并返回该单尚未签收的 SKU 明细。 security: [{ bearerAuth: [] }] requestBody: { required: true, content: { application/json: { schema: { type: object, required: [returnNo], properties: { returnNo: { type: string, maxLength: 128 } } } } } } responses: { '200': { description: 可开始签收的退货单及未签收 SKU 明细 }, '404': { description: 当前仓没有待签收或签收中的退货单 } } /api/pda/v1/last-leg/return-receipts/sku-candidates: post: summary: PDA 扫描 SKU 查询候选退货单 description: 仅查询当前 PDA 绑定仓内待签收或签收中的退货单,最多返回 50 个候选。仓库人员根据退货单号、客户和数量选择后,再调用 start 进入统一签收流程。 security: [{ bearerAuth: [] }] requestBody: { required: true, content: { application/json: { schema: { type: object, required: [skuCode], properties: { skuCode: { type: string, maxLength: 128 } } } } } } responses: { '200': { description: SKU 及候选退货单列表;没有匹配时 candidates 为空数组 } } /api/pda/v1/last-leg/return-receipts/confirm: post: summary: PDA 确认退货签收 description: PDA 仅能操作绑定海外仓。startedBy 记录通过退货单号或 SKU 候选进入;按 PALLET、BOX、PARCEL 选择现场实物维度。托盘必须提交托盘码、长宽高和重量并计算体积;箱子可散装,也可额外绑定托盘;包裹只需提交包裹/快递单号。按预报可签收数量校验、禁止超收;每次成功确认创建唯一签收单及仓储计费批次。全部预报 SKU 数量吻合时自动 COMPLETED。 security: [{ bearerAuth: [] }] requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/ReturnReceiptConfirm' } } } } responses: { '200': { description: 签收结果及自动完成状态 }, '409': { description: 超收、错绑或幂等键冲突 } } /api/merchant/v1/last-leg/return-inventory: get: summary: 客户查询退货库存 description: 客户范围只取认证 Token。库存按客户、海外仓、SKU 和箱号查询,数量以仓库 PDA 实收上架数量为准。 security: [{ bearerAuth: [] }] parameters: - { name: page, in: query, schema: { type: integer, minimum: 1, default: 1 } } - { name: size, in: query, schema: { type: integer, minimum: 1, maximum: 200, default: 20 } } - { name: overseasWarehouseId, in: query, schema: { type: string, maxLength: 128 } } - { name: skuCode, in: query, schema: { type: string, maxLength: 128 } } - { name: cartonMark, in: query, schema: { type: string, maxLength: 128 } } responses: { '200': { description: 当前客户退货库存分页 } } /api/merchant/v1/last-leg/return-inventory/summary: get: summary: 客户查询退货库存 SKU 汇总 description: 客户范围只取认证 Token。按海外仓和 SKU 汇总 PDA 实收上架数量及可用箱数。relabelLockedQuantity 为换标处理中整箱锁定的该 SKU 在库件数,包含同箱未申请换标但无法使用的余量;不包含合箱、待清点或出库占用,不等同于未完成换标任务件数。 security: [{ bearerAuth: [] }] parameters: - { name: page, in: query, schema: { type: integer, minimum: 1, default: 1 } } - { name: size, in: query, schema: { type: integer, minimum: 1, maximum: 200, default: 20 } } - { name: overseasWarehouseId, in: query, schema: { type: string, maxLength: 128 } } - { name: skuCode, in: query, schema: { type: string, maxLength: 128 } } responses: { '200': { description: 当前客户 SKU 汇总库存分页 } } /api/merchant/v1/last-leg/return-inventory/cartons: get: summary: 客户退货箱号分页 description: 需要 merchant:overseas-warehouse:return-inventory:list。客户范围仅取登录身份且精确匹配;每个实物箱一条记录,SKU 筛选使用存在性条件,不重复箱号或放大总箱数。 security: [{ bearerAuth: [] }] parameters: - { name: page, in: query, schema: { type: integer, minimum: 1, default: 1 } } - { name: size, in: query, schema: { type: integer, minimum: 1, maximum: 200, default: 20 } } - { name: overseasWarehouseId, in: query, schema: { type: string } } - { name: skuCode, in: query, schema: { type: string } } - { name: cartonMark, in: query, schema: { type: string } } - { name: returnNo, in: query, schema: { type: string } } - { name: status, in: query, schema: { type: string } } responses: '200': { description: 分页 records 每箱一行,包含 cartonMark、overseasWarehouseId、sourceBatchNo、sourceReturnNo、status、skuTypes、totalQuantity、length、width、height、weight、createdAt、relabelStatus、relabelledQuantity、relabelReservedQuantity;total 为实际箱数。换标状态取实际当前或最新轮次事实,申请占用为未完成申请件数,两者不从可用库存差值推算 } /api/merchant/v1/last-leg/return-inventory/cartons/{cartonMark}: get: summary: 客户查询退货箱明细 description: 仅返回当前客户的箱号、签收批次和箱内 SKU 数量;relabelStatus 为 UNLABELLED/PROCESSING/PARTIALLY_COMPLETED/COMPLETED,relabelledQuantity 为当前或最新轮次实际商品换标件数,relabelReservedQuantity 为未完成申请件数。items.availableQuantity 为实物可用库存,历史换标不会永久扣减下一轮可申请量。 security: [{ bearerAuth: [] }] parameters: [{ name: cartonMark, in: path, required: true, schema: { type: string, maxLength: 128 } }] responses: { '200': { description: 当前客户退货箱明细 }, '404': { description: 当前客户下退货箱不存在 } } /api/merchant/v1/last-leg/return-inventory/cartons/{cartonMark}/label: get: summary: 客户获取退货箱唛 description: 返回当前客户退货箱的可打印标签及 SKU 数量,客户可据此打印或复核箱唛。 security: [{ bearerAuth: [] }] parameters: [{ name: cartonMark, in: path, required: true, schema: { type: string, maxLength: 128 } }] responses: { '200': { description: 当前客户退货箱唛 }, '404': { description: 当前客户下退货箱不存在 } } /api/pda/v1/last-leg/return-inventory/cartons/merge: post: summary: PDA 合并退货箱 description: 仅当前 PDA 绑定海外仓可操作。选择同一客户的已完成退货单,按查询出的 SKU 填写本箱数量并录入箱规;系统扣减可用库存并生成合箱箱号。 security: [{ bearerAuth: [] }] requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/ReturnInventoryMerge' } } } } responses: { '200': { description: 新箱号、SKU 汇总数量及可打印箱唛 }, '409': { description: 箱状态、客户或 SKU 不满足合箱条件,或幂等键冲突 } } /api/pda/v1/last-leg/return-inventory/cartons/merge-boxes: post: summary: PDA 按实物来源箱合箱 description: 同一客户、当前绑定仓内合箱;新请求必须携带扫码时全部来源箱 SKU 数量,在来源行锁内校验,过期返回冲突,重新扫描后操作。 security: [{ bearerAuth: [] }] requestBody: { required: true, content: { application/json: { schema: { $ref: '#/components/schemas/ReturnInventoryBoxMerge' } } } } responses: { '200': { description: 合箱实物箱号与标签 }, '400': { description: 缺少或无效来源库存快照 }, '409': { description: 来源库存或资格已变化,或幂等键冲突 } } /api/pda/v1/last-leg/return-inventory/packing/orders: get: summary: PDA 查询可合箱退货单和 SKU 库存 security: [{ bearerAuth: [] }] parameters: [{ name: returnNo, in: query, required: false, schema: { type: string, maxLength: 128 } }] responses: { '200': { description: 当前仓已完成签收退货单及可用 SKU 数量 } } /api/pda/v1/last-leg/return-inventory/cartons/{cartonMark}/label: get: summary: PDA 获取退货箱唛 description: 返回当前绑定仓退货箱的结构化数据及 100mm x 150mm 可打印 HTML,包含箱号、仓库、客户、签收批次及 SKU 数量。 security: [{ bearerAuth: [] }] parameters: [{ name: cartonMark, in: path, required: true, schema: { type: string, maxLength: 128 } }] responses: { '200': { description: 退货箱唛打印数据 }, '404': { description: 当前仓没有该退货箱 } } components: schemas: WarehouseTransferDetailApiResponse: type: object properties: data: { $ref: '#/components/schemas/WarehouseTransferDetail' } WarehouseTransferDetail: type: object description: 保留原转运详情字段;新增持久实收命令投影供平台与当前客户恢复。成功实收返回本地事务完成后的命令状态,不暴露内部资源锁或reservationKey。 required: [receiptCommands] properties: packageCount: { type: integer, description: 下单预计箱数,不随实际签收覆盖 } items: type: array items: type: object properties: quantity: { type: integer, format: int64, nullable: true, description: SKU 申报件数,历史未申报为 null } packageCount: { type: integer, description: 该 SKU 预计箱数 } cartons: { type: array, items: { type: object }, description: 实际签收仅统计状态 COUNTED 的箱子 } receiptCommands: type: array items: { $ref: '#/components/schemas/WarehouseTransferReceiptCommand' } WarehouseTransferReceiptCommand: type: object additionalProperties: false required: [sourceInventoryPositionId, status, requestHash, request, target] properties: sourceInventoryPositionId: { type: string, description: 原来源库存位置标识,仅用于原命令恢复 } status: { type: string, enum: [PREPARED, RESERVED, COMPLETED] } requestHash: { type: string, pattern: '^[a-f0-9]{64}$' } request: { $ref: '#/components/schemas/WarehouseTransferReceiptRequest' } target: { $ref: '#/components/schemas/WarehouseTransferReceiptTarget' } WarehouseTransferReceiptTarget: type: object additionalProperties: false required: [warehouseId, warehouseCode, warehouseName, palletId, palletNo, locationId, locationCode, fbaId, fbaCode, fbaName] properties: warehouseId: { type: string } warehouseCode: { type: string } warehouseName: { type: string } palletId: { type: string } palletNo: { type: string } locationId: { type: string } locationCode: { type: string } fbaId: { type: string } fbaCode: { type: string } fbaName: { type: string } WarehouseTransferReceiptRequest: type: object additionalProperties: false required: [sourceInventoryPositionId, destinationOverseasWarehouseId, destinationWarehouseCode, destinationPalletId, destinationPalletNo, idempotencyKey] properties: sourceInventoryPositionId: { type: integer, format: int64 } destinationOverseasWarehouseId: { type: string, maxLength: 128 } destinationOverseasWarehouseCode: { type: string, nullable: true, maxLength: 128 } destinationOverseasWarehouseName: { type: string, nullable: true, maxLength: 255 } destinationWarehouseId: { type: string, nullable: true, maxLength: 128 } destinationWarehouseCode: { type: string, maxLength: 128 } destinationWarehouseName: { type: string, nullable: true, maxLength: 255 } destinationPalletId: { type: integer, format: int64 } destinationPalletNo: { type: string, maxLength: 128 } batchNo: { type: string, nullable: true, maxLength: 128 } warehouseLocationId: { type: integer, format: int64, nullable: true } warehouseLocationCode: { type: string, nullable: true, maxLength: 128 } idempotencyKey: { type: string, maxLength: 255 } remark: { type: string, nullable: true, maxLength: 1000 } ExceptionOrderDetailResponse: type: object properties: code: { type: string } data: type: object required: [order, returnSources, returnReceipts] properties: order: { type: object } returnSources: { type: array, items: { type: object }, description: 当前异常剩余可收来源,不是实收历史 } returnReceipts: type: array description: 全部真实退回实收批次;无实收时为空数组,不因库存耗尽而隐藏 items: type: object required: [receiptNo, receivedPackages, receivedAt, redispatches] properties: receiptNo: { type: string } receivedPackages: { type: string, pattern: '^[0-9]+$', description: 本批实际实收箱数,Java long按统一JSON合同返回字符串 } receivedAt: { type: string, format: date-time } redispatches: type: array description: 本凭据关联的全部重派排车;尚未关联时为空数组 items: type: object required: [dispatchNo, status, selectedPackages, pickedPackages, deliveries] properties: dispatchNo: { type: string } status: { type: string } selectedPackages: { type: string, pattern: '^[0-9]+$', description: 本凭据在该排车冻结选定箱数,按排车项去重 } pickedPackages: { type: string, pattern: '^[0-9]+$', description: 本凭据在该排车的实际PDA拣货箱数,未拣为0 } deliveries: type: array description: 仅关联该退回排车项目的地的派送,不返回同排车其他目的地单据 items: type: object required: [deliveryNo, status] properties: deliveryNo: { type: string } status: { type: string } DeliveryOrderRow: type: object required: [deliveryNo, packageCount, signedPackages] properties: deliveryNo: { type: string } customerName: { type: string, nullable: true, description: 客户名称快照;退货换标直出创建时从权威客户目录获取,查询不按ID猜名 } overseasWarehouseName: { type: string, nullable: true, description: 作业海外仓名称快照;退货换标直出创建时从权威仓库目录获取 } totalWeightKg: { type: number, nullable: true, description: 实物毛重千克;退货换标直出按选中实际箱每箱一次汇总,任一箱缺测则为空,不按SKU件数倍乘 } totalVolumeCbm: { type: number, nullable: true, description: 实物体积立方米;退货换标直出按每箱实测长宽高厘米相乘除以1000000,任一箱缺尺寸则为空 } packageCount: { type: integer, minimum: 0 } signedPackages: type: integer nullable: true minimum: 0 description: 数据库冻结的实际签收箱数;字段始终返回,null 表示未知,0 与正整数保留原值,不以发货箱数替代。 signedAt: { type: string, format: date-time, nullable: true } DeliveryOrderPageResponse: type: object properties: code: { type: string } data: type: object properties: records: { type: array, items: { $ref: '#/components/schemas/DeliveryOrderRow' } } DeliveryOrderDetailResponse: type: object properties: code: { type: string } data: type: object required: [order] properties: order: { $ref: '#/components/schemas/DeliveryOrderRow' } skus: type: array description: 当前派送目的地的本次排车货物投影;数量按冻结排车与本次PDA实拣归属,不返回整单申报箱数。未实拣或MIXED库存没有单SKU归属时保留数量,SKU及品名为null;没有本次SKU测量事实时重量与体积为null,不按比例分摊整单测量。退货换标直接出库沿签收货物约定,按每实物箱的sku_code排序,仅首SKU行承载1箱及冻结的整箱重量/体积,其余SKU行承载0箱、物理量为空;每行productQuantity仍是对应SKU件数,整箱物理量不是单SKU净重。 items: { $ref: '#/components/schemas/DeliveryCargoSku' } DeliveryCargoSku: type: object required: [packageCount] properties: inboundCode: { type: string, nullable: true } customerName: { type: string, nullable: true } destinationWarehouseCode: { type: string, nullable: true } receivingAddress: { type: string, nullable: true } shipmentNo: { type: string, nullable: true } fbaTrackingNo: { type: string, nullable: true } skuCode: { type: string, nullable: true } productName: { type: string, nullable: true } packageCount: { type: integer, minimum: 0, description: 本次实物箱贡献数,不是件数或整单申报箱数;退货换标直出同箱仅首SKU行计1,其余为0 } productQuantity: { type: string, nullable: true, pattern: '^[0-9]+$', description: 退货箱中本行SKU件数,long按字符串返回;不用于乘算箱级重量或体积 } weightKg: { type: number, nullable: true, description: 千克;退货换标直出同箱首SKU行承载冻结整箱毛重,其余行或缺测为null } volumeCbm: { type: number, nullable: true, description: 立方米;退货换标直出同箱首SKU行承载冻结整箱体积,其余行或缺测为null } ReturnOrderCreate: type: object required: [overseasWarehouseId, needRelabel, idempotencyKey, items] properties: overseasWarehouseId: { type: string, maxLength: 128 } warehouseContactName: { type: string, maxLength: 128, description: 中转仓联系人快照;仓库未维护时可由客户填写 } warehouseContactPhone: { type: string, maxLength: 64, description: 中转仓联系电话快照;仓库未维护时可由客户填写 } customerReferenceNo: { type: string, maxLength: 128 } needRelabel: { type: boolean, default: false, description: 是否需要换标 } remark: { type: string, maxLength: 1000 } idempotencyKey: { type: string, maxLength: 255 } items: type: array minItems: 1 maxItems: 500 items: type: object required: [skuCode, expectedQuantity] properties: skuCode: { type: string, maxLength: 128 } productNameZh: { type: string, maxLength: 255 } expectedQuantity: { type: integer, minimum: 1 } ReturnReceiptConfirm: type: object required: [returnNo, startedBy, items, idempotencyKey, expectedReceivedQuantity] properties: expectedReceivedQuantity: { type: integer, format: int64, minimum: 0, description: '提交前退货单全部 SKU 的累计实收数量;在订单锁内校验,过期返回冲突,刷新后重新操作' } returnNo: { type: string, maxLength: 128 } trackingNo: { type: string, nullable: true, maxLength: 128, description: '本次签收包裹有快递面单时扫描绑定;没有时为空' } startedBy: { type: string, enum: [RETURN_NO, SKU], description: '本次通过退货单号查询或 SKU 候选开始签收' } unitType: { type: string, enum: [PALLET, BOX, PARCEL], default: PALLET, description: 本次签收实物维度 } unitCode: { type: string, nullable: true, maxLength: 128, description: 托盘码或包裹/快递单号;箱子不传时由系统生成内部箱号 } palletCode: { type: string, nullable: true, maxLength: 128, description: 箱子可选的托盘绑定码;托盘类型下与 unitCode 相同 } length: { type: number, nullable: true, exclusiveMinimum: true, description: 托盘长度,CM;托盘类型必填 } width: { type: number, nullable: true, exclusiveMinimum: true, description: 托盘宽度,CM;托盘类型必填 } height: { type: number, nullable: true, exclusiveMinimum: true, description: 托盘高度,CM;托盘类型必填 } weight: { type: number, nullable: true, exclusiveMinimum: true, description: 托盘重量,KG;托盘类型必填 } idempotencyKey: { type: string, maxLength: 255 } items: type: array minItems: 1 maxItems: 500 items: type: object required: [skuCode, receivedQuantity] properties: skuCode: { type: string, maxLength: 128 } receivedQuantity: { type: integer, minimum: 1 } boxCount: { type: integer, nullable: true, minimum: 1, description: 托盘或箱子签收时该 SKU 对应箱数,包裹签收不填 } ReturnInventoryBoxMerge: type: object required: [sourceCartonMarks, idempotencyKey, expectedSourceQuantities] properties: sourceCartonMarks: { type: array, minItems: 1, maxItems: 100, items: { type: string } } targetCartonMark: { type: string, nullable: true, description: 不填时生成新箱 } idempotencyKey: { type: string, maxLength: 255 } expectedSourceQuantities: type: array minItems: 1 maxItems: 1000 description: 扫码时全部来源箱各 SKU 的数量,必须完整且不能重复 items: type: object required: [cartonMark, skuCode, quantity] properties: cartonMark: { type: string } skuCode: { type: string } quantity: { type: integer, format: int64, minimum: 0 } sourceDeductions: type: array maxItems: 1000 items: type: object required: [cartonMark, skuCode, quantity] properties: cartonMark: { type: string } skuCode: { type: string } quantity: { type: integer, format: int64, minimum: 1 } length: { type: number, minimum: 0, exclusiveMinimum: true } width: { type: number, minimum: 0, exclusiveMinimum: true } height: { type: number, minimum: 0, exclusiveMinimum: true } weight: { type: number, minimum: 0, exclusiveMinimum: true } ReturnInventoryMerge: type: object required: [returnNos, items, length, width, height, weight, idempotencyKey] properties: returnNos: type: array minItems: 1 maxItems: 100 items: { type: string, minLength: 1, maxLength: 128 } items: type: array minItems: 1 maxItems: 500 items: type: object required: [skuCode, quantity] properties: skuCode: { type: string, maxLength: 128 } quantity: { type: integer, minimum: 1 } length: { type: number, minimum: 0, exclusiveMinimum: true, description: '箱长,CM' } width: { type: number, minimum: 0, exclusiveMinimum: true, description: '箱宽,CM' } height: { type: number, minimum: 0, exclusiveMinimum: true, description: '箱高,CM' } weight: { type: number, minimum: 0, exclusiveMinimum: true, description: '箱重,KG' } idempotencyKey: { type: string, minLength: 1, maxLength: 255 } InventoryBalance: type: object required: [id, customerId, totalPackages, availablePackages, holdPackages, allocatedPackages, pickedPackages, inTransitPackages, receivingPackages, procurementPackages] properties: id: { type: string, pattern: '^[1-9][0-9]*$', description: 库存余额长整型ID,按字符串传输 } customerId: { type: string } customerName: { type: string, nullable: true } overseasWarehouseId: { type: string, nullable: true } overseasWarehouseCode: { type: string, nullable: true } overseasWarehouseName: { type: string, nullable: true } destinationWarehouseId: { type: string, nullable: true } destinationWarehouseCode: { type: string, nullable: true } destinationWarehouseName: { type: string, nullable: true } inboundOrderId: { type: string, nullable: true, pattern: '^[1-9][0-9]*$', description: 长整型ID按字符串传输 } inboundOrderNo: { type: string, nullable: true } inboundCode: { type: string, nullable: true } skuCode: { type: string, nullable: true } productNameZh: { type: string, nullable: true } productNameEn: { type: string, nullable: true } totalPackages: { type: integer, format: int64, minimum: 0 } availablePackages: { type: integer, format: int64, minimum: 0 } holdPackages: { type: integer, format: int64, minimum: 0 } allocatedPackages: { type: integer, format: int64, minimum: 0 } pickedPackages: { type: integer, format: int64, minimum: 0 } inTransitPackages: { type: integer, format: int64, minimum: 0 } receivingPackages: { type: integer, format: int64, minimum: 0 } procurementPackages: { type: integer, format: int64, minimum: 0 } updatedAt: { type: string, format: date-time, nullable: true } InventoryBalanceApiResponse: allOf: - { $ref: '#/components/schemas/ReceivingApiResponseBase' } - type: object properties: { data: { $ref: '#/components/schemas/InventoryBalance' } } InboundCodeRelationship: type: object required: [inboundCode, found, taillegOrders, inboundPlans, palletCodes, inventory] properties: inboundCode: { type: string } found: { type: boolean } customer: { $ref: '#/components/schemas/InboundCodeRelationshipCustomer', nullable: true } overseasWarehouse: { $ref: '#/components/schemas/InboundCodeRelationshipWarehouse', nullable: true } overseasReceivingStatus: { type: string, nullable: true } taillegOrders: { type: array, items: { $ref: '#/components/schemas/InboundCodeRelationshipOrder' } } inboundPlans: { type: array, items: { $ref: '#/components/schemas/InboundCodeRelationshipPlan' } } palletCodes: { type: array, uniqueItems: true, items: { type: string } } inventory: { type: array, items: { $ref: '#/components/schemas/InboundCodeRelationshipInventorySku' } } InboundCodeRelationshipCustomer: type: object required: [customerId] properties: customerId: { type: string, description: 字符串业务隔离标识,禁止按JavaScript number处理 } customerName: { type: string, nullable: true } InboundCodeRelationshipWarehouse: type: object properties: warehouseId: { type: string, nullable: true, description: 字符串共享仓库ID,禁止按JavaScript number处理 } warehouseCode: { type: string, nullable: true } warehouseName: { type: string, nullable: true } InboundCodeRelationshipOrder: type: object required: [orderNo] properties: orderNo: { type: string } orderStatus: { type: string, nullable: true } InboundCodeRelationshipPlan: type: object required: [planNo] properties: planNo: { type: string } planStatus: { type: string, nullable: true } receivingStatus: { type: string, nullable: true } InboundCodeRelationshipInventorySku: type: object required: [skuCode, packageCount] properties: skuCode: { type: string } productNameZh: { type: string, nullable: true } productNameEn: { type: string, nullable: true } packageCount: { type: integer, format: int64, minimum: 0 } InboundCodeRelationshipApiResponse: allOf: - { $ref: '#/components/schemas/ReceivingApiResponseBase' } - type: object properties: { data: { $ref: '#/components/schemas/InboundCodeRelationship' } } FbaTransferDestination: type: object required: [warehouseId, warehouseCode, warehouseName] properties: warehouseId: { type: string, pattern: '^[1-9][0-9]*$', description: 国内 Warehouse Service 平台公共 FBA 仓 ID } warehouseCode: { type: string, minLength: 1, maxLength: 128 } warehouseName: { type: string, minLength: 1, maxLength: 255 } remark: { type: string, nullable: true, maxLength: 500 } FbaBatchTransferDestination: allOf: - { $ref: '#/components/schemas/FbaTransferDestination' } - type: object required: [orderIds] properties: orderIds: type: array minItems: 1 maxItems: 200 uniqueItems: true items: { type: string, pattern: '^[1-9][0-9]*$' } ContainerPlanProgressSummary: type: object required: [sourceContainerBookingId, containerNo, overseasWarehouseId, overseasWarehouseCode, overseasWarehouseName, assignmentVersion, canChangeReceivingWarehouse, totalOrderCount, inboundCodeCount, missingInboundCodeCount, planCount, plannedInboundCodeCount, pendingPlanCount, resourcePendingPlanCount, allPlansReady] properties: sourceContainerBookingId: { type: string } containerNo: { type: string, minLength: 1, description: 装柜完成事件中非空且已移除空白并转大写的真实集装箱号,不校验 ISO 6346 长度、结构、设备类别或校验位;不使用 cabinetNo、订单号或内部 ID 回退 } overseasWarehouseId: { type: string, pattern: '^[1-9][0-9]*$', description: 平台预分配的海外接柜仓ID,不是FBA目的仓 } overseasWarehouseCode: { type: string, description: 海外接柜仓业务编码 } overseasWarehouseName: { type: string, description: 海外接柜仓业务名称 } assignmentVersion: { type: integer, minimum: 0, description: 柜级接柜仓乐观锁版本 } canChangeReceivingWarehouse: { type: boolean } receivingWarehouseLockReason: { type: string, nullable: true } totalOrderCount: { type: integer, format: int64 } inboundCodeCount: { type: integer, format: int64 } missingInboundCodeCount: { type: integer, format: int64 } planCount: { type: integer, format: int64 } plannedInboundCodeCount: { type: integer, format: int64 } pendingPlanCount: { type: integer, format: int64, description: 尚未生成有效计划的尾程订单数,即未操作数 } resourcePendingPlanCount: { type: integer, format: int64, description: 已有有效计划但尚未完整绑定海外仓真实托盘的订单数 } plannedArrivalAt: { type: string, format: date-time, nullable: true, description: 整柜一致的 ll_order.estimated_warehouse_at,可由装柜事件初始化并在计划生成前人工维护 } allPlansReady: { type: boolean, description: 全柜每票均有入仓码且均存在有效独立计划时为 true } blockingReason: { type: string, nullable: true } ChangeReceivingWarehouseRequest: type: object required: [overseasWarehouseId, expectedVersion] properties: overseasWarehouseId: { type: integer, format: int64, minimum: 1 } expectedVersion: { type: integer, minimum: 0 } remark: { type: string, maxLength: 500, nullable: true } ContainerArrivalTimeQuery: type: object required: [sourceContainerBookingIds] properties: sourceContainerBookingIds: type: array minItems: 1 maxItems: 200 uniqueItems: true items: { type: string, minLength: 1, maxLength: 128 } ChangeExpectedWarehouseArrivalRequest: type: object required: [estimatedWarehouseArrivalAt, expectedVersion] properties: estimatedWarehouseArrivalAt: { type: string, format: date-time } expectedVersion: { type: integer, minimum: 0 } remark: { type: string, maxLength: 500, nullable: true } ContainerArrivalTimeView: type: object required: [sourceContainerBookingId, version, planCount] properties: sourceContainerBookingId: { type: string } estimatedWarehouseArrivalAt: { type: string, format: date-time, nullable: true, description: 人工维护的整柜时间;默认日期及只有日期的冻结计划不补造时间 } plannedDate: { type: string, format: date, nullable: true, description: 与日历和入库计划共用的服务端日期,人工或冻结日期优先,否则按权威到港当地日期加两个自然日 } isDefault: { type: boolean, description: 未人工维护未建计划时使用权威到港推算日期 } actualWarehouseArrivalAt: { type: string, format: date-time, nullable: true, description: 海外 PDA 首次开始收货时间 } version: { type: integer, minimum: -1, description: -1表示柜内时间版本不一致 } planCount: { type: integer, format: int64, minimum: 0, description: 整柜已有入库计划数量;非零时禁止默认推算及改期 } ContainerPlanProgressDetail: type: object required: [summary, orders] properties: summary: { $ref: '#/components/schemas/ContainerPlanProgressSummary' } orders: type: array items: { $ref: '#/components/schemas/ContainerPlanProgressItem' } ContainerPlanProgressItem: type: object required: [orderId, customerId, orderStatus, planValid] properties: orderId: { type: string, pattern: '^[1-9][0-9]*$' } customerId: { type: string } orderNo: { type: string, nullable: true } inboundCode: { type: string, nullable: true } lxCode: { type: string, nullable: true, maxLength: 128, description: 一件代发领星入库单代码 } orderStatus: { type: string } planId: { type: string, nullable: true, pattern: '^[1-9][0-9]*$' } planNo: { type: string, nullable: true } planStatus: { type: string, nullable: true } planValid: { type: boolean } plannedArrivalAt: { type: string, format: date-time, nullable: true, description: ll_order.estimated_warehouse_at } LastMileFeeCreate: type: object required: [feeItemCode, feeItemName, direction, currency, amount, businessDate] properties: feeItemCode: { type: string, minLength: 1, maxLength: 64 } feeItemName: { type: string, minLength: 1, maxLength: 128 } feeRemark: { type: string, maxLength: 500, nullable: true, description: 费用说明;同单同方向已有相同项目时须填写补收或重复作业原因 } direction: { type: string, enum: [RECEIVABLE, PAYABLE] } currency: { type: string, enum: [CNY, USD] } amount: { type: number, format: decimal, minimum: 0.01 } businessDate: { type: string, format: date } supplierId: { type: string, pattern: '^[1-9][0-9]*$' } supplierName: { type: string, maxLength: 200 } supplierCategory: { type: string, maxLength: 32 } settlementMode: { type: string, enum: [BILL, WALLET, ON_ACCOUNT, DIRECT_PAID], nullable: true, description: 应收可选推送结算或余额扣费;应付使用账期或已付 } chargeableQuantity: { type: number, minimum: 0, exclusiveMinimum: true } quantityUnit: { type: string, maxLength: 32 } unitPrice: { type: number, minimum: 0, exclusiveMinimum: true } periodStart: { type: string, format: date } periodEnd: { type: string, format: date } LastMileFee: type: object required: [id, sourceFeeId, sourceVersion, customerId, feeItemCode, feeItemName, direction, currency, amount, originalCurrency, originalAmount, reviewStatus, publicationStatus, sourceStatus] properties: id: { type: string, pattern: '^[1-9][0-9]*$' } sourceFeeId: { type: string, pattern: '^[1-9][0-9]*$' } sourceVersion: { type: integer, minimum: 1 } customerId: { type: string } orderId: { type: string, pattern: '^[1-9][0-9]*$' } feeItemCode: { type: string } feeItemName: { type: string } feeRemark: { type: string, maxLength: 500, nullable: true, description: 业务费用说明,与审核原因分开保存 } direction: { type: string, enum: [RECEIVABLE, PAYABLE] } currency: { type: string, enum: [CNY] } amount: { type: number, format: decimal } originalCurrency: { type: string, enum: [CNY, USD] } originalAmount: { type: number, format: decimal } exchangeRate: { type: number, format: decimal } exchangeRateMonth: { type: string, pattern: '^\\d{4}-\\d{2}$' } reviewStatus: { type: string, enum: [DRAFT, PENDING, APPROVED, REJECTED] } publicationStatus: { type: string } sourceStatus: { type: string } LastMileFeeApiResponse: type: object required: [code, message, data] properties: code: { type: string } message: { type: string } data: { $ref: '#/components/schemas/LastMileFee' } PdaWarehouseScan: type: object required: [code] properties: { code: { type: string, minLength: 1, maxLength: 128 } } PdaInventoryItem: type: object required: [customerId, balanceId, positionId, inboundCode, palletId, palletCode, availablePackages, holdPackages, receivingPackages, status, version] properties: customerId: { type: string } customerName: { type: string, nullable: true } balanceId: { type: integer, format: int64 } positionId: { type: integer, format: int64 } skuCode: { type: string, nullable: true } productName: { type: string, nullable: true } inboundCode: { type: string } cartonMark: { type: string, nullable: true } palletId: { type: integer, format: int64 } palletCode: { type: string } locationId: { type: integer, format: int64, nullable: true } locationCode: { type: string, nullable: true } availablePackages: { type: integer, format: int64, minimum: 0 } holdPackages: { type: integer, format: int64, minimum: 0 } receivingPackages: { type: integer, format: int64, minimum: 0 } status: { type: string } version: { type: integer, format: int64, minimum: 0 } PdaInventoryScan: type: object required: [queryCode, items] properties: queryCode: { type: string } items: { type: array, items: { $ref: '#/components/schemas/PdaInventoryItem' } } PdaLocation: type: object required: [locationId, locationCode, locationType, status, occupiedPackages, inventoryPositionCount] properties: locationId: { type: integer, format: int64 } locationCode: { type: string } locationType: { type: string } maxLoadKg: { type: number, nullable: true } status: { type: string } occupiedPackages: { type: integer, format: int64, minimum: 0 } inventoryPositionCount: { type: integer, minimum: 0 } PdaPallet: type: object required: [palletId, palletCode, status, version, locationId, locationCode, occupiedPackages, inventoryPositionCount, inventory] properties: palletId: { type: integer, format: int64 } palletCode: { type: string } status: { type: string } version: { type: integer, minimum: 0 } locationId: { type: integer, format: int64 } locationCode: { type: string } occupiedPackages: { type: integer, format: int64, minimum: 0 } inventoryPositionCount: { type: integer, minimum: 0 } inventory: { type: array, items: { $ref: '#/components/schemas/PdaInventoryItem' } } PdaOperation: type: object required: [operationId, operationType, businessKey, status, occurredAt] properties: operationId: { type: integer, format: int64 } operationType: { type: string } businessKey: { type: string } status: { type: string } summary: { type: string, nullable: true } customerId: { type: string, nullable: true } occurredAt: { type: string, format: date-time } PdaInventoryScanApiResponse: allOf: - { $ref: '#/components/schemas/ReceivingApiResponseBase' } - type: object properties: { data: { $ref: '#/components/schemas/PdaInventoryScan' } } PdaLocationApiResponse: allOf: - { $ref: '#/components/schemas/ReceivingApiResponseBase' } - type: object properties: { data: { $ref: '#/components/schemas/PdaLocation' } } PdaPalletApiResponse: allOf: - { $ref: '#/components/schemas/ReceivingApiResponseBase' } - type: object properties: { data: { $ref: '#/components/schemas/PdaPallet' } } PdaOperationPageApiResponse: allOf: - { $ref: '#/components/schemas/ReceivingApiResponseBase' } - type: object properties: data: type: object required: [records, page, size, total, pages] properties: records: { type: array, items: { $ref: '#/components/schemas/PdaOperation' } } page: { type: integer } size: { type: integer } total: { type: integer, format: int64 } pages: { type: integer, format: int64 } ReceivingAction: type: object required: [idempotencyKey] properties: { idempotencyKey: { type: string, minLength: 1, maxLength: 255 } } ReceivingComplete: type: object required: [allowDifference, idempotencyKey] properties: allowDifference: { type: boolean } idempotencyKey: { type: string, minLength: 1, maxLength: 255 } ReceivingSign: type: object required: [photos, idempotencyKey] properties: photos: { type: array, minItems: 3, maxItems: 3, items: { $ref: '#/components/schemas/ReceivingSignedPhoto' } } idempotencyKey: { type: string, minLength: 1, maxLength: 255 } ReceivingSignedPhoto: type: object required: [role, fileId] properties: role: { type: string, enum: [LICENSE_PLATE, CONTAINER_SEAL, DOOR_OPEN] } fileId: { type: string, pattern: '^[1-9][0-9]{0,18}$', description: Snowflake file ID kept as a decimal string } ReceivingSignedSessionPhoto: type: object required: [role, fileId, downloadPath] properties: role: { type: string, enum: [LICENSE_PLATE, CONTAINER_SEAL, DOOR_OPEN] } fileId: { type: string, pattern: '^[1-9][0-9]{0,18}$', description: Snowflake file ID kept as a decimal string } downloadPath: { type: string, description: 用于会话恢复时直接下载签收照片 } ReceivingBulk: type: object required: [inboundCode, palletCode, packageCount, idempotencyKey] properties: inboundCode: { type: string, minLength: 1 } palletCode: { type: string, minLength: 1 } packageCount: { type: integer, minimum: 1, maximum: 66 } expectedPalletVersion: { type: integer, minimum: 0, nullable: true } idempotencyKey: { type: string, minLength: 1, maxLength: 255 } ReceivingCarton: type: object required: [cartonMark, palletCode, idempotencyKey] properties: cartonMark: { type: string, minLength: 1 } palletCode: { type: string, minLength: 1 } idempotencyKey: { type: string, minLength: 1, maxLength: 255 } ReceivingWholePallet: type: object required: [sourcePalletNo, idempotencyKey] properties: sourcePalletNo: { type: string, minLength: 1 } idempotencyKey: { type: string, minLength: 1, maxLength: 255 } ReceivingApiResponseBase: type: object required: [code, message, timestamp] properties: code: { type: string, example: '200' } message: { type: string } requestId: { type: string, nullable: true } traceId: { type: string, nullable: true } timestamp: { type: string, format: date-time } ReceivingInbound: type: object required: [inboundCode, destinationType, plannedPalletCount, totalPackages, receivedPackages, pendingPackages, assigned, mergeAllowed, urgent, wholePalletInbound] properties: inboundCode: { type: string } destinationType: { type: string, enum: [FBA, OVERSEAS] } overseasWarehouseId: { type: string, nullable: true, description: 实际海外收货仓ID;与FBA或其他业务目的仓ID严格区分 } overseasWarehouseName: { type: string, nullable: true, description: 实际海外收货仓名称快照 } destinationWarehouseId: { type: string, nullable: true } destinationWarehouseCode: { type: string, nullable: true } destinationWarehouseName: { type: string, nullable: true } fbaWarehouseCode: { type: string, nullable: true } plannedPalletCount: { type: integer } totalPackages: { type: integer } receivedPackages: { type: integer } pendingPackages: { type: integer } assigned: { type: boolean, description: 入库计划是否已分配 } mergeAllowed: { type: boolean, description: 入库计划是否允许现场选择合托;true不代表强制合托 } urgent: { type: boolean, description: 入库计划是否加急 } mergeHint: { type: string, nullable: true, description: 允许合托时供PDA直接展示的非强制中文提示 } ReceivingWarehouseProfile: type: object required: [warehouseId, warehouseCode, warehouseName] properties: warehouseId: { type: string, pattern: '^\d+$' } warehouseCode: { type: string } warehouseName: { type: string, description: 国内Warehouse Service主档维护的当前中文名称 } ReceivingCandidate: type: object required: [sourceContainerBookingId, containerNo, overseasWarehouseCode, overseasWarehouseName, status, totalOrderCount, inboundCodeCount, missingInboundCodeCount, planCount, plannedInboundCodeCount, pendingPlanCount, destinationCodes, plannedPalletCount, totalPackages, receivedPackages, operable, allPlansReady, currentAccount] properties: sourceContainerBookingId: { type: string, description: 头程与尾程共享的稳定柜身份 } containerNo: { type: string } overseasWarehouseCode: { type: string } overseasWarehouseName: { type: string } status: { type: string, enum: [WAIT_SIGN, SIGNED, RECEIVING, COMPLETED] } totalOrderCount: { type: integer, minimum: 1 } missingInboundCodeCount: { type: integer, minimum: 0 } planCount: { type: integer } inboundCodeCount: { type: integer } plannedInboundCodeCount: { type: integer, minimum: 0 } pendingPlanCount: { type: integer, minimum: 0 } destinationCodes: { type: array, uniqueItems: true, items: { type: string } } plannedPalletCount: { type: integer } totalPackages: { type: integer } receivedPackages: { type: integer } operable: { type: boolean } allPlansReady: { type: boolean } blockReason: { type: string, nullable: true } plannedArrivalAt: { type: string, format: date-time, nullable: true } currentAccount: { type: boolean } ReceivingSession: type: object required: [containerNo, overseasWarehouseId, overseasWarehouseCode, overseasWarehouseName, status, version, photos, domesticLoadingPhotos, totalPackages, receivedPackages, pendingPackages, hasDifference, inbounds] properties: containerNo: { type: string } overseasWarehouseId: { type: string, pattern: '^\d+$', description: 平台预分配并与PDA Token匹配的海外接柜仓ID } overseasWarehouseCode: { type: string, description: 海外接柜仓业务编码快照 } overseasWarehouseName: { type: string, description: Warehouse Overseas服务校验后的共享实际海外收货仓名称快照 } status: { type: string, enum: [WAIT_SIGN, SIGNED, RECEIVING, COMPLETED, COMPLETED_WITH_DIFFERENCE] } operatorName: { type: string, nullable: true } version: { type: integer } photos: { type: array, maxItems: 3, items: { $ref: '#/components/schemas/ReceivingSignedSessionPhoto' } } domesticLoadingPhotos: { type: array, maxItems: 5, items: { $ref: '#/components/schemas/DomesticLoadingPhoto' }, description: 当前物理柜国内装柜五类只读照片,不含客户信息与内部文件ID } preparedAt: { type: string, format: date-time, nullable: true } signedAt: { type: string, format: date-time, nullable: true } receivingAt: { type: string, format: date-time, nullable: true } completedAt: { type: string, format: date-time, nullable: true } totalPackages: { type: integer } receivedPackages: { type: integer } pendingPackages: { type: integer } hasDifference: { type: boolean, description: 是否存在短少或普通FBA超收差异 } inbounds: { type: array, items: { $ref: '#/components/schemas/ReceivingInbound' } } ReceivingPhoto: type: object required: [fileId, fileName, contentType, sizeBytes] properties: fileId: { type: string, pattern: '^[1-9][0-9]{0,18}$', description: Snowflake file ID kept as a decimal string } fileName: { type: string } contentType: { type: string } sizeBytes: { type: integer, format: int64 } DomesticLoadingPhoto: type: object required: [evidenceType, label, downloadPath] properties: evidenceType: { type: string, enum: [PHOTO_STEP_1, PHOTO_STEP_2, PHOTO_STEP_3, PHOTO_STEP_4, SEAL] } label: { type: string, enum: [空仓, 半仓, 满仓, 锁仓, 带锁码] } downloadPath: { type: string, description: 当前接柜会话鉴权下载路径 } ReceivingCartonResolved: allOf: - { $ref: '#/components/schemas/ReceivingInbound' } - type: object required: [cartonMark, operationMode, groupKey, inboundCodes] properties: cartonMark: { type: string } operationMode: { type: string, enum: [DROPSHIP_PALLET, FBA_GROUP], nullable: true } groupKey: { type: string, nullable: true } inboundCodes: { type: array, items: { type: string } } sourcePalletNo: { type: string, nullable: true } ReceivingPalletResolved: type: object required: [palletCode, warehouseId, status, inboundCode, destinationType, compatible, version, currentReceivedPackages] properties: palletCode: { type: string } warehouseId: { type: integer, format: int64 } status: { type: string } fbaWarehouseCode: { type: string, nullable: true } inboundCode: { type: string } destinationType: { type: string, enum: [FBA, OVERSEAS] } compatible: { type: boolean } version: { type: integer, minimum: 0 } currentReceivedPackages: { type: integer, minimum: 0 } ReceivingReceipt: type: object required: [result, containerNo, inboundCode, destinationType, palletCode, acceptedPackages, receivedPackages, pendingPackages, sessionStatus, assigned, mergeAllowed, urgent] properties: result: { type: string } containerNo: { type: string } inboundCode: { type: string } destinationType: { type: string, enum: [FBA, OVERSEAS] } palletCode: { type: string } acceptedPackages: { type: integer } receivedPackages: { type: integer } pendingPackages: { type: integer } sessionStatus: { type: string, enum: [SIGNED, RECEIVING] } assigned: { type: boolean } mergeAllowed: { type: boolean, description: 现场可选择合托,不作为实收或完成门禁 } urgent: { type: boolean } mergeHint: { type: string, nullable: true } orderType: { type: string, nullable: true } wholePalletInbound: { type: boolean, description: 一件代发必须按完整来源托盘扫描收货 } groupKey: { type: string, nullable: true } inboundCodes: { type: array, items: { type: string } } ReceivingCandidateListApiResponse: allOf: - { $ref: '#/components/schemas/ReceivingApiResponseBase' } - type: object required: [data] properties: { data: { type: array, items: { $ref: '#/components/schemas/ReceivingCandidate' } } } ReceivingWarehouseProfileApiResponse: allOf: - { $ref: '#/components/schemas/ReceivingApiResponseBase' } - type: object required: [data] properties: { data: { $ref: '#/components/schemas/ReceivingWarehouseProfile' } } ReceivingSessionApiResponse: allOf: - { $ref: '#/components/schemas/ReceivingApiResponseBase' } - type: object required: [data] properties: { data: { $ref: '#/components/schemas/ReceivingSession' } } ReceivingPhotoApiResponse: allOf: - { $ref: '#/components/schemas/ReceivingApiResponseBase' } - type: object required: [data] properties: { data: { $ref: '#/components/schemas/ReceivingPhoto' } } ReceivingCartonResolvedApiResponse: allOf: - { $ref: '#/components/schemas/ReceivingApiResponseBase' } - type: object required: [data] properties: { data: { $ref: '#/components/schemas/ReceivingCartonResolved' } } ReceivingPalletResolvedApiResponse: allOf: - { $ref: '#/components/schemas/ReceivingApiResponseBase' } - type: object required: [data] properties: { data: { $ref: '#/components/schemas/ReceivingPalletResolved' } } ReceivingReceiptApiResponse: allOf: - { $ref: '#/components/schemas/ReceivingApiResponseBase' } - type: object required: [data] properties: { data: { $ref: '#/components/schemas/ReceivingReceipt' } } DispatchUpdate: type: object x-java-record: DispatchCommands.Update properties: recordVersion: oneOf: - type: string pattern: ^[0-9]+$ - type: integer minimum: 0 description: 已有单写入必填;0合法。响应Long按十进制字符串输出。 idempotencyKey: type: string vehicle: allOf: - $ref: '#/components/schemas/DispatchVehicle' nullable: true driver: allOf: - $ref: '#/components/schemas/DispatchDriver' nullable: true plannedDepartureAt: type: string format: date-time nullable: true estimatedArrivalAt: type: string format: date-time nullable: true remark: type: string nullable: true maintenance: allOf: - $ref: '#/components/schemas/DispatchMaintenance' nullable: true description: 本趟可空补充资料,八字段均可空;空白字符串规范为null,不替代正式FBA预约或实际发车时间。 required: - recordVersion - idempotencyKey DeliveryStatusChange: type: object required: [status, expectedVersion] properties: status: { type: string, enum: [WAIT_DELIVERY, DELIVERING, REJECTED] } expectedVersion: { type: integer, format: int64, minimum: 0 } remark: { type: string, nullable: true, maxLength: 500 } DeliveryAllowedAction: type: string enum: [START_DELIVERY, REJECT_DELIVERY, MARK_RETURN] description: START/REJECT 仅在关联出库已实际 OUTBOUNDED 后使用通用 status 接口;取消统一经未执行出库取消命令;MARK_RETURN 使用 mark-return 接口;派送完成由签收资料保存成功自动触发。 DeliveryMarkReturn: type: object required: [lastMileOrderId, reason, returnDirection, items, idempotencyKey] description: 按候选中真实尾程主单定位;普通及退货换标主单无需普通入仓单,不接受虚构入仓关系。 properties: lastMileOrderId: { type: string, pattern: '^[1-9][0-9]*$' } reason: { type: string, minLength: 1, maxLength: 1000 } returnDirection: { type: string, enum: [OVERSEAS_WAREHOUSE, CUSTOMER, OTHER] } returnLogisticsNo: { type: string, nullable: true, maxLength: 128 } idempotencyKey: { type: string, minLength: 1, maxLength: 255 } items: type: array minItems: 1 maxItems: 200 items: type: object required: [outboundPalletItemId, packageCount] properties: outboundPalletItemId: { type: string, pattern: '^[1-9][0-9]*$' } inventoryPositionId: { type: string, nullable: true, pattern: '^[1-9][0-9]*$', description: 普通库存来源;与returnCartonId必须二选一 } returnCartonId: { type: string, nullable: true, pattern: '^[1-9][0-9]*$', description: 原生退货箱来源;按整箱实收,不得虚构库存仓位 } packageCount: { type: integer, format: int64, minimum: 1 } ExceptionStartProcessing: type: object required: [expectedVersion, idempotencyKey] properties: expectedVersion: { type: integer, format: int64, minimum: 0 } idempotencyKey: { type: string, minLength: 1, maxLength: 255 } handlingAction: { type: string, nullable: true, maxLength: 1000 } ExceptionCancel: type: object required: [expectedVersion, idempotencyKey, reason] properties: expectedVersion: { type: integer, format: int64, minimum: 0 } idempotencyKey: { type: string, minLength: 1, maxLength: 255 } reason: { type: string, minLength: 1, maxLength: 1000 } ExceptionComplete: type: object required: [expectedVersion, idempotencyKey, handlingResult, evidenceFileIds] properties: expectedVersion: { type: integer, format: int64, minimum: 0 } idempotencyKey: { type: string, minLength: 1, maxLength: 255 } handlingResult: { type: string, minLength: 1, maxLength: 2000 } evidenceFileIds: { type: array, minItems: 1, maxItems: 20, items: { type: string } } receipts: type: array maxItems: 200 items: type: object required: [outboundPalletItemId, receivedPackages, targetPalletId, targetPalletNo, targetLocationId, targetLocationCode] properties: outboundPalletItemId: { type: string, pattern: '^[1-9][0-9]*$' } inventoryPositionId: { type: string, nullable: true, pattern: '^[1-9][0-9]*$', description: 普通库存来源;与returnCartonId必须二选一 } returnCartonId: { type: string, nullable: true, pattern: '^[1-9][0-9]*$', description: 原生退货箱来源;按整箱实收,不得虚构库存仓位 } receivedPackages: { type: integer, format: int64, minimum: 1 } targetPalletId: { type: string, pattern: '^[1-9][0-9]*$' } targetPalletNo: { type: string, minLength: 1, maxLength: 128 } targetLocationId: { type: string, pattern: '^[1-9][0-9]*$' } targetLocationCode: { type: string, minLength: 1, maxLength: 128 } ExceptionAllowedAction: type: string enum: [START_PROCESSING, COMPLETE_EXCEPTION, CANCEL_EXCEPTION] DeliveryFeeInput: type: object required: [feeType, feeName, direction, currency, amount] properties: feeType: { type: string, maxLength: 64 } feeName: { type: string, maxLength: 128 } direction: { type: string, enum: [RECEIVABLE, PAYABLE] } currency: { type: string, enum: [CNY, USD] } amount: { type: number, minimum: 0, exclusiveMinimum: true } supplierId: { type: string, pattern: '^[1-9][0-9]*$' } supplierName: { type: string, maxLength: 200 } supplierCategory: { type: string, maxLength: 32 } settlementMode: { type: string, enum: [BILL, WALLET, ON_ACCOUNT, DIRECT_PAID], nullable: true, description: 应收可选推送结算或余额扣费;应付使用账期或已付 } chargeableQuantity: { type: number, minimum: 0, exclusiveMinimum: true } quantityUnit: { type: string, maxLength: 32 } unitPrice: { type: number, minimum: 0, exclusiveMinimum: true } periodStart: { type: string, format: date } periodEnd: { type: string, format: date } remark: { type: string, nullable: true, maxLength: 500 } OneClickOutboundCreate: type: object description: 同一幂等键只重放相同请求;收件人、明细、箱唛或备注变化返回 A0409。 required: [recipient, items, idempotencyKey] properties: recipient: { type: string, maxLength: 1000 } remark: { type: string, nullable: true, maxLength: 1000 } idempotencyKey: { type: string, minLength: 1, maxLength: 255 } items: type: array minItems: 1 maxItems: 200 items: type: object required: [inventoryPositionId, packages, sku] properties: inventoryPositionId: { type: string, pattern: '^[1-9][0-9]*$' } packages: { type: integer, format: int64, minimum: 1 } sku: { type: string, maxLength: 128 } cartonMarks: type: array maxItems: 200 description: 指定出库箱唛,提供时必须唯一且与箱数一致。 items: { type: string, minLength: 1, maxLength: 128 } OneClickOutboundCandidate: type: object required: [inventoryPositionId, overseasWarehouseId, palletNo, skuCode, availablePackages, grossWeightKg, volumeWeightKg, volumeCbm] properties: inventoryPositionId: { type: string, pattern: '^[1-9][0-9]*$', description: 创建命令提交键,不作为用户展示编号 } overseasWarehouseId: { type: string } overseasWarehouseName: { type: string, nullable: true } palletNo: { type: string } inboundCode: { type: string, nullable: true } skuCode: { type: string } productName: { type: string, nullable: true } availablePackages: { type: integer, format: int64, minimum: 1, description: 库存位置、SKU余额和AVAILABLE箱唛三者的可用最小值 } grossWeightKg: { type: number, minimum: 0, description: 当前可出箱数按装柜实装箱数比例分摊的毛重 } volumeWeightKg: { type: number, minimum: 0, description: 当前可出箱数按装柜实装箱数比例分摊的材积重 } volumeCbm: { type: number, minimum: 0, description: 当前可出箱数按装柜实装箱数比例分摊的体积 } OutboundCancel: type: object required: [reason] properties: { reason: { type: string, minLength: 1, maxLength: 1000 } } DispatchBatchSource: type: object x-java-record: DispatchContracts.BatchSource properties: sourceKey: type: string nullable: true destinationKey: type: string nullable: true packageCount: type: integer required: - sourceKey - destinationKey - packageCount DispatchBatchReference: type: object x-java-record: DispatchContracts.BatchReference properties: batchKey: type: string nullable: true batchNo: type: string nullable: true customerId: type: string nullable: true sources: type: array items: $ref: '#/components/schemas/DispatchBatchSource' nullable: true recordVersion: oneOf: - type: string pattern: ^[0-9]+$ - type: integer minimum: 0 description: 所属batchKey的权威版本,必填且0合法;FBA取原预约版本,自动DISPATCH引用取真实主单版本。不能使用外层整车版本、客户端时间或默认0替代。Long响应保留十进制字符串。 required: - batchKey - batchNo - customerId - sources - recordVersion description: 服务端权威批次引用,包含来源集合及所属批次原版本;显示预约号不能替代batchKey。 DispatchReview: type: object x-java-record: DispatchContracts.Review properties: status: allOf: - $ref: '#/components/schemas/DispatchReviewStatus' nullable: true reason: type: string nullable: true reviewerId: type: string nullable: true reviewedAt: type: string format: date-time nullable: true reviewRound: type: string pattern: ^[0-9]+$ basisHash: type: string nullable: true invalidatedReason: type: string nullable: true attachments: $ref: '#/components/schemas/DispatchReviewAttachments' required: - attachments - status - reason - reviewerId - reviewedAt - reviewRound - basisHash - invalidatedReason RelabelStatus: { type: string, enum: [PENDING_REVIEW, PENDING_PROCESSING, PROCESSING, CUSTOMER_CONFIRM_PENDING, READY_FOR_OUTBOUND, COMPLETED, REJECTED, CANCELLED] } RelabelMerchantPageResponse: allOf: - { $ref: '#/components/schemas/MerchantApiResponse' } - type: object properties: { data: { $ref: '#/components/schemas/RelabelMerchantPage' } } RelabelMerchantPage: type: object properties: page: { type: integer } size: { type: integer } total: { type: integer, format: int64 } records: { type: array, items: { $ref: '#/components/schemas/RelabelSummary' } } RelabelMerchantDetailResponse: allOf: - { $ref: '#/components/schemas/MerchantApiResponse' } - type: object properties: { data: { $ref: '#/components/schemas/RelabelDetail' } } RelabelSummary: type: object properties: id: { type: string } relabelNo: { type: string } lastlegOrderNo: { type: string, nullable: true } customerOrderNo: { type: string } overseasWarehouseId: { type: string } labelDeadline: { type: string, format: date-time } status: { $ref: '#/components/schemas/RelabelStatus' } itemCount: { type: integer } skuCodes: { type: string, description: 汇总全部箱内 skuItems 的旧 SKU 并去重,以逗号分隔;无 SKU 换标子明细时汇总主明细 SKU } totalPackageCount: { type: integer } notifiedPackageCount: { type: integer } productNameZh: { type: string, description: 明细非空中文品名按原顺序去重并以顿号连接 } labelRequirement: { type: string, description: 明细非空贴标要求按原顺序去重并以中文分号连接 } deliveryMethod: { type: string, nullable: true, enum: [TRUCK, EXPRESS, PICKUP, AMAZON_PICKUP, CUSTOMER_PICKUP], description: 仅TRUCK进入平台预排车;快递及全部自提直接创建出库任务 } printShippingLabel: { type: boolean } shippingLabelFileId: { type: string, nullable: true } fulfillmentStatus: { type: string, nullable: true, enum: [WAIT_RELABEL, WAIT_PRE_DISPATCH, WAIT_TRANSFER_OUTBOUND, READY_FOR_OUTBOUND, OUTBOUND_CREATED, OUTBOUNDED, COMPLETED] } outboundOrderNo: { type: string, nullable: true } customerConfirmedAt: { type: string, format: date-time, nullable: true } reviewChannel: { type: string, enum: [TAIL_ORDER, RELABEL_ORDER], description: TAIL_ORDER 表示客户直接贴标,RELABEL_ORDER 表示其他业务关联换标 } reviewRemark: { type: string, nullable: true, description: 当前驳回状态最近一次审核驳回原因 } reviewedAt: { type: string, format: date-time, nullable: true, description: 最近一次申请审核通过或驳回时间 } relabelCompletedAt: { type: string, format: date-time, nullable: true, description: 本轮贴标作业提交完成时间,退回重做后完成前为空 } outboundAt: { type: string, format: date-time, nullable: true, description: 实际出库时间,无需出库的纯 SKU 贴标完成不会产生出库时间 } createdAt: { type: string, format: date-time } RelabelDetail: type: object properties: application: { $ref: '#/components/schemas/RelabelSummary' } remark: { type: string, nullable: true } items: { type: array, items: { $ref: '#/components/schemas/RelabelItem' } } history: { type: array, items: { $ref: '#/components/schemas/RelabelHistory' } } completionEvidence: { $ref: '#/components/schemas/RelabelCompletionEvidence' } RelabelHistory: type: object properties: fromStatus: { type: string, nullable: true } toStatus: { type: string } operatorId: { type: string } remark: { type: string, nullable: true } createdAt: { type: string, format: date-time } RelabelCompletionEvidence: type: object nullable: true properties: taskId: { type: string, nullable: true } photoFileIds: { type: array, items: { type: string } } completionRemark: { type: string, nullable: true } reviewerName: { type: string, nullable: true } reviewRemark: { type: string, nullable: true } completedAt: { type: string, format: date-time, nullable: true } RelabelInventoryCandidate: type: object properties: cartonAvailablePackages: { type: integer, format: int64, minimum: 0, maximum: 1, description: 仅换箱唛可选择的当前实物箱数;已换 SKU 不影响可选箱数,占用和合箱预留仍不可选 } cartonSkuItems: type: array description: 当前实物箱内全部 SKU 和件数,包含换标后的新 SKU items: type: object properties: skuCode: { type: string } quantity: { type: integer, minimum: 1 } skuConversions: { type: array, items: { $ref: '#/components/schemas/ReturnSkuConversion' }, description: 当前实物关联的旧新SKU转换、实际件数和客户确认状态 } relabelStatus: { type: string, nullable: true, enum: [UNLABELLED, PROCESSING, PARTIALLY_COMPLETED, COMPLETED], description: 退货实物按实际完成件数和未完成申请占用计算 } relabelledPackages: { type: integer, format: int64, description: 退货实际已完成商品换标件数,不从可用库存差值推导 } relabelledQuantity: { type: integer, format: int64, minimum: 0 } relabelReservedQuantity: { type: integer, format: int64, minimum: 0, description: 未完成申请件数,取消或完成后释放 } inventoryBalanceId: { type: string } inboundOrderId: { type: string } inboundOrderNo: { type: string } inboundCode: { type: string } overseasWarehouseId: { type: string } overseasWarehouseCode: { type: string } overseasWarehouseName: { type: string } destinationFbaWarehouseCode: { type: string, nullable: true } destinationFbaWarehouseName: { type: string, nullable: true } skuCode: { type: string, nullable: true } productNameZh: { type: string } availablePackages: { type: integer, format: int64 } version: { type: integer, format: int64 } positions: { type: array, items: { $ref: '#/components/schemas/RelabelInventoryPosition' } } sourceType: { type: string, enum: [INBOUND, RETURN_CARTON, RETURN_PARCEL], description: RETURN_PARCEL与RETURN_CARTON均支持整实体箱唛、SKU或混贴,实物单位计1;SKU按件,编码转换保留原识别码及总件数,部分出库需先隔离为独立新箱 } returnCartonId: { type: string, nullable: true, description: 退货合箱库存主键;sourceType=RETURN_CARTON 时提供 } cartonMark: { type: string, nullable: true, description: 仓库合箱后打印并贴箱的仓库唛头 } skuItems: type: array description: 退货箱内 SKU 与件数 items: type: object properties: skuCode: { type: string } newSkuCode: { type: string, nullable: true } quantity: { type: integer, minimum: 1 } remark: { type: string, nullable: true } ReturnSkuConversion: type: object properties: relabelNo: { type: string } cartonMark: { type: string, description: 完工时的包裹或箱识别码 } oldSkuCode: { type: string } newSkuCode: { type: string } quantity: { type: integer, format: int64, minimum: 1 } status: { type: string, enum: [APPLIED, CONFIRMED, REVERSED] } completedAt: { type: string, format: date-time } RelabelInventoryPosition: type: object properties: positionId: { type: string } palletNo: { type: string, nullable: true } batchNo: { type: string, nullable: true } warehouseLocationCode: { type: string, nullable: true } availablePackages: { type: integer, format: int64 } RelabelSubOrder: type: object description: 同一主单可分批生成多张换标申请;各自保留独立状态,取消或完成子单不会覆盖主单签收状态。 properties: lastlegOrderId: { type: string } relabelNo: { type: string } status: { type: string } quantity: { type: integer, description: 本次申请数量 } createdAt: { type: string, format: date-time } RelabelHistoricalOrder: type: object properties: id: { type: string, nullable: true } orderNo: { type: string } sourceOrderNo: { type: string, nullable: true } outboundOrderNo: { type: string, nullable: true } relabelOrderNo: { type: string, nullable: true } orderType: { type: string, nullable: true } status: { type: string, nullable: true } packageCount: { type: integer, nullable: true } createdAt: { type: string, format: date-time, nullable: true } RelabelCustomerConfirm: type: object required: [idempotencyKey] properties: idempotencyKey: { type: string, maxLength: 255 } remark: { type: string, nullable: true, maxLength: 1000 } RelabelCreate: type: object required: [customerOrderNo, operationWarehouseId, labelDeadline, contactName, contactPhone, idempotencyKey, items] properties: customerOrderNo: { type: string, maxLength: 128 } operationWarehouseId: { type: string, maxLength: 128, description: 当前库存所在海外操作仓 } labelDeadline: { type: string, format: date-time } contactName: { type: string, maxLength: 128 } contactPhone: { type: string, maxLength: 64 } chargeAmount: { type: number, nullable: true, minimum: 0.01, description: 换标报价快照(CNY);不自动冻结或收费,应收由海外费用登记审核 } remark: { type: string, nullable: true, maxLength: 1000 } idempotencyKey: { type: string, maxLength: 255 } deliveryMethod: { type: string, nullable: true, enum: [TRUCK, EXPRESS, AMAZON_PICKUP, CUSTOMER_PICKUP, PICKUP], description: 只换箱唛或SKU与箱唛同时换时必填;只换SKU时不传;仅TRUCK进入平台预排车,其余方式直接创建出库任务 } printShippingLabel: { type: boolean, default: false, description: 仅快递派送可选,客户确认前必须已上传面单 } items: { type: array, minItems: 1, maxItems: 500, items: { $ref: '#/components/schemas/RelabelItem' } } RelabelItem: type: object required: [productNameZh, totalPackageCount, notifiedPackageCount, shipmentNo, newSkuCode, cartonMark, fbaCartonMark] properties: sourceInventoryBalanceId: { type: string, nullable: true, description: 普通入仓库存来源;与 returnCartonId 二选一 } sourceInventoryPositionId: { type: string, nullable: true, description: 普通入仓库存仓位;与 returnCartonId 二选一 } sourceInboundOrderId: { type: string, nullable: true, description: 普通入仓单;与 returnCartonId 二选一 } returnCartonId: { type: string, nullable: true, description: 仓库合箱产生的退货箱库存;与普通入仓库存字段二选一 } skuCode: { type: string, nullable: true, maxLength: 128, description: 商品 SKU(选填) } productImageFileId: { type: string, nullable: true, maxLength: 128 } productImageFileName: { type: string, nullable: true, maxLength: 255 } productImageUrl: { type: string, nullable: true, maxLength: 1000 } productNameZh: { type: string, maxLength: 255 } totalPackageCount: { type: integer, minimum: 1 } notifiedPackageCount: { type: integer, minimum: 1 } shipmentNo: { type: string, maxLength: 128 } trackingCode: { type: string, nullable: true, maxLength: 255 } newSkuCode: { type: string, maxLength: 128 } labelRequirement: { type: string, nullable: true, maxLength: 1000 } relabelFileId: { type: string, nullable: true, maxLength: 128 } relabelFileName: { type: string, nullable: true, maxLength: 255 } relabelFileUrl: { type: string, nullable: true, maxLength: 1000 } cartonMark: { type: string, maxLength: 255, description: 客户自有箱唛(不在编辑列表展示) } fbaCartonMark: { type: string, maxLength: 255, description: 关联 FBA 箱唛 } destinationWarehouseId: { type: string, nullable: true, maxLength: 128, description: 该箱目的海外仓;为空时使用申请统一目的仓 } RelabelStatusChange: type: object required: [status] properties: status: { $ref: '#/components/schemas/RelabelStatus' } remark: { type: string, nullable: true, maxLength: 1000 } RelabelResubmit: type: object required: [labelDeadline, contactName, contactPhone, idempotencyKey] properties: labelDeadline: { type: string, format: date-time } contactName: { type: string, minLength: 1, maxLength: 128 } contactPhone: { type: string, minLength: 1, maxLength: 64 } remark: { type: string, nullable: true, maxLength: 1000 } idempotencyKey: { type: string, minLength: 1, maxLength: 255 } WalletFreezeRetry: type: object required: [idempotencyKey] properties: idempotencyKey: { type: string, minLength: 1, maxLength: 255 } remark: { type: string, nullable: true, maxLength: 1000 } MerchantApiResponse: type: object required: [code, data] properties: code: { type: string, example: '200' } message: { type: string, nullable: true } data: { nullable: true } requestId: { type: string, nullable: true } traceId: { type: string, nullable: true } timestamp: { type: string, format: date-time, nullable: true } ProcurementPageResponse: allOf: - { $ref: '#/components/schemas/MerchantApiResponse' } - type: object properties: { data: { $ref: '#/components/schemas/ProcurementPage' } } TruckPageResponse: allOf: - { $ref: '#/components/schemas/MerchantApiResponse' } - type: object properties: { data: { $ref: '#/components/schemas/TruckPage' } } TruckDetailResponse: allOf: - { $ref: '#/components/schemas/MerchantApiResponse' } - type: object properties: { data: { $ref: '#/components/schemas/TruckDetail' } } LooseboardPageResponse: allOf: - { $ref: '#/components/schemas/MerchantApiResponse' } - type: object properties: { data: { $ref: '#/components/schemas/LooseboardPage' } } LooseboardDetailResponse: allOf: - { $ref: '#/components/schemas/MerchantApiResponse' } - type: object properties: { data: { $ref: '#/components/schemas/LooseboardDetail' } } InboundPlanPageResponse: allOf: - { $ref: '#/components/schemas/MerchantApiResponse' } - type: object properties: { data: { $ref: '#/components/schemas/InboundPlanPage' } } InboundPlanDetailResponse: allOf: - { $ref: '#/components/schemas/MerchantApiResponse' } - type: object properties: { data: { $ref: '#/components/schemas/InboundPlanDetail' } } ContainerInboundPlanPreviewApiResponse: allOf: - { $ref: '#/components/schemas/MerchantApiResponse' } - type: object properties: { data: { $ref: '#/components/schemas/ContainerInboundPlanPreview' } } LastlegOrderHoldRequest: type: object required: [held, chargeable, reason, expectedVersion] properties: held: { type: boolean } chargeable: { type: boolean, description: 仅 held=true 时生效;解除暂扣后固定为 false } reason: { type: string, minLength: 1, maxLength: 500 } expectedVersion: { type: integer, minimum: 0 } LastlegOrderHoldResponse: type: object required: [orderId, held, chargeable, version] properties: orderId: { type: integer, format: int64 } held: { type: boolean } chargeable: { type: boolean } reason: { type: string, nullable: true } version: { type: integer, minimum: 0 } LastlegOrderManualNodeCode: type: string enum: [DOMESTIC_CUSTOMS_COMPLETED, ESTIMATED_DEPARTURE, ACTUAL_DEPARTURE, ESTIMATED_ARRIVAL, OVERSEAS_CUSTOMS_COMPLETED, ACTUAL_ARRIVAL_WAITING_UNLOAD, PICKUP_APPOINTED, UNLOADED] LastlegOrderManualNode: type: object required: [nodeCode] properties: nodeCode: { $ref: '#/components/schemas/LastlegOrderManualNodeCode' } nodeAt: { type: string, format: date-time, nullable: true } LastlegOrderManualNodesRequest: type: object required: [expectedVersion, nodes] properties: expectedVersion: { type: integer, minimum: 0 } nodes: type: array minItems: 8 maxItems: 8 description: 必须包含8个枚举节点且各出现一次,至少一个 nodeAt 非空。 items: { $ref: '#/components/schemas/LastlegOrderManualNode' } ManualInboundPlanRequest: type: object description: 单票人工计划只能使用所属柜已冻结的接柜仓;接柜仓变更必须通过柜级接口完成。预计到仓日期由共用服务端解析器返回 plannedDate:人工时间或已有计划冻结日期优先,其余按 Firstleg 权威到港当地日期加两个自然日;同柜所有计划保持一致,不接受人工提交,不补造默认时间。 required: [customerId, orderId, expectedOrderVersion, palletCount, palletType, assigned, mergeRequired, urgent] properties: customerId: { type: string, pattern: '^[1-9][0-9]*$' } orderId: { type: integer, format: int64, minimum: 1 } expectedOrderVersion: { type: integer, minimum: 0 } palletCount: { type: integer, minimum: 1, maximum: 999 } palletType: { type: string, minLength: 1, maxLength: 64 } assigned: { type: boolean } mergeRequired: { type: boolean } urgent: { type: boolean } remark: { type: string, nullable: true, maxLength: 1000 } PageMetadata: type: object required: [page, size, total, pages] properties: page: { type: integer, format: int64 } size: { type: integer, format: int64 } total: { type: integer, format: int64 } pages: { type: integer, format: int64 } ProcurementPage: allOf: - { $ref: '#/components/schemas/PageMetadata' } - type: object required: [records] properties: { records: { type: array, items: { $ref: '#/components/schemas/ProcurementSummary' } } } ProcurementDirection: type: string enum: [OVERSEAS_TO_DOMESTIC, DOMESTIC_TO_OVERSEAS] default: OVERSEAS_TO_DOMESTIC description: 海外采购回国内或国内采购发海外;创建可选,待审核时可核定,通过后锁定。历史运输段编码保持不变,区域文案按方向展示。 ProcurementSummary: type: object required: [id, orderNo, customerId, purchaseCategory, productName, purchaseQuantity, status, version, createdAt, updatedAt] properties: procurementDirection: { $ref: '#/components/schemas/ProcurementDirection' } id: { type: string, pattern: '^[0-9]+$' } orderNo: { type: string } customerId: { type: string } customerName: { type: string, nullable: true } purchaseCategory: { type: string } productName: { type: string } productSpecification: { type: string, nullable: true } purchaseQuantity: { type: integer, format: int64 } budgetUnitPrice: { type: number, nullable: true } currency: { type: string, nullable: true } purchaseWarehouseId: { type: string, nullable: true } purchaseWarehouseName: { type: string, nullable: true } status: { type: string, description: 以 ProcurementStatus 中的真实履约阶段返回,不按通用出库数量推断 } version: { type: integer, format: int64 } createdAt: { type: string, format: date-time } updatedAt: { type: string, format: date-time } TruckPage: allOf: - { $ref: '#/components/schemas/PageMetadata' } - type: object required: [records] properties: { records: { type: array, items: { $ref: '#/components/schemas/TruckSummary' } } } TruckSummary: type: object description: 卡车商业主单摘要;池来源附带同客户fleetArrangement,独立订单该字段为null。列表批量查询承运摘要,不逐行请求车次。 required: [id, customerId, orderNo, origin, destination, palletCount, packageCount, receivedPalletCount, allocatedPalletCount, totalWeightKg, totalVolumeCbm, status, version, createdAt, updatedAt] properties: id: { type: string, pattern: '^[0-9]+$' } customerId: { type: string } orderNo: { type: string } vehicleType: { type: string, enum: [PALLET_15, PALLET_30], description: '15拖或30拖;拼车来源未知时为空', nullable: true } origin: { type: string } destination: { type: string } palletCount: { type: integer, description: 已确认托数;新建独立订单为0,首次实收确定,不从车型推导 } packageCount: { type: integer } receivedPalletCount: { type: integer } allocatedPalletCount: { type: integer } totalWeightKg: { type: number } totalVolumeCbm: { type: number } budgetAmount: { type: number, nullable: true } currency: { type: string, nullable: true } originContactName: { type: string, nullable: true, maxLength: 128 } originContactPhone: { type: string, nullable: true, maxLength: 128 } destinationContactName: { type: string, nullable: true, maxLength: 128 } destinationContactPhone: { type: string, nullable: true, maxLength: 128 } pickupAt: { type: string, nullable: true, format: date-time, description: '取货日期时分,使用无偏移量的本地时间,不转换时区' } deliveryAt: { type: string, nullable: true, format: date-time, description: '送货日期时分,不能早于取货时间,不转换时区' } status: { $ref: '#/components/schemas/TruckStatus' } version: { type: integer, format: int64 } createdAt: { type: string, format: date-time } updatedAt: { type: string, format: date-time } fleetArrangement: { $ref: '#/components/schemas/FleetArrangement' } TruckDetail: type: object description: 承运安排位于summary.fleetArrangement,与列表摘要使用同一真实来源;根对象不重复该字段。池来源手工状态入口禁止旁路实际履约。 required: [summary, pallets, histories] properties: summary: { $ref: '#/components/schemas/TruckSummary' } originAddress: { type: string, nullable: true } destinationAddress: { type: string, nullable: true } remark: { type: string, nullable: true } createdBy: { type: string, nullable: true } pallets: { type: array, items: { $ref: '#/components/schemas/TruckPallet' } } histories: { type: array, items: { $ref: '#/components/schemas/BusinessHistory' } } TruckPallet: type: object properties: id: { type: string, pattern: '^[0-9]+$' } palletNo: { type: string } sequenceNo: { type: integer } source: { type: string } status: { type: string } warehousePalletId: { type: string, pattern: '^[0-9]+$', nullable: true } packageCount: { type: integer, nullable: true } receivedAt: { type: string, format: date-time, nullable: true } LooseboardPage: allOf: - { $ref: '#/components/schemas/PageMetadata' } - type: object required: [records] properties: { records: { type: array, items: { $ref: '#/components/schemas/LooseboardSummary' } } } LooseboardSummary: type: object description: 散板商业主单摘要;池来源附带同客户fleetArrangement,独立订单该字段为null。池来源不创建第二张占位尾程来源。 required: [id, customerId, orderNo, origin, destination, estimatedPalletCount, packageCount, totalWeightKg, totalVolumeCbm, status, version, createdAt, updatedAt] properties: id: { type: string, pattern: '^[0-9]+$' } customerId: { type: string } orderNo: { type: string } palletRequired: { type: string, nullable: true, enum: [YES, NO], description: 是否委托打盘服务;池询价未提供时未知,不从实托数或托位推断YES } transportType: { type: string, nullable: true } origin: { type: string } destination: { type: string } productName: { type: string, nullable: true, maxLength: 255 } estimatedPalletCount: { type: integer, minimum: 0, description: 申报预计托数,独立于实际收货 } packageCount: { type: integer } totalWeightKg: { type: number } totalVolumeCbm: { type: number } budgetAmount: { type: number, nullable: true } currency: { type: string, nullable: true } originContactName: { type: string, nullable: true } originContactPhone: { type: string, nullable: true } destinationContactName: { type: string, nullable: true } destinationContactPhone: { type: string, nullable: true } pickupAt: { type: string, format: date-time, nullable: true, description: 当地日期时间不带时区;按分钟输入 } deliveryAt: { type: string, format: date-time, nullable: true, description: 当地日期时间,不能早于取货时间 } status: { $ref: '#/components/schemas/LooseboardStatus' } version: { type: integer, format: int64 } createdAt: { type: string, format: date-time } updatedAt: { type: string, format: date-time } fleetArrangement: { $ref: '#/components/schemas/FleetArrangement' } LooseboardDetail: type: object description: 承运安排位于summary.fleetArrangement,与列表摘要使用同一真实来源;根对象不重复该字段。池来源状态只能由实际履约推进。 required: [summary, histories] properties: summary: { $ref: '#/components/schemas/LooseboardSummary' } originAddress: { type: string, nullable: true } destinationAddress: { type: string, nullable: true } remark: { type: string, nullable: true } createdBy: { type: string, nullable: true } histories: { type: array, items: { $ref: '#/components/schemas/BusinessHistory' } } FleetArrangement: type: object nullable: true description: 公司内部拼车成交后的客户隔离承运摘要。无发布池内部ID、他人货物、司机私人信息或采购成本;agreedFreightAmount是约定运费,不代表已收款。未知数量保持null。 required: [sourceType, businessType, businessOrderNo, bookingNo, tripNo, plannedDepartureAt, originWarehouseName, destinationLabel, deliveryMode, fulfillmentStage, stageOccurredAt, readOnlyReason] properties: sourceType: { type: string, enum: [FLEET_CAPACITY_OFFER] } businessType: { type: string, enum: [LOCAL_LOOSEBOARD, US_TRUCK] } businessOrderNo: { type: string } bookingNo: { type: string } tripNo: { type: string } plannedDepartureAt: { type: string, format: date-time, description: UTC Instant,明确包含Z,不将数据库UTC墙钟值当成本地时间 } originWarehouseName: { type: string } destinationLabel: { type: string } deliveryMode: { type: string, enum: [SELF_DELIVERY, MANUAL_PICKUP_TO_WAREHOUSE] } deliveryInstructions: { type: string, nullable: true } fulfillmentStage: { type: string, enum: [WAITING_INBOUND, RECEIVING, WAITING_CONSOLIDATION, PENDING_DISPATCH, IN_TRANSIT, COMPLETED, CANCELLED] } stageOccurredAt: { type: string, format: date-time, description: 真实履约阶段时间,按业务运行时区转换为Instant } agreedFreightAmount: { type: number, nullable: true } currency: { type: string, nullable: true, enum: [CNY, USD] } incomingNo: { type: string, nullable: true } dispatchNo: { type: string, nullable: true } deliveryNo: { type: string, nullable: true } signedPackages: { type: integer, minimum: 0, nullable: true } unsignedPackages: { type: integer, minimum: 0, nullable: true } returnedPackages: { type: integer, minimum: 0, nullable: true } exceptionSummary: { type: string, nullable: true } readOnlyReason: { type: string } BusinessHistory: type: object properties: operationType: { type: string } fromStatus: { type: string, nullable: true } toStatus: { type: string, nullable: true } operatorId: { type: string, nullable: true } idempotencyKey: { type: string, nullable: true } changeDetail: { type: string, nullable: true } remark: { type: string, nullable: true } createdAt: { type: string, format: date-time } InboundPlanPage: allOf: - { $ref: '#/components/schemas/PageMetadata' } - type: object required: [records] properties: { records: { type: array, items: { $ref: '#/components/schemas/InboundPlanSummary' } } } InboundPlanSummary: type: object required: [lineId, planId, planNo, customerId, orderId, inboundCode, overseasWarehouseCode, overseasWarehouseName, packageCount, pickedPackageCount, grossWeightKg, netWeightKg, palletCount, assigned, mergeAllowed, urgent, status, createdAt, version] properties: lineId: { type: string, pattern: '^[0-9]+$' } planId: { type: string, pattern: '^[0-9]+$' } planNo: { type: string } customerId: { type: string } orderId: { type: string, pattern: '^[0-9]+$' } inboundCode: { type: string } orderType: { type: string, nullable: true } overseasWarehouseId: { type: string, pattern: '^[0-9]+$', nullable: true, description: 入库计划冻结的接柜海外仓ID,不是FBA目的仓ID } overseasWarehouseCode: { type: string, description: 按入库计划冻结接柜仓ID从海外仓权威目录解析的编码 } overseasWarehouseName: { type: string, description: 按入库计划冻结接柜仓ID从海外仓权威目录解析的名称 } warehouseId: { type: string, nullable: true } warehouseCode: { type: string, nullable: true } warehouseName: { type: string, nullable: true } fbaWarehouseCode: { type: string, nullable: true } customerName: { type: string, nullable: true } packageCount: { type: integer } pickedPackageCount: { type: integer } grossWeightKg: { type: number, description: 头程冻结货物毛重(千克) } netWeightKg: { type: number, description: 头程冻结货物净重(千克) } volumeCbm: { type: number, nullable: true } palletCount: { type: integer } assigned: { type: boolean, description: 入库计划是否已分配 } mergeAllowed: { type: boolean, description: 入库计划是否允许现场选择合托;不作为强制门禁 } urgent: { type: boolean, description: 入库计划是否加急 } status: { type: string } appointmentNo: { type: string, nullable: true } appointmentStatus: { type: string, nullable: true } appointmentAt: { type: string, format: date-time, nullable: true } expectedLoadingAt: { type: string, format: date-time, nullable: true } dispatchStatus: { type: string, nullable: true } createdAt: { type: string, format: date-time } version: { type: integer } InboundPlanDetail: type: object required: [id, planNo, customerId, overseasWarehouseCode, overseasWarehouseName, status, lineCount, palletCount, totalGrossWeightKg, totalNetWeightKg, totalVolumeCbm, expectedPackageCount, pickedPackageCount, lines, pallets, allocations, version, createdAt, updatedAt] properties: id: { type: string, pattern: '^[0-9]+$' } planNo: { type: string } customerId: { type: string } sourceOrderId: { type: string, pattern: '^[0-9]+$', nullable: true } sourceOrderNo: { type: string, nullable: true, description: 关联尾程订单业务单号;手工入库计划为空 } customerName: { type: string, nullable: true, description: 货主名称;手工入库计划为空 } orderType: { type: string, nullable: true, description: 关联尾程订单类型;手工入库计划为空 } containerNo: { type: string, nullable: true } overseasWarehouseCode: { type: string, description: 接柜仓编码,取自尾程订单预分配接收仓事实 } overseasWarehouseName: { type: string, description: 接柜仓名称,取自尾程订单预分配接收仓事实 } status: { type: string } lineCount: { type: integer } palletCount: { type: integer } totalGrossWeightKg: { type: number, description: 入库单关联头程货物毛重合计(千克) } totalNetWeightKg: { type: number, description: 入库单关联头程货物净重合计(千克) } totalVolumeCbm: { type: number } expectedPackageCount: { type: integer } pickedPackageCount: { type: integer } plannedArrivalDate: { type: string, format: date, nullable: true } palletType: { type: string, nullable: true } assigned: { type: boolean } mergeRequired: { type: boolean } urgent: { type: boolean } creationMode: { type: string, enum: [AUTO, MANUAL] } remark: { type: string, nullable: true } createdAt: { type: string, format: date-time } updatedAt: { type: string, format: date-time } lines: { type: array, items: { $ref: '#/components/schemas/InboundPlanLine' } } pallets: { type: array, items: { $ref: '#/components/schemas/InboundPlanPallet' } } allocations: { type: array, items: { $ref: '#/components/schemas/InboundPlanAllocation' } } version: { type: integer } ContainerInboundPlanPreview: type: object required: [sourceContainerBookingId, snapshotVersion, snapshotHash, totalOrderCount, readyOrderCount, blockedOrderCount, pendingOrderCount, pendingPalletCount, sourcePalletCount, supplementPalletCount, existingPlannedPalletCount, totalSuggestedPalletCount, totalPlannedPalletCount, ready, groups] properties: sourceContainerBookingId: { type: string } containerNo: { type: string, nullable: true } overseasWarehouseId: { type: string, nullable: true } overseasWarehouseCode: { type: string, nullable: true } overseasWarehouseName: { type: string, nullable: true } snapshotVersion: { type: integer, format: int64, minimum: 0 } snapshotHash: { type: string, pattern: '^[0-9a-f]{64}$' } totalOrderCount: { type: integer } resourceRetry: type: object nullable: true description: 仅本地计划已提交而资源确认未完成时返回原命令。重试必须使用此键和快照,当前外层快照仍用于展示;不得重新生成命令或预留第二批资源。 required: [idempotencyKey, snapshotVersion, snapshotHash] properties: idempotencyKey: { type: string, minLength: 1, maxLength: 128 } snapshotVersion: { type: integer, format: int64, minimum: 0 } snapshotHash: { type: string, pattern: '^[0-9a-f]{64}$' } readyOrderCount: { type: integer } blockedOrderCount: { type: integer } pendingOrderCount: { type: integer, description: 本次确认将新建计划的 READY 订单数 } pendingPalletCount: { type: integer, description: 本次确认最终向资源服务批量预留的托盘总数,包含头程已有编码及海外补充编码 } sourcePalletCount: { type: integer, description: 本次处理订单随头程装柜完成事件冻结并传入的托盘码数 } supplementPalletCount: { type: integer, description: 最终托数超过头程已有托盘码数时,在海外仓连续补充的托盘码数 } existingPlannedPalletCount: { type: integer, description: 已有有效计划的托盘总数,不计入本次新增 } totalSuggestedPalletCount: { type: integer } totalPlannedPalletCount: { type: integer } ready: { type: boolean } groups: { type: array, items: { $ref: '#/components/schemas/ContainerInboundPlanPreviewGroup' } } ContainerInboundPlanPreviewGroup: type: object required: [destinationType, orderCount, pendingOrderCount, pendingPalletCount, sourcePalletCount, supplementPalletCount, existingPlannedPalletCount, suggestedPalletCount, plannedPalletCount, orders] properties: destinationType: { type: string, enum: [FBA, ONE_CLICK_DROPSHIP, PRIVATE_ADDRESS] } destinationWarehouseId: { type: string, nullable: true } destinationWarehouseCode: { type: string, nullable: true } destinationWarehouseName: { type: string, nullable: true } orderCount: { type: integer } pendingOrderCount: { type: integer } pendingPalletCount: { type: integer } sourcePalletCount: { type: integer } supplementPalletCount: { type: integer } existingPlannedPalletCount: { type: integer } suggestedPalletCount: { type: integer } plannedPalletCount: { type: integer } orders: { type: array, items: { $ref: '#/components/schemas/ContainerInboundPlanPreviewOrder' } } ContainerInboundPlanPreviewOrder: type: object required: [customerId, orderId, businessOrderNo, orderType, destinationType, packageCount, volumeCbm, sourcePalletCount, targetPalletCount, supplementPalletCount, orderVersion, readiness, blockers] properties: customerId: { type: string } customerName: { type: string, nullable: true } orderId: { type: string, pattern: '^[0-9]+$' } businessOrderNo: { type: string } inboundCode: { type: string, nullable: true } orderType: { type: string } destinationType: { type: string, enum: [FBA, ONE_CLICK_DROPSHIP, PRIVATE_ADDRESS] } destinationWarehouseId: { type: string, nullable: true } destinationWarehouseCode: { type: string, nullable: true } destinationWarehouseName: { type: string, nullable: true } fbaWarehouseCode: { type: string, nullable: true, description: 底层目的类型为 FBA 时的目的仓编码;一件代发展示分类不改变该事实 } packageCount: { type: integer } volumeCbm: { type: number } suggestedPalletCount: { type: integer, nullable: true } sourcePalletCount: { type: integer, description: 头程已经冻结并传入的托盘码数 } targetPalletCount: { type: integer, description: 本票最终生成的托盘总数,不少于头程已有托盘码数 } supplementPalletCount: { type: integer, description: 本票需要在海外仓连续补充的托盘码数 } plannedPalletCount: { type: integer, nullable: true } existingPlanNo: { type: string, nullable: true } planStatus: { type: string, nullable: true } orderVersion: { type: integer, minimum: 0 } readiness: { type: string, enum: [READY, RESOURCE_PENDING, PLANNED, BLOCKED] } blockers: { type: array, items: { type: string } } InboundPlanLine: type: object properties: id: { type: string, pattern: '^[0-9]+$' } orderId: { type: string, pattern: '^[0-9]+$' } inboundCode: { type: string } fbaWarehouseCode: { type: string, nullable: true } destinationWarehouseId: { type: string, nullable: true } destinationWarehouseCode: { type: string, nullable: true } destinationWarehouseName: { type: string, nullable: true } grossWeightKg: { type: number, description: 本入仓码头程冻结货物毛重(千克) } netWeightKg: { type: number, description: 本入仓码头程冻结货物净重(千克) } volumeCbm: { type: number } requiredPackageCount: { type: integer } plannedPalletCount: { type: integer } InboundPlanPallet: type: object properties: id: { type: string, pattern: '^[0-9]+$' } palletNo: { type: string } palletType: { type: string, nullable: true } destinationWarehouseId: { type: string, nullable: true } destinationWarehouseCode: { type: string, nullable: true } destinationWarehouseName: { type: string, nullable: true } capacityCbm: { type: number } allocatedVolumeCbm: { type: number } sequenceNo: { type: integer } warehousePalletId: { type: string, pattern: '^[0-9]+$', nullable: true } warehouseLocationId: { type: string, pattern: '^[0-9]+$', nullable: true } warehouseResourceLockId: { type: string, pattern: '^[0-9]+$', nullable: true } assignmentStatus: { type: string, nullable: true } lockedAt: { type: string, format: date-time, nullable: true } actualVolumeCbm: { type: number, nullable: true } actualPackageCount: { type: integer } InboundPlanAllocation: type: object properties: lineId: { type: string, pattern: '^[0-9]+$' } palletId: { type: string, pattern: '^[0-9]+$' } palletNo: { type: string, description: 分配实际引用的托盘码,跨计划合托时仍返回真实托盘码 } palletOwnerPlanNo: { type: string, description: 托盘所属入库计划号 } palletOwnedByCurrentPlan: { type: boolean, description: 托盘是否归属当前详情入库计划 } allocatedVolumeCbm: { type: number } plannedPackageCount: { type: integer } countedPackageCount: { type: integer } pickedPackageCount: { type: integer } actualVolumeCbm: { type: number, nullable: true } status: { type: string } version: { type: integer } ProcurementStatus: { type: string, enum: [PENDING_REVIEW, WAIT_PURCHASE, WAIT_OVERSEAS_RECEIPT, OVERSEAS_RECEIVING, WAIT_PACKING, WAIT_LABELS, WAIT_OVERSEAS_DISPATCH, WAIT_OVERSEAS_SHIPMENT, INTERNATIONAL_TRANSIT, DOMESTIC_RECEIVING, WAIT_CHARGES, WAIT_CUSTOMER_DISPATCH, WAIT_CUSTOMER_SHIPMENT, SHIPPED_TO_CUSTOMER, REJECTED, CANCELLED, EXCEPTION_CLOSED] } ProcurementReview: type: object required: [version, decision, idempotencyKey] description: 审核通过必须选择与采购方向匹配的有效公共收货仓;国内采购选择国内仓,海外采购选择海外收货仓;拒绝不要求仓库,但 remark 必须填写非空白拒绝原因。审核不得修改客户下单采购方向。 properties: procurementDirection: { $ref: '#/components/schemas/ProcurementDirection' } version: { type: integer, format: int64, minimum: 0 } decision: { type: string, enum: [APPROVE, REJECT] } idempotencyKey: { type: string, minLength: 1, maxLength: 255 } remark: { type: string, nullable: true, maxLength: 1000 } purchaseWarehouseId: { type: integer, format: int64, minimum: 1, nullable: true } ProcurementCreate: type: object required: [productName, purchaseQuantity, budgetUnitPrice, currency, receivingAddress, contactName, contactPhone, idempotencyKey] properties: procurementDirection: { $ref: '#/components/schemas/ProcurementDirection' } customerName: { type: string, nullable: true, maxLength: 255 } purchaseCategory: { type: string, maxLength: 128 } productName: { type: string, maxLength: 255 } productSpecification: { type: string, nullable: true, maxLength: 500 } productUrl: { type: string, nullable: true, maxLength: 2000 } purchaseQuantity: { type: integer, format: int64, minimum: 1 } budgetUnitPrice: { type: number, minimum: 0, multipleOf: 0.01, description: 客户授权的货款预算单价;零表示仅授权免费样品 } currency: { type: string, enum: [CNY, USD] } receivingAddress: { type: string, minLength: 1, maxLength: 1000, description: 最终客户目的地完整地址;国内采购发海外时填写海外地址 } contactName: { type: string, maxLength: 128 } contactPhone: { type: string, maxLength: 64 } remark: { type: string, nullable: true, maxLength: 1000 } idempotencyKey: { type: string, maxLength: 255 } NullableTextPatch: { type: string, nullable: true, description: 缺失不修改;null 或空串清空 } ProcurementUpdate: type: object additionalProperties: false description: 只维护内部备注;商品、数量、仓库、实收和运输必须通过独立节点操作。 required: [version] properties: version: { type: integer, format: int64, minimum: 0 } remark: { $ref: '#/components/schemas/NullableTextPatch' } CustomerOptionResponse: type: object properties: code: { type: string, enum: ['200'] } data: { type: array, items: { type: object, properties: { customerId: { type: string }, customerName: { type: string } } } } WarehouseOptionResponse: type: object properties: code: { type: string, enum: ['200'] } data: { type: array, items: { type: object, properties: { warehouseId: { type: string }, warehouseCode: { type: string }, warehouseName: { type: string }, countryCode: { type: string } } } } TruckStatus: { type: string, enum: [PENDING_REVIEW, WAITING_INBOUND, RECEIVING, WAITING_CONSOLIDATION, PALLET_OVERAGE_REVIEW, PARTIALLY_ALLOCATED, ALLOCATED, PENDING_DISPATCH, DISPATCHED, IN_TRANSIT, COMPLETED, REJECTED, CANCELLED] } TruckReview: type: object required: [version, decision, idempotencyKey] properties: version: { type: integer, format: int64, minimum: 0 } decision: { type: string, enum: [APPROVE, REJECT] } idempotencyKey: { type: string, minLength: 1, maxLength: 255 } remark: { type: string, nullable: true, maxLength: 1000 } TruckCancel: type: object required: [version, status, idempotencyKey] properties: version: { type: integer, format: int64, minimum: 0 } status: { type: string, enum: [CANCELLED] } idempotencyKey: { type: string, minLength: 1, maxLength: 255 } remark: { type: string, nullable: true, maxLength: 1000 } TruckReceivePallets: type: object required: [version, actualPalletCount, idempotencyKey] properties: version: { type: integer, format: int64, minimum: 0 } actualPalletCount: { type: integer, minimum: 1 } packageCount: { type: integer, nullable: true, minimum: 0 } palletPackageCounts: { type: array, maxItems: 500, items: { type: integer, minimum: 0 } } idempotencyKey: { type: string, minLength: 1, maxLength: 255 } remark: { type: string, nullable: true, maxLength: 1000 } TruckReviewPalletOverage: allOf: [{ $ref: '#/components/schemas/TruckReview' }] TruckAllocatePallets: type: object required: [version, palletIds, idempotencyKey] properties: version: { type: integer, format: int64, minimum: 0 } palletIds: { type: array, minItems: 1, maxItems: 500, uniqueItems: true, items: { type: integer, format: int64, minimum: 1 } } idempotencyKey: { type: string, minLength: 1, maxLength: 255 } remark: { type: string, nullable: true, maxLength: 1000 } TruckCommand: type: object required: [version, idempotencyKey] properties: version: { type: integer, format: int64, minimum: 0 } idempotencyKey: { type: string, minLength: 1, maxLength: 255 } remark: { type: string, nullable: true, maxLength: 1000 } TruckCreate: type: object required: [vehicleType, origin, destination, totalWeightKg, totalVolumeCbm, originContactName, originContactPhone, destinationContactName, destinationContactPhone, pickupAt, deliveryAt, idempotencyKey] properties: vehicleType: { type: string, enum: [PALLET_15, PALLET_30], description: '15拖或30拖;拼车来源未知时为空' } origin: { type: string, maxLength: 255 } originAddress: { type: string, nullable: true, maxLength: 500 } destination: { type: string, maxLength: 255 } destinationAddress: { type: string, nullable: true, maxLength: 500 } packageCount: { type: integer, nullable: true, minimum: 0 } totalWeightKg: { type: number, minimum: 0 } totalVolumeCbm: { type: number, minimum: 0 } budgetAmount: { type: number, nullable: true, minimum: 0 } currency: { type: string, minLength: 3, maxLength: 3, default: USD } originContactName: { type: string, maxLength: 128 } originContactPhone: { type: string, maxLength: 128 } destinationContactName: { type: string, maxLength: 128 } destinationContactPhone: { type: string, maxLength: 128 } pickupAt: { type: string, format: date-time, description: '取货日期时分,使用无偏移量的本地时间,不转换时区' } deliveryAt: { type: string, format: date-time, description: '送货日期时分,不能早于取货时间,不转换时区' } remark: { type: string, nullable: true, maxLength: 1000 } idempotencyKey: { type: string, maxLength: 255 } TruckUpdate: type: object required: [version, vehicleType, originContactName, originContactPhone, destinationContactName, destinationContactPhone, pickupAt, deliveryAt] properties: version: { type: integer, format: int64, minimum: 0 } vehicleType: { type: string, enum: [PALLET_15, PALLET_30], description: '15拖或30拖;拼车来源未知时为空' } origin: { type: string, maxLength: 255 } originAddress: { type: string, nullable: true, maxLength: 500 } destination: { type: string, maxLength: 255 } destinationAddress: { type: string, nullable: true, maxLength: 500 } packageCount: { type: integer, minimum: 0 } totalWeightKg: { type: number, minimum: 0 } totalVolumeCbm: { type: number, minimum: 0 } budgetAmount: { type: number, nullable: true, minimum: 0 } currency: { type: string, minLength: 3, maxLength: 3 } originContactName: { type: string, maxLength: 128 } originContactPhone: { type: string, maxLength: 128 } destinationContactName: { type: string, maxLength: 128 } destinationContactPhone: { type: string, maxLength: 128 } pickupAt: { type: string, format: date-time, description: '取货日期时分,使用无偏移量的本地时间,不转换时区' } deliveryAt: { type: string, format: date-time, description: '送货日期时分,不能早于取货时间,不转换时区' } remark: { type: string, nullable: true, maxLength: 1000 } LooseboardStatus: { type: string, enum: [PENDING_ACCEPTANCE, WAITING_INBOUND, RECEIVING, WAITING_CONSOLIDATION, PENDING_DISPATCH, DISPATCHED, IN_TRANSIT, COMPLETED, CANCELLED] } LooseboardStatusChange: type: object required: [version, status, idempotencyKey] properties: version: { type: integer, format: int64, minimum: 0 } status: { $ref: '#/components/schemas/LooseboardStatus' } idempotencyKey: { type: string, minLength: 1, maxLength: 255 } remark: { type: string, nullable: true, maxLength: 1000 } LooseboardCreate: type: object required: [originContactName, originContactPhone, destinationContactName, destinationContactPhone, pickupAt, deliveryAt, origin, destination, estimatedPalletCount, packageCount, totalWeightKg, totalVolumeCbm, idempotencyKey] properties: origin: { type: string, maxLength: 255 } originAddress: { type: string, nullable: true, maxLength: 500 } destination: { type: string, maxLength: 255 } destinationAddress: { type: string, nullable: true, maxLength: 500 } productName: { type: string, nullable: true, maxLength: 255 } estimatedPalletCount: { type: integer, minimum: 0, description: 申报预计托数,独立于实际收货 } packageCount: { type: integer, minimum: 0 } totalWeightKg: { type: number, minimum: 0 } totalVolumeCbm: { type: number, minimum: 0 } budgetAmount: { type: number, nullable: true, minimum: 0 } currency: { type: string, minLength: 3, maxLength: 3, default: USD } originContactName: { type: string, minLength: 1, maxLength: 128 } originContactPhone: { type: string, minLength: 1, maxLength: 128 } destinationContactName: { type: string, minLength: 1, maxLength: 128 } destinationContactPhone: { type: string, minLength: 1, maxLength: 128 } pickupAt: { type: string, format: date-time, description: 当地日期时间不带时区;按分钟输入 } deliveryAt: { type: string, format: date-time, description: 当地日期时间,不能早于取货时间 } remark: { type: string, nullable: true, maxLength: 1000 } idempotencyKey: { type: string, maxLength: 255 } LooseboardUpdate: type: object required: [originContactName, originContactPhone, destinationContactName, destinationContactPhone, pickupAt, deliveryAt, version, origin, destination, estimatedPalletCount, packageCount, totalWeightKg, totalVolumeCbm] properties: version: { type: integer, format: int64, minimum: 0 } origin: { type: string, maxLength: 255 } originAddress: { type: string, nullable: true, maxLength: 500 } destination: { type: string, maxLength: 255 } destinationAddress: { type: string, nullable: true, maxLength: 500 } productName: { type: string, nullable: true, maxLength: 255 } estimatedPalletCount: { type: integer, minimum: 0, description: 申报预计托数,独立于实际收货 } packageCount: { type: integer, minimum: 0 } totalWeightKg: { type: number, minimum: 0 } totalVolumeCbm: { type: number, minimum: 0 } budgetAmount: { type: number, nullable: true, minimum: 0 } currency: { type: string, minLength: 3, maxLength: 3, default: USD } originContactName: { type: string, minLength: 1, maxLength: 128 } originContactPhone: { type: string, minLength: 1, maxLength: 128 } destinationContactName: { type: string, minLength: 1, maxLength: 128 } destinationContactPhone: { type: string, minLength: 1, maxLength: 128 } pickupAt: { type: string, format: date-time, description: 当地日期时间不带时区;按分钟输入 } deliveryAt: { type: string, format: date-time, description: 当地日期时间,不能早于取货时间 } remark: { type: string, nullable: true, maxLength: 1000 } DispatchStatus: type: string enum: - ACTIVE - CANCELLED DispatchStage: type: string enum: - BEFORE_LOADING - LOADING - AFTER_LOADING - DELIVERING - DELIVERED DispatchReviewState: type: string enum: - DRAFT - DISPATCH_PENDING - DISPATCH_REJECTED - LOADING_PENDING - LOADING_REJECTED - APPROVED DispatchReviewStatus: type: string enum: - NOT_SUBMITTED - PENDING - APPROVED - REJECTED DispatchDecision: type: string enum: - APPROVED - REJECTED DispatchResourceMode: type: string enum: - MASTER - EXTERNAL DispatchActorMode: type: string enum: - PLATFORM - PDA DispatchSourceType: type: string enum: - INBOUND_PLAN - RETURN_RECEIPT - RELABEL DispatchBeforeLoadingSection: type: string enum: - VEHICLE_INFO - DISPATCH_REVIEW - LOADING_REVIEW DispatchStatusFilter: type: string enum: - ACTIVE - CANCELLED - ALL DispatchEffect: type: string enum: - APPLIED - EXISTING DispatchAction: type: string enum: - CREATE - EDIT - ADD_CARGO - REMOVE_CARGO - CANCEL - SUBMIT_REVIEW - DISPATCH_REVIEW - LOADING_REVIEW - RETURN_TO_REVIEW - PICK - LOADING_COMPLETE - ARRANGE_DELIVERY - DEPART - MARK_EXCEPTION DispatchGate: type: object x-java-record: DispatchContracts.Gate properties: allowed: type: boolean blockCode: type: string nullable: true blockReason: type: string nullable: true required: - allowed - blockCode - blockReason DispatchCounts: type: object x-java-record: DispatchContracts.Counts properties: itemCount: type: string pattern: ^[0-9]+$ palletCount: type: string pattern: ^[0-9]+$ packageCount: type: string pattern: ^[0-9]+$ pickedPackageCount: type: string pattern: ^[0-9]+$ shippedPackageCount: type: string pattern: ^[0-9]+$ required: - itemCount - palletCount - packageCount - pickedPackageCount - shippedPackageCount DispatchCapacity: type: object x-java-record: DispatchContracts.Capacity properties: palletSpaces: type: integer nullable: true maxLoadKg: type: number nullable: true maxVolumeCbm: type: number nullable: true required: - palletSpaces - maxLoadKg - maxVolumeCbm DispatchDriverEvidence: type: object x-java-record: DispatchContracts.DriverEvidence properties: masterLicenseFileId: type: string pattern: ^[1-9][0-9]*$ nullable: true description: 取货排车显式冻结的司机主档驾驶证ID,包含在响应fileIds中;其余取货证照为本车上传。普通派送沿既有MASTER证照语义。 photoFileIds: type: array maxItems: 20 uniqueItems: true description: 维护车辆司机时保存的本趟司机照片,按DRIVER_PHOTO类别校验,与驾驶证附件独立。 items: type: string pattern: ^[1-9][0-9]*$ licenseNo: type: string nullable: true licenseExpiresOn: type: string format: date nullable: true fileIds: type: array items: type: string pattern: ^[0-9]+$ nullable: true expectedTaskEndAt: type: string format: date-time nullable: true required: - licenseNo - licenseExpiresOn - fileIds - expectedTaskEndAt description: 临时司机证照和预计任务结束依据,审核前核齐;文件绑定本趟。 DispatchVehicleSnapshot: type: object x-java-record: DispatchContracts.VehicleSnapshot properties: mode: allOf: - $ref: '#/components/schemas/DispatchResourceMode' nullable: true vehicleId: type: string pattern: ^[0-9]+$ nullable: true plate: type: string nullable: true carrierName: type: string nullable: true vehicleStatus: type: string nullable: true capacity: allOf: - $ref: '#/components/schemas/DispatchCapacity' nullable: true evidenceFileIds: type: array items: type: string pattern: ^[0-9]+$ nullable: true required: - mode - vehicleId - plate - carrierName - vehicleStatus - capacity - evidenceFileIds DispatchDriverSnapshot: type: object x-java-record: DispatchContracts.DriverSnapshot properties: mode: allOf: - $ref: '#/components/schemas/DispatchResourceMode' nullable: true driverId: type: string pattern: ^[0-9]+$ nullable: true name: type: string nullable: true phone: type: string nullable: true evidence: allOf: - $ref: '#/components/schemas/DispatchDriverEvidence' nullable: true required: - mode - driverId - name - phone - evidence DispatchMaintenance: type: object x-java-record: DispatchContracts.Maintenance description: 保存于排车resourcesJson.maintenance;预约按本车目的仓登记,保存可暂缺,提交审核及后续执行须填写完整。 properties: plannedDeliveryDate: type: string format: date nullable: true deliveryMethod: type: string enum: [FBA自提, 客户自提, 卡派打托, 卡派地板, 快递, 外配] nullable: true pickupMethod: type: string enum: [一提一卸, 一提多卸] nullable: true loadType: type: string enum: [托盘, 地板, 混装] nullable: true fleetEmail: type: string maxLength: 254 nullable: true vehicleType: type: string enum: [厢式货车, 平板车, 集装箱卡车] nullable: true appointmentAccount: type: string maxLength: 128 nullable: true destinationAppointments: type: array maxItems: 500 items: { $ref: '#/components/schemas/DispatchDestinationAppointment' } DispatchDestinationAppointment: type: object x-java-record: DispatchContracts.DestinationAppointment description: 同一排车同一FBA目的仓仅一个预约号,空白可暂存。 required: [destinationKey, appointmentNo] properties: destinationKey: { type: string, pattern: '^FBA:.+', maxLength: 256 } appointmentNo: { type: string, maxLength: 128, nullable: true } DispatchResources: type: object x-java-record: DispatchContracts.Resources properties: vehicle: allOf: - $ref: '#/components/schemas/DispatchVehicleSnapshot' nullable: true driver: allOf: - $ref: '#/components/schemas/DispatchDriverSnapshot' nullable: true maintenance: allOf: - $ref: '#/components/schemas/DispatchMaintenance' nullable: true description: 本趟可空补充资料,八字段均可空;空白字符串规范为null,不替代正式FBA预约或实际发车时间。 required: - vehicle - driver DispatchDestination: type: object x-java-record: DispatchContracts.Destination properties: key: type: string nullable: true type: type: string nullable: true warehouseId: type: string nullable: true warehouseCode: type: string nullable: true warehouseName: type: string nullable: true address: type: string nullable: true postalCode: type: string nullable: true contactName: type: string nullable: true contactPhone: type: string nullable: true required: - key - type - warehouseId - warehouseCode - warehouseName - address - postalCode - contactName - contactPhone DispatchReviews: type: object x-java-record: DispatchContracts.Reviews properties: dispatchReview: allOf: - $ref: '#/components/schemas/DispatchReview' nullable: true loadingReview: allOf: - $ref: '#/components/schemas/DispatchReview' nullable: true required: - dispatchReview - loadingReview DispatchBatchAllocation: type: object x-java-record: DispatchContracts.BatchAllocation properties: planPalletId: type: string pattern: ^[0-9]+$ nullable: true batchKey: type: string nullable: true customerId: type: string nullable: true sourceKey: type: string nullable: true destinationKey: type: string nullable: true packageCount: type: integer recordVersion: oneOf: - type: string pattern: ^[0-9]+$ - type: integer minimum: 0 description: 所属batchKey的权威版本,必填且0合法;FBA取原预约版本,自动DISPATCH引用取真实主单版本。不能使用外层整车版本、客户端时间或默认0替代。Long响应保留十进制字符串。 required: - planPalletId - batchKey - customerId - sourceKey - destinationKey - packageCount - recordVersion description: 按真实客户、来源和目的地分配;原批次recordVersion随选择透传,锁后复核,不清空本车其他客户的原分配。 DispatchCargoLine: type: object x-java-record: DispatchContracts.CargoLine properties: dispatchItemId: type: string pattern: ^[0-9]+$ nullable: true customerId: type: string nullable: true customerName: type: string nullable: true orderId: type: string pattern: ^[0-9]+$ nullable: true orderNo: type: string nullable: true sourceKey: type: string nullable: true sourceStage: type: string nullable: true sourceRegion: type: string nullable: true sourceInboundId: type: string nullable: true inboundCode: type: string nullable: true planPalletId: type: string pattern: ^[0-9]+$ nullable: true warehousePalletId: type: string pattern: ^[0-9]+$ nullable: true palletNo: type: string nullable: true pickId: type: string pattern: ^[0-9]+$ nullable: true attributionId: type: string pattern: ^[0-9]+$ nullable: true inventoryPositionId: type: string pattern: ^[0-9]+$ nullable: true receiptId: type: string pattern: ^[0-9]+$ nullable: true returnReceiptId: type: string pattern: ^[0-9]+$ nullable: true returnCartonId: type: string pattern: ^[0-9]+$ nullable: true cartonMark: type: string nullable: true relabelNo: type: string nullable: true destination: allOf: - $ref: '#/components/schemas/DispatchDestination' nullable: true packages: type: string pattern: ^[0-9]+$ productQuantity: type: string pattern: ^[0-9]+$ grossWeightKg: type: number nullable: true volumeCbm: type: number nullable: true batchAllocations: type: array items: $ref: '#/components/schemas/DispatchBatchAllocation' nullable: true sourceOrigin: allOf: - $ref: '#/components/schemas/DispatchSourceOrigin' nullable: true required: - dispatchItemId - customerId - customerName - orderId - orderNo - sourceKey - sourceStage - sourceRegion - sourceInboundId - inboundCode - planPalletId - warehousePalletId - palletNo - pickId - attributionId - inventoryPositionId - receiptId - returnReceiptId - returnCartonId - cartonMark - relabelNo - destination - packages - productQuantity - grossWeightKg - volumeCbm - batchAllocations - sourceOrigin DispatchCommandResult: type: object x-java-record: DispatchContracts.CommandResult properties: dispatchNo: type: string nullable: true action: allOf: - $ref: '#/components/schemas/DispatchAction' nullable: true idempotencyKey: type: string recordVersion: oneOf: - type: string pattern: ^[0-9]+$ - type: integer minimum: 0 description: 已有单写入必填;0合法。响应Long按十进制字符串输出。 status: allOf: - $ref: '#/components/schemas/DispatchStatus' nullable: true stage: allOf: - $ref: '#/components/schemas/DispatchStage' nullable: true occurredAt: type: string format: date-time nullable: true effect: allOf: - $ref: '#/components/schemas/DispatchEffect' nullable: true counts: allOf: - $ref: '#/components/schemas/DispatchCounts' nullable: true result: allOf: - $ref: '#/components/schemas/DispatchPayload' nullable: true replayed: type: boolean alreadyArranged: type: boolean required: - dispatchNo - action - idempotencyKey - recordVersion - status - stage - occurredAt - effect - counts - result - replayed - alreadyArranged description: 原主体、动作、排车号、版本和完整载荷绑定的不可变结果;replayed与alreadyArranged语义独立。读取当前详情另发GET。 DispatchLoadingMeasurement: type: object x-java-record: DispatchContracts.LoadingMeasurement properties: warehousePalletId: type: string pattern: ^[0-9]+$ nullable: true palletSpaces: type: integer weightKg: type: number nullable: true volumeCbm: type: number nullable: true deliveryIndex: type: integer required: - warehousePalletId - palletSpaces - weightKg - volumeCbm - deliveryIndex DispatchConfirmedLoad: type: object x-java-record: DispatchContracts.ConfirmedLoad properties: manifestHash: type: string nullable: true pallets: type: array items: $ref: '#/components/schemas/DispatchLoadingMeasurement' nullable: true operatorId: type: string nullable: true confirmedAt: type: string format: date-time nullable: true required: - manifestHash - pallets - operatorId - confirmedAt DispatchVehicle: type: object x-java-record: DispatchCommands.Vehicle properties: mode: allOf: - $ref: '#/components/schemas/DispatchResourceMode' nullable: true vehicleId: type: string pattern: ^[0-9]+$ nullable: true plate: type: string nullable: true carrierName: type: string nullable: true capacity: allOf: - $ref: '#/components/schemas/DispatchCapacity' nullable: true evidenceFileIds: type: array items: type: string pattern: ^[0-9]+$ nullable: true DispatchDriver: type: object x-java-record: DispatchCommands.Driver properties: mode: allOf: - $ref: '#/components/schemas/DispatchResourceMode' nullable: true driverId: type: string pattern: ^[0-9]+$ nullable: true name: type: string nullable: true phone: type: string nullable: true evidence: allOf: - $ref: '#/components/schemas/DispatchDriverEvidence' nullable: true DispatchCargoSelection: type: object x-java-record: DispatchCommands.CargoSelection properties: sourceType: allOf: - $ref: '#/components/schemas/DispatchSourceType' planPalletId: type: string pattern: ^[0-9]+$ nullable: true returnReceiptId: type: string pattern: ^[0-9]+$ nullable: true relabelNo: type: string nullable: true warehousePalletId: type: string pattern: ^[0-9]+$ nullable: true sourceVersion: type: string required: - sourceType - sourceVersion DispatchCapacityDemand: type: object x-java-record: DispatchCapacityDemands.Demand properties: dispatchNo: { type: string } warehouseName: { type: string, nullable: true } route: { type: string, nullable: true } plannedDepartureAt: { type: string, format: date-time, nullable: true } vehiclePalletSpaces: { type: integer, nullable: true } scheduledPalletCount: { type: integer, nullable: true } remainingPalletSpaces: { type: integer, nullable: true } remainingWeightKg: { type: number, nullable: true } remainingVolumeCbm: { type: number, nullable: true } capacityKnown: { type: boolean } capacityReason: { type: string, nullable: true } required: [dispatchNo, capacityKnown] DispatchCreate: type: object x-java-record: DispatchCommands.Create properties: publishLooseboardDemand: type: boolean description: 是否向内部散板需求池发布本车余位;仅智能排车建单时选择,默认不发布。 default: false idempotencyKey: type: string warehouseId: type: string vehicle: allOf: - $ref: '#/components/schemas/DispatchVehicle' nullable: true driver: allOf: - $ref: '#/components/schemas/DispatchDriver' nullable: true plannedDepartureAt: type: string format: date-time nullable: true estimatedArrivalAt: type: string format: date-time nullable: true remark: type: string nullable: true cargo: type: array items: $ref: '#/components/schemas/DispatchCargoSelection' nullable: true batchAllocations: type: array items: $ref: '#/components/schemas/DispatchBatchAllocation' nullable: true required: - idempotencyKey - warehouseId description: 同一起运仓,允许空单或多客户、多目的仓。普通入仓FBA货物须先取得覆盖本客户、来源和箱数的正式预约时间才能选入,不能等提交审核才检查;换标和退货独立来源保留原流程。客户和来源归属由服务端解析,临时资源不生成假档案。 DispatchAddCargo: type: object x-java-record: DispatchCommands.AddCargo properties: recordVersion: oneOf: - type: string pattern: ^[0-9]+$ - type: integer minimum: 0 description: 已有单写入必填;0合法。响应Long按十进制字符串输出。 idempotencyKey: type: string cargo: type: array items: $ref: '#/components/schemas/DispatchCargoSelection' nullable: true batchAllocations: type: array items: $ref: '#/components/schemas/DispatchBatchAllocation' nullable: true required: - recordVersion - idempotencyKey DispatchReasonCommand: type: object x-java-record: DispatchCommands.ReasonCommand properties: recordVersion: oneOf: - type: string pattern: ^[0-9]+$ - type: integer minimum: 0 description: 已有单写入必填;0合法。响应Long按十进制字符串输出。 idempotencyKey: type: string reason: type: string nullable: true required: - recordVersion - idempotencyKey DispatchSubmitReview: type: object x-java-record: DispatchCommands.SubmitReview properties: recordVersion: oneOf: - type: string pattern: ^[0-9]+$ - type: integer minimum: 0 description: 已有单写入必填;0合法。响应Long按十进制字符串输出。 idempotencyKey: type: string remark: type: string nullable: true required: - recordVersion - idempotencyKey DispatchReviewAttachments: type: object description: 本次审核补充证据;省略或null为三组空数组。每类最多20个且不得重复;逐个验证本车和类别归属,不接受MASTER档案证照冒充本车审核上传。 x-java-record: DispatchContracts.ReviewAttachments properties: vehicleFileIds: type: array maxItems: 20 uniqueItems: true description: 本车VEHICLE证据文件ID。 items: oneOf: - type: string pattern: ^[1-9][0-9]*$ - type: integer format: int64 minimum: 1 driverPhotoFileIds: type: array maxItems: 20 uniqueItems: true description: 本车DRIVER_PHOTO证据文件ID。 items: oneOf: - type: string pattern: ^[1-9][0-9]*$ - type: integer format: int64 minimum: 1 licenseFileIds: type: array maxItems: 20 uniqueItems: true description: 本车DRIVER证据文件ID。 items: oneOf: - type: string pattern: ^[1-9][0-9]*$ - type: integer format: int64 minimum: 1 DispatchReviewCommand: type: object x-java-record: DispatchCommands.ReviewCommand properties: recordVersion: oneOf: - type: string pattern: ^[0-9]+$ - type: integer minimum: 0 description: 已有单写入必填;0合法。响应Long按十进制字符串输出。 idempotencyKey: type: string decision: allOf: - $ref: '#/components/schemas/DispatchDecision' nullable: true reason: type: string nullable: true attachments: allOf: - $ref: '#/components/schemas/DispatchReviewAttachments' nullable: true required: - recordVersion - idempotencyKey DispatchReturnToReview: type: object x-java-record: DispatchCommands.ReturnToReview properties: recordVersion: oneOf: - type: string pattern: ^[0-9]+$ - type: integer minimum: 0 description: 已有单写入必填;0合法。响应Long按十进制字符串输出。 idempotencyKey: type: string reason: type: string nullable: true required: - recordVersion - idempotencyKey DispatchPick: type: object x-java-record: DispatchCommands.Pick properties: recordVersion: oneOf: - type: string pattern: ^[0-9]+$ - type: integer minimum: 0 description: 已有单写入必填;0合法。响应Long按十进制字符串输出。 idempotencyKey: type: string positionId: type: string pattern: ^[0-9]+$ nullable: true packages: type: string pattern: ^[0-9]+$ productQuantity: type: string pattern: ^[0-9]+$ cartonMark: type: string nullable: true remark: type: string nullable: true required: - recordVersion - idempotencyKey DispatchLoadingComplete: type: object x-java-record: DispatchCommands.LoadingComplete properties: recordVersion: oneOf: - type: string pattern: ^[0-9]+$ - type: integer minimum: 0 description: 已有单写入必填;0合法。响应Long按十进制字符串输出。 idempotencyKey: type: string manifestHash: type: string nullable: true remark: type: string nullable: true required: - recordVersion - idempotencyKey description: 必须先由真实PDA拣货核平;按已扫实托确认装车;重量体积由服务端已有测量带出,缺失不阻塞,不接受现场补填测量或箱数。 DispatchDepart: type: object x-java-record: DispatchCommands.Depart properties: recordVersion: oneOf: - type: string pattern: ^[0-9]+$ - type: integer minimum: 0 description: 已有单写入必填;0合法。响应Long按十进制字符串输出。 idempotencyKey: type: string remark: type: string nullable: true required: - recordVersion - idempotencyKey DispatchQuery: type: object x-java-record: DispatchViews.Query properties: page: type: string pattern: ^[0-9]+$ size: type: string pattern: ^[0-9]+$ dispatchNo: type: string nullable: true vehiclePlate: type: string nullable: true warehouseId: type: string nullable: true customerId: type: string nullable: true fbaAppointmentNo: type: string nullable: true status: allOf: - $ref: '#/components/schemas/DispatchStatusFilter' nullable: true stage: allOf: - $ref: '#/components/schemas/DispatchStage' nullable: true beforeLoadingSection: allOf: - $ref: '#/components/schemas/DispatchBeforeLoadingSection' nullable: true reviewStatus: allOf: - $ref: '#/components/schemas/DispatchReviewStatus' nullable: true required: - page - size - dispatchNo - vehiclePlate - warehouseId - customerId - fbaAppointmentNo - status - stage - beforeLoadingSection - reviewStatus DispatchReviewCounts: type: object x-java-record: DispatchViews.ReviewCounts properties: notSubmitted: type: string pattern: ^[0-9]+$ pending: type: string pattern: ^[0-9]+$ approved: type: string pattern: ^[0-9]+$ rejected: type: string pattern: ^[0-9]+$ required: - notSubmitted - pending - approved - rejected DispatchBeforeLoadingCounts: type: object x-java-record: DispatchViews.BeforeLoadingCounts properties: vehicleInfoTotal: type: string pattern: ^[0-9]+$ dispatchReview: allOf: - $ref: '#/components/schemas/DispatchReviewCounts' nullable: true loadingReview: allOf: - $ref: '#/components/schemas/DispatchReviewCounts' nullable: true required: - vehicleInfoTotal - dispatchReview - loadingReview DispatchStatistics: type: object x-java-record: DispatchViews.Statistics properties: matchedTotal: type: string pattern: ^[0-9]+$ activeTotal: type: string pattern: ^[0-9]+$ cancelledTotal: type: string pattern: ^[0-9]+$ stageCounts: type: object additionalProperties: type: string pattern: ^[0-9]+$ nullable: true beforeLoadingReviewCounts: allOf: - $ref: '#/components/schemas/DispatchBeforeLoadingCounts' nullable: true required: - matchedTotal - activeTotal - cancelledTotal - stageCounts - beforeLoadingReviewCounts DispatchPage: type: object x-java-record: DispatchViews.Page properties: records: type: array items: $ref: '#/components/schemas/DispatchListRow' nullable: true total: type: string pattern: ^[0-9]+$ page: type: string pattern: ^[0-9]+$ size: type: string pattern: ^[0-9]+$ pages: type: string pattern: ^[0-9]+$ statistics: allOf: - $ref: '#/components/schemas/DispatchStatistics' nullable: true snapshotAt: type: string format: date-time nullable: true required: - records - total - page - size - pages - statistics - snapshotAt DispatchListRow: type: object x-java-record: DispatchViews.ListRow properties: createdAt: type: string format: date-time nullable: true description: 排车单真实创建时间,取原排车主单created_at。 fbaAppointments: type: array items: { $ref: '#/components/schemas/DispatchFbaAppointment' } dispatchNo: type: string nullable: true status: allOf: - $ref: '#/components/schemas/DispatchStatus' nullable: true stage: allOf: - $ref: '#/components/schemas/DispatchStage' nullable: true recordVersion: oneOf: - type: string pattern: ^[0-9]+$ - type: integer minimum: 0 description: 已有单写入必填;0合法。响应Long按十进制字符串输出。 reviewState: allOf: - $ref: '#/components/schemas/DispatchReviewState' nullable: true reviews: allOf: - $ref: '#/components/schemas/DispatchReviews' nullable: true resources: allOf: - $ref: '#/components/schemas/DispatchResources' nullable: true warehouseId: type: string nullable: true warehouseCode: type: string nullable: true warehouseName: type: string nullable: true plannedDepartureAt: type: string format: date-time nullable: true departedAt: type: string format: date-time nullable: true counts: allOf: - $ref: '#/components/schemas/DispatchCounts' nullable: true pickingReconciled: type: boolean arranged: type: boolean actions: type: object additionalProperties: $ref: '#/components/schemas/DispatchGate' nullable: true required: - createdAt - dispatchNo - status - stage - recordVersion - reviewState - reviews - resources - warehouseId - warehouseCode - warehouseName - plannedDepartureAt - departedAt - counts - pickingReconciled - arranged - actions - fbaAppointments DispatchVehicleInfo: type: object x-java-record: DispatchViews.VehicleInfo properties: vehicle: allOf: - $ref: '#/components/schemas/DispatchVehicleSnapshot' nullable: true driver: allOf: - $ref: '#/components/schemas/DispatchDriverSnapshot' nullable: true maintenance: allOf: - $ref: '#/components/schemas/DispatchMaintenance' nullable: true description: 本趟可空补充资料,八字段均可空;空白字符串规范为null,不替代正式FBA预约或实际发车时间。 required: - vehicle - driver DispatchFbaAppointment: type: object x-java-record: DispatchViews.FbaAppointment description: 按本车目的仓汇总的预约;唯一已约编号自动带入,人工登记不冒充正式确认时间。批次及客户在目的仓汇总行为空。 properties: customerId: type: string nullable: true shipmentNumbers: type: array items: { type: string } batchKey: type: string nullable: true batchNo: type: string nullable: true appointmentNo: type: string nullable: true destinationKey: type: string nullable: true destinationWarehouseCode: type: string nullable: true status: type: string nullable: true confirmedAt: type: string format: date-time nullable: true blockReason: type: string nullable: true required: - batchKey - batchNo - appointmentNo - destinationKey - destinationWarehouseCode - status - confirmedAt - blockReason - customerId - shipmentNumbers DispatchDispatchInfo: type: object x-java-record: DispatchViews.DispatchInfo properties: route: type: string nullable: true plannedDepartureAt: type: string format: date-time nullable: true departedAt: type: string format: date-time nullable: true estimatedArrivalAt: type: string format: date-time nullable: true fbaAppointments: type: array items: $ref: '#/components/schemas/DispatchFbaAppointment' nullable: true appointmentBatches: type: array items: $ref: '#/components/schemas/DispatchBatchReference' nullable: true exceptions: type: array items: $ref: '#/components/schemas/DispatchExceptionRecord' required: - route - plannedDepartureAt - departedAt - estimatedArrivalAt - fbaAppointments - appointmentBatches - exceptions DispatchDocuments: type: object x-java-record: DispatchViews.Documents properties: dispatchNo: type: string nullable: true outbounds: type: array items: $ref: '#/components/schemas/DispatchOutboundReference' nullable: true deliveries: type: array items: $ref: '#/components/schemas/DispatchDeliveryReference' nullable: true createdAt: type: string format: date-time nullable: true updatedAt: type: string format: date-time nullable: true remark: type: string nullable: true required: - dispatchNo - outbounds - deliveries - createdAt - updatedAt - remark DispatchOrderDetail: type: object x-java-record: DispatchViews.OrderDetail properties: customerId: type: string nullable: true customerName: type: string nullable: true orderNo: type: string nullable: true inboundCode: type: string nullable: true grossWeightKg: type: number nullable: true palletCount: type: integer nullable: true destinationFbaWarehouse: type: string nullable: true volumeCbm: type: number nullable: true containerNo: type: string nullable: true sourceKey: type: string nullable: true sourceBusinessType: type: string nullable: true sourceBusinessNo: type: string nullable: true required: - customerId - customerName - orderNo - inboundCode - grossWeightKg - palletCount - destinationFbaWarehouse - volumeCbm - containerNo - sourceKey - sourceBusinessType - sourceBusinessNo DispatchDetail: type: object x-java-record: DispatchViews.Detail properties: publishLooseboardDemand: type: boolean description: 建单时确定的散板需求发布选择,维护车辆不可修改。 dispatchNo: type: string nullable: true status: allOf: - $ref: '#/components/schemas/DispatchStatus' nullable: true stage: allOf: - $ref: '#/components/schemas/DispatchStage' nullable: true recordVersion: oneOf: - type: string pattern: ^[0-9]+$ - type: integer minimum: 0 description: 已有单写入必填;0合法。响应Long按十进制字符串输出。 reviewState: allOf: - $ref: '#/components/schemas/DispatchReviewState' nullable: true reviews: allOf: - $ref: '#/components/schemas/DispatchReviews' nullable: true counts: allOf: - $ref: '#/components/schemas/DispatchCounts' nullable: true pickingReconciled: type: boolean actions: type: object additionalProperties: $ref: '#/components/schemas/DispatchGate' nullable: true vehicleInfo: allOf: - $ref: '#/components/schemas/DispatchVehicleInfo' nullable: true dispatchInfo: allOf: - $ref: '#/components/schemas/DispatchDispatchInfo' nullable: true documents: allOf: - $ref: '#/components/schemas/DispatchDocuments' nullable: true orderDetails: type: array items: $ref: '#/components/schemas/DispatchOrderDetail' nullable: true required: - publishLooseboardDemand - dispatchNo - status - stage - recordVersion - reviewState - reviews - counts - pickingReconciled - actions - vehicleInfo - dispatchInfo - documents - orderDetails description: 页头与动作资格之外只含车辆信息、排车信息、单据信息、关联订单明细四块。 DispatchPdaTask: type: object x-java-record: DispatchViews.PdaTask properties: taskNo: type: string nullable: true dispatchNo: type: string nullable: true warehouseId: type: string nullable: true status: allOf: - $ref: '#/components/schemas/DispatchStatus' nullable: true stage: allOf: - $ref: '#/components/schemas/DispatchStage' nullable: true recordVersion: oneOf: - type: string pattern: ^[0-9]+$ - type: integer minimum: 0 description: 已有单写入必填;0合法。响应Long按十进制字符串输出。 reviews: allOf: - $ref: '#/components/schemas/DispatchReviews' nullable: true resources: allOf: - $ref: '#/components/schemas/DispatchResources' nullable: true counts: allOf: - $ref: '#/components/schemas/DispatchCounts' nullable: true plannedDepartureAt: type: string format: date-time nullable: true description: 当前排车计划发车时间,审核必须核对。 estimatedArrivalAt: type: string format: date-time nullable: true description: 当前排车预计送达时间。 fbaAppointments: type: array items: $ref: '#/components/schemas/DispatchFbaAppointment' description: 按本车各客户批次读取当前有效收货确认;缺失确认显示PENDING。 pickingReconciled: type: boolean items: type: array items: $ref: '#/components/schemas/DispatchPdaItem' nullable: true actions: type: object additionalProperties: $ref: '#/components/schemas/DispatchGate' nullable: true required: - taskNo - dispatchNo - warehouseId - status - stage - recordVersion - reviews - resources - counts - pickingReconciled - items - actions DispatchPdaItem: type: object x-java-record: DispatchViews.PdaItem properties: dispatchItemId: type: string pattern: ^[0-9]+$ nullable: true customerId: type: string nullable: true customerName: type: string nullable: true palletNo: type: string nullable: true destination: allOf: - $ref: '#/components/schemas/DispatchDestination' nullable: true scheduledPackages: type: string pattern: ^[0-9]+$ pickedPackages: type: string pattern: ^[0-9]+$ positions: type: array items: $ref: '#/components/schemas/DispatchPosition' nullable: true returnCartons: type: array items: $ref: '#/components/schemas/DispatchReturnCarton' nullable: true sourceKey: type: string sourceBusinessType: type: string nullable: true sourceBusinessNo: type: string nullable: true required: - dispatchItemId - customerId - customerName - palletNo - destination - scheduledPackages - pickedPackages - positions - returnCartons - sourceKey - sourceBusinessType - sourceBusinessNo DispatchPosition: type: object x-java-record: DispatchViews.Position properties: positionId: type: string pattern: ^[0-9]+$ nullable: true balanceId: type: string pattern: ^[0-9]+$ nullable: true availablePackages: type: string pattern: ^[0-9]+$ allocatedPackages: type: string pattern: ^[0-9]+$ pickedPackages: type: string pattern: ^[0-9]+$ required: - positionId - balanceId - availablePackages - allocatedPackages - pickedPackages DispatchReturnCarton: type: object x-java-record: DispatchViews.ReturnCarton properties: returnCartonId: type: string pattern: ^[0-9]+$ nullable: true cartonMark: type: string nullable: true status: type: string nullable: true productQuantity: type: string pattern: ^[0-9]+$ required: - returnCartonId - cartonMark - status - productQuantity DispatchCargoItem: type: object x-java-record: DispatchWorkModels.CargoItem properties: dispatchItemId: type: string pattern: ^[0-9]+$ nullable: true customerId: type: string nullable: true customerName: type: string nullable: true sourceKey: type: string nullable: true sourceVersion: type: string nullable: true sourceType: allOf: - $ref: '#/components/schemas/DispatchSourceType' nullable: true planPalletId: type: string pattern: ^[0-9]+$ nullable: true returnReceiptId: type: string pattern: ^[0-9]+$ nullable: true relabelNo: type: string nullable: true warehousePalletId: type: string pattern: ^[0-9]+$ nullable: true palletNo: type: string nullable: true orderNo: type: string nullable: true inboundCode: type: string nullable: true destination: allOf: - $ref: '#/components/schemas/DispatchDestination' nullable: true scheduledPackages: type: string pattern: ^[0-9]+$ pickedPackages: type: string pattern: ^[0-9]+$ remove: allOf: - $ref: '#/components/schemas/DispatchGate' nullable: true DispatchItems: type: object x-java-record: DispatchWorkModels.Items properties: dispatchNo: type: string nullable: true recordVersion: oneOf: - type: string pattern: ^[0-9]+$ - type: integer minimum: 0 description: 已有单写入必填;0合法。响应Long按十进制字符串输出。 status: allOf: - $ref: '#/components/schemas/DispatchStatus' nullable: true stage: allOf: - $ref: '#/components/schemas/DispatchStage' nullable: true items: type: array items: $ref: '#/components/schemas/DispatchCargoItem' nullable: true required: - recordVersion DispatchStop: type: object x-java-record: DispatchWorkModels.Stop properties: index: type: integer name: type: string nullable: true address: type: string nullable: true destinationKey: type: string nullable: true DispatchAppointmentAllocations: type: object x-java-record: DispatchWorkModels.AppointmentAllocations required: [dispatchNo, recordVersion, items, edit] properties: dispatchNo: {type: string} recordVersion: type: string pattern: ^[0-9]+$ items: type: array items: $ref: '#/components/schemas/DispatchAppointmentItem' edit: $ref: '#/components/schemas/DispatchGate' DispatchAppointmentItem: type: object x-java-record: DispatchWorkModels.AppointmentItem required: [dispatchItemId, planPalletId, customerId, palletNo, sources, allocations] properties: dispatchItemId: {type: string} planPalletId: {type: string} customerId: {type: string} customerName: {type: string, nullable: true} palletNo: {type: string} sources: type: array items: $ref: '#/components/schemas/DispatchAppointmentSource' allocations: type: array items: $ref: '#/components/schemas/DispatchBatchAllocation' DispatchAppointmentSource: type: object required: [sourceKey, destinationKey, options, blockReasons] properties: sourceKey: {type: string} orderNo: {type: string, nullable: true} inboundCode: {type: string, nullable: true} destinationKey: {type: string} packageCount: {type: integer, nullable: true, minimum: 1} options: type: array items: $ref: '#/components/schemas/DispatchAppointmentOption' blockReasons: type: array items: {type: string} DispatchAppointmentOption: type: object required: [batchKey, batchNo, recordVersion, availablePackages, appointmentAt, timezone] properties: batchKey: {type: string} batchNo: {type: string} recordVersion: type: string pattern: ^[0-9]+$ availablePackages: {type: integer, minimum: 1} confirmationNo: {type: string, nullable: true} appointmentAt: type: string description: 目的仓当地确认开始时间,须结合timezone解释,不按浏览器时区转换。 appointmentEndAt: {type: string, nullable: true} timezone: {type: string} DispatchAppointmentAllocationCommand: type: object x-java-record: DispatchWorkModels.AppointmentAllocationCommand required: [recordVersion, idempotencyKey, dispatchItemIds, batchAllocations] properties: recordVersion: oneOf: - type: string pattern: ^[0-9]+$ - type: integer minimum: 0 idempotencyKey: {type: string} dispatchItemIds: type: array minItems: 1 maxItems: 1000 uniqueItems: true items: {type: string} batchAllocations: type: array maxItems: 1000 items: $ref: '#/components/schemas/DispatchBatchAllocation' DispatchRoute: type: object x-java-record: DispatchWorkModels.Route properties: dispatchNo: type: string nullable: true recordVersion: oneOf: - type: string pattern: ^[0-9]+$ - type: integer minimum: 0 description: 已有单写入必填;0合法。响应Long按十进制字符串输出。 stops: type: array items: $ref: '#/components/schemas/DispatchStop' nullable: true edit: allOf: - $ref: '#/components/schemas/DispatchGate' nullable: true required: - recordVersion DispatchRouteCommand: type: object x-java-record: DispatchWorkModels.RouteCommand properties: recordVersion: oneOf: - type: string pattern: ^[0-9]+$ - type: integer minimum: 0 description: 已有单写入必填;0合法。响应Long按十进制字符串输出。 idempotencyKey: type: string destinationKeys: type: array items: type: string nullable: true reason: type: string nullable: true required: - recordVersion - idempotencyKey description: 只对既有全部目的地重排,保留外接目的地;原因必填,改变后两级审核失效。 DispatchCandidateQuery: type: object x-java-record: DispatchPlanningModels.CandidateQuery properties: warehouseId: type: string nullable: true planIds: type: array items: type: string pattern: ^[0-9]+$ nullable: true orderNo: type: string nullable: true destinationWarehouseCode: type: string nullable: true sourceStage: type: string nullable: true draftToken: type: string nullable: true DispatchCandidate: type: object x-java-record: DispatchPlanningModels.Candidate properties: selection: allOf: - $ref: '#/components/schemas/DispatchCargoSelection' nullable: true sourceKey: type: string nullable: true sourceVersion: type: string nullable: true customerId: type: string nullable: true customerName: type: string nullable: true warehouseId: type: string nullable: true warehouseCode: type: string nullable: true warehouseName: type: string nullable: true orderNo: type: string nullable: true inboundCode: type: string nullable: true planNo: type: string nullable: true palletNo: type: string nullable: true containerNo: type: string nullable: true destination: allOf: - $ref: '#/components/schemas/DispatchDestination' nullable: true availablePackages: type: string pattern: ^[0-9]+$ suggestedWeightKg: type: number nullable: true suggestedVolumeCbm: type: number nullable: true measurementSource: type: string nullable: true appointmentBatches: type: array items: $ref: '#/components/schemas/DispatchBatchReference' nullable: true blockReasons: type: array items: type: string nullable: true selectionGroup: allOf: - $ref: '#/components/schemas/DispatchSelectionGroup' required: - selectionGroup DispatchCandidateList: type: object x-java-record: DispatchPlanningModels.CandidateList properties: candidates: type: array items: $ref: '#/components/schemas/DispatchCandidate' nullable: true snapshotAt: type: string format: date-time nullable: true complete: type: boolean description: 仅当前响应包含筛选后的全部候选时为true;分页中的false不影响每个selectionGroup的完整性。 total: type: string pattern: ^[0-9]+$ description: 同一筛选下的来源总行数。 page: type: integer size: type: integer pages: type: string pattern: ^[0-9]+$ required: [candidates, snapshotAt, complete, total, page, size, pages] DispatchDraftContainer: type: object x-java-record: DispatchPlanningModels.DraftContainer properties: draftContainerId: type: string pattern: ^[0-9]+$ nullable: true sequenceNo: type: integer capacity: type: integer sourceKeys: type: array items: type: string nullable: true DispatchDraft: type: object x-java-record: DispatchPlanningModels.Draft properties: draftToken: type: string nullable: true recordVersion: oneOf: - type: string pattern: ^[0-9]+$ - type: integer minimum: 0 description: 已有单写入必填;0合法。响应Long按十进制字符串输出。 status: type: string nullable: true warehouseId: type: string nullable: true containers: type: array items: $ref: '#/components/schemas/DispatchDraftContainer' nullable: true sources: type: array items: $ref: '#/components/schemas/DispatchCandidate' nullable: true expiresAt: type: string format: date-time nullable: true required: - recordVersion DispatchCreateDraft: type: object x-java-record: DispatchPlanningModels.CreateDraft properties: idempotencyKey: type: string warehouseId: type: string required: - idempotencyKey - warehouseId DispatchCreateContainer: type: object x-java-record: DispatchPlanningModels.CreateContainer properties: recordVersion: oneOf: - type: string pattern: ^[0-9]+$ - type: integer minimum: 0 description: 已有单写入必填;0合法。响应Long按十进制字符串输出。 idempotencyKey: type: string draftToken: type: string capacity: type: integer required: - recordVersion - idempotencyKey - draftToken - capacity DispatchDraftSelection: type: object x-java-record: DispatchPlanningModels.DraftSelection properties: recordVersion: oneOf: - type: string pattern: ^[0-9]+$ - type: integer minimum: 0 description: 已有单写入必填;0合法。响应Long按十进制字符串输出。 idempotencyKey: type: string draftToken: type: string draftContainerId: type: string pattern: ^[0-9]+$ source: allOf: - $ref: '#/components/schemas/DispatchCargoSelection' required: - recordVersion - idempotencyKey - draftToken - draftContainerId - source DispatchDraftSnapshot: type: object x-java-record: DispatchPlanningModels.DraftSnapshot properties: recordVersion: oneOf: - type: string pattern: ^[0-9]+$ - type: integer minimum: 0 description: 已有单写入必填;0合法。响应Long按十进制字符串输出。 idempotencyKey: type: string draftToken: type: string planIds: type: array items: type: string pattern: ^[0-9]+$ containers: type: array items: $ref: '#/components/schemas/DispatchDraftContainer' required: - recordVersion - idempotencyKey - draftToken - planIds - containers DispatchDraftRelease: type: object x-java-record: DispatchPlanningModels.DraftRelease properties: recordVersion: oneOf: - type: string pattern: ^[0-9]+$ - type: integer minimum: 0 description: 已有单写入必填;0合法。响应Long按十进制字符串输出。 idempotencyKey: type: string draftToken: type: string required: - recordVersion - idempotencyKey - draftToken DispatchDraftVehicle: type: object x-java-record: DispatchPlanningModels.DraftVehicle properties: draftContainerId: type: string pattern: ^[0-9]+$ nullable: true dispatch: allOf: - $ref: '#/components/schemas/DispatchCreate' nullable: true DispatchConvertDraft: type: object x-java-record: DispatchPlanningModels.ConvertDraft properties: recordVersion: oneOf: - type: string pattern: ^[0-9]+$ - type: integer minimum: 0 description: 已有单写入必填;0合法。响应Long按十进制字符串输出。 idempotencyKey: type: string draftToken: type: string groups: type: array items: $ref: '#/components/schemas/DispatchDraftVehicle' required: - recordVersion - idempotencyKey - draftToken - groups DispatchConvertedVehicle: type: object x-java-record: DispatchPlanningModels.ConvertedVehicle properties: draftContainerId: type: string pattern: ^[0-9]+$ nullable: true dispatch: allOf: - $ref: '#/components/schemas/DispatchCommandResult' nullable: true DispatchConvertedDraft: type: object x-java-record: DispatchPlanningModels.ConvertedDraft properties: draftToken: type: string nullable: true vehicles: type: array items: $ref: '#/components/schemas/DispatchConvertedVehicle' nullable: true replayed: type: boolean DispatchMeasurementEvidence: type: object x-java-record: DispatchPlanningModels.MeasurementEvidence properties: field: type: string nullable: true sourceType: type: string nullable: true sourceBusinessNo: type: string nullable: true observedAt: type: string format: date-time nullable: true value: type: number nullable: true actual: type: boolean DispatchLoadingPallet: type: object x-java-record: DispatchPlanningModels.LoadingPallet properties: warehousePalletId: type: string pattern: ^[0-9]+$ nullable: true palletNo: type: string nullable: true scheduledPackages: type: string pattern: ^[0-9]+$ pickedPackages: type: string pattern: ^[0-9]+$ palletSpaces: type: integer nullable: true weightKg: type: number nullable: true volumeCbm: type: number nullable: true deliveryIndex: type: integer nullable: true missingFields: type: array items: type: string nullable: true evidence: type: array items: $ref: '#/components/schemas/DispatchMeasurementEvidence' nullable: true DispatchLoadingPreview: type: object x-java-record: DispatchPlanningModels.LoadingPreview properties: dispatchNo: type: string nullable: true recordVersion: oneOf: - type: string pattern: ^[0-9]+$ - type: integer minimum: 0 description: 已有单写入必填;0合法。响应Long按十进制字符串输出。 status: allOf: - $ref: '#/components/schemas/DispatchStatus' nullable: true stage: allOf: - $ref: '#/components/schemas/DispatchStage' nullable: true manifestHash: type: string nullable: true pickingReconciled: type: boolean resources: allOf: - $ref: '#/components/schemas/DispatchResources' nullable: true pallets: type: array items: $ref: '#/components/schemas/DispatchLoadingPallet' nullable: true confirmedLoad: allOf: - $ref: '#/components/schemas/DispatchConfirmedLoad' nullable: true loadingComplete: allOf: - $ref: '#/components/schemas/DispatchGate' nullable: true missingFields: type: array items: type: string nullable: true required: - recordVersion DispatchCoverageSelection: type: object x-java-record: DispatchDeliveryModels.CoverageSelection properties: financeFeeId: type: string pattern: ^[0-9]+$ nullable: true sourceVersion: type: integer sourceHash: type: string nullable: true services: type: array items: type: string nullable: true DispatchFeeItem: type: object description: 派送应付费用。客户应收费用统一到海外费用登记并审核,派送完成不自动生成应收。 x-java-record: DispatchDeliveryModels.FeeItem properties: feeType: type: string nullable: true feeName: type: string nullable: true direction: type: string enum: [PAYABLE] nullable: true currency: type: string nullable: true amount: type: number nullable: true supplierId: type: string pattern: ^[0-9]+$ nullable: true supplierName: type: string nullable: true supplierCategory: type: string nullable: true settlementMode: type: string nullable: true paidAt: type: string format: date-time nullable: true paymentMethod: type: string nullable: true paymentReferenceNo: type: string nullable: true paymentVoucherFileIds: type: array items: type: string nullable: true chargeableQuantity: type: number nullable: true quantityUnit: type: string nullable: true unitPrice: type: number nullable: true periodStart: type: string format: date nullable: true periodEnd: type: string format: date nullable: true remark: type: string nullable: true DispatchArrangeGroup: type: object x-java-record: DispatchDeliveryModels.ArrangeGroup properties: groupKey: type: string nullable: true groupCargoHash: type: string nullable: true plannedDeliveryAt: type: string format: date-time nullable: true deliveryMethod: type: string nullable: true waybillNo: type: string nullable: true carrierName: type: string nullable: true pickupMethod: type: string nullable: true loadingType: type: string nullable: true vehicleType: type: string nullable: true vehicleSize: type: string nullable: true appointmentAccount: type: string nullable: true sellerName: type: string nullable: true remark: type: string nullable: true externalFreightHash: type: string nullable: true feeCoverageCargoHash: type: string nullable: true feeCoverage: type: array items: $ref: '#/components/schemas/DispatchCoverageSelection' nullable: true fees: type: array items: $ref: '#/components/schemas/DispatchFeeItem' nullable: true DispatchArrangeDelivery: type: object x-java-record: DispatchDeliveryModels.ArrangeDelivery properties: recordVersion: oneOf: - type: string pattern: ^[0-9]+$ - type: integer minimum: 0 description: 已有单写入必填;0合法。响应Long按十进制字符串输出。 idempotencyKey: type: string cargoHash: type: string nullable: true loadingCompletionHash: type: string nullable: true groups: type: array items: $ref: '#/components/schemas/DispatchArrangeGroup' nullable: true required: - recordVersion - idempotencyKey description: 全车原子安排;每客户出库,每客户目的仓派送。包含全部组,费用和来源依据重新校验,不重复库存SHIP。 DispatchOutboundReference: type: object x-java-record: DispatchDeliveryModels.OutboundReference properties: customerId: type: string nullable: true customerName: type: string nullable: true outboundNo: type: string nullable: true status: type: string nullable: true packageCount: type: string pattern: ^[0-9]+$ palletCount: type: string pattern: ^[0-9]+$ DispatchDeliveryReference: type: object x-java-record: DispatchDeliveryModels.DeliveryReference properties: groupKey: type: string nullable: true customerId: type: string nullable: true customerName: type: string nullable: true outboundNo: type: string nullable: true deliveryNo: type: string nullable: true destination: allOf: - $ref: '#/components/schemas/DispatchDestination' nullable: true status: type: string nullable: true packageCount: type: string pattern: ^[0-9]+$ palletCount: type: string pattern: ^[0-9]+$ DispatchArrangementResult: type: object x-java-record: DispatchDeliveryModels.ArrangementResult properties: dispatchNo: type: string nullable: true recordVersion: oneOf: - type: string pattern: ^[0-9]+$ - type: integer minimum: 0 description: 已有单写入必填;0合法。响应Long按十进制字符串输出。 arrangementKey: type: string nullable: true cargoHash: type: string nullable: true arrangedAt: type: string format: date-time nullable: true outbounds: type: array items: $ref: '#/components/schemas/DispatchOutboundReference' nullable: true deliveries: type: array items: $ref: '#/components/schemas/DispatchDeliveryReference' nullable: true required: - dispatchNo - recordVersion - arrangementKey - cargoHash - arrangedAt - outbounds - deliveries DispatchExternalQuote: type: object x-java-record: DispatchDeliveryModels.ExternalQuote properties: customerId: type: string nullable: true groupKey: type: string nullable: true bookingNo: type: string nullable: true inboundCode: type: string nullable: true currency: type: string nullable: true amount: type: number nullable: true sourceHash: type: string nullable: true DispatchFeeCandidate: type: object x-java-record: DispatchDeliveryModels.FeeCandidate properties: financeFeeId: type: string pattern: ^[0-9]+$ nullable: true customerId: type: string nullable: true currency: type: string nullable: true amount: type: number nullable: true sourceVersion: type: integer sourceHash: type: string nullable: true status: type: string nullable: true services: type: array items: type: string nullable: true sourceKeys: type: array items: type: string nullable: true DispatchPreviewGroup: type: object x-java-record: DispatchDeliveryModels.PreviewGroup properties: groupKey: type: string nullable: true customerId: type: string nullable: true customerName: type: string nullable: true destination: allOf: - $ref: '#/components/schemas/DispatchDestination' nullable: true groupCargoHash: type: string nullable: true cargo: type: array items: $ref: '#/components/schemas/DispatchCargoLine' nullable: true externalFreightHash: type: string nullable: true externalQuotes: type: array items: $ref: '#/components/schemas/DispatchExternalQuote' nullable: true feeCoverageCargoHash: type: string nullable: true feeSources: type: array items: $ref: '#/components/schemas/DispatchFeeCandidate' nullable: true requiredServices: type: array items: type: string nullable: true blockReasons: type: array items: type: string nullable: true DispatchArrangementPreview: type: object x-java-record: DispatchDeliveryModels.ArrangementPreview properties: dispatchNo: type: string nullable: true recordVersion: oneOf: - type: string pattern: ^[0-9]+$ - type: integer minimum: 0 description: 已有单写入必填;0合法。响应Long按十进制字符串输出。 status: allOf: - $ref: '#/components/schemas/DispatchStatus' nullable: true stage: allOf: - $ref: '#/components/schemas/DispatchStage' nullable: true cargoHash: type: string nullable: true loadingCompletionHash: type: string nullable: true arrange: allOf: - $ref: '#/components/schemas/DispatchGate' nullable: true groups: type: array items: $ref: '#/components/schemas/DispatchPreviewGroup' nullable: true arrangement: allOf: - $ref: '#/components/schemas/DispatchArrangementResult' nullable: true required: - recordVersion DispatchSaved: type: object x-java-record: DispatchResults.Saved properties: dispatchNo: type: string nullable: true changedItemIds: type: array items: type: string pattern: ^[0-9]+$ nullable: true required: - dispatchNo - changedItemIds DispatchPicked: type: object x-java-record: DispatchResults.Picked properties: dispatchItemId: type: string pattern: ^[0-9]+$ nullable: true positionId: type: string pattern: ^[0-9]+$ nullable: true returnCartonId: type: string pattern: ^[0-9]+$ nullable: true packages: type: string pattern: ^[0-9]+$ pickedPackages: type: string pattern: ^[0-9]+$ pickingReconciled: type: boolean required: - dispatchItemId - positionId - returnCartonId - packages - pickedPackages - pickingReconciled DispatchLoaded: type: object x-java-record: DispatchResults.Loaded properties: loadingCompletionHash: type: string nullable: true loadingCompletedAt: type: string format: date-time nullable: true confirmedLoad: allOf: - $ref: '#/components/schemas/DispatchConfirmedLoad' nullable: true required: - loadingCompletionHash - loadingCompletedAt - confirmedLoad DispatchDeparted: type: object x-java-record: DispatchResults.Departed properties: departedAt: type: string format: date-time nullable: true shippedPackages: type: string pattern: ^[0-9]+$ outbounds: type: array items: $ref: '#/components/schemas/DispatchOutboundReference' nullable: true deliveries: type: array items: $ref: '#/components/schemas/DispatchDeliveryReference' nullable: true required: - departedAt - shippedPackages - outbounds - deliveries DispatchPayload: oneOf: - $ref: '#/components/schemas/DispatchSaved' - $ref: '#/components/schemas/DispatchPicked' - $ref: '#/components/schemas/DispatchLoaded' - $ref: '#/components/schemas/DispatchDeparted' - $ref: '#/components/schemas/DispatchArrangementResult' DispatchEvidenceFile: type: object properties: fileId: type: string pattern: ^[1-9][0-9]*$ fileName: type: string contentType: type: string enum: - application/pdf - image/jpeg - image/png sizeBytes: type: string pattern: ^[0-9]+$ DispatchSelectionGroup: type: object x-java-record: DispatchPlanningModels.SelectionGroup properties: groupKey: type: string groupVersion: type: string sources: type: array items: $ref: '#/components/schemas/DispatchSelectionGroupSource' pallets: type: array items: $ref: '#/components/schemas/DispatchSelectionGroupPallet' complete: type: boolean blockReasons: type: array items: type: string required: - groupKey - groupVersion - sources - pallets - complete - blockReasons description: 服务端按完整实托及整换标申请计算未被页面筛选截断的来源集合;版本绑定组成、完工轮次、实际位置和各来源版本。complete=false或blockReasons非空禁止选入。 DispatchSelectionGroupSource: type: object x-java-record: DispatchPlanningModels.SelectionGroupSource properties: selection: allOf: - $ref: '#/components/schemas/DispatchCargoSelection' sourceKey: type: string customerId: type: string customerName: type: string nullable: true sourceBusinessType: type: string nullable: true sourceBusinessNo: type: string nullable: true packages: type: string pattern: ^[0-9]+$ required: - selection - sourceKey - customerId - customerName - sourceBusinessType - sourceBusinessNo - packages description: 客户和换标业务号按逻辑来源保留;selection携带本来源权威版本,正式建单和加货显式提交完整组,不从展示sourceKey推业务号。 DispatchSelectionGroupPallet: type: object x-java-record: DispatchPlanningModels.SelectionGroupPallet properties: warehousePalletId: type: string pattern: ^[0-9]+$ palletNo: type: string sourceKeys: type: array items: type: string packageCount: type: string pattern: ^[0-9]+$ required: - warehousePalletId - palletNo - sourceKeys - packageCount description: 每实托只列一次,sourceKeys列出全部逻辑贡献;实际装载按实托测量,不能把整托容量重复计到各来源。 DispatchSourceOrigin: type: object x-java-record: DispatchContracts.SourceOrigin properties: dispatchItemSourceId: type: string pattern: ^[0-9]+$ nullable: true relabelApplicationId: type: string pattern: ^[0-9]+$ nullable: true relabelItemId: type: string pattern: ^[0-9]+$ nullable: true sourceInventoryBalanceId: type: string pattern: ^[0-9]+$ nullable: true sourceInboundOrderId: type: string pattern: ^[0-9]+$ nullable: true sourceInboundOrderNo: type: string nullable: true sourceInboundCode: type: string nullable: true productQuantity: type: string pattern: ^[0-9]+$ nullable: true required: - dispatchItemSourceId - relabelApplicationId - relabelItemId - sourceInventoryBalanceId - sourceInboundOrderId - sourceInboundOrderNo - sourceInboundCode - productQuantity DispatchExceptionType: type: string enum: [REFUSED, PARTIAL_RECEIPT, VEHICLE_EXCEPTION] description: 拒收、部分签收、车辆异常。 DispatchReturnDirection: type: string enum: [OVERSEAS_WAREHOUSE, OTHER] description: 退回海外仓、其他;仅登记去向,不自动退货入库。 DispatchMarkException: type: object x-java-record: DispatchCommands.MarkException required: [recordVersion, idempotencyKey, exceptionType] properties: recordVersion: oneOf: - type: string pattern: ^[0-9]+$ - type: integer minimum: 0 idempotencyKey: type: string exceptionType: $ref: '#/components/schemas/DispatchExceptionType' returnDirection: allOf: - $ref: '#/components/schemas/DispatchReturnDirection' nullable: true description: type: string maxLength: 1000 nullable: true imageFileIds: type: array maxItems: 20 uniqueItems: true items: type: string pattern: ^[1-9][0-9]*$ DispatchExceptionRecord: type: object x-java-record: DispatchViews.ExceptionRecord required: [exceptionType, returnDirection, description, imageFileIds, occurredAt] properties: exceptionType: $ref: '#/components/schemas/DispatchExceptionType' returnDirection: allOf: - $ref: '#/components/schemas/DispatchReturnDirection' nullable: true description: type: string nullable: true imageFileIds: type: array items: type: string occurredAt: type: string format: date-time securitySchemes: bearerAuth: { type: http, scheme: bearer, bearerFormat: JWT }