♻️ 车辆管理移除旧认证审核入口,认证状态改用统一状态词表

认证审核职责已迁到「认证审核-车辆」页:审核对象是一条认证记录,生效值与
待审值分离后,原来「看车辆行当前值直接通过/驳回」的单条模型语义不再成立。

- vehicle.vue:移除操作列的「审核」入口与认证审核弹窗及其方法、样式,
  同时删除 api/transportCapacity/transport-vehicle.js 的 auditCertification 封装
  (后端旧接口仅保留兼容,前端不再调用)
- 认证状态列与筛选项统一为 审核中 / 已通过 / 已驳回 / 已作废(新增 已作废,
  原先的「认证中/已认证」不再使用),缓存为空时显示「未认证」
- 去掉按证件到期日期推断「已认证 / 已过期」的兜底:是否已认证由生效快照指针
  决定(曾审核通过即永久保持),与证件日期无关;到期信息仍由列表顶部到期标签
  与日期列标色展示
- driver.vue 选择车辆弹窗的车辆认证状态文案一并统一
This commit is contained in:
2026-10-02 17:15:09 +08:00
parent 7c6ac2e5db
commit 71a6f7c4f8
4 changed files with 14 additions and 404 deletions
@@ -51,14 +51,6 @@ export const changeStatus = (id, status) => {
});
};
export const auditCertification = (id, certificationStatus, rejectReason) => {
return request({
url: '/blade-transport/transport-vehicle/audit-certification',
method: 'post',
params: { id, certificationStatus, rejectReason },
});
};
export const getExpiryStat = params => {
return request({
url: '/blade-transport/transport-vehicle/expiry-stat',
@@ -95,6 +95,8 @@ export const option = {
align: 'center',
},
{
// 这里是「最新一次提交的状态」缓存,不等于该车当前是否已认证:
// 已认证由生效快照指针决定,曾审核通过即永久保持,重新提交不会让它退回审核中
label: '认证状态',
prop: 'certificationStatus',
slot: true,
@@ -104,9 +106,10 @@ export const option = {
type: 'select',
dicData: [
{ label: '全部', value: '' },
{ label: '认证中', value: 0 },
{ label: '已认证', value: 1 },
{ label: '审核中', value: 0 },
{ label: '已通过', value: 1 },
{ label: '已驳回', value: 2 },
{ label: '已作废', value: 3 },
],
minWidth: 110,
align: 'center',
+3 -6
View File
@@ -649,6 +649,7 @@ import { getDictionary } from '@/api/system/dictbiz';
import { getLazyTree } from '@/api/base/region';
import { exportBlob } from '@/api/common';
import { getToken, isAdministrator } from '@/utils/auth';
import { certStatusTag } from '@/utils/cert-audit';
import { getUploadHeaders } from '@/utils/upload';
import { downloadXls } from '@/utils/util';
import ImageUploadField from '@/components/image-upload-field/main.vue';
@@ -1233,13 +1234,9 @@ export default {
this.driverForm.drivingVehicle = row.plateNo || '';
this.vehicleSelectorVisible = false;
},
// 车辆认证状态展示的是「最新一次提交的状态」缓存,与审核页使用同一套状态词表
getVehicleCertificationStatus(row) {
const statusMap = {
0: { label: '认证中', type: 'warning' },
1: { label: '已认证', type: 'success' },
2: { label: '已驳回', type: 'danger' },
};
return statusMap[row.certificationStatus] || { label: '-', type: 'info' };
return certStatusTag(row.certificationStatus);
},
setImage(prop, url) {
this.driverForm[prop] = url;
+6 -388
View File
@@ -105,9 +105,6 @@
修改
</el-link>
<el-link type="primary" @click="openVehicleLedger(row)">综合台账</el-link>
<el-link type="primary" v-if="row.certificationStatus === 0" @click="openCertificationAudit(row)">
审核
</el-link>
<el-link
type="primary"
v-if="hasPermission('transport_vehicle_status')"
@@ -120,271 +117,6 @@
<vehicle-ledger v-model="vehicleLedgerBox" :vehicle="ledgerVehicle" />
<el-dialog
v-model="certificationAuditBox"
title="车辆认证审核"
width="92%"
top="4vh"
class="certification-audit-dialog"
>
<el-form
label-position="right"
label-width="calc(4em + 12px)"
class="certification-audit archive-form"
>
<section-card title="基础信息">
<el-row :gutter="18">
<el-col :span="6">
<el-form-item label="车牌号">
<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('vehicleType') }}</span>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="外廓尺寸">
<div class="dimension-group">
<div class="dimension-group__item">
<span class="dimension-group__label">长</span>
<span class="certification-audit__value">
{{ auditValueWithUnit('outerLength', 'mm') }}
</span>
</div>
<div class="dimension-group__item">
<span class="dimension-group__label">宽</span>
<span class="certification-audit__value">
{{ auditValueWithUnit('outerWidth', 'mm') }}
</span>
</div>
<div class="dimension-group__item">
<span class="dimension-group__label">高</span>
<span class="certification-audit__value">
{{ auditValueWithUnit('outerHeight', 'mm') }}
</span>
</div>
</div>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="18">
<el-col :span="6">
<el-form-item label="核定载质量">
<span class="certification-audit__value">
{{ auditValueWithUnit('approvedLoadKg', 'KG') }}
</span>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="准牵引总质量">
<span class="certification-audit__value">
{{ auditValueWithUnit('tractionMassKg', 'KG') }}
</span>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="业务关系">
<span class="certification-audit__value">{{ auditValue('businessRelation') }}</span>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="能源类型">
<span class="certification-audit__value">{{ auditValue('energyType') }}</span>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="18">
<el-col :span="6">
<el-form-item label="强制报废日期">
<span class="certification-audit__value">
{{ auditValue('compulsoryScrapDate') }}
</span>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="海关备案号">
<span class="certification-audit__value">{{ auditValue('customsRecordNo') }}</span>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="所有组织">
<span class="certification-audit__value">
{{ auditValue('organizationName') }}
</span>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="使用部门">
<span class="certification-audit__value">{{ auditValue('useDepartment') }}</span>
</el-form-item>
</el-col>
</el-row>
</section-card>
<section-card title="证件信息">
<el-row :gutter="18">
<el-col :span="6">
<el-form-item label="行驶证有效期止">
<span class="certification-audit__value">
{{ auditValue('drivingLicenseEndDate') }}
</span>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="道路运输证号">
<span class="certification-audit__value">
{{ auditValue('roadTransportCertNo') }}
</span>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="道路运输证有效期止">
<span class="certification-audit__value">
{{ auditValue('roadTransportCertEndDate') }}
</span>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="道路运输年审有效期">
<span class="certification-audit__value">
{{ auditValue('annualReviewEndDate') }}
</span>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="18">
<el-col :span="6">
<el-form-item label="机动车登记编号">
<span class="certification-audit__value">{{ auditValue('registrationNo') }}</span>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="机动车登记日期">
<span class="certification-audit__value">{{ auditValue('registrationDate') }}</span>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="行驶证档案编号">
<span class="certification-audit__value">{{ auditValue('drivingLicenseNo') }}</span>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="行驶证有效期起">
<span class="certification-audit__value">
{{ auditValue('drivingLicenseStartDate') }}
</span>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="18">
<el-col :span="6">
<el-form-item label="道路运输证有效期起">
<span class="certification-audit__value">
{{ auditValue('roadTransportCertStartDate') }}
</span>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="18">
<el-col :span="24">
<el-form-item label="备注">
<span class="certification-audit__value">{{ auditValue('remark') }}</span>
</el-form-item>
</el-col>
</el-row>
</section-card>
<section-card title="证件图片">
<el-row :gutter="18">
<el-col :span="6">
<image-upload-field
label="行驶证主页正面"
prop="drivingLicenseImage"
:value="certificationAuditForm.drivingLicenseImage"
readonly
large
class-prefix="vehicle"
/>
</el-col>
<el-col :span="6">
<image-upload-field
label="行驶证主页反面"
prop="drivingLicenseMainBack"
:value="certificationAuditForm.drivingLicenseMainBack"
readonly
large
class-prefix="vehicle"
/>
</el-col>
<el-col :span="6">
<image-upload-field
label="行驶证副页正面"
prop="drivingLicenseViceFront"
:value="certificationAuditForm.drivingLicenseViceFront"
readonly
large
class-prefix="vehicle"
/>
</el-col>
</el-row>
<el-row :gutter="18">
<el-col :span="6">
<image-upload-field
label="行驶证副页反面"
prop="drivingLicenseViceBack"
:value="certificationAuditForm.drivingLicenseViceBack"
readonly
large
class-prefix="vehicle"
/>
</el-col>
<el-col :span="6">
<image-upload-field
label="道路运输证图片"
prop="roadTransportCertImage"
:value="certificationAuditForm.roadTransportCertImage"
readonly
large
class-prefix="vehicle"
/>
</el-col>
<el-col :span="6">
<image-upload-field
label="机动车登记本"
prop="registrationImage"
:value="certificationAuditForm.registrationImage"
readonly
large
class-prefix="vehicle"
/>
</el-col>
</el-row>
</section-card>
</el-form>
<el-form
v-if="showRejectReason"
class="certification-audit__reason"
label-position="right"
label-width="calc(4em + 24px)"
>
<el-form-item label="驳回原因" required>
<el-input
v-model="certificationRejectReason"
type="textarea"
maxlength="200"
show-word-limit
/>
</el-form-item>
</el-form>
<template #footer>
<el-button @click="certificationAuditBox = false">取消</el-button>
<el-button type="danger" @click="handleCertificationReject">认证驳回</el-button>
<el-button type="primary" @click="handleCertificationApprove">认证通过</el-button>
</template>
</el-dialog>
<el-dialog
:title="dialogTitle"
append-to-body
@@ -809,7 +541,6 @@ import {
submit,
remove,
changeStatus,
auditCertification,
getExpiryStat,
recognitionTransportCertificates,
recognizeBaiduOcr,
@@ -818,6 +549,7 @@ import { getDeptTree } from '@/api/system/dept';
import organizationSearch from '@/mixins/organization-search';
import { exportBlob } from '@/api/common';
import { getToken, isAdministrator } from '@/utils/auth';
import { certStatusTag } from '@/utils/cert-audit';
import { getUploadHeaders } from '@/utils/upload';
import { downloadXls } from '@/utils/util';
import ImageUploadField from '@/components/image-upload-field/main.vue';
@@ -895,10 +627,6 @@ export default {
vehicleBox: false,
vehicleLedgerBox: false,
ledgerVehicle: {},
certificationAuditBox: false,
certificationAuditForm: {},
certificationRejectReason: '',
showRejectReason: false,
readonly: false,
vehicleForm: emptyForm(),
vehicleCertificateUploads: {},
@@ -1107,49 +835,6 @@ export default {
this.ledgerVehicle = { ...row };
this.vehicleLedgerBox = true;
},
openCertificationAudit(row) {
getDetail(row.id).then(res => {
this.certificationAuditForm = { ...(res.data.data || {}) };
this.certificationRejectReason = '';
this.showRejectReason = false;
this.certificationAuditBox = true;
});
},
auditValue(prop) {
// 长期有效字段:勾选后显示「长期有效」,避免与未填写的「-」混淆
const longTermMap = {
drivingLicenseEndDate: 'drivingLicenseLongTerm',
roadTransportCertEndDate: 'roadTransportCertLongTerm',
annualReviewEndDate: 'annualReviewLongTerm',
compulsoryScrapDate: 'compulsoryScrapLongTerm',
};
const longTermProp = longTermMap[prop];
if (longTermProp && this.certificationAuditForm[longTermProp] === 1) {
return '长期有效';
}
const value = this.certificationAuditForm[prop];
return value === undefined || value === null || value === '' ? '-' : value;
},
auditValueWithUnit(prop, unit) {
const value = this.auditValue(prop);
return value === '-' ? value : `${value}${unit}`;
},
handleCertificationApprove() {
auditCertification(this.certificationAuditForm.id, 1).then(() => {
this.$message.success('认证已通过');
this.certificationAuditBox = false;
this.onLoad(this.page);
});
},
handleCertificationReject() {
if (!this.showRejectReason) { this.showRejectReason = true; return; }
if (!this.certificationRejectReason.trim()) { this.$message.warning('请输入认证驳回原因'); return; }
auditCertification(this.certificationAuditForm.id, 2, this.certificationRejectReason).then(() => {
this.$message.success('认证已驳回');
this.certificationAuditBox = false;
this.onLoad(this.page);
});
},
resetVehicle() {
this.vehicleForm = emptyForm();
this.vehicleCertificateUploads = {};
@@ -1648,26 +1333,11 @@ export default {
}
return '';
},
// 认证状态展示的是「最新一次提交的状态」缓存,不代表该车当前是否已认证
// (是否已认证由生效快照指针决定,即曾审核通过即永久保持)。
// 证书是否临近到期另有列表顶部的到期标签与日期列标色展示,不在这里推断。
getCertificationStatus(row) {
if (row.certificationStatus === 0) return { label: '认证中', type: 'warning' };
if (row.certificationStatus === 1) return { label: '已认证', type: 'success' };
if (row.certificationStatus === 2) return { label: '已驳回', type: 'danger' };
const today = this.$dayjs().startOf('day');
const certificateDates = [
[row.drivingLicenseEndDate, row.drivingLicenseLongTerm],
[row.roadTransportCertEndDate, row.roadTransportCertLongTerm],
];
if (certificateDates.some(([date, longTerm]) => longTerm !== 1 && !date)) {
return { label: '未认证', type: 'info' };
}
if (
certificateDates.some(
([date, longTerm]) => longTerm !== 1 && this.$dayjs(date).isBefore(today, 'day')
)
) {
return { label: '已过期', type: 'danger' };
}
return { label: '已认证', type: 'success' };
return certStatusTag(row.certificationStatus);
},
},
};
@@ -1695,9 +1365,7 @@ export default {
}
}
// 车辆认证审核弹窗:与编辑弹窗一致,灰底 + section-card 白卡分组
.certification-audit,
.certification-audit__reason,
// 编辑弹窗:灰底 + section-card 白卡分组
.vehicle-form {
:deep(.el-form-item__label) {
height: auto;
@@ -1723,60 +1391,10 @@ export default {
line-height: 18px;
margin-right: 4px;
}
}
.certification-audit {
:deep(.el-form-item__label) {
flex: 0 0 calc(4em + 12px) !important;
width: calc(4em + 12px) !important;
max-width: calc(4em + 12px);
}
}
.certification-audit__reason {
:deep(.el-form-item__label) {
flex: 0 0 calc(4em + 24px) !important;
width: calc(4em + 24px) !important;
max-width: calc(4em + 24px);
}
}
.vehicle-form {
:deep(.el-form-item__label) {
flex: 0 0 calc(4em + 24px) !important;
width: calc(4em + 24px) !important;
}
}
.certification-audit {
&__value {
display: block;
color: #303133;
word-break: break-all;
}
// 外廓尺寸长/宽/高组合,排版复用编辑弹窗的 dimension-group
.dimension-group {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 8px;
align-items: center;
}
.dimension-group__item {
display: flex;
align-items: center;
gap: 8px;
min-width: 0;
}
.dimension-group__label {
flex-shrink: 0;
color: #303133;
}
&__reason {
margin-top: 12px;
}
}