Files
baiyue-firstleg/lastleg-service/src/main/resources/openapi/fleet-vehicle-records-v1.yaml
T

244 lines
15 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: >-
平台车辆运维事实,支持保养、加油、维修、紧急故障、应急救援和异常。每条记录固定属于一辆车,使用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}