✨ 车辆认证扩到6张证件图,字段与车辆档案对齐;补齐建车必填列

司机端车辆认证此前只有 3 张图、5 个字段,且语义与车辆管理不一致
(「副页」字段里装的其实是主页反面)。本次把证件内容整体对齐车辆表列:

- 车辆表新增 owner_name(所有人:行驶证登记的单位名称,不是司机)与 vin;
- 提交请求与司机端车辆卡片全量对齐表列,行驶证四张图各自独立、
  不再把「主页反面」与「副页正面」挤在同一个字段;
- 业务关系新增为司机自选(自有/管理挂靠/业务合作),不再由后端替用户猜。

顺带修掉三处会直接让功能不可用的缺陷:

1. 司机建车必失败:organization_name、approved_load_kg、business_relation、
   energy_type、registration_no 五列 NOT NULL 且无默认值,而建车链路一个都不设置,
   严格模式下 INSERT 直接报「doesn't have a default value」。已补齐并加服务端校验
   (司机提交链路此前一句都不查,全靠前端)。
2. OCR 自动填充从未生效:后端按契约透传百度原始结果(中文键),
   前端读的却是扁平字段名,永远 undefined 且不报错。新增 OcrFieldSupport
   做归一化(键名别名容错、数值/日期/「长期」归一化、外廓尺寸拆三段、
   有效期区间拆起止),响应的 fields 即前端直接回填的字段。
3. 审核通过不写回车辆档案:状态已通过、内容却还是旧的,自相矛盾。
   现把生效快照的证件内容与指针合并成同一次 UPDATE 写回;快照是改造前
   旧格式时明确报错,而不是静默写一堆空值。
