Files
baiyue-firstleg/lastleg-service/src/main/resources/openapi/appointment-planning-v1.yaml
T

536 lines
29 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
openapi: 3.0.3
info:
title: 美国预约筹划货源
version: 1.0.0
description: 读取真实已开船头程货物,不要求预先创建入仓计划,不生成库存、车次或对外确认。
security:
- bearerAuth: []
paths:
/api/platform/v1/last-leg/appointment-planning/external-candidates:
get:
operationId: listExternalAppointmentCandidates
summary: 分页发现已确认承运的美国FBA外接货
description: '仅平台;同时要求platform:appointment:list与platform:overseas-warehouse:last-mile-order:list。按权威启用美国接仓点/FBA目录筛选原拼车登记,排除询价、取消和已完成车次。来货前后仅返回同一BOOKING来源;已有预约仍展示覆盖状态,不能重复加入。整页批量解析及核对覆盖,不逐条HTTP请求。'
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: warehouseId, in: query, schema: {type: string}}
- {name: destination, in: query, schema: {type: string}, description: 美国FBA仓码}
- {name: keyword, in: query, schema: {type: string, maxLength: 128}, description: 登记号、车次号、客户名称或来货号}
responses:
'200':
description: 业务响应;data为服务器分页结果
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:
customerName: {type: string, nullable: true}
tripNo: {type: string}
source: {$ref: '#/components/schemas/PlanningSource'}
coverage: {$ref: '#/components/schemas/Coverage'}
'403': {description: 非平台或缺少读取权限}
'503': {description: 仓库目录失败,不能当作无货}
/api/platform/v1/last-leg/appointment-planning/appointments:
post:
operationId: createAppointmentFromSources
summary: 在入仓前按稳定货源保存跨客户预约安排
description: >-
仅平台;同时需要platform:appointment:list、platform:overseas-warehouse:last-mile-order:list及platform:overseas-warehouse:inbound-order:fba-appointment。
与入仓明细入口共用同一FBA预约聚合;系统生成AP单号,不创建入仓计划、库存或车次。
PENDING允许日期、时段、外部约号及箱数暂缺。SUCCESS必须有权威目的仓时区、真实货件材料、确定箱数及外部约号和确认时段。
实际客户、起运仓、目的仓及原BOOKING由服务端核对;活动来源与已形成订单均唯一占用,取消后释放并保留历史。
命令与主单、明细同事务;同键同操作人同内容重试返回原快照,不受后来编辑影响。异内容或来源占用冲突拒绝。
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [sources, originWarehouseId, fbaWarehouseCode, details, idempotencyKey]
properties:
originWarehouseId: {type: string, minLength: 1, description: 选择货源时的接仓点,保存时重新核对}
fbaWarehouseCode: {type: string, minLength: 1, maxLength: 64, description: 选择货源时的目的仓编码,变化则拒绝保存}
sources:
type: array
minItems: 1
maxItems: 100
items:
type: object
required: [sourceKey, customerId]
properties:
sourceKey: {type: string, maxLength: 160}
customerId: {type: string, maxLength: 128}
destinationKey: {type: string}
details: {$ref: './fba-appointment-calendar-v1.yaml#/components/schemas/AppointmentDetails'}
idempotencyKey: {type: string, minLength: 1, maxLength: 64}
responses:
'200': {$ref: './fba-appointment-calendar-v1.yaml#/components/responses/AppointmentResult'}
'400': {description: 来源、时段或正式确认材料无效}
'403': {description: 权限不足或非平台身份}
'404': {description: 来源不存在或客户不匹配}
'409': {description: 同键异内容、版本或活动货物占用冲突}
'503': {description: 权威仓库目录或时区暂不可用}
/api/platform/v1/last-leg/appointment-planning/appointments/unscheduled:
get:
operationId: listUnscheduledAppointments
summary: 分页读取没有日期或时段的预约安排
description: 仅平台,权限platform:appointment:list;排除取消/失败,不用09点或零点占位。
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为分页
content:
application/json:
schema:
type: object
properties:
code: {type: string}
data:
type: object
properties:
records: {type: array, items: {$ref: './fba-appointment-calendar-v1.yaml#/components/schemas/Appointment'}}
total: {type: integer}
page: {type: integer}
size: {type: integer}
pages: {type: integer}
'403': {description: 无列表权限或非平台身份}
/api/platform/v1/last-leg/appointment-planning/batches/preview:
post:
operationId: previewAppointmentBatch
summary: 核对跨客户同仓货源合批资格
description: >-
只读核对,不保存预约安排、不占货、不确认预约。仅平台,同时要求platform:appointment:list与platform:overseas-warehouse:last-mile-order:list。
最多100票,批量查询货源、实际开船节点和美国仓目录,支持ORDER与已确认承运BOOKING混合;同一订单重复别名拒绝。
必须同美国起运仓及同美国FBA目的仓;暂扣、多目的地、已有有效预约或已取消完成货源拒绝;未知箱数保留待核实,不填0。
未建入仓计划及尚未来货的已确认BOOKING不伪造计划、库存或入仓码;正式确认前必须核实箱数。
未接入权威备妥窗口时返回readinessIncomplete及READY_WINDOW_UNVERIFIED,不拿到港/到仓预测代替。
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [sources]
properties:
sources:
type: array
minItems: 1
maxItems: 100
items:
type: object
required: [sourceKey, customerId]
properties:
sourceKey: {type: string, maxLength: 160}
customerId: {type: string, maxLength: 128}
destinationKey: {type: string, description: 可选预期目的地;存在时必须与来源一致}
responses:
'200':
description: code=200时data为本次核对结果,不是已保存单据
content:
application/json:
schema:
type: object
properties:
code: {type: string}
message: {type: string}
data:
type: object
properties:
originWarehouseName: {type: string}
destinationWarehouseCode: {type: string}
destinationTimezone: {type: string, nullable: true, description: 当前目的仓主档IANA时区;主档为空时为null,读取失败返回错误,不使用历史预约快照}
sources: {type: array, items: {$ref: '#/components/schemas/PlanningSource'}}
missingFields: {type: array, items: {type: string}}
group:
type: object
properties:
originWarehouseId: {type: string}
destinationKey: {type: string}
packages: {type: integer, nullable: true}
unknownQuantitySources: {type: integer}
sourceCount: {type: integer}
customerCount: {type: integer}
readyFrom: {type: string, format: date-time, nullable: true}
readyTo: {type: string, format: date-time, nullable: true}
readinessIncomplete: {type: boolean}
'400': {description: 来源重复、跨仓、数量不明或不满足合批资格}
'403': {description: 权限不足或非平台身份}
'404': {description: 来源与客户不匹配}
'503': {description: 美国仓目录不可用}
/api/platform/v1/last-leg/appointment-planning/containers:
get:
operationId: appointmentPlanningContainers
summary: 分页读取美国整柜提柜与接仓范围
description: >-
仅平台,同时要求platform:appointment:list与platform:overseas-warehouse:last-mile-order:list。
已实际开船且仍有效的FIRST_LEG货物按柜汇总,不限FBA目的地,不要求入仓计划。
仅统计美国接仓点货物;存在未知或非美国接仓点的同柜有效货物时incompleteScope=true,禁止新增整柜跟进。
关键词命中某票时仍返回整柜美国范围数量;任一数量缺失时packages为空。预计到港保留来源快照,不代表实时船司ETA。
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: keyword, in: query, schema: {type: string, maxLength: 128}}
responses:
'200':
description: 核对code后读取整柜分页
content:
application/json:
schema:
type: object
properties:
code: {type: string}
message: {type: string}
data:
type: object
properties:
records: {type: array, items: {$ref: '#/components/schemas/Container'}}
page: {type: integer}
size: {type: integer}
total: {type: integer}
pages: {type: integer}
'400': {description: 分页或搜索条件无效}
'403': {description: 缺少读取权限或非平台身份}
'503': {description: 美国仓库目录不可用}
/api/platform/v1/last-leg/appointment-planning/containers/{containerId}:
parameters:
- {$ref: '#/components/parameters/ContainerId'}
- {$ref: '#/components/parameters/ReceivingWarehouse'}
get:
operationId: resolveAppointmentContainer
summary: 核对整柜或接仓点的跟进资格
description: 仅平台,同时要求两项列表权限;接仓点必须属于当前柜次。内部柜次ID仅供关联,不能作为展示柜号。
responses:
'200':
description: code=200时data为已核实上下文
content:
application/json:
schema:
type: object
properties:
code: {type: string}
data: {$ref: '#/components/schemas/ContainerContext'}
'400': {description: 标识无效或接仓点不属于该柜}
'403': {description: 缺少读取权限或非平台身份}
'404': {description: 未找到有效美国整柜来源}
'503': {description: 仓库目录不可用}
/api/platform/v1/last-leg/appointment-planning/containers/{containerId}/follow-ups:
parameters:
- {$ref: '#/components/parameters/ContainerId'}
- {$ref: '#/components/parameters/ReceivingWarehouse'}
get:
operationId: appointmentContainerFollowupHistory
summary: 读取整柜或接仓点共享跟进历史
description: 仅平台,同时要求两项列表权限;已有历史在来源离开活动列表后仍可读取,不按客户拆分。
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': {$ref: '#/paths/~1api~1platform~1v1~1last-leg~1appointment-planning~1sources~1{sourceKey}~1follow-ups/get/responses/200'}
'400': {description: 标识或分页无效}
'403': {description: 缺少读取权限或非平台身份}
'404': {description: 无历史且来源不存在}
post:
operationId: appendAppointmentContainerFollowup
summary: 追加整柜提柜联系或指定仓库接仓联系
description: >-
仅平台,两项列表权限及platform:appointment:followup均必需。
未传warehouseId只接受DRAYAGE_CONTACT或TERMINAL_APPOINTMENT;传入时只接受WAREHOUSE_RECEIVING。
服务端产生共享来源键,不接收customerId或操作者字段;同柜跨客户共用一份历史。
版本、持久化幂等和跟进日期规则与货源跟进相同,不产生正式预约或执行结果。
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [stage, expectedVersion, idempotencyKey, result]
properties:
stage: {type: string, enum: [DRAYAGE_CONTACT, TERMINAL_APPOINTMENT, WAREHOUSE_RECEIVING]}
expectedVersion: {type: integer, minimum: 0}
idempotencyKey: {type: string, minLength: 1, maxLength: 64}
contactedParty: {type: string, maxLength: 200, nullable: true}
result: {type: string, minLength: 1, maxLength: 1000}
nextAction: {type: string, maxLength: 500, nullable: true}
followupDate: {type: string, format: date, nullable: true}
responses:
'200': {$ref: '#/paths/~1api~1platform~1v1~1last-leg~1appointment-planning~1sources~1{sourceKey}~1follow-ups/post/responses/200'}
'400': {description: 事项与范围不符或参数无效}
'403': {description: 缺少权限或非平台身份}
'404': {description: 来源不存在}
'409': {description: 范围待核对、版本或幂等内容冲突}
'503': {description: 仓库目录不可用}
/api/platform/v1/last-leg/appointment-planning/cargo:
get:
operationId: appointmentPlanningCargo
summary: 分页读取美国FBA筹划货源
description: >-
仅平台身份;同时要求platform:appointment:list与platform:overseas-warehouse:last-mile-order:list。
从公共仓库目录核对美国接仓点与美国FBA目的仓;目录失败返回错误,不冒充空结果。
当前读取FIRST_LEG货物与已确认开船或更晚的实际船节点,未建计划可见;已有计划不重复计数。
预计时间来自尾程订单保存的来源快照,不代表实时船司ETA;shippingObservedAt仅是实际节点观察时间。
sourcePalletCount是头程预报托数,不是海外实测托位。其他货源由后续正式合同接入,不能从本接口推断已支持。
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: warehouseId, in: query, schema: {type: string}, description: 美国接仓点主档ID,仅用于关联}
- {name: destination, in: query, schema: {type: string}, description: 美国FBA仓编码}
- {name: keyword, in: query, schema: {type: string, maxLength: 128}, description: 入仓码、柜号或客户名称}
responses:
'200':
description: 业务响应,必须核对code
content:
application/json:
schema:
type: object
properties:
code: {type: string}
message: {type: string}
data:
type: object
properties:
records: {type: array, items: {$ref: '#/components/schemas/Cargo'}}
page: {type: integer}
size: {type: integer}
total: {type: integer}
pages: {type: integer}
'400': {description: 查询参数或美国范围无效}
'403': {description: 无来源读取权限或非平台身份}
'503': {description: 仓库目录暂不可用,不能证明美国货源范围}
/api/platform/v1/last-leg/appointment-planning/sources/resolve:
get:
operationId: resolveAppointmentPlanningSource
summary: 核对深链来源并读取预约覆盖
description: >-
仅平台;同时要求platform:appointment:list与platform:overseas-warehouse:last-mile-order:list。
依据真实客户、货源与美国仓目录核对来源,URL参数不能授予预约资格。
ORDER接受已开船头程FBA货和没有外接登记的真实仓储转运;有原登记必须使用BOOKING稳定身份,确认承运后尚未生成入仓单也能跟进。
此查询不建单、不确认预约。当前覆盖读取已有FBA预约,尚未生成货物时返回SOURCE_NOT_MATERIALIZED。
parameters:
- {name: sourceKey, in: query, required: true, schema: {type: string, maxLength: 160}, description: 'ORDER:<内部关联ID>或BOOKING:<登记号>,非用户展示编号'}
- {name: customerId, in: query, required: true, schema: {type: string, maxLength: 128}}
- {name: destinationKey, in: query, schema: {type: string}, description: 'FBA:<仓编码>,传入后必须与真实来源一致'}
responses:
'200':
description: code=200时data包含已核实来源和预约覆盖
content:
application/json:
schema:
type: object
properties:
code: {type: string}
message: {type: string}
data:
type: object
properties:
source: {$ref: '#/components/schemas/PlanningSource'}
coverage: {$ref: '#/components/schemas/Coverage'}
'400': {description: 非美国FBA来源、尚未开船或目的地变化}
'403': {description: 无读取权限或非平台身份}
'404': {description: 客户与来源不匹配或来源不存在}
'503': {description: 仓库目录不可用}
/api/platform/v1/last-leg/appointment-planning/sources/{sourceKey}/follow-ups:
parameters:
- {name: sourceKey, in: path, required: true, schema: {type: string, maxLength: 160}, description: 'ORDER或BOOKING稳定来源键,路径须URL编码'}
- {name: customerId, in: query, required: true, schema: {type: string, maxLength: 128}}
get:
summary: 分页读取分事项跟进历史与最新版本
description: 仅平台;同时要求platform:appointment:list与platform:overseas-warehouse:last-mile-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含history分页和按stage排列的versions;createdAt为UTC时间点,followupDate为业务地点当地日期。
content:
application/json:
schema:
type: object
properties:
code: {type: string}
message: {type: string}
data:
type: object
properties:
history:
type: object
properties:
records: {type: array, items: {$ref: '#/components/schemas/FollowupRecord'}}
page: {type: integer}
size: {type: integer}
total: {type: integer}
pages: {type: integer}
versions: {type: object, additionalProperties: {type: integer, minimum: 0}, description: 四个事项各自的最新版本}
'403': {description: 无读取权限或非平台身份}
'404': {description: 无历史且来源不具备美国筹划资格}
post:
summary: 追加人工联系结果与下次跟进
description: >-
仅平台;除读取权限外要求platform:appointment:followup。
跟进人来自登录主体,不接受客户端操作者ID。核实来源后按stage版本追加,以持久化唯一约束防止并发覆盖;幂等键持久化,同键同操作者同内容返回原记录,异内容拒绝。
不要求已创建入仓计划、外部预约号或司机,不更新正式预约、库存和车次。设置followupDate时nextAction必填。
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [stage, expectedVersion, idempotencyKey, result]
properties:
stage: {type: string, enum: [FBA_RECEIVING], description: 提柜及接仓统一使用整柜接口,不按客户货源重复登记}
expectedVersion: {type: integer, minimum: 0, description: 初次为0,后续取history.versions中对应事项版本}
idempotencyKey: {type: string, maxLength: 64}
contactedParty: {type: string, maxLength: 200, nullable: true}
result: {type: string, minLength: 1, maxLength: 1000}
nextAction: {type: string, maxLength: 500, nullable: true}
followupDate: {type: string, format: date, nullable: true}
responses:
'200':
description: data为原记录或新增记录
content:
application/json:
schema:
type: object
properties:
code: {type: string}
message: {type: string}
data: {$ref: '#/components/schemas/FollowupRecord'}
'400': {description: 无效事项或缺少下一步安排}
'403': {description: 无写权限或非平台身份}
'404': {description: 来源不存在或不可筹划}
'409': {description: 版本冲突或同键异内容}
components:
parameters:
ContainerId: {name: containerId, in: path, required: true, schema: {type: string, pattern: '^[A-Za-z0-9_-]{1,64}$'}}
ReceivingWarehouse: {name: warehouseId, in: query, schema: {type: string, pattern: '^[0-9]{1,20}$'}, description: 不传表示整柜,传入表示该柜实际接仓点}
securitySchemes:
bearerAuth: {type: http, scheme: bearer, bearerFormat: JWT}
schemas:
Container:
type: object
properties:
containerBookingId: {type: string}
containerNo: {type: string, nullable: true}
orderCount: {type: integer}
customerCount: {type: integer}
packages: {type: integer, nullable: true}
unknownPackageOrders: {type: integer}
earliestArrivalAt: {type: string, nullable: true}
latestArrivalAt: {type: string, nullable: true}
standardNode: {type: string}
sourceVersion: {type: string, nullable: true}
incompleteScope: {type: boolean}
warehouses:
type: array
items:
type: object
properties:
containerBookingId: {type: string}
warehouseId: {type: string}
warehouseName: {type: string}
orderCount: {type: integer}
customerCount: {type: integer}
ContainerContext:
type: object
properties:
containerBookingId: {type: string}
containerNo: {type: string, nullable: true}
warehouseId: {type: string, nullable: true}
warehouseName: {type: string, nullable: true}
canFollowup: {type: boolean}
blockReasons: {type: array, items: {type: string}}
FollowupRecord:
type: object
properties:
stage: {type: string, enum: [DRAYAGE_CONTACT, TERMINAL_APPOINTMENT, WAREHOUSE_RECEIVING, FBA_RECEIVING]}
version: {type: integer, minimum: 1}
contactedParty: {type: string, nullable: true}
result: {type: string}
nextAction: {type: string, nullable: true}
followupDate: {type: string, format: date, nullable: true}
operatorName: {type: string, nullable: true}
createdAt: {type: string, format: date-time, description: UTC时间点}
PlanningSource:
type: object
properties:
sourceKey: {type: string}
customerId: {type: string}
orderId: {type: string, nullable: true}
inboundCode: {type: string, nullable: true}
bookingNo: {type: string, nullable: true}
containerNo: {type: string, nullable: true}
originWarehouseId: {type: string}
originWarehouseName: {type: string}
destinationKey: {type: string}
destinationWarehouseCode: {type: string}
packages: {type: integer, nullable: true, description: 未知数量保持空值,不能替换为0}
sourceVersion: {type: string, nullable: true}
canFollowup: {type: boolean}
blockReasons: {type: array, items: {type: string}}
Coverage:
type: object
properties:
customerId: {type: string}
sourceKey: {type: string}
destinationKey: {type: string}
status: {type: string, enum: [SOURCE_NOT_FOUND, SOURCE_NOT_MATERIALIZED, SOURCE_NOT_READY, DESTINATION_MISMATCH, UNASSIGNED, PARTIAL, PENDING, CONFIRMED, REVIEW_REQUIRED]}
sourceVersion: {type: string, nullable: true}
changeReviewRequired: {type: boolean}
missingFields: {type: array, items: {type: string}, description: 缺项或待核实原因代码,客户端需显示业务文案}
appointments:
type: array
items:
type: object
properties:
appointmentNo: {type: string}
confirmationNo: {type: string, nullable: true}
status: {type: string}
confirmedAt: {type: string, nullable: true}
confirmedEndAt: {type: string, nullable: true}
timezone: {type: string, nullable: true, description: 旧预约未记录时区时为空并返回缺项,不能按浏览器时区推定}
Cargo:
type: object
properties:
sourceKey: {type: string, description: 稳定ORDER来源键,不因生成入仓计划而变化;非展示编号}
orderId: {type: string}
customerId: {type: string}
customerName: {type: string, nullable: true}
inboundCode: {type: string, nullable: true}
containerBookingId: {type: string}
containerNo: {type: string, nullable: true}
originWarehouseId: {type: string}
originWarehouseCode: {type: string}
originWarehouseName: {type: string}
destinationWarehouseCode: {type: string}
packages: {type: integer, nullable: true}
receivedPackages: {type: integer, nullable: true}
shippedPackages: {type: integer, nullable: true}
sourcePalletCount: {type: integer, nullable: true}
volumeCbm: {type: number, nullable: true}
estimatedArrivalAt: {type: string, nullable: true, description: 来源预计到港快照,保留原业务当地时间;不得按浏览器时区转换}
estimatedWarehouseAt: {type: string, nullable: true, description: 已保存预计到仓,不因本查询改变}
orderVersion: {type: integer}
standardNode: {type: string}
shippingVersion: {type: string, nullable: true}
shippingObservedAt: {type: string, nullable: true}
shippingProvider: {type: string, nullable: true}
hasInboundPlan: {type: boolean}
hasActiveAppointment: {type: boolean}
detained: {type: boolean}
mixedDestinations: {type: boolean, description: 存在其他目的地明细时,不能按整票默认为同仓货物}