270 lines
16 KiB
YAML
270 lines
16 KiB
YAML
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,清除当前有效计划日期、确认号及时段;旧计划与确认保存在不可变取消命令历史。货物分配保持有效,不能再次从整票创建相同货量;不删除客户货物或回退库存。已有关联有效排车时拒绝。取消原因必填,独立保存于取消命令历史,不覆盖原业务备注;按系统单号、版本、操作者及原因校验幂等,异内容拒绝。'
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required: [version, cancelReason]
|
||
properties:
|
||
version: {type: integer, minimum: 0}
|
||
cancelReason: {type: string, minLength: 1, maxLength: 1000, description: 实际取消原因,不能仅含空白}
|
||
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。平台限定,版本及持久化幂等校验;已有有效排车时先处理运输安排。未约成必须写原因,清除无效确认,但保留本批货物分配。禁止通过更新设置CANCELLED,取消必须调用DELETE并通过独立取消权限、实际原因和历史规则。重新安排时重新核对来源、目的仓和占用,沿原批次数量继续;不能直接将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/cancellations:
|
||
get:
|
||
summary: 分页发现预约快捷取消记录
|
||
description: '仅平台;权限同详情:platform:appointment:list或platform:overseas-warehouse:inbound-order:list。仅取消命令摘要,不扩展普通编辑历史。服务端分页,不逐行读取详情;按取消时间倒序。'
|
||
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}}
|
||
responses:
|
||
'200':
|
||
description: code为字符串200;data含records、page、size、total、pages
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
code: {type: string}
|
||
data:
|
||
type: object
|
||
properties:
|
||
page: {type: integer}
|
||
size: {type: integer}
|
||
total: {type: integer, format: int64}
|
||
pages: {type: integer, format: int64}
|
||
records:
|
||
type: array
|
||
items:
|
||
type: object
|
||
properties:
|
||
appointmentNo: {type: string}
|
||
version: {type: integer}
|
||
cancelReason: {type: string, nullable: true}
|
||
cancelledAt: {type: string, description: UTC取消时间}
|
||
fbaWarehouseCode: {type: string}
|
||
selectedCount: {type: integer}
|
||
'400': {description: 分页参数无效}
|
||
'403': {description: 非平台身份或无读取权限}
|
||
/api/platform/v1/last-leg/inbound-plans/fba-appointments/{appointmentNo}/cancellations:
|
||
get:
|
||
summary: 分页读取此预约的快捷取消命令历史
|
||
description: '仅平台;权限同预约详情:platform:appointment:list或platform:overseas-warehouse:inbound-order:list。按预约业务号限定,最新取消在前。不包含普通编辑记录,不返回原始JSON、命令键或内部账号ID;历史缺原因返回null,不回填。'
|
||
parameters:
|
||
- {name: appointmentNo, in: path, required: true, schema: {type: string}}
|
||
- {name: page, in: query, schema: {type: integer, minimum: 1, default: 1}}
|
||
- {name: size, in: query, schema: {type: integer, minimum: 1, maximum: 100, default: 20}}
|
||
responses:
|
||
'200':
|
||
description: 业务响应,code为字符串200
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
code: {type: string}
|
||
message: {type: string}
|
||
data:
|
||
type: object
|
||
properties:
|
||
page: {type: integer}
|
||
size: {type: integer}
|
||
total: {type: integer, format: int64}
|
||
pages: {type: integer, format: int64}
|
||
records:
|
||
type: array
|
||
items:
|
||
type: object
|
||
properties:
|
||
appointmentNo: {type: string}
|
||
version: {type: integer, description: 取消后版本}
|
||
cancelReason: {type: string, nullable: true}
|
||
cancelledAt: {type: string, description: UTC取消命令时间,yyyy-MM-ddTHH:mm:ss}
|
||
snapshot:
|
||
type: object
|
||
properties:
|
||
fbaWarehouseCode: {type: string}
|
||
appointmentStatus: {type: string}
|
||
appointmentRemark: {type: string, nullable: true, description: 原业务备注}
|
||
plannedDate: {type: string, format: date, nullable: true}
|
||
plannedAt: {type: string, nullable: true}
|
||
plannedEndAt: {type: string, nullable: true}
|
||
confirmationNo: {type: string, nullable: true}
|
||
appointmentAt: {type: string, nullable: true}
|
||
appointmentEndAt: {type: string, nullable: true}
|
||
timezone: {type: string, nullable: true}
|
||
selectedCount: {type: integer}
|
||
'400': {description: 分页参数无效}
|
||
'403': {description: 非平台身份或无详情读取权限}
|
||
'404': {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]}
|
||
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业务单号}
|
||
batchKey: {type: string, description: FBA_APPOINTMENT加不可变主键,用于工作事项关联,不展示内部键}
|
||
replacementBatchKeys: {type: array, items: {type: string}, description: 分批/合并后的稳定批次键;旧批次历史保留}
|
||
replacementAppointmentNos: {type: array, items: {type: string}, description: 替代批次业务号;非空时原批次只读}
|
||
repartitionReason: {type: string, nullable: true}
|
||
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}
|
||
destinationKey: {type: string, description: 本票目的地FBA加仓码,与原来源归属一同保留}
|
||
sourceVersion: {type: string, nullable: true}
|
||
orderId: {type: string, nullable: true}
|
||
inboundCode: {type: string, nullable: true}
|
||
packageCount: {type: integer, nullable: true}
|
||
cargoVerificationVersion: {type: integer, nullable: true, description: 本次采用的独立核实版本,后续单独核实不改写此快照}
|
||
shipmentReferences: {type: array, items: {type: string}, description: 本次采用的独立核实货件或追踪号快照,无核实资料时为空列表}
|
||
fbaWarehouseCode: {type: string}
|