244 lines
15 KiB
YAML
244 lines
15 KiB
YAML
openapi: 3.0.3
|
||
info:
|
||
title: 车辆运维记录
|
||
version: 1.0.0
|
||
description: >-
|
||
平台车辆运维事实,支持保养、加油、维修、紧急故障、应急救援和异常。每条记录固定属于一辆车,使用VR业务编号;读取、修改、照片和历史均校验路径中的车辆归属。
|
||
原始里程必须明确KM或MI,加油量必须明确L、US_GAL或IMP_GAL;不自动推测或换算,不更新车辆主档公里数。
|
||
核验状态是人工记录的PENDING或VERIFIED,不代表财务审批或车辆可派,不自动产生账单、付款或变更车辆状态。
|
||
创建按车辆、操作者和幂等键去重;更正须版本及原因。照片上传按记录与幂等键去重并核对内容摘要,丢失响应可原样重试。
|
||
照片最多20张,每张非空JPG/PNG且最多10MiB;File按平台0、FLEET_VEHICLE_RECORD_PHOTO和记录内部主键复合归属,验证内容签名。
|
||
维修和救援项目、地点独立保存;处理中或已完成须有处理人,异常须有明确分类。
|
||
费用只是运维申报金额,填金额则必须填有效币种;未填金额和零金额有区别,不生成应付或付款。
|
||
运维响应paymentStatus为空,不保存可变财务结论;维修/救援通过finance-status批量读取公司财务状态,不得由processingStatus推定付款。
|
||
显式提交公司成本时取已保存申报金额、服务端供应商与月份汇率,来源映射及Outbox同事务保存;不会自动入账或付款。
|
||
已提交费用须先在Finance作废才可修改费用项目/金额/币种或重新提交;处理进度、地点和处理人仍可独立更新。
|
||
不提供物理删除;编辑与上传历史同事务不可变保存。本接口不提供财务结算或车辆占用/状态自动变更。
|
||
security: [{bearerAuth: []}]
|
||
paths:
|
||
/api/platform/v1/last-leg/fleet/vehicles/{vehicleId}/records/finance-status:
|
||
parameters: [{$ref: '#/components/parameters/Vehicle'}]
|
||
post:
|
||
description: platform:overseas-master-data:vehicle:list;校验本车维修/救援记录,最多100条批量读取,不逐行调用Finance;依赖失败明确返回错误,不能伪造未关联或付款状态
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required: [recordNos]
|
||
properties:
|
||
recordNos: {type: array, minItems: 1, maxItems: 100, items: {type: string, minLength: 1, maxLength: 64}}
|
||
responses:
|
||
'200':
|
||
description: ApiResponse;data为每条请求记录的状态;Finance接收状态PENDING为待入账,APPROVED为已入账未付,不等于付款
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
code: {type: string}
|
||
data: {type: array, items: {$ref: '#/components/schemas/FinanceStatus'}}
|
||
/api/platform/v1/last-leg/fleet/vehicles/{vehicleId}/records/{recordNo}/finance:
|
||
parameters:
|
||
- {$ref: '#/components/parameters/Vehicle'}
|
||
- {name: recordNo, in: path, required: true, schema: {type: string}}
|
||
post:
|
||
description: platform:overseas-master-data:vehicle:record-finance-submit;不复用普通运维编辑权限。前端选择供应商候选另需platform:supplier:list。首次提交或Finance已作废后才可登记新来源版本,未知结果保留原键重试
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required: [recordVersion, supplierId, businessDate, idempotencyKey]
|
||
properties:
|
||
recordVersion: {type: integer, format: int64, minimum: 0}
|
||
supplierId: {type: integer, format: int64, minimum: 1}
|
||
businessDate: {type: string, format: date, description: 明确选择实际费用业务日期,用于获取业务月份有效汇率}
|
||
idempotencyKey: {type: string, minLength: 8, maxLength: 128}
|
||
responses:
|
||
'200':
|
||
description: ApiResponse;仅表示提交请求已登记,PENDING_FINANCE不是已入账或付款
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
code: {type: string}
|
||
data:
|
||
type: object
|
||
properties:
|
||
recordNo: {type: string}
|
||
sourceVersion: {type: integer, format: int64}
|
||
submittedRecordVersion: {type: integer, format: int64}
|
||
replayed: {type: boolean}
|
||
status: {type: string, enum: [PENDING_FINANCE]}
|
||
/api/platform/v1/last-leg/fleet/vehicles/{vehicleId}/records:
|
||
parameters: [{$ref: '#/components/parameters/Vehicle'}]
|
||
get:
|
||
summary: 分页查询当前车辆运维记录
|
||
description: '权限:platform:overseas-master-data:vehicle: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}}
|
||
- {name: recordType, in: query, schema: {type: string, enum: [MAINTENANCE, FUEL, REPAIR, BREAKDOWN, RESCUE, EXCEPTION]}}
|
||
responses:
|
||
'200': {description: '统一响应data为records/page/size/total/pages,records元素为Record'}
|
||
post:
|
||
summary: 新增记录
|
||
description: '权限:platform:overseas-master-data:vehicle:record-create;同键同内容返回原记录,不同内容冲突。'
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required: [idempotencyKey, details]
|
||
properties:
|
||
idempotencyKey: {type: string, minLength: 1, maxLength: 128}
|
||
details: {$ref: '#/components/schemas/Draft'}
|
||
responses:
|
||
'200': {$ref: '#/components/responses/Record'}
|
||
/api/platform/v1/last-leg/fleet/vehicles/{vehicleId}/records/{recordNo}:
|
||
parameters: [{$ref: '#/components/parameters/Vehicle'}, {$ref: '#/components/parameters/RecordNumber'}]
|
||
get:
|
||
summary: 读取记录详情
|
||
description: '权限:platform:overseas-master-data:vehicle:list;跨车辆记录返回404,不泄露其他车辆数据。'
|
||
responses:
|
||
'200': {$ref: '#/components/responses/Record'}
|
||
put:
|
||
summary: 更正记录
|
||
description: '权限:platform:overseas-master-data:vehicle:record-edit;类型及车辆不可更换,保留历史。'
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
required: [recordVersion, reason, details]
|
||
properties:
|
||
recordVersion: {type: integer, format: int64, minimum: 0}
|
||
reason: {type: string, minLength: 1, maxLength: 1000}
|
||
details: {$ref: '#/components/schemas/Draft'}
|
||
responses:
|
||
'200': {$ref: '#/components/responses/Record'}
|
||
/api/platform/v1/last-leg/fleet/vehicles/{vehicleId}/records/{recordNo}/files:
|
||
parameters: [{$ref: '#/components/parameters/Vehicle'}, {$ref: '#/components/parameters/RecordNumber'}]
|
||
post:
|
||
summary: 上传并关联运维图片
|
||
description: '权限:platform:overseas-master-data:vehicle:record-upload;记录保存成功后再上传,失败重试不得重复建记录。'
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
multipart/form-data:
|
||
schema:
|
||
type: object
|
||
required: [recordVersion, idempotencyKey, file]
|
||
properties:
|
||
recordVersion: {type: integer, format: int64, minimum: 0}
|
||
idempotencyKey: {type: string, minLength: 1, maxLength: 128}
|
||
file: {type: string, format: binary}
|
||
responses:
|
||
'200': {$ref: '#/components/responses/Record'}
|
||
/api/platform/v1/last-leg/fleet/vehicles/{vehicleId}/records/{recordNo}/files/{fileId}:
|
||
parameters:
|
||
- {$ref: '#/components/parameters/Vehicle'}
|
||
- {$ref: '#/components/parameters/RecordNumber'}
|
||
- {name: fileId, in: path, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
|
||
get:
|
||
summary: 读取当前记录已关联图片
|
||
description: '权限:platform:overseas-master-data:vehicle:list;先校验记录关联,再校验File复合归属;no-store和nosniff,不返回存储路径。'
|
||
responses:
|
||
'200': {description: 图片字节, content: {image/png: {schema: {type: string, format: binary}}, image/jpeg: {schema: {type: string, format: binary}}}}
|
||
/api/platform/v1/last-leg/fleet/vehicles/{vehicleId}/records/{recordNo}/history:
|
||
parameters: [{$ref: '#/components/parameters/Vehicle'}, {$ref: '#/components/parameters/RecordNumber'}]
|
||
get:
|
||
summary: 分页读取不可变修改历史
|
||
description: '权限:platform:overseas-master-data:vehicle: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: '统一响应data为分页对象;records包含recordVersion/action/reason/operatorId/occurredAt/snapshot,snapshot为Record'}
|
||
components:
|
||
securitySchemes:
|
||
bearerAuth: {type: http, scheme: bearer, bearerFormat: JWT}
|
||
parameters:
|
||
Vehicle: {name: vehicleId, in: path, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
|
||
RecordNumber: {name: recordNo, in: path, required: true, schema: {type: string}}
|
||
responses:
|
||
Record:
|
||
description: 统一业务响应;失败保留code、message及诊断标识
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
properties:
|
||
code: {type: string}
|
||
data: {$ref: '#/components/schemas/Record'}
|
||
schemas:
|
||
Draft:
|
||
type: object
|
||
required: [recordType, occurredAt]
|
||
oneOf:
|
||
- properties: {recordType: {enum: [MAINTENANCE]}}
|
||
required: [distanceUnit, odometer, verificationStatus, lastServiceOdometer, nextServiceOdometer]
|
||
- properties: {recordType: {enum: [FUEL]}}
|
||
required: [distanceUnit, odometer, verificationStatus, fuelQuantity, fuelUnit]
|
||
- properties: {recordType: {enum: [REPAIR, BREAKDOWN, RESCUE, EXCEPTION]}}
|
||
required: [incident]
|
||
properties:
|
||
recordType: {type: string, enum: [MAINTENANCE, FUEL, REPAIR, BREAKDOWN, RESCUE, EXCEPTION]}
|
||
occurredAt: {type: string, format: date-time, description: 带偏移或Z的实际发生时间,不晚于当前时间,保存UTC}
|
||
distanceUnit: {type: string, nullable: true, enum: [KM, MI], description: 保养加油必填;其他类型必须为空}
|
||
odometer: {type: number, nullable: true, minimum: 0, multipleOf: 0.001, description: 保养加油必填;其他类型必须为空}
|
||
lastServiceOdometer: {type: number, nullable: true, minimum: 0, description: 保养必填,不大于记录时里程;加油必须为空}
|
||
nextServiceOdometer: {type: number, nullable: true, minimum: 0, description: 保养必填且大于上次保养里程,可低于当前里程表示已超保养里程;不默认一万迈}
|
||
fuelQuantity: {type: number, nullable: true, minimum: 0, exclusiveMinimum: true, description: 加油必填正数;保养必须为空}
|
||
fuelUnit: {type: string, nullable: true, enum: [L, US_GAL, IMP_GAL], description: 加油必填明确单位;保养必须为空}
|
||
verificationStatus: {type: string, nullable: true, enum: [PENDING, VERIFIED], description: 保养加油必填;其他类型必须为空,不能混作处理状态}
|
||
remark: {type: string, nullable: true, maxLength: 1000}
|
||
incident: {$ref: '#/components/schemas/Incident'}
|
||
Incident:
|
||
type: object
|
||
nullable: true
|
||
description: 维修/故障/救援/异常必填;保养加油必须为空,并禁止混入里程、加油或核验字段
|
||
required: [description, processingStatus]
|
||
properties:
|
||
description: {type: string, minLength: 1, maxLength: 2000}
|
||
item: {type: string, nullable: true, maxLength: 256, description: 维修或救援项目,此两类必填;其他类型为空}
|
||
place: {type: string, nullable: true, maxLength: 512, description: 维修或救援地点,此两类必填;其他类型为空}
|
||
handler: {type: string, nullable: true, maxLength: 128, description: 实际处理人;处理中或完成时必填,与系统操作人分别保留}
|
||
processingStatus: {type: string, enum: [PENDING, IN_PROGRESS, COMPLETED]}
|
||
exceptionType: {type: string, nullable: true, enum: [ROUTE, TIMEOUT, DELIVERY, VEHICLE_BREAKDOWN], description: 异常记录必填;其他类型为空}
|
||
reportedCost: {type: number, nullable: true, minimum: 0, multipleOf: 0.01, maximum: 999999999999.99, description: 仅维修/救援允许;空为未登记,零为已登记零费用,不表示付款}
|
||
currency: {type: string, nullable: true, pattern: '^[A-Z]{3}$', description: 金额非空时必填有效币种;未填金额时为空,不自动换算}
|
||
File:
|
||
type: object
|
||
properties:
|
||
fileId: {type: string}
|
||
fileName: {type: string}
|
||
contentType: {type: string, enum: [image/jpeg, image/png]}
|
||
sizeBytes: {type: integer, format: int64}
|
||
Record:
|
||
type: object
|
||
properties:
|
||
recordNo: {type: string}
|
||
vehicleId: {type: string}
|
||
vehiclePlate: {type: string, description: 建档时车牌快照}
|
||
details: {$ref: '#/components/schemas/Draft'}
|
||
files: {type: array, items: {$ref: '#/components/schemas/File'}}
|
||
recordVersion: {type: integer, format: int64, minimum: 0}
|
||
updatedBy: {type: string}
|
||
updatedAt: {type: string, format: date-time}
|
||
paymentStatus: {type: string, nullable: true, readOnly: true, description: 运维快照不记录可变财务状态,当前为空;读取finance-status获取财务事实}
|
||
FinanceStatus:
|
||
type: object
|
||
properties:
|
||
recordNo: {type: string}
|
||
status: {type: string, enum: [UNLINKED, PENDING_FINANCE, FINANCE_ATTENTION, PENDING, APPROVED, PARTIALLY_PAID, PAID, VOIDED]}
|
||
sourceVersion: {type: integer, format: int64, nullable: true}
|
||
submittedRecordVersion: {type: integer, format: int64, nullable: true}
|
||
finance: {type: object, nullable: true, description: Finance公司费用Cost完整只读快照;来源版本及内容须与本地提交一致;未接收不虚构金额,具体结构见finance-vehicle-costs-v1.yaml的Cost}
|