This commit is contained in:
2026-10-20 23:34:22 +08:00
parent 0dd9c8db07
commit 9f6e43ef3f
42 changed files with 1526 additions and 146 deletions
@@ -0,0 +1,304 @@
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 } } }
@@ -2,7 +2,7 @@ openapi: "3.0.3"
info:
title: "原排车自有车辆运营视图"
version: "1.0.0"
description: "装车完成时冻结车辆OWNED/DISPATCHED;所有主单事实来自原dispatch。新增数据仅附加运营记录、命令、历史及归属证据。油耗L/100km手工登记,金额CNY/USD不默认、不换汇;零与未登记不同。"
description: "装车完成时冻结车辆OWNED/DISPATCHED;所有主单事实来自原dispatch。新增数据仅附加运营记录、命令、历史及归属证据。油耗L/100km手工登记,金额CNY/USD不默认、不换汇;零与未登记不同。响应遵循NON_NULL:可空属性可省略,省略与null均表示空值,0仍是明确登记值;请求必填项仍以required及DTO校验为准。"
security:
-
bearerAuth: []
@@ -237,15 +237,6 @@ paths:
-
"$ref": "#/components/schemas/Photo"
nullable: true
parameters:
-
name: "idempotencyKey"
in: "query"
required: true
schema:
type: "string"
minLength: 8
maxLength: 128
requestBody:
required: true
content:
@@ -254,7 +245,13 @@ paths:
type: "object"
required:
- "file"
- "idempotencyKey"
properties:
idempotencyKey:
type: "string"
minLength: 8
maxLength: 128
description: "原上传请求键,以multipart表单字段提交,绑定使用独立请求键。"
file:
type: "string"
format: "binary"
@@ -432,7 +429,6 @@ components:
x-java-record: "OwnedBusinessModels.Arrival"
required:
- "destinationKey"
- "actualArrivedAt"
properties:
destinationKey:
type: "string"
@@ -446,9 +442,6 @@ components:
type: "object"
x-java-record: "OwnedBusinessModels.Operations"
required:
- "money"
- "actualDistanceMiles"
- "fuelConsumptionLitresPer100Km"
- "arrivals"
properties:
money:
@@ -512,7 +505,6 @@ components:
x-java-record: "OwnedBusinessModels.Gate"
required:
- "allowed"
- "blockReason"
properties:
allowed:
type: "boolean"
@@ -563,9 +555,6 @@ components:
Driver:
type: "object"
x-java-record: "OwnedBusinessModels.Driver"
required:
- "name"
- "phone"
properties:
name:
type: "string"
@@ -578,8 +567,6 @@ components:
x-java-record: "OwnedBusinessModels.Appointment"
required:
- "appointmentNo"
- "confirmationNo"
- "scheduledAt"
- "allocatedPackages"
properties:
appointmentNo:
@@ -599,11 +586,7 @@ components:
x-java-record: "OwnedBusinessModels.Destination"
required:
- "destinationKey"
- "warehouseCode"
- "warehouseName"
- "address"
- "appointments"
- "actualArrivedAt"
properties:
destinationKey:
type: "string"
@@ -635,7 +618,6 @@ components:
- "contentType"
- "sizeBytes"
- "uploadedAt"
- "savedAt"
properties:
slot:
"$ref": "#/components/schemas/PhotoSlot"
@@ -684,15 +666,11 @@ components:
- "stage"
- "plannedDepartureAt"
- "loadingCompletedAt"
- "departedAt"
- "deliveryCompletedAt"
- "origin"
- "vehicle"
- "driver"
- "destinations"
- "actualPalletCount"
- "operations"
- "unitPrice"
- "recordVersion"
- "dispatchRecordVersion"
- "photoSummary"
@@ -804,9 +782,6 @@ components:
required:
- "sourceKey"
- "customerId"
- "customerName"
- "orderNo"
- "inboundCode"
- "palletNo"
- "destinationKey"
- "packages"
@@ -856,13 +831,8 @@ components:
x-java-record: "OwnedBusinessModels.History"
required:
- "eventSource"
- "recordVersion"
- "dispatchRecordVersion"
- "action"
- "operatorName"
- "occurredAt"
- "reason"
- "operations"
- "photos"
properties:
eventSource:
@@ -925,15 +895,13 @@ components:
Command:
type: "object"
x-java-record: "OwnedBusinessModels.Command"
description: "SAVE_OPERATIONS/BIND_PHOTO成功时recordVersion和result必须有值;UPLOAD_PHOTO成功时result必须含fileId,recordVersion可空。仅可空的未确定或拒绝结果字段允许省略,不放宽成功回执的关联要求。"
required:
- "dispatchNo"
- "action"
- "idempotencyKey"
- "state"
- "recordVersion"
- "replayed"
- "result"
- "errorCode"
- "retryAllowed"
properties:
dispatchNo: