698 lines
42 KiB
YAML
698 lines
42 KiB
YAML
openapi: 3.0.3
|
||
info:
|
||
title: 平台运输车次与资源分配
|
||
version: 1.0.0
|
||
description: >-
|
||
车次是一次实际运输的稳定业务编号,客户排车、库存和派送单继续保留各自客户归属。
|
||
本文件定义计划、资源分配及客户排车单关联命令;分配或关联不会扣库存或标记发车。
|
||
创建可暂不指定车与司机,幂等键按创建人隔离;相同键相同内容返回同一车次,不同内容拒绝。
|
||
正式分配要求在役海外车辆及已确认的托位/载重/容积,以及海外司机;司机按预计任务结束时间重新核验且验证证照文件。
|
||
发车预览与实际发车重新核对司机当前海外区域和身份;分配后档案变更不能沿用原分配时的资格结果。
|
||
一个车辆或司机同时只能占用一个未释放车次;当前不提供多个未来时段的并行预约。
|
||
改派先取得新资源,成功后释放旧资源;整次写入与历史处于同一事务。
|
||
司机预计结束包含承担的返程/转场;修改预计结束须重新核验司机,所有写命令使用recordVersion。
|
||
普通计划接口不提供修改发车或签收状态的入口;PDA统一发车,结案检查所有客户派送终态及实发数量。
|
||
货物结案不释放车辆或司机;结束各资源任务独立提交实际结束时间、地点和原因,车辆另确认可用/维修/停用/已归还状态。
|
||
结案和结束任务命令携带版本及幂等键;结束司机任务不要求其证照仍有效,也不自动恢复其派车资格。
|
||
关联要求已分配车和司机,客户排车单同起运仓且未开始拣货;可跨客户关联但不改变客户数据归属。
|
||
同一排车单唯一关联一个车次;关联、改派、解除及尚未执行的派送单车/司机快照同步使用同一事务。
|
||
关联后子排车不能独立编辑、取消或单独发车;取消车次前须解除关联,已开工不允许直接解除或变更路线。
|
||
发车前允许在车次统一换车、换司机或调整时间,保留全部拣货事实与客户归属;已确认装载须能容纳于替换车辆。
|
||
改派或调整计划使原装载确认失效,发车前须重新确认;不支持用计划接口处理在途换车或撤销已执行货物。
|
||
关联只建立执行单据关系,不代表实际装载量、容量核验或审核已完成。
|
||
每张客户排车单调度审核通过后允许新拣货;整车确认实际装载并通过理货审核后允许发车。
|
||
审核仅通过或打回,通过意见选填、打回原因必填;无需额外提交或不同审核人。
|
||
换车换司机、修改路线或时间使调度与理货审核待审;仅修改备注保留审核及装载。
|
||
关联变更、重新确认装载或重新审核客户排车单使理货审核待审;保留全部拣货事实及历史审核快照。
|
||
security:
|
||
- bearerAuth: []
|
||
paths:
|
||
/api/platform/v1/last-leg/fleet/trips:
|
||
get:
|
||
summary: 分页查询车次
|
||
description: '权限:platform:fleet:trip:list'
|
||
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: keyword, in: query, schema: {type: string, maxLength: 128}, description: 车次号/车牌/司机}
|
||
- {name: status, in: query, schema: {type: string, enum: [PLANNED, IN_TRANSIT, COMPLETED, CANCELLED]}}
|
||
- {name: warehouseId, in: query, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
|
||
responses:
|
||
'200':
|
||
description: 统一业务响应,data包含records/page/size/total/pages;不逐行请求司机详情
|
||
content:
|
||
application/json:
|
||
schema:
|
||
allOf:
|
||
- {$ref: '#/components/schemas/Envelope'}
|
||
- properties:
|
||
data:
|
||
type: object
|
||
properties:
|
||
records: {type: array, items: {$ref: '#/components/schemas/Trip'}}
|
||
page: {type: integer}
|
||
size: {type: integer}
|
||
total: {type: integer}
|
||
pages: {type: integer}
|
||
post:
|
||
summary: 幂等创建车次计划
|
||
description: '权限:platform:fleet:trip:create;起运仓使用公共有效海外仓目录;不推断GPS路线。'
|
||
requestBody: {required: true, content: {application/json: {schema: {$ref: '#/components/schemas/Create'}}}}
|
||
responses: {'200': {$ref: '#/components/responses/Detail'}}
|
||
/api/platform/v1/last-leg/fleet/trips/customer-options:
|
||
get:
|
||
summary: 查询有效委托客户候选
|
||
description: '权限:platform:fleet:trip:list;读取IAM当前客户主档;不使用采购历史或允许输入不存在的客户。'
|
||
parameters: [{name: keyword, in: query, schema: {type: string}}]
|
||
responses: {'200': {description: 统一响应data为客户id/code/name/contactName/contactPhone数组}}
|
||
/api/platform/v1/last-leg/fleet/trips/{tripNo}/bookings/quote-candidates:
|
||
parameters: [{$ref: '#/components/parameters/TripNo'}]
|
||
get:
|
||
summary: 按本车真实起运仓及当地计划日期查询客户销售报价
|
||
description: '同时要求platform:fleet:trip:list与platform:fleet:quote:list。城市来自有效公共海外仓的唯一明确地址城市,日期为计划起运UTC时间转换到仓库明确时区;不接收浏览器城市或日期。目的地须为本车既有FBA卸货站;私人地址、缺失或歧义城市/时区明确拒绝查询,仍可手工询价。'
|
||
parameters:
|
||
- {name: customerId, in: query, required: true, schema: {type: integer, format: int64, minimum: 1}}
|
||
- {name: destinationKey, in: query, required: true, schema: {type: string, maxLength: 160}}
|
||
- {name: currency, in: query, required: true, schema: {type: string, enum: [CNY, USD]}}
|
||
- {name: priceBasis, in: query, required: true, schema: {type: string, enum: [PALLET, ORDER]}}
|
||
- {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: 统一业务响应,data为报价来源候选分页;无价不列入,零价保留
|
||
content:
|
||
application/json:
|
||
schema:
|
||
allOf:
|
||
- {$ref: '#/components/schemas/Envelope'}
|
||
- properties:
|
||
data:
|
||
type: object
|
||
properties:
|
||
records: {type: array, items: {$ref: 'fleet-quote-candidates-v1.yaml#/components/schemas/SourceSnapshot'}}
|
||
page: {type: integer}
|
||
size: {type: integer}
|
||
total: {type: integer}
|
||
pages: {type: integer}
|
||
'403': {description: 缺少任一读取权限}
|
||
'409': {description: 无法确定本车报价查询上下文}
|
||
/api/platform/v1/last-leg/fleet/trips/{tripNo}/bookings:
|
||
parameters: [{$ref: '#/components/parameters/TripNo'}]
|
||
get:
|
||
summary: 查询本车外接询价与承运预订
|
||
description: '权限:platform:fleet:trip:list;返回tripRecordVersion及records;约定金额不是应收或实收。'
|
||
responses: {'200': {description: 统一响应data为版本及Booking数组}}
|
||
post:
|
||
summary: 登记外接询价
|
||
description: '权限:platform:fleet:trip:booking-create;DRAFT不占位。客户由IAM校验,报价和预计载荷可待确认再补;起点固定本起运仓,卸货站为既有路线站点。相同创建键与内容重放原预订。'
|
||
requestBody: {required: true, content: {application/json: {schema: {$ref: '#/components/schemas/BookingCreate'}}}}
|
||
responses: {'200': {$ref: '#/components/responses/BookingResult'}}
|
||
/api/platform/v1/last-leg/fleet/trips/{tripNo}/bookings/{bookingNo}:
|
||
parameters: [{$ref: '#/components/parameters/TripNo'}, {$ref: '#/components/parameters/BookingNo'}]
|
||
put:
|
||
summary: 编辑尚未确认的外接询价
|
||
description: '权限:platform:fleet:trip:booking-edit;仅DRAFT;客户与预订业务编号不变,更新前核对车次及预订版本。'
|
||
requestBody: {required: true, content: {application/json: {schema: {$ref: '#/components/schemas/BookingUpdate'}}}}
|
||
responses: {'200': {$ref: '#/components/responses/BookingResult'}}
|
||
/api/platform/v1/last-leg/fleet/trips/{tripNo}/bookings/{bookingNo}/confirm:
|
||
parameters: [{$ref: '#/components/parameters/TripNo'}, {$ref: '#/components/parameters/BookingNo'}]
|
||
post:
|
||
summary: 确认外接承运并占用计划容量
|
||
description: '权限:platform:fleet:trip:booking-confirm;父车次锁内核对来源仍有效的自有货容量计划及全部已确认预订;报价/币种/预计托位重量体积完整。幂等重放返回当前预订事实,不重复占位;确认不代表已收货、已发运或已入财务。'
|
||
requestBody: {required: true, content: {application/json: {schema: {$ref: '#/components/schemas/BookingCommand'}}}}
|
||
responses: {'200': {$ref: '#/components/responses/BookingResult'}, '409': {description: 版本、资格或容量不满足}}
|
||
/api/platform/v1/last-leg/fleet/trips/{tripNo}/bookings/{bookingNo}/incoming:
|
||
parameters: [{$ref: '#/components/parameters/TripNo'}, {$ref: '#/components/parameters/BookingNo'}]
|
||
get:
|
||
summary: 查询外接来货及实际测量依据
|
||
description: '权限:platform:fleet:trip:list;固定预订客户范围,返回tripRecordVersion、recordVersion与incoming;尚未登记时incoming为null,不逐行预取。'
|
||
responses: {'200': {description: 统一响应data为版本及IncomingEvidence}}
|
||
post:
|
||
summary: 为已确认承运生成真实来货单
|
||
description: '权限:platform:fleet:trip:booking-edit;复用仓储转运创建/审核,在同一事务建立客户自送来货并关联预订;不写库存,不冒充实收;已有来货拒绝重复创建,同键同内容重放。'
|
||
requestBody: {required: true, content: {application/json: {schema: {$ref: '#/components/schemas/BookingIncoming'}}}}
|
||
responses: {'200': {$ref: '#/components/responses/BookingResult'}}
|
||
/api/platform/v1/last-leg/fleet/trips/{tripNo}/bookings/{bookingNo}/receipt-confirmation:
|
||
parameters: [{$ref: '#/components/parameters/TripNo'}, {$ref: '#/components/parameters/BookingNo'}]
|
||
post:
|
||
summary: 运营确认委托方实收货量与运费
|
||
description: '权限:platform:fleet:trip:booking-confirm;实际来货已完成测量,receiptHash和实托集合一致,重新核算容量和约定金额,引用真实收货证据并确认原来货流程;不重复入库。差异必须显式确认,超容量回滚。'
|
||
requestBody: {required: true, content: {application/json: {schema: {$ref: '#/components/schemas/BookingAcceptReceipt'}}}}
|
||
responses: {'200': {$ref: '#/components/responses/BookingResult'}}
|
||
/api/platform/v1/last-leg/fleet/trips/{tripNo}/bookings/{bookingNo}/dispatch:
|
||
parameters: [{$ref: '#/components/parameters/TripNo'}, {$ref: '#/components/parameters/BookingNo'}]
|
||
post:
|
||
summary: 将外接实收货物关联客户排车
|
||
description: '权限:同时要求platform:fleet:trip:booking-edit和platform:fleet:trip:edit;排车必须同客户同仓,完整包含预订来货的实收托盘与数量且目的地一致;原子绑定共享车次,防止绕过预订挂到其他车次。解除未开工关联后回到RECEIVED并重新预留容量,已拣货不允许直接解除。'
|
||
requestBody: {required: true, content: {application/json: {schema: {$ref: '#/components/schemas/BookingBindDispatch'}}}}
|
||
responses: {'200': {$ref: '#/components/responses/BookingResult'}}
|
||
/api/platform/v1/last-leg/fleet/trips/{tripNo}/bookings/{bookingNo}/cancel:
|
||
parameters: [{$ref: '#/components/parameters/TripNo'}, {$ref: '#/components/parameters/BookingNo'}]
|
||
post:
|
||
summary: 取消未执行的外接预订并释放容量
|
||
description: '权限:platform:fleet:trip:booking-cancel;仅计划中车次的DRAFT/CONFIRMED/RECEIVED;只释放承运预留,不删除来货或库存;同键同内容重放不重复释放,历史保留报价及承运确认。'
|
||
requestBody: {required: true, content: {application/json: {schema: {$ref: '#/components/schemas/BookingCommand'}}}}
|
||
responses: {'200': {$ref: '#/components/responses/BookingResult'}}
|
||
/api/platform/v1/last-leg/fleet/trips/{tripNo}:
|
||
parameters: [{$ref: '#/components/parameters/TripNo'}]
|
||
get:
|
||
summary: 查询车次详情和当前司机资格
|
||
description: '权限:platform:fleet:trip:list;司机资格仅是详情预览,实际命令必须重新核验。'
|
||
responses: {'200': {$ref: '#/components/responses/Detail'}}
|
||
/api/platform/v1/last-leg/fleet/trips/{tripNo}/dispatches/{dispatchNo}/review:
|
||
parameters:
|
||
- {$ref: '#/components/parameters/TripNo'}
|
||
- {name: dispatchNo, in: path, required: true, schema: {type: string}}
|
||
post:
|
||
summary: 通过或打回单张客户排车调度审核
|
||
description: '权限:platform:fleet:trip:dispatch-review;仅PLANNED;审核所属车次内的排车单,成功后理货审核待审;审批不扣库存。'
|
||
requestBody: {required: true, content: {application/json: {schema: {$ref: '#/components/schemas/Review'}}}}
|
||
responses: {'200': {$ref: '#/components/responses/Detail'}, '409': {description: 版本、关联或资格冲突}}
|
||
/api/platform/v1/last-leg/fleet/trips/{tripNo}/loading-review:
|
||
parameters: [{$ref: '#/components/parameters/TripNo'}]
|
||
post:
|
||
summary: 通过或打回整车理货审核
|
||
description: '权限:platform:fleet:trip:loading-review;仅PLANNED;通过要求全部调度审核、拣货和实际装载确认已完成,当前司机资格有效。'
|
||
requestBody: {required: true, content: {application/json: {schema: {$ref: '#/components/schemas/Review'}}}}
|
||
responses: {'200': {$ref: '#/components/responses/Detail'}, '409': {description: 版本、调度审核、装载或资格冲突}}
|
||
/api/platform/v1/last-leg/fleet/trips/{tripNo}/plan:
|
||
parameters: [{$ref: '#/components/parameters/TripNo'}]
|
||
put:
|
||
summary: 修改计划时间和路线
|
||
description: '权限:platform:fleet:trip:edit;仅PLANNED;司机预计结束变更重新核验;原因必填。已开始拣货时路线须完全一致,仅可调整时间和备注;调整时间使审核及装载确认失效,仅修改备注保留。'
|
||
requestBody: {required: true, content: {application/json: {schema: {$ref: '#/components/schemas/Plan'}}}}
|
||
responses: {'200': {$ref: '#/components/responses/Detail'}}
|
||
/api/platform/v1/last-leg/fleet/trips/{tripNo}/assignment:
|
||
parameters: [{$ref: '#/components/parameters/TripNo'}]
|
||
post:
|
||
summary: 分配或更换车辆与司机
|
||
description: '权限:platform:fleet:trip:assign;仅PLANNED且全部关联单未发车、未出库;允许已拣货时统一改派并同步派送快照,保留拣货和到达时间。替换车辆须满足已确认装载容量,成功后清除原装载确认并重新核验;行锁和唯一占用键防重复派车,资格校验不得通过人工审核绕过。'
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required: [recordVersion, vehicleId, driverId, reason]
|
||
properties:
|
||
recordVersion: {type: integer, format: int64, minimum: 0}
|
||
vehicleId: {type: string, pattern: '^[1-9][0-9]*$'}
|
||
driverId: {type: string, pattern: '^[1-9][0-9]*$'}
|
||
reason: {type: string, minLength: 1, maxLength: 1000}
|
||
responses: {'200': {$ref: '#/components/responses/Detail'}}
|
||
/api/platform/v1/last-leg/fleet/trips/{tripNo}/cancel:
|
||
parameters: [{$ref: '#/components/parameters/TripNo'}]
|
||
post:
|
||
summary: 取消计划并释放车和司机
|
||
description: '权限:platform:fleet:trip:cancel;仅PLANNED;保留车次快照和历史。已执行货物后续须按实际执行状态校验,不允许取消抹除作业事实。'
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required: [recordVersion, reason]
|
||
properties:
|
||
recordVersion: {type: integer, format: int64, minimum: 0}
|
||
reason: {type: string, minLength: 1, maxLength: 1000}
|
||
responses: {'200': {$ref: '#/components/responses/Detail'}}
|
||
/api/platform/v1/last-leg/fleet/trips/{tripNo}/dispatches/bind:
|
||
parameters: [{$ref: '#/components/parameters/TripNo'}]
|
||
post:
|
||
summary: 将客户排车单关联到车次
|
||
description: '权限:platform:fleet:trip:edit;按业务单号解析客户归属,同仓且未开工;关联、车/司机快照同步及按真实货物目的地标识补齐卸货站原子提交;目的地缺失拒绝关联,已有有效站点顺序与索引保留,初始默认占位站替换为真实目的地。'
|
||
requestBody: {required: true, content: {application/json: {schema: {$ref: '#/components/schemas/BindingCommand'}}}}
|
||
responses: {'200': {$ref: '#/components/responses/Detail'}}
|
||
/api/platform/v1/last-leg/fleet/trips/{tripNo}/dispatches/unbind:
|
||
parameters: [{$ref: '#/components/parameters/TripNo'}]
|
||
post:
|
||
summary: 解除尚未执行的客户排车单关联
|
||
description: '权限:platform:fleet:trip:edit;清除排车及派送单当前车辆司机快照,历史保留;已拣货禁止直接解除。'
|
||
requestBody: {required: true, content: {application/json: {schema: {$ref: '#/components/schemas/BindingCommand'}}}}
|
||
responses: {'200': {$ref: '#/components/responses/Detail'}}
|
||
/api/platform/v1/last-leg/fleet/trips/{tripNo}/history:
|
||
parameters: [{$ref: '#/components/parameters/TripNo'}]
|
||
get:
|
||
summary: 分页读取车次操作历史
|
||
description: '权限:platform:fleet:trip:list;版本倒序;不将历史快照当作当前资格。'
|
||
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}}
|
||
responses:
|
||
'200':
|
||
description: 统一响应;data为PageResult,records项包含recordVersion/action/reason/operatorId/occurredAt/snapshot,snapshot包含trip、带review的dispatches、capacityPlan、confirmedLoad、completion及loadingReview、externalBookings不可变快照
|
||
/api/platform/v1/last-leg/fleet/trips/{tripNo}/capacity-plan:
|
||
parameters: [{$ref: '#/components/parameters/TripNo'}]
|
||
get:
|
||
summary: 读取拣货前计划载荷和逐段余位
|
||
description: '权限:platform:fleet:trip:list;按当前关联货物返回manifestHash;planValid为false表示尚未核对或来源已经变化,不能据旧计划承诺外接运力。'
|
||
responses:
|
||
'200': {description: 统一响应data为Planning, content: {application/json: {schema: {$ref: '#/components/schemas/PlanningEnvelope'}}}}
|
||
post:
|
||
summary: 核对本车货物计划载荷
|
||
description: '权限:platform:fleet:trip:edit;仅PLANNED;允许尚未拣货或审核,通过实托去重及逐段容量检查。保存计划不推进审核、库存或发车,不代替实际装载确认;调整计划/资源/关联使容量计划失效,纯备注保留。'
|
||
requestBody: {required: true, content: {application/json: {schema: {$ref: '#/components/schemas/ConfirmLoad'}}}}
|
||
responses:
|
||
'200': {description: 已保存容量计划, content: {application/json: {schema: {$ref: '#/components/schemas/PlanningEnvelope'}}}}
|
||
'409': {description: 版本、来源变化或容量超限}
|
||
/api/platform/v1/last-leg/fleet/trips/{tripNo}/loading:
|
||
parameters: [{$ref: '#/components/parameters/TripNo'}]
|
||
get:
|
||
summary: 读取整车实物装载核对依据
|
||
description: '权限:platform:fleet:trip:list;返回各客户货物组成、manifestHash和当前装载确认,实际重量不得使用计费材积重。'
|
||
responses:
|
||
'200': {description: 统一响应data为Loading, content: {application/json: {schema: {$ref: '#/components/schemas/LoadingEnvelope'}}}}
|
||
post:
|
||
summary: 确认整车实际装载及逐段容量
|
||
description: '权限:platform:fleet:trip:edit;全部客户拣货核平且转派送后确认;同一实物托盘只计量一次。货物hash或车次版本变化拒绝,托盘卸货站须匹配原货物目的地。'
|
||
requestBody: {required: true, content: {application/json: {schema: {$ref: '#/components/schemas/ConfirmLoad'}}}}
|
||
responses:
|
||
'200': {description: 已确认装载快照,统一响应data为Loading, content: {application/json: {schema: {$ref: '#/components/schemas/LoadingEnvelope'}}}}
|
||
/api/platform/v1/last-leg/fleet/trips/{tripNo}/completion:
|
||
parameters: [{$ref: '#/components/parameters/TripNo'}]
|
||
get:
|
||
summary: 核对各客户货物是否全部结束履约
|
||
description: '权限:platform:fleet:trip:list;返回tripNo、recordVersion、canComplete、blockReason、outcomes。签收以signedAt为准,退回须有RETURN_COMPLETED操作事实,不以updatedAt代替实际终态时间。'
|
||
responses:
|
||
'200': {description: 统一响应data包含结案检查结果与逐张派送Outcome, content: {application/json: {schema: {$ref: '#/components/schemas/CompletionEnvelope'}}}}
|
||
/api/platform/v1/last-leg/fleet/trips/{tripNo}/complete:
|
||
parameters: [{$ref: '#/components/parameters/TripNo'}]
|
||
post:
|
||
summary: 核对全部货物并结案车次
|
||
description: '权限:platform:fleet:trip:complete;仅IN_TRANSIT,实发数量由全部已签收或已真实退回派送单覆盖;拒收、待退回、取消不算终态完成。不改写客户单、不新增收费、不释放资源;同键同内容重放,旧版本或不同内容拒绝。'
|
||
requestBody: {required: true, content: {application/json: {schema: {$ref: '#/components/schemas/Complete'}}}}
|
||
responses: {'200': {$ref: '#/components/responses/Detail'}}
|
||
/api/platform/v1/last-leg/fleet/trips/{tripNo}/resources/release:
|
||
parameters: [{$ref: '#/components/parameters/TripNo'}]
|
||
post:
|
||
summary: 单独结束车辆或司机本次任务并释放占用
|
||
description: '权限:platform:fleet:trip:release;货物结案后才允许;实际结束时间不早于货物完成且不晚于当前时间,地点及原因必填。车辆状态与释放同事务更新;司机可继续返程而保持占用。原请求重放不释放后来另一个车次的占用。'
|
||
requestBody: {required: true, content: {application/json: {schema: {$ref: '#/components/schemas/Release'}}}}
|
||
responses: {'200': {$ref: '#/components/responses/Detail'}}
|
||
components:
|
||
securitySchemes:
|
||
bearerAuth: {type: http, scheme: bearer, bearerFormat: JWT}
|
||
parameters:
|
||
BookingNo:
|
||
name: bookingNo
|
||
in: path
|
||
required: true
|
||
schema: {type: string}
|
||
TripNo: {name: tripNo, in: path, required: true, schema: {type: string}}
|
||
responses:
|
||
BookingResult:
|
||
description: 统一响应data含tripRecordVersion、booking及replayed;客户端使用当前状态,重放不覆盖后续已发生的取消
|
||
content:
|
||
application/json:
|
||
schema:
|
||
allOf:
|
||
- {$ref: '#/components/schemas/Envelope'}
|
||
- properties:
|
||
data:
|
||
type: object
|
||
properties:
|
||
tripRecordVersion: {type: integer, format: int64}
|
||
booking: {$ref: '#/components/schemas/Booking'}
|
||
replayed: {type: boolean}
|
||
Detail:
|
||
description: 统一响应,code为200代表成功,data为车次详情;业务冲突使用业务错误,不降级为成功
|
||
content:
|
||
application/json:
|
||
schema:
|
||
allOf:
|
||
- {$ref: '#/components/schemas/Envelope'}
|
||
- properties:
|
||
data:
|
||
type: object
|
||
properties:
|
||
trip: {$ref: '#/components/schemas/Trip'}
|
||
dispatches: {type: array, items: {$ref: '#/components/schemas/DispatchBinding'}}
|
||
loadingReview: {$ref: '#/components/schemas/ReviewState'}
|
||
driverQualification:
|
||
type: object
|
||
nullable: true
|
||
description: 未分配司机为null;字段与fleet-drivers-v1的Qualification一致
|
||
properties:
|
||
canDispatch: {type: boolean}
|
||
expiringSoon: {type: boolean}
|
||
reason: {type: string}
|
||
licenseExpiresOn: {type: string, format: date, nullable: true}
|
||
schemas:
|
||
BookingCargo:
|
||
type: object
|
||
required: [destinationKey]
|
||
properties:
|
||
destinationKey: {type: string, maxLength: 160}
|
||
cargoName: {type: string, nullable: true, maxLength: 255}
|
||
packageCount: {type: integer, nullable: true, minimum: 1, description: 询价未知可为空,确认承运前必须补齐正数箱数}
|
||
palletSpaces: {type: integer, nullable: true, minimum: 1}
|
||
weightKg: {type: number, nullable: true, minimum: 0.001}
|
||
volumeCbm: {type: number, nullable: true, minimum: 0.001}
|
||
priceBasis: {type: string, nullable: true, enum: [PALLET, ORDER], description: 为空时默认PALLET}
|
||
unitPrice: {type: number, nullable: true, minimum: 0, multipleOf: 0.01}
|
||
currency: {type: string, nullable: true, maxLength: 3}
|
||
contactName: {type: string, nullable: true, maxLength: 128}
|
||
contactPhone: {type: string, nullable: true, maxLength: 128}
|
||
remark: {type: string, nullable: true, maxLength: 1000}
|
||
IncomingEvidence:
|
||
type: object
|
||
properties:
|
||
incomingNo: {type: string}
|
||
inboundCode: {type: string}
|
||
warehouseId: {type: string}
|
||
destinationKey: {type: string}
|
||
status: {type: string}
|
||
receiptHash: {type: string, description: 实托、数量、实测值及来源匹配摘要,不包含可变作业状态}
|
||
receivedPackages: {type: integer}
|
||
pallets:
|
||
type: array
|
||
items:
|
||
type: object
|
||
properties:
|
||
warehousePalletId: {type: string}
|
||
palletNo: {type: string}
|
||
packages: {type: integer}
|
||
weightKg: {type: number, nullable: true}
|
||
volumeCbm: {type: number, nullable: true}
|
||
BookingIncoming:
|
||
allOf:
|
||
- {$ref: '#/components/schemas/BookingCommand'}
|
||
- properties:
|
||
estimatedArrivalAt: {type: string, format: date-time, nullable: true, description: 缺省为计划发车前2小时的预计值}
|
||
deliveryInstructions: {type: string, nullable: true, maxLength: 1000}
|
||
privateAddress: {type: string, nullable: true, maxLength: 1000}
|
||
postalCode: {type: string, nullable: true, maxLength: 32}
|
||
recipientName: {type: string, nullable: true, maxLength: 128}
|
||
recipientPhone: {type: string, nullable: true, maxLength: 64}
|
||
BookingPalletSpaces:
|
||
type: object
|
||
required: [warehousePalletId, palletSpaces]
|
||
properties:
|
||
warehousePalletId: {type: string}
|
||
palletSpaces: {type: integer, minimum: 1}
|
||
BookingAcceptReceipt:
|
||
allOf:
|
||
- {$ref: '#/components/schemas/BookingCommand'}
|
||
- required: [receiptHash, pallets, unitPrice]
|
||
properties:
|
||
receiptHash: {type: string}
|
||
pallets: {type: array, minItems: 1, items: {$ref: '#/components/schemas/BookingPalletSpaces'}}
|
||
unitPrice: {type: number, minimum: 0, multipleOf: 0.01}
|
||
BookingBindDispatch:
|
||
allOf:
|
||
- {$ref: '#/components/schemas/BookingCommand'}
|
||
- required: [dispatchNo]
|
||
properties:
|
||
dispatchNo: {type: string, maxLength: 64}
|
||
BookingCreate:
|
||
type: object
|
||
required: [tripRecordVersion, customerId, cargo, idempotencyKey]
|
||
properties:
|
||
tripRecordVersion: {type: integer, format: int64, minimum: 0}
|
||
customerId: {type: string, pattern: '^[1-9][0-9]*$'}
|
||
quoteRef: {$ref: '#/components/schemas/BookingQuoteRef'}
|
||
cargo: {$ref: '#/components/schemas/BookingCargo'}
|
||
idempotencyKey: {type: string, minLength: 8, maxLength: 128}
|
||
BookingUpdate:
|
||
type: object
|
||
required: [tripRecordVersion, recordVersion, cargo]
|
||
properties:
|
||
tripRecordVersion: {type: integer, format: int64, minimum: 0}
|
||
recordVersion: {type: integer, format: int64, minimum: 0}
|
||
quoteRef: {$ref: '#/components/schemas/BookingQuoteRef'}
|
||
cargo: {$ref: '#/components/schemas/BookingCargo'}
|
||
BookingQuoteRef:
|
||
type: object
|
||
nullable: true
|
||
description: '选填;null或省略为手工询价。引用或清除已有来源另要求platform:fleet:quote:list。服务端在承运写事务内锁定并核对精确版本、SALE/ACTIVE、客户、路线、币种、仓库当地计划日期及价项;只保存可信来源,不接收浏览器快照。PALLET选LOOSE_DELIVERY,ORDER选FULL_DELIVERY。'
|
||
allOf: [{$ref: 'fleet-quote-candidates-v1.yaml#/components/schemas/QuoteRef'}]
|
||
BookingCommand:
|
||
type: object
|
||
required: [tripRecordVersion, recordVersion, idempotencyKey]
|
||
properties:
|
||
tripRecordVersion: {type: integer, format: int64, minimum: 0}
|
||
recordVersion: {type: integer, format: int64, minimum: 0}
|
||
idempotencyKey: {type: string, minLength: 8, maxLength: 128}
|
||
reason: {type: string, nullable: true, maxLength: 1000}
|
||
Booking:
|
||
type: object
|
||
properties:
|
||
offerNo: {type: string, nullable: true, description: 来源拼车发布号,池来源的成交和取消必须经专用接口}
|
||
expectedPalletCount: {type: integer, nullable: true, minimum: 1, description: 预计实托数,不等同托位}
|
||
bookingNo: {type: string}
|
||
tripNo: {type: string}
|
||
customerId: {type: string}
|
||
customerCode: {type: string}
|
||
customerName: {type: string}
|
||
status: {type: string, enum: [DRAFT, CONFIRMED, RECEIVED, BOUND, CANCELLED]}
|
||
cargo: {$ref: '#/components/schemas/BookingCargo'}
|
||
quoteSource:
|
||
type: object
|
||
nullable: true
|
||
description: '可信报价来源,独立于cargo.unitPrice及agreedAmount。确认承运重新核对报价及当前计划日期;确认后的报价变更或实收议价不覆盖已保存来源。'
|
||
allOf: [{$ref: 'fleet-quote-candidates-v1.yaml#/components/schemas/SourceSnapshot'}]
|
||
destinationLabel: {type: string}
|
||
agreedAmount: {type: number, nullable: true, description: 约定运费,非财务应收或实收}
|
||
incomingNo: {type: string, nullable: true}
|
||
dispatchNo: {type: string, nullable: true}
|
||
receipt:
|
||
type: object
|
||
nullable: true
|
||
properties:
|
||
source: {$ref: '#/components/schemas/IncomingEvidence'}
|
||
pallets: {type: array, items: {$ref: '#/components/schemas/BookingPalletSpaces'}}
|
||
operatorId: {type: string}
|
||
confirmedAt: {type: string, format: date-time}
|
||
recordVersion: {type: integer, format: int64}
|
||
updatedAt: {type: string, format: date-time}
|
||
Outcome:
|
||
description: packages保留原实发量;signedPackages为不可变实签量,returnedPackages只计原运输实际退回,remainingPackages必须为零且三者守恒才可结案。签收后的另行退货不重开原运输。
|
||
type: object
|
||
properties:
|
||
dispatchNo: {type: string}
|
||
deliveryNo: {type: string}
|
||
customerId: {type: string}
|
||
destination: {type: string, nullable: true}
|
||
status: {type: string}
|
||
packages: {type: integer}
|
||
terminalAt: {type: string, format: date-time, nullable: true}
|
||
signedPackages: {type: integer, minimum: 0}
|
||
returnedPackages: {type: integer, minimum: 0}
|
||
remainingPackages: {type: integer, minimum: 0}
|
||
CompletionEnvelope:
|
||
allOf:
|
||
- {$ref: '#/components/schemas/Envelope'}
|
||
- properties:
|
||
data:
|
||
type: object
|
||
properties:
|
||
tripNo: {type: string}
|
||
recordVersion: {type: integer, format: int64}
|
||
canComplete: {type: boolean}
|
||
blockReason: {type: string, nullable: true}
|
||
outcomes: {type: array, items: {$ref: '#/components/schemas/Outcome'}}
|
||
Complete:
|
||
type: object
|
||
required: [recordVersion, idempotencyKey, reason]
|
||
properties:
|
||
recordVersion: {type: integer, format: int64, minimum: 0}
|
||
idempotencyKey: {type: string, minLength: 8, maxLength: 128}
|
||
reason: {type: string, minLength: 1, maxLength: 1000}
|
||
Release:
|
||
type: object
|
||
required: [recordVersion, resourceKind, actualEndAt, endLocation, idempotencyKey, reason]
|
||
properties:
|
||
recordVersion: {type: integer, format: int64, minimum: 0}
|
||
resourceKind: {type: string, enum: [VEHICLE, DRIVER]}
|
||
actualEndAt: {type: string, format: date-time}
|
||
endLocation: {type: string, minLength: 1, maxLength: 500}
|
||
vehicleStatus: {type: string, nullable: true, enum: [IN_SERVICE, MAINTENANCE, INACTIVE, RETURNED], description: 结束车辆任务必填,结束司机任务必须为空}
|
||
idempotencyKey: {type: string, minLength: 8, maxLength: 128}
|
||
reason: {type: string, minLength: 1, maxLength: 1000}
|
||
ReleaseInfo:
|
||
type: object
|
||
nullable: true
|
||
properties:
|
||
actualEndAt: {type: string, format: date-time}
|
||
endLocation: {type: string}
|
||
vehicleStatus: {type: string, nullable: true, description: 结束本次车辆任务时的状态快照,不代表车辆此后的实时可派状态}
|
||
LoadingEnvelope:
|
||
allOf:
|
||
- {$ref: '#/components/schemas/Envelope'}
|
||
- properties:
|
||
data:
|
||
type: object
|
||
properties:
|
||
tripNo: {type: string}
|
||
recordVersion: {type: integer, format: int64}
|
||
manifestHash: {type: string}
|
||
cargo: {type: array, items: {$ref: '#/components/schemas/Cargo'}}
|
||
blockReason: {type: string, nullable: true}
|
||
confirmedLoad:
|
||
type: object
|
||
nullable: true
|
||
properties:
|
||
manifestHash: {type: string}
|
||
cargo: {type: array, items: {$ref: '#/components/schemas/Cargo'}}
|
||
pallets: {type: array, items: {$ref: '#/components/schemas/Measurement'}}
|
||
segments: {type: array, items: {type: object}, description: 逐段fromIndex/toIndex及occupied/remaining托位、weightKg、volumeCbm}
|
||
operatorId: {type: string}
|
||
confirmedAt: {type: string, format: date-time}
|
||
Cargo:
|
||
type: object
|
||
properties:
|
||
dispatchNo: {type: string}
|
||
customerId: {type: string}
|
||
dispatchItemId: {type: string}
|
||
warehousePalletId: {type: string, nullable: true}
|
||
palletNo: {type: string, nullable: true}
|
||
packages: {type: integer}
|
||
destinationKey: {type: string, nullable: true, description: 原货物目的地稳定匹配键,选择路线站点时透传}
|
||
destinationLabel: {type: string, nullable: true}
|
||
Measurement:
|
||
type: object
|
||
required: [warehousePalletId, palletSpaces, weightKg, volumeCbm, deliveryIndex]
|
||
properties:
|
||
warehousePalletId: {type: string}
|
||
palletSpaces: {type: integer, minimum: 1}
|
||
weightKg: {type: number, minimum: 0.001, multipleOf: 0.001, maximum: 999999999.999}
|
||
volumeCbm: {type: number, minimum: 0.001, multipleOf: 0.001, maximum: 999999999.999}
|
||
deliveryIndex: {type: integer, minimum: 1, description: 卸货站索引,起运仓固定为0}
|
||
PlanningEnvelope:
|
||
allOf:
|
||
- {$ref: '#/components/schemas/Envelope'}
|
||
- properties:
|
||
data:
|
||
type: object
|
||
properties:
|
||
tripNo: {type: string}
|
||
recordVersion: {type: integer, format: int64}
|
||
cargo: {type: array, items: {$ref: '#/components/schemas/Cargo'}}
|
||
manifestHash: {type: string}
|
||
planValid: {type: boolean, description: 计划已经核对且来源hash仍一致}
|
||
availableSegments: {type: array, items: {$ref: '#/components/schemas/Segment'}, description: 当前自有货计划加已确认外接预订后的逐段占用与余位;计划失效返回空数组}
|
||
blockReason: {type: string, nullable: true}
|
||
capacityPlan:
|
||
type: object
|
||
nullable: true
|
||
description: 计划值,不能作为实际装载确认
|
||
properties:
|
||
manifestHash: {type: string}
|
||
cargo: {type: array, items: {$ref: '#/components/schemas/Cargo'}}
|
||
pallets: {type: array, items: {$ref: '#/components/schemas/Measurement'}}
|
||
segments: {type: array, items: {$ref: '#/components/schemas/Segment'}}
|
||
operatorId: {type: string}
|
||
confirmedAt: {type: string, format: date-time}
|
||
Segment:
|
||
type: object
|
||
properties:
|
||
fromIndex: {type: integer}
|
||
toIndex: {type: integer}
|
||
occupied: {$ref: '#/components/schemas/CapacityLoad'}
|
||
remaining: {$ref: '#/components/schemas/CapacityLoad'}
|
||
CapacityLoad:
|
||
type: object
|
||
properties:
|
||
palletSpaces: {type: integer}
|
||
weightKg: {type: number}
|
||
volumeCbm: {type: number}
|
||
ConfirmLoad:
|
||
type: object
|
||
required: [recordVersion, manifestHash, pallets, reason]
|
||
properties:
|
||
recordVersion: {type: integer, format: int64, minimum: 0}
|
||
manifestHash: {type: string, pattern: '^[0-9a-f]{64}$'}
|
||
pallets: {type: array, minItems: 1, maxItems: 1000, items: {$ref: '#/components/schemas/Measurement'}}
|
||
reason: {type: string, minLength: 1, maxLength: 1000}
|
||
BindingCommand:
|
||
type: object
|
||
required: [recordVersion, dispatchNo, reason]
|
||
properties:
|
||
recordVersion: {type: integer, format: int64, minimum: 0}
|
||
dispatchNo: {type: string, minLength: 1, maxLength: 64}
|
||
reason: {type: string, minLength: 1, maxLength: 1000}
|
||
Review:
|
||
type: object
|
||
required: [recordVersion, decision]
|
||
properties:
|
||
recordVersion: {type: integer, format: int64, minimum: 0}
|
||
decision: {type: string, enum: [APPROVED, REJECTED]}
|
||
reason: {type: string, nullable: true, maxLength: 1000, description: 通过选填;打回必填}
|
||
ReviewState:
|
||
type: object
|
||
required: [status]
|
||
properties:
|
||
status: {type: string, enum: [PENDING, APPROVED, REJECTED]}
|
||
reason: {type: string, nullable: true}
|
||
reviewerId: {type: string, nullable: true}
|
||
reviewedAt: {type: string, format: date-time, nullable: true}
|
||
recordVersion: {type: integer, format: int64, nullable: true, description: 本次审核所核对的车次版本}
|
||
DispatchBinding:
|
||
type: object
|
||
properties:
|
||
dispatchNo: {type: string}
|
||
customerId: {type: string, description: 排车单自身客户归属,由服务端解析}
|
||
packageCount: {type: integer, description: 关联时待发运箱数,不是实物托位数}
|
||
boundBy: {type: string}
|
||
boundAt: {type: string, format: date-time}
|
||
review: {$ref: '#/components/schemas/ReviewState'}
|
||
Envelope:
|
||
type: object
|
||
properties:
|
||
code: {type: string}
|
||
message: {type: string, nullable: true}
|
||
data: {type: object, nullable: true}
|
||
Stop:
|
||
type: object
|
||
required: [name]
|
||
properties:
|
||
name: {type: string, minLength: 1, maxLength: 128}
|
||
address: {type: string, nullable: true, maxLength: 500}
|
||
destinationKey: {type: string, nullable: true, maxLength: 160, description: 卸货站匹配Loading货物的destinationKey;未配置时可以保存计划但不能确认装载}
|
||
Create:
|
||
type: object
|
||
required: [warehouseId, plannedDepartureAt, expectedDriverEndAt, stops, idempotencyKey]
|
||
properties:
|
||
warehouseId: {type: string, pattern: '^[1-9][0-9]*$'}
|
||
plannedDepartureAt: {type: string, format: date-time}
|
||
expectedDriverEndAt: {type: string, format: date-time}
|
||
stops: {type: array, minItems: 2, maxItems: 200, items: {$ref: '#/components/schemas/Stop'}}
|
||
remark: {type: string, nullable: true, maxLength: 1000}
|
||
idempotencyKey: {type: string, minLength: 8, maxLength: 128}
|
||
Plan:
|
||
type: object
|
||
required: [recordVersion, plannedDepartureAt, expectedDriverEndAt, stops, reason]
|
||
properties:
|
||
recordVersion: {type: integer, format: int64, minimum: 0}
|
||
plannedDepartureAt: {type: string, format: date-time}
|
||
expectedDriverEndAt: {type: string, format: date-time}
|
||
stops: {type: array, minItems: 2, maxItems: 200, items: {$ref: '#/components/schemas/Stop'}}
|
||
remark: {type: string, nullable: true, maxLength: 1000}
|
||
reason: {type: string, minLength: 1, maxLength: 1000}
|
||
Trip:
|
||
type: object
|
||
properties:
|
||
tripNo: {type: string}
|
||
status: {type: string, enum: [PLANNED, IN_TRANSIT, COMPLETED, CANCELLED]}
|
||
warehouseId: {type: string}
|
||
warehouseCode: {type: string}
|
||
warehouseName: {type: string}
|
||
vehicleId: {type: string, nullable: true}
|
||
vehiclePlate: {type: string, nullable: true}
|
||
driverId: {type: string, nullable: true}
|
||
driverName: {type: string, nullable: true}
|
||
driverPhone: {type: string, nullable: true}
|
||
maxPalletSpaces: {type: integer, nullable: true}
|
||
maxLoadKg: {type: number, nullable: true}
|
||
maxVolumeCbm: {type: number, nullable: true}
|
||
plannedDepartureAt: {type: string, format: date-time}
|
||
expectedDriverEndAt: {type: string, format: date-time}
|
||
departedAt: {type: string, format: date-time, nullable: true}
|
||
completedAt: {type: string, format: date-time, nullable: true}
|
||
stops: {type: array, items: {$ref: '#/components/schemas/Stop'}}
|
||
remark: {type: string, nullable: true}
|
||
recordVersion: {type: integer, format: int64}
|
||
updatedAt: {type: string, format: date-time}
|
||
vehicleRelease: {$ref: '#/components/schemas/ReleaseInfo'}
|
||
driverRelease: {$ref: '#/components/schemas/ReleaseInfo'}
|