feat(vehicle): 优化车辆管理相关表单布局和字段

- 车牌号组件改为单一输入框,去除省简称和颜色选择,实现完整车牌号输入
- 重写车牌号校验逻辑,校验完整车牌号格式,错误提示更加明确
- 车辆新增/编辑弹窗输入框宽度统一调整,基础信息和资质图片区按四列布局排列
- 修复所有组织字段宽度不一致问题,补充级联选择器样式支持
- 司机新增/编辑弹窗调整为四列布局,调整字段排列顺序,提升界面整洁度
- 客商档案中「客商类型」改名为「客商分类」,新增「客商类型」字段支持外部客商和内部组织区分
- 上传证件项 label 贴顶问题修复,统一提升到全局样式实现垂直居中
- 移除车牌颜色只读展示,审核弹窗同步删除车牌颜色字段
- 保持后端接口兼容,数据库字段未变,OCR同步调用链路无影响
This commit is contained in:
2026-09-09 17:19:33 +08:00
parent 1972115173
commit 14c6ad0a31
5 changed files with 125 additions and 100 deletions
+8
View File
@@ -1085,6 +1085,14 @@ td.el-table-fixed-column--right {
line-height: inherit;
margin-right: 4px;
}
// ============ archive-formlabel 与控件垂直居中(全站复用) ============
// archive-form class 被 driver / vehicle / ship / credit-score-quantification / loading-manage 等
// 多个页面复用,但「垂直居中」规则原本锁在 customer-archive.vue 的 scoped 样式里,
// 其它页面拿不到 → 高控件行(证件上传 151px)label 贴顶。提升为全局统一生效。
.archive-form .el-form-item {
align-items: center;
}
//.el-form-item {
// margin-bottom: 15px !important;
//}
+7 -17
View File
@@ -156,8 +156,6 @@
/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="18">
<el-col :span="6">
<el-form-item label="性别" prop="gender">
<el-select v-model="driverForm.gender" clearable placeholder="请选择性别">
@@ -195,8 +193,6 @@
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="18">
<el-col :span="6">
<el-form-item label="住址" prop="addressRegion">
<el-cascader
@@ -244,7 +240,7 @@
</el-input>
</el-form-item>
</el-col>
<el-col :span="6">
<el-col :span="8">
<el-form-item label="岗位" prop="postList">
<el-checkbox-group v-model="driverForm.postList">
<el-checkbox label="司机" />
@@ -321,7 +317,7 @@
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-col :span="8">
<el-form-item label="有效期" prop="drivingLicenseEndDate">
<div class="date-range">
<el-date-picker
@@ -342,9 +338,7 @@
</div>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="18">
<el-col :span="6">
<el-col :span="4">
<el-form-item label="长期有效" prop="drivingLicenseLongTerm">
<el-checkbox
v-model="driverForm.drivingLicenseLongTerm"
@@ -358,7 +352,7 @@
</el-col>
</el-row>
<el-row :gutter="18">
<el-col :span="12">
<el-col :span="6">
<image-upload-field
label="驾驶证主页"
prop="drivingLicenseFront"
@@ -371,7 +365,7 @@
"
/>
</el-col>
<el-col :span="12">
<el-col :span="6">
<image-upload-field
label="驾驶证副页"
prop="drivingLicenseBack"
@@ -427,8 +421,6 @@
/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="18">
<el-col :span="6">
<el-form-item label="长期有效" prop="qualificationLongTerm">
<el-checkbox
@@ -443,7 +435,7 @@
</el-col>
</el-row>
<el-row :gutter="18">
<el-col :span="12">
<el-col :span="6">
<image-upload-field
label="封面页"
prop="qualificationFront"
@@ -454,7 +446,7 @@
@success="url => handleQualificationUploadSuccess('qualificationFront', url)"
/>
</el-col>
<el-col :span="12">
<el-col :span="6">
<image-upload-field
label="内容页"
prop="qualificationBack"
@@ -498,8 +490,6 @@
/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="18">
<el-col :span="6">
<el-form-item label="紧急联系人手机号" prop="emergencyContactMobile">
<el-input
+20 -79
View File
@@ -142,11 +142,6 @@
<span class="certification-audit__value">{{ auditValue('plateNo') }}</span>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="车牌颜色">
<span class="certification-audit__value">{{ auditValue('plateColor') }}</span>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="车辆类型">
<span class="certification-audit__value">{{ auditValue('vehicleType') }}</span>
@@ -394,7 +389,7 @@
>
<section-card title="基础车辆信息">
<el-row :gutter="18">
<el-col :span="10">
<el-col :span="6">
<el-form-item label="车牌号" prop="plateNo">
<el-input
v-model="vehicleForm.plateNo"
@@ -423,7 +418,7 @@
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-col :span="12">
<el-form-item label="外廓尺寸(毫米)">
<div class="dimension-group">
<div class="dimension-group__item">
@@ -460,6 +455,7 @@
<el-input
v-model="vehicleForm.approvedLoadKg"
inputmode="numeric"
placeholder="请输入"
@input="vehicleForm.approvedLoadKg = digitsOnly($event)"
/>
</el-form-item>
@@ -469,6 +465,7 @@
<el-input
v-model="vehicleForm.tractionMassKg"
inputmode="numeric"
placeholder="请输入"
@input="vehicleForm.tractionMassKg = digitsOnly($event)"
/>
</el-form-item>
@@ -485,8 +482,6 @@
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="18">
<el-col :span="6">
<el-form-item label="能源类型" prop="energyType">
<el-select
@@ -504,6 +499,8 @@
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="18">
<el-col :span="6">
<el-form-item label="强制报废日期" prop="compulsoryScrapDate">
<div class="date-with-flag">
@@ -529,8 +526,6 @@
<el-input v-model="vehicleForm.customsRecordNo" maxlength="50" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="18">
<el-col :span="6">
<el-form-item label="所有组织" prop="organizationName">
<el-cascader
@@ -565,11 +560,6 @@
<section-card title="车辆资质图片">
<el-row :gutter="18">
<el-col :span="6">
<el-form-item label="行驶证档案编号" prop="drivingLicenseNo">
<el-input v-model="vehicleForm.drivingLicenseNo" maxlength="50" />
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="行驶证有效期" prop="drivingLicenseEndDate">
<div class="date-with-flag">
@@ -595,8 +585,6 @@
<el-input v-model="vehicleForm.roadTransportCertNo" maxlength="50" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="18">
<el-col :span="6">
<el-form-item label="道路运输证有效期" prop="roadTransportCertEndDate">
<div class="date-with-flag">
@@ -653,6 +641,11 @@
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="行驶证档案编号" prop="drivingLicenseNo">
<el-input v-model="vehicleForm.drivingLicenseNo" maxlength="50" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="18">
<el-col :span="6">
@@ -1402,9 +1395,13 @@ export default {
);
return option ? option.value : vehicleType;
},
handlePlateBodyInput(value) {
this.vehicleForm.plateNoBody = String(value || '').toUpperCase();
this.syncPlateNo();
handlePlateNoInput(value) {
this.vehicleForm.plateNo = String(value || '')
.replace(/\s/g, '')
.toUpperCase();
},
validatePlateFormat() {
this.$refs.vehicleForm?.validateField('plateNo');
},
syncPlateNo(validate = true) {
const plateNo = String(this.vehicleForm.plateNo || '')
@@ -1651,67 +1648,11 @@ export default {
:deep(.el-date-editor.el-input__wrapper),
:deep(.el-select),
:deep(.el-input),
:deep(.el-input-number) {
:deep(.el-input-number),
:deep(.el-cascader) {
width: 100%;
}
.plate-group {
display: flex;
align-items: center;
overflow: hidden;
border: 1px solid #dcdfe6;
border-radius: 4px;
background: #fff;
transition: border-color 0.2s;
&:hover {
border-color: #c0c4cc;
}
&:focus-within {
border-color: #409eff;
}
// 三个子控件:去掉各自边框,整体形成一个输入框
:deep(.el-select),
:deep(.el-input) {
position: relative;
flex: 1;
min-width: 0;
height: 32px;
}
:deep(.el-select:first-child) {
flex: 0 0 12%;
}
:deep(.el-select:last-child) {
flex: 0 0 18%;
}
:deep(.el-input__wrapper),
:deep(.el-select__wrapper) {
box-shadow: none !important;
border-radius: 0;
padding: 0 8px;
}
// 子项之间用竖线分隔,视觉上是一个整体
:deep(.el-select + .el-select),
:deep(.el-select + .el-input),
:deep(.el-input + .el-select) {
&::before {
content: '';
position: absolute;
left: 0;
top: 6px;
bottom: 6px;
width: 1px;
background: #e4e7ed;
}
}
}
.dimension-group {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
+34 -4
View File
@@ -224,7 +224,7 @@
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="客商类" prop="customerType">
<el-form-item label="客商类" prop="customerType">
<el-select
v-model="archiveForm.customerType"
multiple
@@ -241,6 +241,23 @@
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="客商类型" prop="customerKind">
<el-select
v-model="archiveForm.customerKind"
placeholder="请选择"
filterable
clearable
>
<el-option
v-for="item in customerKindOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="企业法人" prop="legalPerson">
<el-input v-model="archiveForm.legalPerson" maxlength="10" show-word-limit />
@@ -1660,7 +1677,7 @@ export default {
trigger: 'blur',
},
],
customerType: [{ required: true, message: '请选择客商类', trigger: 'change' }],
customerType: [{ required: true, message: '请选择客商类', trigger: 'change' }],
legalPerson: [{ required: true, message: '请输入企业法人', trigger: 'blur' }],
contactPhone: [
{ required: true, message: '请输入联系电话', trigger: 'blur' },
@@ -1767,7 +1784,7 @@ export default {
overHidden: true,
},
{
label: '客户类型',
label: '客商分类',
prop: 'customerType',
search: true,
searchType: 'select',
@@ -1777,6 +1794,16 @@ export default {
minWidth: 140,
dicData: [{ label: '全部', value: '' }],
},
{
label: '客商类型',
prop: 'customerKind',
type: 'select',
minWidth: 120,
dicData: [
{ label: '外部客商', value: 'external' },
{ label: '内部组织', value: 'internal' },
],
},
{
label: '客户性质',
prop: 'customerNature',
@@ -2188,7 +2215,8 @@ export default {
customerCode: '客商编号',
shortName: '客商简称',
fullName: '客商名称',
customerType: '客户类型',
customerType: '客商分类',
customerKind: '客商类型',
customerNature: '客户性质',
unifiedCreditCode: '统一信用代码',
deptName: '所属组织',
@@ -2376,6 +2404,7 @@ export default {
rejected: '审核不通过',
},
status: { 1: '启用', 2: '停用', 0: '停用' },
customerKind: { external: '外部客商', internal: '内部组织' },
};
if (Array.isArray(value)) {
return value.map(item => this.formatChangeFieldValue(normalizedField, item)).join('、');
@@ -3661,6 +3690,7 @@ export default {
...detail,
deptId: this.normalizeDeptIds(detail),
customerType: this.splitValue(detail.customerType),
customerKind: detail.customerKind || 'external',
invoiceTaxRate: this.normalizeOptionalAmount(detail.invoiceTaxRate),
registeredCapital: this.normalizeOptionalAmount(detail.registeredCapital),
maxCreditLimit: this.normalizeOptionalAmount(detail.maxCreditLimit),