openapi: 3.0.3 info: title: 跨客户 FBA 预约与日历 version: 2.0.0 description: 同一美国起运仓和目的FBA仓的跨客户安排。系统单号与外部约号分开;入仓前后共用稳定货源,只有平台可维护完整预约,不推进库存或现场作业。 security: - bearerAuth: [] paths: /api/platform/v1/last-leg/inbound-plans/fba-appointments/batch: post: summary: 为同一目的仓的跨客户入仓明细创建预约 description: '权限:platform:overseas-warehouse:inbound-order:fba-appointment。平台身份限定。入仓明细仅作选择入口,服务端转成原ORDER/BOOKING整票来源,不另建别名。系统生成appointmentNo,不接受主单客户或外部号冒充系统单号。同键、同操作者、同内容返回原命令快照;异内容拒绝。与入仓前货源入口共用同一主表及唯一占用约束。' requestBody: required: true content: application/json: schema: allOf: - {$ref: '#/components/schemas/AppointmentWrite'} - type: object required: [lineIds, originWarehouseId, fbaWarehouseCode] properties: originWarehouseId: {type: string, minLength: 1, description: 选择时的接仓点,保存时核对} fbaWarehouseCode: {type: string, minLength: 1, maxLength: 64, description: 选择时的目的仓,变化则拒绝} lineIds: {type: array, minItems: 1, maxItems: 100, items: {type: string}} responses: '200': {$ref: '#/components/responses/AppointmentResult'} '403': {description: 非平台身份或无写权限} /api/platform/v1/last-leg/inbound-plans/fba-appointments/{appointmentNo}: parameters: - name: appointmentNo in: path required: true schema: {type: string} delete: summary: 取消未关联有效排车的预约并释放占用 description: '平台专用,权限platform:appointment:delete。校验版本后保留主单、确认事实及明细历史,设置CANCELLED并释放货源占用;不删除客户货物或回退库存。已有关联有效排车时拒绝。取消命令按系统单号、版本和操作者幂等。' parameters: - {name: version, in: query, required: true, schema: {type: integer, minimum: 0}} responses: '200': {description: 业务响应,成功code为字符串200;版本冲突或已关联排车返回业务错误} '403': {description: 无删除权限} get: summary: 读取完整跨客户预约 description: '仅平台,权限:platform:appointment:list 或 platform:overseas-warehouse:inbound-order:list。客户只能经原订单/入仓单接口读取自己的货物,不开放整张预约。' responses: '200': {$ref: '#/components/responses/AppointmentResult'} '403': {description: 无读取权限} put: summary: 按版本更新预约 description: '权限:platform:overseas-warehouse:inbound-order:fba-appointment。平台限定,版本及持久化幂等校验;已有有效排车时先处理运输安排。取消/失败必须写原因并保留原确认时间。恢复时重新核对来源、目的仓和占用;不能直接将SUCCESS退回PENDING。' requestBody: required: true content: application/json: schema: allOf: - {$ref: '#/components/schemas/AppointmentWrite'} - type: object required: [version] properties: version: {type: integer, minimum: 0} responses: '200': {$ref: '#/components/responses/AppointmentResult'} '403': {description: 无写权限} /api/platform/v1/last-leg/inbound-plans/fba-appointments/calendar: get: operationId: fbaAppointmentCalendar summary: 按日期范围查询 FBA 预约 description: '权限:platform:appointment:list。按确认当地时间、计划时段或仅计划日期选取,排除取消/失败。跨日时段只要与查询区间相交即返回,结束时间为不包含的边界;已有确认开始时间时只使用对应确认结束时间,不借用计划结束时间。仅有日期时不补造零点时段;无日期记录走未定时分页入口。固定批量查询预约及明细,不逐预约查详情。跨时区总览仍需按地点标注,不将当地值当成浏览器时区。' parameters: - name: from in: query required: true description: 包含该日期零点,以现有预约业务日期为准。 schema: {type: string, format: date} - name: to in: query required: true description: 不包含该日期零点;必须晚于from,间隔不超过42天。 schema: {type: string, format: date} responses: '200': description: 业务响应;成功code为字符串200,空区间返回空数组。 content: application/json: schema: type: object properties: code: {type: string} message: {type: string} data: type: array items: {$ref: '#/components/schemas/Appointment'} '401': {description: 未登录或会话失效} '403': {description: 无列表权限} components: responses: AppointmentResult: description: 业务响应,成功code为字符串200,业务冲突返回对应业务错误码。 content: application/json: schema: type: object properties: code: {type: string} message: {type: string} data: {$ref: '#/components/schemas/Appointment'} securitySchemes: bearerAuth: {type: http, scheme: bearer, bearerFormat: JWT} schemas: AppointmentWrite: type: object required: [details, idempotencyKey] properties: details: {$ref: '#/components/schemas/AppointmentDetails'} idempotencyKey: {type: string, minLength: 1, maxLength: 64} AppointmentDetails: type: object required: [appointmentStatus] properties: plannedDate: {type: string, format: date, nullable: true, description: 计划当地日期,允许未定} plannedAt: {type: string, nullable: true, description: 已知的计划开始当地时段,日期必须与plannedDate一致} plannedEndAt: {type: string, nullable: true} confirmationNo: {type: string, maxLength: 128, nullable: true, description: 仅SUCCESS登记收货方的外部约号;同一FBA仓不得重复} appointmentAt: {type: string, nullable: true, description: 对方确认开始当地时间;SUCCESS必填,PENDING不能当作计划填写} appointmentEndAt: {type: string, nullable: true, description: 明确结束时间时必须晚于开始时间;未知留空,不推算} appointmentStatus: {type: string, enum: [PENDING, SUCCESS, FAILED, CANCELLED]} appointmentRemark: {type: string, maxLength: 1000, nullable: true} startOffset: {type: string, maxLength: 6, nullable: true, description: 当地重叠时刻的明确时差;必须符合目的仓IANA时区} endOffset: {type: string, maxLength: 6, nullable: true} Appointment: type: object properties: id: {type: string, description: 内部标识,不作为展示编号} appointmentNo: {type: string, description: 系统生成AP业务单号} confirmationNo: {type: string, nullable: true, description: 对方正式外部确认号} plannedDate: {type: string, format: date, nullable: true} plannedAt: {type: string, nullable: true} plannedEndAt: {type: string, nullable: true} appointmentAt: {type: string, nullable: true, description: 对方确认的地点当地时间} appointmentEndAt: {type: string, nullable: true} version: {type: integer, minimum: 0} appointmentStartUtc: {type: string, format: date-time, nullable: true} appointmentEndUtc: {type: string, format: date-time, nullable: true} timezone: {type: string, nullable: true, description: 来自美国FBA仓主档的IANA时区;缺失不得正式确认} originWarehouseId: {type: string} appointmentStatus: {type: string, enum: [PENDING, SUCCESS, FAILED, CANCELLED]} appointmentRemark: {type: string, nullable: true} fbaWarehouseCode: {type: string} selectedCount: {type: integer} createdBy: {type: string, nullable: true} createdAt: {type: string} updatedAt: {type: string} items: type: array items: type: object properties: id: {type: string} customerId: {type: string, description: 本票货物客户归属,不在预约主单指定客户} sourceKey: {type: string} sourceVersion: {type: string, nullable: true} orderId: {type: string, nullable: true} inboundCode: {type: string, nullable: true} packageCount: {type: integer, nullable: true} fbaWarehouseCode: {type: string}