This commit is contained in:
2026-10-03 16:34:47 +08:00
parent 214ff38ef8
commit 04a7846328
14 changed files with 1172 additions and 69 deletions
@@ -51,37 +51,65 @@ public class VehicleCertSubmitRequest implements Serializable {
private Long id;
@Schema(description = "车牌号")
private String plateNo;
@Schema(description = "车辆类型")
private String vehicleType;
@Schema(description = "车辆识别代号(车架号)")
private String vin;
@Schema(description = "发动机号")
private String engineNo;
@Schema(description = "所有人:行驶证登记的单位名称,不是司机")
private String ownerName;
@Schema(description = "车牌颜色")
private String plateColor;
@Schema(description = "车辆类型")
private String vehicleType;
@Schema(description = "车辆识别代号(车架号),选填")
private String vin;
@Schema(description = "外廓长度,毫米")
private Integer outerLength;
@Schema(description = "外廓宽度,毫米")
private Integer outerWidth;
@Schema(description = "外廓高度,毫米")
private Integer outerHeight;
@Schema(description = "核定载质量,KG")
private Integer approvedLoadKg;
@Schema(description = "准牵引总质量,KG")
private Integer tractionMassKg;
@Schema(description = "能源类型")
private String energyType;
@Schema(description = "业务关系:自有 / 管理挂靠 / 业务合作")
private String businessRelation;
@Schema(description = "强制报废日期")
private LocalDate compulsoryScrapDate;
@Schema(description = "强制报废长期有效:0否 1是")
private Integer compulsoryScrapLongTerm;
@Schema(description = "行驶证档案编号")
private String licenseNo;
@Schema(description = "行驶证主页照片")
private String licenseFrontUrl;
@Schema(description = "行驶证副页照片")
private String licenseBackUrl;
private String drivingLicenseNo;
@Schema(description = "行驶证主页正面照片")
private String drivingLicenseImage;
@Schema(description = "行驶证主页反面照片")
private String drivingLicenseMainBack;
@Schema(description = "行驶证副页正面照片")
private String drivingLicenseViceFront;
@Schema(description = "行驶证副页反面照片")
private String drivingLicenseViceBack;
@Schema(description = "行驶证有效期起")
private LocalDate licenseValidStart;
private LocalDate drivingLicenseStartDate;
@Schema(description = "行驶证有效期止")
private LocalDate licenseValidEnd;
@Schema(description = "行驶证长期有效")
private Integer licenseLongTerm;
private LocalDate drivingLicenseEndDate;
@Schema(description = "行驶证长期有效:0否 1是")
private Integer drivingLicenseLongTerm;
@Schema(description = "道路运输证号")
private String roadTransportNo;
private String roadTransportCertNo;
@Schema(description = "道路运输证照片")
private String roadTransportUrl;
private String roadTransportCertImage;
@Schema(description = "道路运输证有效期起")
private LocalDate roadTransportValidStart;
private LocalDate roadTransportCertStartDate;
@Schema(description = "道路运输证有效期止")
private LocalDate roadTransportValidEnd;
@Schema(description = "道路运输证长期有效")
private Integer roadTransportLongTerm;
private LocalDate roadTransportCertEndDate;
@Schema(description = "道路运输证长期有效:0否 1是")
private Integer roadTransportCertLongTerm;
@Schema(description = "机动车登记编号")
private String registrationNo;
@Schema(description = "机动车登记本照片")
private String registrationImage;
}
@@ -66,6 +66,11 @@ public class TransportVehicle extends TenantEntity {
*/
@Schema(description = "车牌号")
private String plateNo;
/**
* 所有人:行驶证登记的单位名称,不是司机
*/
@Schema(description = "所有人(行驶证登记的单位名称,不是司机)")
private String ownerName;
/**
* 车牌颜色
*/
@@ -76,6 +81,11 @@ public class TransportVehicle extends TenantEntity {
*/
@Schema(description = "车辆类型")
private String vehicleType;
/**
* 车辆识别代号(车架号)
*/
@Schema(description = "车辆识别代号(车架号)")
private String vin;
/**
* 外廓长度,毫米
*/
@@ -56,4 +56,14 @@ public class BaiduOcrResultVO implements Serializable {
@Schema(description = "百度OCR原始返回结果")
private Map<String, Object> result;
/**
* 归一化后的业务字段
* <p>
* 键与提交请求里的字段同名({@code plateNo}、{@code ownerName}…),调用方直接回填即可,
* 不需要认识百度那套中文键名。只包含**识别到**的字段,没识别到的不出现(而不是给空串),
* 调用方据此就能区分「没识别到」与「识别到空值」,不会把用户已填的内容覆盖成空。
*/
@Schema(description = "归一化后的业务字段,键与提交请求同名")
private Map<String, Object> fields;
}
@@ -44,29 +44,89 @@ public class DriverVehicleCardVO implements Serializable {
@Schema(description = "车牌号")
private String plateNo;
@Schema(description = "所有人(行驶证登记的单位名称,不是司机)")
private String ownerName;
@Schema(description = "车牌颜色")
private String plateColor;
@Schema(description = "车辆类型")
private String vehicleType;
@Schema(description = "行驶证主页照片")
private String licenseFrontUrl;
@Schema(description = "行驶证副页照片")
private String licenseBackUrl;
@Schema(description = "道路运输证号")
private String roadTransportNo;
@Schema(description = "道路运输证照片")
private String roadTransportUrl;
@Schema(description = "车架号")
@Schema(description = "车辆识别代号(车架号),选填")
private String vin;
@Schema(description = "发动机号")
private String engineNo;
@Schema(description = "外廓长度,毫米")
private Integer outerLength;
@Schema(description = "外廓宽度,毫米")
private Integer outerWidth;
@Schema(description = "外廓高度,毫米")
private Integer outerHeight;
@Schema(description = "核定载质量,KG")
private Integer approvedLoadKg;
@Schema(description = "准牵引总质量,KG")
private Integer tractionMassKg;
@Schema(description = "能源类型")
private String energyType;
@Schema(description = "业务关系:自有 / 管理挂靠 / 业务合作")
private String businessRelation;
@Schema(description = "强制报废日期")
private String compulsoryScrapDate;
@Schema(description = "强制报废长期有效:0否 1是")
private Integer compulsoryScrapLongTerm;
@Schema(description = "行驶证档案编号")
private String drivingLicenseNo;
@Schema(description = "行驶证主页正面照片")
private String drivingLicenseImage;
@Schema(description = "行驶证主页反面照片")
private String drivingLicenseMainBack;
@Schema(description = "行驶证副页正面照片")
private String drivingLicenseViceFront;
@Schema(description = "行驶证副页反面照片")
private String drivingLicenseViceBack;
@Schema(description = "行驶证有效期起")
private String drivingLicenseStartDate;
@Schema(description = "行驶证有效期止")
private String licenseValidEnd;
private String drivingLicenseEndDate;
@Schema(description = "行驶证长期有效:0否 1是")
private Integer drivingLicenseLongTerm;
@Schema(description = "道路运输证号")
private String roadTransportCertNo;
@Schema(description = "道路运输证照片")
private String roadTransportCertImage;
@Schema(description = "道路运输证有效期起")
private String roadTransportCertStartDate;
@Schema(description = "道路运输证有效期止")
private String roadTransportCertEndDate;
@Schema(description = "道路运输证长期有效:0否 1是")
private Integer roadTransportCertLongTerm;
@Schema(description = "机动车登记编号")
private String registrationNo;
@Schema(description = "机动车登记本照片")
private String registrationImage;
@Schema(description = "认证状态:0认证中 1认证通过 2认证驳回")
private Integer certificationStatus;