hl-api-changelog/changelogs-v2/2026-05/21_车辆档案-修改接口-管理后台.md
yaosutu 761ca0742d 新增 车辆档案 6 接口 + 司机档案 6 接口 全模块快照 changelog(fleet 模块批量补发)
两份 changelog 都按 SKILL.md 多接口模板(按接口分小节)+ 严格代码契约(不照搬文档)写:

文件 1: changelogs-v2/2026-05/21_车辆档案-修改接口-管理后台.md
- 6 接口(page/detail/create/update/delete/import)全契约
- 真枚举 VehicleAttachmentCategoryEnum(6 类目 + 张数上限)+ fleet/vehicleStatus @Pattern 强校验
- 错误码:600100 + 600107-600110(与文档 v1.4 差异已显式注解)+ 共用 601001-601005
- 标注:本模块无单独 PR 改动,本次为全模块快照首推

文件 2: changelogs-v2/2026-05/21_2791_司机档案-修改接口-管理后台.md
- 6 接口全契约 + 详情接口新增 relatedOrders mock 字段(PR #2796)
- 真枚举 DriverAttachmentCategoryEnum(8 类目 + 张数上限,前 3 类换证留历史语义)
+ DriverStatusEnum / SeasonEnum / InsuranceTypeEnum @Pattern 强校验
- 4 嵌套 VO 完整字段表(DriverLicenseVO/DriverEmergencyVO/DriverInsuranceVO/DriverStatsVO)
- attachments 是 Map<category, List> 按类目分组
- 错误码:600200-600205 + 601001-601005
- 5 tab 后端实现说明(season=active/pending/archived/blacklist + 全部不传)
- 关联 Issue #2791 + PR #2796
- mock 警示(固定 3 条假数据,所有司机返回相同,待真实化)

校准(代码 vs 文档):
- 车辆错误码段位实际避让到 600107-600110(与车型管理库 600101-600106 冲突)
- 司机详情 attachments 是 Map<String, List<Item>> 按类目分组返回(不是扁平 array)
- DriverImportRespVO 字段名与 VehicleImportRespVO 不同(前者 insertedCount/renewedCount/errorCount,后者 success/failed/errorRows)
2026-05-21 15:33:02 +08:00

19 KiB

【修改接口·管理后台】车辆档案 6 接口(全模块首次推送 changelog

PR: 无(本次为首次推送,实质接口契约未变更,配合 §1 §3 模块 changelog 一并补齐 fleet 全档案契约) 服务: hl-fleet-service | 更新时间: 2026-05-21

存放目录: changelogs-v2/2026-05/ 影响范围: 管理后台「车管 / 车辆档案」页(列表 + 详情 + 新增 + 编辑 + 软删 + Excel 批量导入)


⚠️ 关键说明

车辆档案模块 6 接口自 fleet 服务首次落地PR #2724以来契约未变化,本次仅作首次完整 changelog 推送,让前端 v3 项目仓库一次拿全 6 接口契约。

与车型管理库§1 changelog配套:车辆档案的 vehicleModelId 引用车型管理库的型号 ID,前端可在新增车辆页用 §1.5 / §1.7 拉型号下拉。


1. 接口背景

车辆档案是车队所有车辆的主数据:车牌 / 车型 / VIN / 行驶证 / 保险 / 年检 / 多类目附件(外观/内饰/保险/年检/营运证/其他 6 类)。

前端"车管 / 车辆档案"页面提供:

  • 列表筛选(按车牌、车队、车型大类、状态、保险/年检到期日)
  • 详情查看(含附件按类目分组)
  • 新增 / 编辑(含附件 diff 语义批量提交)
  • 软删(业务流水模块上线后会按"未完成派单"拒删)
  • Excel 批量导入

2. 变更清单

# 方法 路径 变更类型 说明
1 GET /admin/fleet/vehicles/page 首推 分页列表(多条件过滤)
2 GET /admin/fleet/vehicles/{vehicleId} 首推 详情(含附件)
3 POST /admin/fleet/vehicles 首推 新增(含附件批量 INSERT
4 PUT /admin/fleet/vehicles/{vehicleId} 首推 编辑(附件 diff 语义)
5 DELETE /admin/fleet/vehicles/{vehicleId} 首推 软删
6 POST /admin/fleet/vehicles/import 首推 Excel 批量导入

3. 接口详情

3.1 分页查询

GET /admin/fleet/vehicles/page

  • 使用场景:车管车辆档案列表页
  • 认证:管理后台 JWT
  • 幂等:是(只读)

Query 入参

字段 类型 必填 默认 校验 说明
page int 1 >= 1 页码
pageSize int 20 1-100 每页条数
keyword string 车牌模糊匹配
fleet string own/coopA/coopB 车队精确过滤
typeKey string 车型大类 key 精确(如 suv
vehicleStatus string idle/busy/maint 状态精确
insureDueBefore date yyyy-MM-dd 保险到期日早于此日(含)
inspectDueBefore date yyyy-MM-dd 年检到期日早于此日(含)

出参Result<PageResult<VehiclePageItemRespVO>> (按 create_time DESC

字段 类型 说明
records[].id string 车辆 IDLong 序列化为 String
records[].plate string 车牌
records[].vehicleModelId string 型号 ID
records[].vehicleTypeId string 大类 ID
records[].modelName string 型号名(如丰田汉兰达)
records[].seats int 座位数
records[].fleet string 车队own/coopA/coopB
records[].vehicleStatus string 状态idle/busy/maint
records[].insurer string 保险公司
records[].insureDue date 保险到期日
records[].inspectDue date 年检到期日
records[].createTime datetime 创建时间
total / page / pageSize int 分页元数据

典型示例 请求

GET /admin/fleet/vehicles/page?page=1&pageSize=20&fleet=own&insureDueBefore=2025-12-31
Authorization: Bearer <token>
(无请求体)

典型示例 响应

{
  "code": 200,
  "data": {
    "records": [
      {
        "id": "1234567890123456789",
        "plate": "蒙A-88888",
        "vehicleModelId": "1234567890123456001",
        "vehicleTypeId": "1234567890123456002",
        "modelName": "丰田汉兰达",
        "seats": 7,
        "fleet": "own",
        "vehicleStatus": "idle",
        "insurer": "中国人保财险",
        "insureDue": "2025-12-31",
        "inspectDue": "2025-12-31",
        "createTime": "2025-05-21 14:00:00"
      }
    ],
    "total": 1,
    "page": 1,
    "pageSize": 20
  },
  "msg": "成功"
}

错误码400 参数校验 / 401 未登录


3.2 详情

GET /admin/fleet/vehicles/{vehicleId}

  • 使用场景:详情页 / 编辑前预填
  • 认证:管理后台 JWT
  • 幂等:是

路径入参

字段 类型 必填 说明
vehicleId Long 车辆 ID

出参Result<VehicleDetailRespVO>

包含 §3.1 全部字段 + 以下扩展:

字段 类型 说明
vin string 车架号VIN
regDate date 注册日期
policyNo string 保单号
regCertNo string 行驶证号
regCertOwner string 行驶证所有人
regCertUsage string 使用性质
regCertFrontUrl string 行驶证正面 OSS URL
regCertBackUrl string 行驶证副页 OSS URL
attachments[] array 附件列表(按 category + sortNo 升序)
attachments[].id string 附件 ID
attachments[].category string 类目(见 §6.1
attachments[].sortNo int 同类目排序0-based
attachments[].url string OSS URL
attachments[].mimeType string image/jpeg
primaryDriverName string|null 目前恒为 null(待业务流水 PR 注入司机姓名)
updateTime datetime

典型示例 响应

{
  "code": 200,
  "data": {
    "id": "1234567890123456789",
    "plate": "蒙A-88888",
    "vehicleModelId": "1234567890123456001",
    "vehicleTypeId": "1234567890123456002",
    "modelName": "丰田汉兰达",
    "seats": 7,
    "fleet": "own",
    "vehicleStatus": "idle",
    "vin": "LSVNV2182E2100001",
    "regDate": "2020-01-01",
    "inspectDue": "2025-12-31",
    "insurer": "中国人保财险",
    "policyNo": "PICC-2024-XXX",
    "insureDue": "2025-12-31",
    "regCertNo": "12345678",
    "regCertOwner": "呼籁旅游服务有限公司",
    "regCertUsage": "营运租赁",
    "regCertFrontUrl": "https://oss.example.com/fleet/cert-front.jpg",
    "regCertBackUrl": "https://oss.example.com/fleet/cert-back.jpg",
    "attachments": [
      {
        "id": "1234567890123456900",
        "vehicleId": "1234567890123456789",
        "category": "exterior",
        "sortNo": 0,
        "url": "https://oss.example.com/fleet/ext-1.jpg",
        "mimeType": "image/jpeg"
      }
    ],
    "primaryDriverName": null,
    "createTime": "2025-05-21 14:00:00",
    "updateTime": "2025-05-21 14:00:00"
  },
  "msg": "成功"
}

错误码600110 车辆不存在 / 401 未登录


3.3 新增

POST /admin/fleet/vehicles

  • 使用场景:新增车辆 + 附件批量提交(前端 STS 直传 OSS 后把 URL 数组放主表单一并提交)
  • 认证:管理后台 JWT
  • 幂等:否(重复抛 600100/600107

Body 入参VehicleSaveReqVO

字段 类型 必填 校验 说明
plate string @Size(max=16) 车牌(全局唯一)
vehicleModelId Long 车型型号 ID引用 §1 模块)
fleet string @Pattern(own|coopA|coopB) 车队
vehicleStatus string @Pattern(idle|busy|maint) 状态,默认 idle
vin string @Size(max=32) 车架号(传则全局唯一)
regDate date 注册日期
inspectDue date 年检到期日
insurer string @Size(max=64) 保险公司
policyNo string @Size(max=64) 保单号
insureDue date 保险到期日
regCertNo string @Size(max=64) 行驶证号
regCertOwner string @Size(max=128) 行驶证所有人
regCertUsage string @Size(max=32) 使用性质
regCertFrontUrl string @Size(max=512) 行驶证正面 OSS URL
regCertBackUrl string @Size(max=512) 行驶证副页 OSS URL
attachments[] array 附件数组(见下)

attachments[] 单项VehicleAttachmentReqVO

字段 类型 必填 校验 说明
id Long 附件 ID新增项不传
category string @Size(max=32) 类目(见 §6.1
url string @Size(max=512) OSS URL
mimeType string @Size(max=64) image/jpeg
sortNo int 同类目排序(不传时按入参顺序自动重写 0..N-1

出参Result<VehicleCreateRespVO>

字段 类型 说明
id string 新增车辆 ID
attachmentIds[] array 附件 ID 列表(按入参顺序)

典型示例 请求

POST /admin/fleet/vehicles
Authorization: Bearer <token>
Content-Type: application/json

{
  "plate": "蒙A-88888",
  "vehicleModelId": "1234567890123456001",
  "fleet": "own",
  "vehicleStatus": "idle",
  "vin": "LSVNV2182E2100001",
  "regDate": "2020-01-01",
  "inspectDue": "2025-12-31",
  "insurer": "中国人保财险",
  "policyNo": "PICC-2024-XXX",
  "insureDue": "2025-12-31",
  "regCertNo": "12345678",
  "regCertOwner": "呼籁旅游服务有限公司",
  "regCertUsage": "营运租赁",
  "regCertFrontUrl": "https://oss.example.com/fleet/cert-front.jpg",
  "regCertBackUrl": "https://oss.example.com/fleet/cert-back.jpg",
  "attachments": [
    { "category": "exterior", "url": "https://oss.example.com/fleet/ext-1.jpg", "mimeType": "image/jpeg" },
    { "category": "exterior", "url": "https://oss.example.com/fleet/ext-2.jpg", "mimeType": "image/jpeg" },
    { "category": "insurance", "url": "https://oss.example.com/fleet/ins.jpg", "mimeType": "image/jpeg" }
  ]
}

典型示例 响应

{
  "code": 200,
  "data": {
    "id": "1234567890123456789",
    "attachmentIds": ["1234567890123456900", "1234567890123456901", "1234567890123456902"]
  },
  "msg": "成功"
}

异常 请求(车牌重复):

{ "code": 600100, "msg": "车牌已存在", "data": null }

异常 请求(附件类目张数超上限 exterior > 6

{ "code": 601003, "msg": "该类目张数已达上限", "data": null }

错误码400 参数校验 / 600100 车牌已存在 / 600107 VIN 已存在 / 600108 车型不存在 / 601002 附件类目非法 / 601003 类目张数达上限 / 401 未登录


3.4 编辑(附件 diff 语义)

PUT /admin/fleet/vehicles/{vehicleId}

  • 使用场景:编辑车辆基本信息 + 附件增删改一次性提交
  • 认证:管理后台 JWT
  • 幂等:是

路径入参

字段 类型 必填 说明
vehicleId Long 车辆 ID

Body 入参:同 §3.3(共用 VehicleSaveReqVO

附件 diff 语义

入参 attachments[] 项 DB 中的对应行 行为
id + DB 命中 存在 保留(可更新 sortNo
id(新增项) INSERT
存在但本次未传 软删

出参Result<VehicleUpdateRespVO>

字段 类型 说明
kept int 保留的附件数
inserted int 新插入的附件数
softDeleted int 软删的附件数

典型示例 响应

{
  "code": 200,
  "data": { "kept": 2, "inserted": 1, "softDeleted": 1 },
  "msg": "成功"
}

错误码400 参数校验 / 600100 车牌已存在 / 600107 VIN 已存在 / 600108 车型不存在 / 600110 车辆不存在 / 601002 类目非法 / 601003 类目张数达上限 / 401 未登录


3.5 软删

DELETE /admin/fleet/vehicles/{vehicleId}

  • 使用场景:下架车辆
  • 认证:管理后台 JWT
  • 幂等:是

路径入参

字段 类型 必填 说明
vehicleId Long 车辆 ID

出参Result<Void>data: null

典型示例 响应

{ "code": 200, "data": null, "msg": "成功" }

异常 请求(车辆有未完成派单 —— 业务流水 PR 落地后才生效

{ "code": 600109, "msg": "车辆有未完成派单,不能删除", "data": null }

错误码600109 有未完成派单(占位,业务流水 PR 上线后生效)/ 600110 车辆不存在 / 401 未登录


3.6 Excel 批量导入

POST /admin/fleet/vehicles/import

  • 使用场景:运营批量录入车辆
  • 认证:管理后台 JWT
  • 幂等:否(重复行按车牌冲突拒绝单行)

入参multipart/form-data

字段 类型 必填 说明
file file Excel.xlsx / .xls)或 CSV

表头约定(第 1 行 12 列,顺序固定)

车牌 | 车型型号ID | 车队(own/coopA/coopB) | 车架号(VIN) |
注册日期(yyyy-MM-dd) | 年检到期日(yyyy-MM-dd) |
保险公司 | 保单号 | 保险到期日(yyyy-MM-dd) |
行驶证号 | 行驶证所有人 | 使用性质

出参Result<VehicleImportRespVO>

字段 类型 说明
total int 总行数(不含表头)
success int 成功导入数
failed int 失败行数
errorRows[] array 失败行详情
errorRows[].row int Excel 行号(从 2 开始,1 为表头)
errorRows[].plate string 车牌(用于定位)
errorRows[].msg string 错误信息(如"车牌已存在"

典型示例 响应

{
  "code": 200,
  "data": {
    "total": 10,
    "success": 8,
    "failed": 2,
    "errorRows": [
      { "row": 3, "plate": "蒙A-88888", "msg": "车牌已存在" },
      { "row": 7, "plate": "蒙A-99999", "msg": "车型型号 ID 不存在" }
    ]
  },
  "msg": "成功"
}

错误码400 文件解析失败 / 401 未登录


6. 枚举 / 数据字典

6.1 附件类目(categoryVehicleAttachmentCategoryEnum

所属字段VehicleAttachmentReqVO.category / VehicleAttachmentRespVO.category | 类型String | 必填

真枚举(后端硬编码,含同类目张数上限):

中文 张数上限
exterior 车辆外观 6
interior 车辆内饰 3
insurance 保险单据 2
inspection 年检单据 2
operation_license 营运证 2
other 其他附件 5

超出上限触发 601003 "该类目张数已达上限"。

6.2 车队(fleet

所属字段VehicleSaveReqVO.fleet / VehiclePageReqVO.fleet / VehiclePageItemRespVO.fleet | 类型String | 必填(新增时)

@Pattern 强校验枚举

含义
own 自营车辆
coopA 合作车队 A
coopB 合作车队 B

6.3 车辆状态(vehicleStatus

所属字段:同 fleet | 类型String | 必填(默认 idle

@Pattern 强校验枚举

含义
idle 空闲
busy 在途
maint 维修中

7. 错误码(全模块汇总)

code 含义 触发条件 涉及接口
400 参数校验失败 字段缺失/长度/枚举值不合法/MIME 非法 所有写入接口
401 未登录 JWT 无效或缺失 全部 6 接口
600100 车牌已存在 plate 全局唯一约束 §3.3 §3.4
600107 VIN 已存在 vin 全局唯一约束 §3.3 §3.4
600108 车型不存在 vehicleModelId 无效或软删 §3.3 §3.4
600109 有未完成派单,不能删除 业务流水 PR 上线后才触发(目前占位) §3.5
600110 车辆不存在 vehicleId 无效或软删 §3.2 §3.4 §3.5
601001 实体不存在 附件关联的主车辆不存在 §3.3 §3.4
601002 附件类目非法 category 不在枚举内 §3.3 §3.4
601003 该类目张数已达上限 超出 §6.1 张数上限 §3.3 §3.4
601004 文件超出大小限制 应用层 + OSS HEAD 校验 §3.6导入,§3.3/§3.4 主体不直接校验
601005 文件类型非法 MIME 不在白名单 §3.3 §3.4

错误码段位 600100-600110 归属车辆档案;601001-601005 归属附件管理(车辆/司机共用)。

注意:与文档 v1.4 的差异 —— 文档原计划 VIN 用 600101 / 车型不存在 600102 / 派单冲突 600103,但因这 3 个段位被车型管理库占用(见 §1 changelog,实际代码避让到 600107/600108/600109。本 changelog 反映代码实际值


9. 业务边界

  • 附件 diff 语义统一§3.3 新增时所有项无 id;§3.4 编辑时按 id 命中度决定保留/插入/软删
  • sortNo 自动重写:附件 sortNo 不传时按入参顺序自动写 0..N-1同 category 内 0-based
  • 行驶证 OSS URL 留主表regCertFrontUrl / regCertBackUrl 是主表字段(不走附件表),与附件分离
  • 唯一约束plate / vin 全局唯一(违反抛 600100 / 600107
  • 车队 / 状态强枚举fleet vehicleStatus@Pattern 校验,违反返 400
  • ⚠️ primaryDriverName 占位§3.2 详情返 primaryDriverName: null,待业务流水 PR 上线后注入司机姓名
  • ⚠️ 派单删除保护占位§3.5 错误码 600109 在业务流水 PR 上线后才会真触发

11. 影响评估

  • 是否破坏向后兼容:否(接口契约自首次落地以来未变更)
  • 前端是否必须同步上线:否(本次仅补发 changelog,无代码改动
  • 影响已有数据:无

12. 注意事项

  • 分页参数名page / pageSize不是 pageNo
  • Long 主键序列化id / vehicleModelId / vehicleTypeId / attachments[].id 等 Long 字段 JSON 返回为 String,前端不要当 Number 解析
  • 错误码不连续600100 / 600107-600110中间 600101-600106 是车型管理库的段位),见 §7 注解
  • 附件 URL 不可改§3.4 编辑时 attachments[].url 不可改(后端忽略),只能保留 / 新增 / 软删
  • primaryDriverName 当前恒为 null:业务流水 PR 上线前前端不要展示该字段或处理为"未指派"

13. 关联 / 联系人

13.1 链接

13.2 联系人

  • 后端负责人: @yst腰苏图
  • 前端对接(管理后台): 待指派