feat(fleet): enforce reviewed trips and original fee coverage for dispatch
This commit is contained in:
@@ -0,0 +1,175 @@
|
||||
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当前固定UNLINKED表示未关联财务,不得由processingStatus推定为已付款,其他类型为空。
|
||||
不提供物理删除;编辑与上传历史同事务不可变保存。本接口不提供财务结算或车辆占用/状态自动变更。
|
||||
security: [{bearerAuth: []}]
|
||||
paths:
|
||||
/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, enum: [UNLINKED], description: 维修/救援未关联财务时为UNLINKED,其余为空;不可用处理完成推定已付款}
|
||||
Reference in New Issue
Block a user