305 lines
16 KiB
YAML
305 lines
16 KiB
YAML
openapi: "3.0.3"
|
||
info:
|
||
title: "原排车外配车辆运营视图"
|
||
version: "1.0.0"
|
||
description: "仅ACTIVE且装车后/派送中/已完成。按原装车归属DISPATCHED及MASTER/EXTERNAL资源快照读取;无快照不回填。复用四张附加表,不推进排车、不触发库存/财务。承运金额CNY/USD显式登记;单价除以实际物理托数并HALF_UP两位。无里程、油耗及油耗照片。响应遵循NON_NULL:可空属性可省略,省略与null均表示空值,0仍是明确登记值;请求必填项仍以required及DTO校验为准。"
|
||
security:
|
||
- bearerAuth: []
|
||
paths:
|
||
/api/platform/v1/last-leg/fleet/outsourced-business:
|
||
get:
|
||
operationId: listOutsourcedBusiness
|
||
summary: "外配列表及同筛选四项完整统计"
|
||
x-permission-code: "platform:fleet:outsourced-business: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: "原排车号、车牌或真实目的仓/FBA编码" }
|
||
- { name: warehouseId, in: query, schema: { type: string, maxLength: 64 } }
|
||
- { name: plannedDepartureFrom, in: query, schema: { type: string, format: date-time }, description: "原计划发车时间下界(含)" }
|
||
- { name: plannedDepartureTo, in: query, schema: { type: string, format: date-time }, description: "原计划发车时间上界(不含)" }
|
||
- { name: stage, in: query, schema: { "$ref": "fleet-owned-business-v1.yaml#/components/schemas/Stage" } }
|
||
responses:
|
||
"200":
|
||
description: "完整条件统计不带分页,不逐行GET;响应为统一ApiResponse。"
|
||
content:
|
||
application/json:
|
||
schema: { "$ref": "#/components/schemas/ListResponse" }
|
||
/api/platform/v1/last-leg/fleet/outsourced-business/{dispatchNo}:
|
||
parameters: [ { "$ref": "#/components/parameters/DispatchNo" } ]
|
||
get:
|
||
operationId: getOutsourcedBusiness
|
||
summary: "外配原排车组合详情"
|
||
x-permission-code: "platform:fleet:outsourced-business:list"
|
||
responses:
|
||
"200": { "$ref": "#/components/responses/DetailResponse" }
|
||
/api/platform/v1/last-leg/fleet/outsourced-business/{dispatchNo}/history:
|
||
parameters: [ { "$ref": "#/components/parameters/DispatchNo" } ]
|
||
get:
|
||
operationId: getOutsourcedBusinessHistory
|
||
summary: "原排车与运营附加历史分页"
|
||
x-permission-code: "platform:fleet:outsourced-business: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: "DISPATCH/OPERATIONS保留独立版本,原历史无虚构运营字段。"
|
||
content:
|
||
application/json:
|
||
schema: { "$ref": "#/components/schemas/HistoryResponse" }
|
||
/api/platform/v1/last-leg/fleet/outsourced-business/{dispatchNo}/operations:
|
||
parameters: [ { "$ref": "#/components/parameters/DispatchNo" } ]
|
||
put:
|
||
operationId: saveOutsourcedBusinessOperations
|
||
summary: "登记或清空整车承运金额和逐目的仓实际到达"
|
||
x-permission-code: "platform:fleet:outsourced-business:edit"
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema: { "$ref": "#/components/schemas/SaveOperations" }
|
||
responses:
|
||
"200": { "$ref": "#/components/responses/DetailResponse" }
|
||
/api/platform/v1/last-leg/fleet/outsourced-business/{dispatchNo}/photos/{slot}/uploads:
|
||
parameters: [ { "$ref": "#/components/parameters/DispatchNo" }, { "$ref": "#/components/parameters/Slot" } ]
|
||
post:
|
||
operationId: uploadOutsourcedBusinessPhoto
|
||
summary: "准备五框照片文件,尚未绑定"
|
||
x-permission-code: "platform:fleet:outsourced-business:upload"
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
multipart/form-data:
|
||
schema:
|
||
type: object
|
||
required: [file, idempotencyKey]
|
||
properties:
|
||
file: { type: string, format: binary, description: "非空JPG/PNG,签名校验,最大10MiB;固定装车File分类" }
|
||
idempotencyKey: { type: string, minLength: 8, maxLength: 128 }
|
||
responses:
|
||
"200":
|
||
description: "savedAt=null;未知结果保留原键查询,不重传。"
|
||
content:
|
||
application/json:
|
||
schema: { "$ref": "#/components/schemas/PhotoResponse" }
|
||
/api/platform/v1/last-leg/fleet/outsourced-business/{dispatchNo}/photos/{slot}:
|
||
parameters: [ { "$ref": "#/components/parameters/DispatchNo" }, { "$ref": "#/components/parameters/Slot" } ]
|
||
put:
|
||
operationId: bindOutsourcedBusinessPhoto
|
||
summary: "以独立稳定键绑定原File编号"
|
||
x-permission-code: "platform:fleet:outsourced-business:upload"
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema: { "$ref": "#/components/schemas/BindPhoto" }
|
||
responses:
|
||
"200": { "$ref": "#/components/responses/DetailResponse" }
|
||
/api/platform/v1/last-leg/fleet/outsourced-business/{dispatchNo}/photos/{slot}/files/{fileId}/content:
|
||
parameters: [ { "$ref": "#/components/parameters/DispatchNo" }, { "$ref": "#/components/parameters/Slot" } ]
|
||
get:
|
||
operationId: readOutsourcedBusinessPhotoContent
|
||
summary: "读取当前或精确历史版本的同车照片引用"
|
||
x-permission-code: "platform:fleet:outsourced-business:list"
|
||
parameters:
|
||
- { name: fileId, in: path, required: true, schema: { type: integer, format: int64, minimum: 1 } }
|
||
- { name: revisionVersion, in: query, schema: { type: integer, format: int64, minimum: 1 } }
|
||
responses:
|
||
"200":
|
||
description: "原始照片字节,Cache-Control=no-store,X-Content-Type-Options=nosniff;无引用不允许探测。"
|
||
content:
|
||
image/png: { schema: { type: string, format: binary } }
|
||
image/jpeg: { schema: { type: string, format: binary } }
|
||
/api/platform/v1/last-leg/fleet/outsourced-business/{dispatchNo}/commands/{idempotencyKey}:
|
||
parameters: [ { "$ref": "#/components/parameters/DispatchNo" } ]
|
||
get:
|
||
operationId: getOutsourcedBusinessCommand
|
||
summary: "仅原操作账号查询原命令结果"
|
||
x-permission-code: "platform:fleet:outsourced-business:list"
|
||
parameters:
|
||
- { name: idempotencyKey, in: path, required: true, schema: { type: string, minLength: 8, maxLength: 128 } }
|
||
responses:
|
||
"200":
|
||
description: "同dispatch唯一账本;相同键异内容/版本冲突,异账号拒绝,未知不自动重试。"
|
||
content:
|
||
application/json:
|
||
schema: { "$ref": "#/components/schemas/CommandResponse" }
|
||
components:
|
||
securitySchemes:
|
||
bearerAuth: { type: http, scheme: bearer, bearerFormat: JWT }
|
||
parameters:
|
||
DispatchNo: { name: dispatchNo, in: path, required: true, schema: { type: string, minLength: 1, maxLength: 128 } }
|
||
Slot: { name: slot, in: path, required: true, schema: { "$ref": "#/components/schemas/PhotoSlot" } }
|
||
responses:
|
||
DetailResponse:
|
||
description: "统一ApiResponse;成功code=200,业务拒绝A0400/A0403/A0404/A0409,认证/网关可真实401/403/503;保留requestId/traceId。"
|
||
content:
|
||
application/json:
|
||
schema:
|
||
allOf:
|
||
- { "$ref": "#/components/schemas/Envelope" }
|
||
- { type: object, properties: { data: { allOf: [ { "$ref": "#/components/schemas/Detail" } ], nullable: true } } }
|
||
schemas:
|
||
Envelope:
|
||
type: object
|
||
properties:
|
||
code: { type: string }
|
||
message: { type: string }
|
||
requestId: { type: string, nullable: true }
|
||
traceId: { type: string, nullable: true }
|
||
Operations:
|
||
type: object
|
||
additionalProperties: false
|
||
x-java-record: OutsourcedBusinessModels.Operations
|
||
required: [arrivals]
|
||
properties:
|
||
money: { allOf: [ { "$ref": "fleet-owned-business-v1.yaml#/components/schemas/Money" } ], nullable: true }
|
||
arrivals: { type: array, items: { "$ref": "fleet-owned-business-v1.yaml#/components/schemas/Arrival" }, description: "只接受原实际destinationKey,禁止重复或其他车辆目的地;省略目的地或null均不推定到达" }
|
||
SaveOperations:
|
||
type: object
|
||
additionalProperties: false
|
||
x-java-record: OutsourcedBusinessModels.SaveOperations
|
||
required: [recordVersion, idempotencyKey, operations]
|
||
properties:
|
||
recordVersion: { type: string, pattern: "^(0|[1-9][0-9]*)$" }
|
||
idempotencyKey: { type: string, minLength: 8, maxLength: 128 }
|
||
operations: { "$ref": "#/components/schemas/Operations" }
|
||
reason: { type: string, nullable: true, maxLength: 1000 }
|
||
BindPhoto:
|
||
type: object
|
||
additionalProperties: false
|
||
x-java-record: OutsourcedBusinessModels.BindPhoto
|
||
required: [recordVersion, idempotencyKey, fileId]
|
||
properties:
|
||
recordVersion: { type: string, pattern: "^(0|[1-9][0-9]*)$" }
|
||
idempotencyKey: { type: string, minLength: 8, maxLength: 128 }
|
||
fileId: { type: string, pattern: "^[1-9][0-9]*$" }
|
||
Vehicle:
|
||
type: object
|
||
x-java-record: OutsourcedBusinessModels.Vehicle
|
||
required: [ownership]
|
||
properties:
|
||
vehicleId: { type: string, nullable: true, description: "原临时EXTERNAL车辆合法为空,档案MASTER核对原捕获ID" }
|
||
plate: { type: string, nullable: true }
|
||
ownership: { type: string, enum: [DISPATCHED] }
|
||
carrierName: { type: string, nullable: true, description: "只取原车辆快照,缺失显示—;不查当前档案补值" }
|
||
PhotoSlot:
|
||
type: string
|
||
enum: [LOADING_SCENE, LOADING_LIST, PRE_DEPARTURE_CHECK, DRIVER_LICENSE, RECEIPT]
|
||
Photo:
|
||
type: object
|
||
x-java-record: OutsourcedBusinessModels.Photo
|
||
required: [slot, category, fileId, fileName, contentType, sizeBytes, uploadedAt]
|
||
properties:
|
||
slot: { "$ref": "#/components/schemas/PhotoSlot" }
|
||
category: { type: string, enum: [LOADING] }
|
||
fileId: { type: string }
|
||
fileName: { type: string }
|
||
contentType: { type: string, enum: [image/png, image/jpeg] }
|
||
sizeBytes: { type: string }
|
||
uploadedAt: { type: string, format: date-time }
|
||
savedAt: { type: string, format: date-time, nullable: true }
|
||
PhotoSummary:
|
||
type: object
|
||
x-java-record: OutsourcedBusinessModels.PhotoSummary
|
||
required: [loadingCount]
|
||
properties:
|
||
loadingCount: { type: integer, minimum: 0, maximum: 5 }
|
||
Row:
|
||
type: object
|
||
x-java-record: OutsourcedBusinessModels.Row
|
||
required: [dispatchNo, stage, plannedDepartureAt, loadingCompletedAt, origin, vehicle, driver, destinations, actualPalletCount, operations, recordVersion, dispatchRecordVersion, photoSummary, actions, sourceIssues]
|
||
properties:
|
||
dispatchNo: { type: string }
|
||
stage: { "$ref": "fleet-owned-business-v1.yaml#/components/schemas/Stage" }
|
||
plannedDepartureAt: { type: string, format: date-time }
|
||
loadingCompletedAt: { type: string, format: date-time }
|
||
departedAt: { type: string, format: date-time, nullable: true }
|
||
deliveryCompletedAt: { type: string, format: date-time, nullable: true }
|
||
origin: { "$ref": "fleet-owned-business-v1.yaml#/components/schemas/Origin" }
|
||
vehicle: { "$ref": "#/components/schemas/Vehicle" }
|
||
driver: { "$ref": "fleet-owned-business-v1.yaml#/components/schemas/Driver" }
|
||
destinations: { type: array, items: { "$ref": "fleet-owned-business-v1.yaml#/components/schemas/Destination" } }
|
||
actualPalletCount: { type: integer, minimum: 0, description: "原实载warehousePalletId去重;同客户/跨客户共托只计一次,不用标准托位作除数" }
|
||
operations: { "$ref": "#/components/schemas/Operations" }
|
||
unitPrice: { type: string, nullable: true, description: "整车金额除实际物理托数,HALF_UP两位;金额null或托数0时null" }
|
||
recordVersion: { type: string, description: "本页附加版本,初始只读虚拟0;原主单版本独立" }
|
||
dispatchRecordVersion: { type: string }
|
||
photoSummary: { "$ref": "#/components/schemas/PhotoSummary" }
|
||
actions: { "$ref": "fleet-owned-business-v1.yaml#/components/schemas/Actions" }
|
||
sourceIssues: { type: array, items: { type: string } }
|
||
ListResult:
|
||
type: object
|
||
x-java-record: OutsourcedBusinessModels.ListResult
|
||
required: [records, page, size, total, summary]
|
||
properties:
|
||
records: { type: array, items: { "$ref": "#/components/schemas/Row" } }
|
||
page: { type: integer }
|
||
size: { type: integer }
|
||
total: { type: integer }
|
||
summary: { "$ref": "fleet-owned-business-v1.yaml#/components/schemas/Summary" }
|
||
Detail:
|
||
type: object
|
||
x-java-record: OutsourcedBusinessModels.Detail
|
||
required: [row, dispatch, cargo, photos]
|
||
properties:
|
||
row: { "$ref": "#/components/schemas/Row" }
|
||
dispatch: { "$ref": "overseas-business-v1.yaml#/components/schemas/DispatchDetail" }
|
||
cargo: { type: array, items: { "$ref": "fleet-owned-business-v1.yaml#/components/schemas/Cargo" } }
|
||
photos: { type: array, items: { "$ref": "#/components/schemas/Photo" } }
|
||
History:
|
||
type: object
|
||
x-java-record: OutsourcedBusinessModels.History
|
||
required: [eventSource, action, occurredAt, photos]
|
||
properties:
|
||
eventSource: { type: string, enum: [DISPATCH, OPERATIONS] }
|
||
recordVersion: { type: string, nullable: true }
|
||
dispatchRecordVersion: { type: string, nullable: true }
|
||
action: { type: string }
|
||
operatorName: { type: string, nullable: true }
|
||
occurredAt: { type: string, format: date-time }
|
||
reason: { type: string, nullable: true }
|
||
operations: { allOf: [ { "$ref": "#/components/schemas/Operations" } ], nullable: true }
|
||
photos: { type: array, items: { "$ref": "#/components/schemas/Photo" } }
|
||
HistoryPage:
|
||
type: object
|
||
x-java-record: OutsourcedBusinessModels.HistoryPage
|
||
required: [records, page, size, total]
|
||
properties:
|
||
records: { type: array, items: { "$ref": "#/components/schemas/History" } }
|
||
page: { type: integer }
|
||
size: { type: integer }
|
||
total: { type: integer }
|
||
Command:
|
||
type: object
|
||
x-java-record: OutsourcedBusinessModels.Command
|
||
description: "SAVE_OPERATIONS/BIND_PHOTO成功时recordVersion和result必须有值;UPLOAD_PHOTO成功时result必须含fileId,recordVersion可空。仅可空的未确定或拒绝结果字段允许省略,不放宽成功回执的关联要求。"
|
||
required: [dispatchNo, action, idempotencyKey, state, replayed, retryAllowed]
|
||
properties:
|
||
dispatchNo: { type: string }
|
||
action: { type: string, enum: [SAVE_OPERATIONS, UPLOAD_PHOTO, BIND_PHOTO] }
|
||
idempotencyKey: { type: string }
|
||
state: { type: string, enum: [SUCCEEDED, PENDING, UNKNOWN_RESULT, REJECTED] }
|
||
recordVersion: { type: string, nullable: true }
|
||
replayed: { type: boolean }
|
||
result: { nullable: true, oneOf: [ { "$ref": "#/components/schemas/Detail" }, { "$ref": "#/components/schemas/Photo" } ] }
|
||
errorCode: { type: string, nullable: true }
|
||
retryAllowed: { type: boolean, enum: [false] }
|
||
ListResponse:
|
||
allOf:
|
||
- { "$ref": "#/components/schemas/Envelope" }
|
||
- { type: object, properties: { data: { allOf: [ { "$ref": "#/components/schemas/ListResult" } ], nullable: true } } }
|
||
HistoryResponse:
|
||
allOf:
|
||
- { "$ref": "#/components/schemas/Envelope" }
|
||
- { type: object, properties: { data: { allOf: [ { "$ref": "#/components/schemas/HistoryPage" } ], nullable: true } } }
|
||
PhotoResponse:
|
||
allOf:
|
||
- { "$ref": "#/components/schemas/Envelope" }
|
||
- { type: object, properties: { data: { allOf: [ { "$ref": "#/components/schemas/Photo" } ], nullable: true } } }
|
||
CommandResponse:
|
||
allOf:
|
||
- { "$ref": "#/components/schemas/Envelope" }
|
||
- { type: object, properties: { data: { allOf: [ { "$ref": "#/components/schemas/Command" } ], nullable: true } } }
|