openapi: 3.0.3 info: title: V13 收货预约覆盖、客户变化及重新预约 version: 1.0.0 description: 稳定批次与有效收货预约身份分离;Agreement.version覆盖资料和成员范围。新共约必须新agreementKey,不以约号相等推断成员。同一次移出为Lastleg本地事务:transport锁序车次→排车→出库/PDA→批次,任一步失败全部回滚,不返回批次部分成功。成功Result持久化且同键重放返回原快照;异内容冲突。后续约仓/配车独立续办使用成功batchKey,不重建已成功货物。WAITING保存原安排和数量,只有CONFIRM按原scope/source/verification及batch版本复验后应用;WITHDRAW保留原安排。实际发车另由原Dispatch/Fleet检查pending及有效收货范围。未知量、版本冲突、来源不可用均拒绝,不伪造0项。 负责人提交ownerId并由平台人员目录校验;后送及再次分批继承权威负责人和跟进资料。重约使用按客户核对的executionVersion,不让同批无关已完成客户阻断未完成员;已完成成员不得再次预约。WITHDRAW只撤回未生效变化,不改原货物/车辆,运输开始或版本变化不阻断撤回;仍须变化版本与幂等校验。 paths: /api/platform/v1/last-leg/appointment-receiving/batches/{batchKey}: get: summary: 读取本批真实收货覆盖和待确认变化 description: '平台身份 tenantId=0。Required authority: platform:appointment:list' security: - bearerAuth: [] responses: '200': description: ApiResponse:成功code="200";业务错误按统一封装返回,不把HTTP 200当业务成功。 content: application/json: schema: type: object properties: code: &id001 type: string message: *id001 data: $ref: '#/components/schemas/Context' parameters: - name: batchKey in: path required: true schema: *id001 /api/platform/v1/last-leg/appointment-receiving/agreements/{agreementKey}: get: summary: 读取当前范围和取消组重约候选及排除原因 description: '平台身份 tenantId=0。Required authority: platform:appointment:list' security: - bearerAuth: [] responses: '200': description: ApiResponse:成功code="200";业务错误按统一封装返回,不把HTTP 200当业务成功。 content: application/json: schema: type: object properties: code: *id001 message: *id001 data: $ref: '#/components/schemas/GroupContext' parameters: - name: agreementKey in: path required: true schema: *id001 /api/platform/v1/last-leg/appointment-receiving/changes: post: summary: 保存客户待确认变化,保留原安排并阻发 description: '平台身份 tenantId=0。Required authority: platform:overseas-warehouse:inbound-order:fba-appointment AND platform:appointment:delete' security: - bearerAuth: [] responses: '200': description: ApiResponse:成功code="200";业务错误按统一封装返回,不把HTTP 200当业务成功。 content: application/json: schema: type: object properties: code: *id001 message: *id001 data: $ref: '#/components/schemas/Result' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/Propose' /api/platform/v1/last-leg/appointment-receiving/changes/{changeKey}/resolve: post: summary: 确认并原子移出,或撤回本次变化 description: '平台身份 tenantId=0。Required authority: platform:overseas-warehouse:inbound-order:fba-appointment AND platform:appointment:delete' security: - bearerAuth: [] responses: '200': description: ApiResponse:成功code="200";业务错误按统一封装返回,不把HTTP 200当业务成功。 content: application/json: schema: type: object properties: code: *id001 message: *id001 data: $ref: '#/components/schemas/Result' parameters: - name: changeKey in: path required: true schema: *id001 requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/Resolve' /api/platform/v1/last-leg/appointment-receiving/bookings: post: summary: 沿用现有批次创建共同或独立收货预约 description: '平台身份 tenantId=0。Required authority: platform:overseas-warehouse:inbound-order:fba-appointment' security: - bearerAuth: [] responses: '200': description: ApiResponse:成功code="200";业务错误按统一封装返回,不把HTTP 200当业务成功。 content: application/json: schema: type: object properties: code: *id001 message: *id001 data: $ref: '#/components/schemas/Result' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/Book' /api/platform/v1/last-leg/appointment-receiving/agreements/{agreementKey}/reschedule: post: summary: 整份当前收货预约改期 description: '平台身份 tenantId=0。Required authority: platform:overseas-warehouse:inbound-order:fba-appointment' security: - bearerAuth: [] responses: '200': description: ApiResponse:成功code="200";业务错误按统一封装返回,不把HTTP 200当业务成功。 content: application/json: schema: type: object properties: code: *id001 message: *id001 data: $ref: '#/components/schemas/Result' parameters: - name: agreementKey in: path required: true schema: *id001 requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/GroupChange' /api/platform/v1/last-leg/appointment-receiving/agreements/{agreementKey}/cancel: post: summary: 整份当前收货预约取消并保留货量及车辆 description: '平台身份 tenantId=0。Required authority: platform:appointment:delete' security: - bearerAuth: [] responses: '200': description: ApiResponse:成功code="200";业务错误按统一封装返回,不把HTTP 200当业务成功。 content: application/json: schema: type: object properties: code: *id001 message: *id001 data: $ref: '#/components/schemas/Result' parameters: - name: agreementKey in: path required: true schema: *id001 requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/GroupChange' /api/platform/v1/last-leg/appointment-receiving/plans: post: summary: 只保存本客户未确认的送仓计划,不改变其他客户正式确认 description: '平台身份 tenantId=0。Required authority: platform:overseas-warehouse:inbound-order:fba-appointment。已正式确认、待变化确认或已执行客户不可直接改计划;清目标仍保留需求。计划不创建预约确认、不重新占量。' security: - bearerAuth: [] responses: '200': description: ApiResponse:成功code="200";业务错误按统一封装返回,不把HTTP 200当业务成功。 content: application/json: schema: type: object properties: code: &id002 type: string message: *id002 data: $ref: '#/components/schemas/Result' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/Plan' /api/platform/v1/last-leg/appointment-receiving/execution-scope: post: summary: 按实际选择的客户批次只读核对执行资格和提交版本 description: '平台身份 tenantId=0。Required authority: platform:appointment:list。只读,不保存计划或预约。跨批次取消组只选部分成员时先读取本范围执行版本,前端重新确认选择;写入仍独立校验批次及取消组版本。' security: - bearerAuth: [] responses: '200': description: ApiResponse:成功code="200";业务错误按统一封装返回,不把HTTP 200当业务成功。 content: application/json: schema: type: object properties: code: &id003 type: string message: *id003 data: $ref: '#/components/schemas/ExecutionScope' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ExecutionQuery' /api/platform/v1/last-leg/appointment-receiving/cargo-refresh: post: summary: 明确核对并采用本客户最新货物资料 description: '平台身份 tenantId=0。Required authority: platform:overseas-warehouse:inbound-order:fba-appointment。仅未确认且未执行客户可采用,清晰核对本批量、最新核实总量及货件号;来源目的地或客户改变不得采用,不修改原订单。' security: - bearerAuth: [] responses: '200': description: ApiResponse:成功code="200";业务错误按统一封装返回,不把HTTP 200当业务成功。 content: application/json: schema: type: object properties: code: &id004 type: string message: *id004 data: $ref: '#/components/schemas/Result' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/RefreshCargo' components: securitySchemes: bearerAuth: type: http scheme: bearer schemas: Source: type: object properties: sourceKey: *id001 destinationKey: *id001 packageCount: type: integer minimum: 1 sourceVersion: *id001 verificationVersion: type: integer nullable: true inboundCode: type: string nullable: true description: 原来源入仓业务号;未知显示— required: - sourceKey - destinationKey - packageCount - sourceVersion - verificationVersion Member: type: object properties: batchKey: *id001 appointmentNo: *id001 batchVersion: &id005 type: integer minimum: 0 customerId: *id001 sources: type: array items: $ref: '#/components/schemas/Source' customerName: type: string nullable: true description: 原订单真实客户名称;未知显示—,不用内部标识回退 required: - batchKey - appointmentNo - batchVersion - customerId - sources Details: type: object properties: plannedDate: &id006 type: string format: date nullable: true plannedAt: type: string format: date-time nullable: true plannedEndAt: type: string format: date-time nullable: true confirmationNo: *id001 appointmentAt: type: string format: date-time appointmentEndAt: type: string format: date-time nullable: true appointmentStatus: type: string enum: - SUCCESS appointmentRemark: type: string nullable: true startOffset: type: string nullable: true endOffset: type: string nullable: true required: - confirmationNo - appointmentAt - appointmentStatus Agreement: type: object properties: agreementKey: *id001 version: *id005 status: type: string enum: - ACTIVE - CANCELLED - SUPERSEDED destinationKey: *id001 details: $ref: '#/components/schemas/Details' timezone: *id001 members: type: array items: $ref: '#/components/schemas/Member' warehouseEvidence: *id001 required: - agreementKey - version - status - destinationKey - details - timezone - members - warehouseEvidence Vehicle: type: object properties: tripNo: type: string nullable: true version: type: integer nullable: true dispatchNo: *id001 customerId: *id001 batchKey: *id001 status: *id001 packageCount: *id005 required: - tripNo - version - dispatchNo - customerId - batchKey - status - packageCount Transport: type: object properties: version: *id001 vehicles: type: array items: $ref: '#/components/schemas/Vehicle' blockReasons: type: array items: *id001 required: - version - vehicles - blockReasons Selection: type: object properties: batchKey: *id001 batchVersion: *id005 customerId: *id001 required: - batchKey - batchVersion - customerId Quantity: type: object properties: sourceKey: *id001 destinationKey: *id001 retainedPackages: *id005 expectedSourceVersion: *id001 expectedVerificationVersion: type: integer nullable: true required: - sourceKey - destinationKey - retainedPackages - expectedSourceVersion - expectedVerificationVersion ChangeIntent: type: object properties: batchKey: *id001 batchVersion: *id005 customerId: *id001 quantities: type: array items: $ref: '#/components/schemas/Quantity' laterDate: *id006 nextFollowupDate: *id006 reason: *id001 transportVersion: *id001 ownerId: *id001 required: - batchKey - batchVersion - customerId - quantities - ownerId - reason - transportVersion Pending: type: object properties: changeKey: *id001 version: *id005 status: type: string enum: - WAITING - APPLIED - WITHDRAWN intent: $ref: '#/components/schemas/ChangeIntent' originalMembers: type: array items: $ref: '#/components/schemas/Member' originalAgreements: type: array items: $ref: '#/components/schemas/Agreement' followup: $ref: '#/components/schemas/Followup' required: - changeKey - version - status - intent - originalMembers - originalAgreements - followup Context: type: object properties: batch: $ref: ./fba-appointment-calendar-v1.yaml#/components/schemas/Appointment agreements: type: array items: $ref: '#/components/schemas/Agreement' pendingChanges: type: array items: $ref: '#/components/schemas/Pending' transport: $ref: '#/components/schemas/Transport' allowedActions: type: array items: type: string enum: - BOOK_RECEIVING - PROPOSE_CUSTOMER_CHANGE blockReasons: type: array items: *id001 executionScope: $ref: '#/components/schemas/ExecutionScope' plans: type: array items: $ref: '#/components/schemas/CustomerPlan' required: - batch - agreements - pendingChanges - transport - allowedActions - blockReasons - executionScope - plans Excluded: type: object properties: member: $ref: '#/components/schemas/Member' reason: *id001 currentAgreementKey: type: string nullable: true required: - member - reason - currentAgreementKey GroupContext: type: object properties: agreement: $ref: '#/components/schemas/Agreement' eligibleMembers: type: array items: $ref: '#/components/schemas/Member' excludedMembers: type: array items: $ref: '#/components/schemas/Excluded' transport: $ref: '#/components/schemas/Transport' executionScope: $ref: '#/components/schemas/ExecutionScope' required: - agreement - eligibleMembers - excludedMembers - transport - executionScope Propose: type: object properties: idempotencyKey: *id001 intent: $ref: '#/components/schemas/ChangeIntent' required: - idempotencyKey - intent Resolve: type: object properties: idempotencyKey: *id001 version: *id005 decision: type: string enum: - CONFIRM - WITHDRAW warehouseEvidence: type: string nullable: true transportVersion: *id001 required: - idempotencyKey - version - decision - transportVersion Booking: type: object properties: members: type: array items: $ref: '#/components/schemas/Selection' details: $ref: '#/components/schemas/Details' warehouseEvidence: *id001 required: - members - details - warehouseEvidence Book: type: object properties: idempotencyKey: *id001 bookings: type: array items: $ref: '#/components/schemas/Booking' cancelledAgreementKey: type: string nullable: true cancelledAgreementVersion: type: integer nullable: true executionVersion: *id001 required: - idempotencyKey - bookings - executionVersion GroupChange: type: object properties: idempotencyKey: *id001 version: *id005 action: type: string enum: - RESCHEDULE - CANCEL details: $ref: '#/components/schemas/Details' nullable: true warehouseEvidence: *id001 transportVersion: *id001 required: - idempotencyKey - version - action - warehouseEvidence - transportVersion Step: type: object properties: step: *id001 status: type: string enum: - SUCCESS targetKey: *id001 message: *id001 required: - step - status - targetKey - message Result: type: object properties: changeKey: type: string nullable: true status: type: string enum: - WAITING - APPLIED - WITHDRAWN - UNCHANGED batches: type: array items: $ref: ./fba-appointment-calendar-v1.yaml#/components/schemas/Appointment agreements: type: array items: $ref: '#/components/schemas/Agreement' steps: type: array items: $ref: '#/components/schemas/Step' nextActions: type: array items: type: string description: 主要下一步及原车辆业务返回的实际后续动作,沿Result中的稳定batchKey继续,不重复创建货物 required: - changeKey - status - batches - agreements - steps - nextActions Followup: type: object properties: ownerId: type: string ownerName: type: string nextFollowupDate: type: string format: date nullable: true required: - ownerId - ownerName - nextFollowupDate ExecutionMember: type: object properties: batchKey: type: string customerId: type: string required: - batchKey - customerId ExecutionEligibility: type: object properties: member: $ref: '#/components/schemas/ExecutionMember' completed: type: boolean canRebook: type: boolean reason: type: string nullable: true required: - member - completed - canRebook - reason ExecutionScope: type: object description: 原业务按客户、批次及逐票履约事实核对;version绑定涉及批次的完整执行事实,资格仅针对所选客户。 properties: version: type: string members: type: array items: $ref: '#/components/schemas/ExecutionEligibility' required: - version - members CustomerPlan: type: object required: - batchKey - customerId - details properties: batchKey: type: string customerId: type: string details: $ref: ./fba-appointment-calendar-v1.yaml#/components/schemas/AppointmentDetails timezone: type: string nullable: true description: 按稳定批次及客户保存的未确认收货计划;仅PENDING/FAILED,目标可空,不包含有效确认或货物分配。 Plan: type: object required: - idempotencyKey - member - details - executionVersion properties: idempotencyKey: type: string maxLength: 64 member: $ref: '#/components/schemas/Selection' details: $ref: ./fba-appointment-calendar-v1.yaml#/components/schemas/AppointmentDetails executionVersion: type: string description: 仅PENDING/FAILED,confirmationNo、appointmentAt、appointmentEndAt必须为空;FAILED必须有原因。服务端校验客户实际执行资格、批次及来源/核实版本,同键幂等。 非空目标须目的仓有效IANA时区;计划时刻按DST与跨日规则校验。此命令中details.startOffset/endOffset对应计划窗口;仅日期或目标为空不携带offset。 ExecutionQuery: type: object required: - members properties: members: type: array minItems: 1 maxItems: 200 uniqueItems: true items: $ref: '#/components/schemas/ExecutionMember' CargoVersion: type: object required: - sourceKey - destinationKey - expectedSourceVersion properties: sourceKey: type: string destinationKey: type: string expectedSourceVersion: type: string expectedVerificationVersion: type: integer minimum: 1 nullable: true RefreshCargo: type: object required: - idempotencyKey - member - sources - executionVersion properties: idempotencyKey: type: string maxLength: 64 member: $ref: '#/components/schemas/Selection' sources: type: array minItems: 1 maxItems: 100 items: $ref: '#/components/schemas/CargoVersion' executionVersion: type: string description: 操作者先读取并核对本客户各原来源最新核实资料,再显式采用。只更新原批次本客户明细的源/核实版本和货件快照,原分配数量、来源身份和其他客户确认保持。已确认、待变化确认、已执行、源/核实版本变化或数量不守恒拒绝;同键幂等,不自动采用。