This commit is contained in:
zlwu committed 2026-07-12 17:55:11 +08:00
1 parent c2cba3e668
commit 2142b33cfa
24 files changed
+4834 -3684

No files matched your search

+2
View File
@@ -99,6 +99,7 @@ export interface Vehicle {
loadCapacity?: number
vehicleStatus: string
remark?: string
certList?: CertRead[]
createTime: string
}
@@ -152,6 +153,7 @@ export interface Personnel {
status: string
remark?: string
nearestExpireDate?: string
certList?: CertRead[]
createTime: string
}
@@ -9,7 +9,13 @@
<div v-if="!certList.length" class="cert-empty">{{ emptyHint }}</div>
<el-table v-else-if="layout === 'table'" :data="certList" stripe class="list-table cert-form-table">
<el-table
v-else-if="layout === 'table'"
:data="certList"
stripe
class="list-table cert-form-table"
:row-class-name="showVehiclePartColumn ? getCertRowClassName : undefined"
>
<el-table-column type="index" label="序号" min-width="68" align="center" header-align="center" />
<el-table-column
v-if="showVehiclePartColumn"
@@ -298,6 +304,13 @@ function handleVehiclePartChange(row: CertRowWithKey, value: string) {
row.vehiclePart = normalizeVehicleCertPart(value)
}
function getCertRowClassName({ row }: { row: CertRowWithKey }) {
if (!props.showVehiclePartColumn) return ''
return normalizeVehicleCertPart(row.vehiclePart) === PL_VEHICLE_CERT_PART_TRAILER
? 'cert-row-trailer'
: 'cert-row-head'
}
const certList = defineModel<CertRowWithKey[]>('modelValue', { default: () => [] })
watch(
@@ -407,6 +420,14 @@ defineExpose({ hasUploading, clearUploadRefs, refreshRequiredSlots })
.cert-form-table {
border-top: 1px solid var(--mint-border, #d9e8e2);
:deep(.cert-row-head td.el-table__cell) {
background-color: #ecfdf5 !important;
}
:deep(.cert-row-trailer td.el-table__cell) {
background-color: #fffbeb !important;
}
:deep(.el-select),
:deep(.el-input),
:deep(.el-date-editor) {
@@ -0,0 +1,80 @@
<template>
<div v-if="badges.length" class="pl-personnel-cert-badges">
<el-tooltip
v-for="badge in badges"
:key="badge.requiredName"
:content="badge.title"
placement="top"
>
<span
class="pl-personnel-cert-badges__item"
:class="`pl-personnel-cert-badges__item--${badge.status}`"
>
{{ badge.shortLabel }}
</span>
</el-tooltip>
</div>
</template>
<script setup lang="ts">
import { computed } from 'vue'
import type { CertRead } from '@/api/pl'
import { getPersonnelRequiredCertBadges } from '@/utils/pl-personnel-cert'
const props = withDefaults(
defineProps<{
personnelType?: string | null
certList?: CertRead[]
}>(),
{
personnelType: '',
certList: () => []
}
)
const badges = computed(() =>
getPersonnelRequiredCertBadges(props.personnelType, props.certList || [])
)
</script>
<style scoped lang="scss">
.pl-personnel-cert-badges {
display: inline-flex;
align-items: center;
gap: 4px;
}
.pl-personnel-cert-badges__item {
display: inline-flex;
align-items: center;
justify-content: center;
min-width: 20px;
height: 20px;
padding: 0 4px;
border-radius: 4px;
font-size: 12px;
font-weight: 600;
line-height: 1;
cursor: default;
}
.pl-personnel-cert-badges__item--missing {
background: #f1f5f9;
color: #64748b;
}
.pl-personnel-cert-badges__item--valid {
background: #ecfdf5;
color: #059669;
}
.pl-personnel-cert-badges__item--expiring {
background: #fffbeb;
color: #d97706;
}
.pl-personnel-cert-badges__item--expired {
background: #fef2f2;
color: #dc2626;
}
</style>
@@ -0,0 +1,135 @@
<template>
<span v-if="badgeGroups.length" class="pl-vehicle-cert-badges">
<span class="pl-vehicle-cert-badges__paren">(</span>
<template v-for="(group, groupIndex) in badgeGroups" :key="group.key">
<span v-if="groupIndex > 0" class="pl-vehicle-cert-badges__divider">|</span>
<span class="pl-vehicle-cert-badges__group">
<el-tooltip
v-for="badge in group.badges"
:key="`${group.key}-${badge.requiredName}`"
:content="badge.title"
placement="top"
>
<span
class="pl-vehicle-cert-badges__item"
:class="`pl-vehicle-cert-badges__item--${badge.status}`"
>
{{ badge.shortLabel }}
</span>
</el-tooltip>
</span>
</template>
<span class="pl-vehicle-cert-badges__paren">)</span>
</span>
</template>
<script setup lang="ts">
import { computed } from 'vue'
import type { CertRead } from '@/api/pl'
import {
PL_VEHICLE_CERT_PART_HEAD,
PL_VEHICLE_CERT_PART_TRAILER,
getVehiclePartRequiredCertBadges,
type PlVehicleCertCheckType
} from '@/utils/pl-vehicle-cert'
const props = withDefaults(
defineProps<{
vehicleType?: PlVehicleCertCheckType
certList?: CertRead[]
trailerNo?: string | null
}>(),
{
vehicleType: 'self',
certList: () => [],
trailerNo: ''
}
)
const hasTrailer = computed(() => Boolean(props.trailerNo?.trim()))
const badgeGroups = computed(() => {
const groups = [
{
key: PL_VEHICLE_CERT_PART_HEAD,
badges: getVehiclePartRequiredCertBadges({
vehicleType: props.vehicleType,
certList: props.certList || [],
part: PL_VEHICLE_CERT_PART_HEAD,
partLabel: hasTrailer.value ? '主车' : ''
})
}
]
if (hasTrailer.value) {
groups.push({
key: PL_VEHICLE_CERT_PART_TRAILER,
badges: getVehiclePartRequiredCertBadges({
vehicleType: props.vehicleType,
certList: props.certList || [],
part: PL_VEHICLE_CERT_PART_TRAILER,
partLabel: '挂车'
})
})
}
return groups
})
</script>
<style scoped lang="scss">
.pl-vehicle-cert-badges {
display: inline-flex;
align-items: center;
flex-wrap: nowrap;
gap: 4px;
white-space: nowrap;
}
.pl-vehicle-cert-badges__paren,
.pl-vehicle-cert-badges__divider {
font-size: 12px;
color: var(--mint-text-muted, #64748b);
line-height: 1;
}
.pl-vehicle-cert-badges__group {
display: inline-flex;
align-items: center;
gap: 4px;
}
.pl-vehicle-cert-badges__item {
display: inline-flex;
align-items: center;
justify-content: center;
min-width: 20px;
height: 20px;
padding: 0 4px;
border-radius: 4px;
font-size: 12px;
font-weight: 600;
line-height: 1;
cursor: default;
}
.pl-vehicle-cert-badges__item--missing {
background: #f1f5f9;
color: #64748b;
}
.pl-vehicle-cert-badges__item--valid {
background: #ecfdf5;
color: #059669;
}
.pl-vehicle-cert-badges__item--expiring {
background: #fffbeb;
color: #d97706;
}
.pl-vehicle-cert-badges__item--expired {
background: #fef2f2;
color: #dc2626;
}
</style>
+109
View File
@@ -72,6 +72,16 @@ export function getRequiredPersonnelCertNamesByType(
return PL_PERSONNEL_DRIVER_REQUIRED_CERT_NAMES
}
/** 车辆关联人员:从人员主数据类型映射为关联角色(司机/押运员) */
export function mapPersonnelTypeToVehicleRole(
personnelType?: string | null
): 'driver' | 'escort' | undefined {
if (personnelType === 'driver') return 'driver'
if (personnelType === 'escort') return 'escort'
if (personnelType === 'both') return 'driver'
return undefined
}
export function validatePersonnelTypeRoleCompat(
personnelType: string | undefined,
role: string | undefined,
@@ -176,3 +186,102 @@ export function getPersonnelCertMissingSuffix(
}
return hasPersonnelMasterCertMissing(certList) ? PL_PERSONNEL_CERT_MISSING_SUFFIX : ''
}
export const PL_PERSONNEL_CERT_SHORT_LABELS: Record<string, string> = {
身份证: '身',
驾驶证: '驾',
从业资格证: '业'
}
export type PersonnelCertBadgeStatus = 'missing' | 'valid' | 'expiring' | 'expired'
export interface PersonnelCertBadgeItem {
requiredName: string
shortLabel: string
status: PersonnelCertBadgeStatus
title: string
}
function getPersonnelCertMissingFieldLabels(
cert: Pick<CertRow, 'certName' | 'certNo' | 'expireDate' | 'attachmentUrls'> | undefined,
requiredName: string
): string[] {
if (!cert || !matchRequiredCertName(cert.certName, requiredName)) {
return ['证号', '有效期', '附件']
}
const missing: string[] = []
if (!cert.certNo?.trim()) missing.push('证号')
if (!cert.expireDate) missing.push('有效期')
if (!cert.attachmentUrls?.trim()) missing.push('附件')
return missing
}
function formatPersonnelCertBadgeTooltip(
requiredName: string,
status: PersonnelCertBadgeStatus,
cert?: Pick<CertRow, 'certName' | 'certNo' | 'expireDate' | 'attachmentUrls' | 'remindDays'>
): string {
if (status === 'missing') {
if (!cert || !matchRequiredCertName(cert.certName, requiredName)) {
return `${requiredName}:缺失(未登记该证书)`
}
const missing = getPersonnelCertMissingFieldLabels(cert, requiredName)
return `${requiredName}:缺失(缺少${missing.join('、')})`
}
const expireDate = cert?.expireDate || '—'
const expDate = new Date(expireDate)
const today = new Date()
today.setHours(0, 0, 0, 0)
expDate.setHours(0, 0, 0, 0)
const diffDays = Math.ceil((expDate.getTime() - today.getTime()) / (1000 * 60 * 60 * 24))
const certNo = cert?.certNo?.trim()
const certNoText = certNo ? `,证号 ${certNo}` : ''
if (status === 'expired') {
return `${requiredName}:已过期,有效期 ${expireDate},已过期 ${Math.abs(diffDays)} 天${certNoText}`
}
if (status === 'expiring') {
return `${requiredName}:临期,有效期 ${expireDate},剩余 ${diffDays} 天${certNoText}`
}
return `${requiredName}:正常,有效期 ${expireDate}${certNoText}`
}
export function getPersonnelCertBadgeStatus(
cert: Pick<CertRow, 'certName' | 'certNo' | 'expireDate' | 'attachmentUrls' | 'remindDays'> | undefined,
requiredName: string
): PersonnelCertBadgeStatus {
if (!isPersonnelCertStrictComplete(cert, requiredName)) {
return 'missing'
}
const expireDate = cert?.expireDate
if (!expireDate) return 'missing'
const remindDays = cert?.remindDays ?? 30
const expDate = new Date(expireDate)
const today = new Date()
today.setHours(0, 0, 0, 0)
expDate.setHours(0, 0, 0, 0)
const diffDays = Math.ceil((expDate.getTime() - today.getTime()) / (1000 * 60 * 60 * 24))
if (diffDays <= 0) return 'expired'
if (diffDays <= remindDays) return 'expiring'
return 'valid'
}
export function getPersonnelRequiredCertBadges(
personnelType: string | null | undefined,
certList: CertRow[] = []
): PersonnelCertBadgeItem[] {
return getRequiredPersonnelCertNamesByType(personnelType).map(requiredName => {
const matched = certList.find(cert => matchRequiredCertName(cert.certName, requiredName))
const status = getPersonnelCertBadgeStatus(matched, requiredName)
const shortLabel = PL_PERSONNEL_CERT_SHORT_LABELS[requiredName] || requiredName.slice(0, 1)
return {
requiredName,
shortLabel,
status,
title: formatPersonnelCertBadgeTooltip(requiredName, status, matched)
}
})
}
+121
View File
@@ -235,3 +235,124 @@ export function validateVehicleCertNamesNotEmpty(
}
return true
}
export const PL_VEHICLE_CERT_SHORT_LABELS: Record<string, string> = {
行驶证: '行',
营运证: '营',
保险单: '保',
罐检报告: '罐'
}
export type VehicleCertBadgeStatus = 'missing' | 'valid' | 'expiring' | 'expired'
export interface VehicleCertBadgeItem {
requiredName: string
shortLabel: string
status: VehicleCertBadgeStatus
title: string
}
function matchVehicleRequiredCertName(
actualName: string | undefined,
requiredName: string
): boolean {
return (actualName?.trim() || '') === requiredName
}
function getVehicleCertMissingFieldLabels(
cert: Pick<CertRow, 'certName' | 'certNo' | 'expireDate' | 'attachmentUrls'> | undefined,
requiredName: string
): string[] {
if (!cert || !matchVehicleRequiredCertName(cert.certName, requiredName)) {
return ['证号', '有效期', '附件']
}
const missing: string[] = []
if (!cert.certNo?.trim()) missing.push('证号')
if (!cert.expireDate) missing.push('有效期')
if (!cert.attachmentUrls?.trim()) missing.push('附件')
return missing
}
function formatVehicleCertBadgeTooltip(
partLabel: string,
requiredName: string,
status: VehicleCertBadgeStatus,
cert?: Pick<CertRow, 'certName' | 'certNo' | 'expireDate' | 'attachmentUrls' | 'remindDays'>
): string {
const prefix = partLabel ? `${partLabel} · ` : ''
if (status === 'missing') {
if (!cert || !matchVehicleRequiredCertName(cert.certName, requiredName)) {
return `${prefix}${requiredName}:缺失(未登记该证书)`
}
const missing = getVehicleCertMissingFieldLabels(cert, requiredName)
return `${prefix}${requiredName}:缺失(缺少${missing.join('、')})`
}
const expireDate = cert?.expireDate || '—'
const expDate = new Date(expireDate)
const today = new Date()
today.setHours(0, 0, 0, 0)
expDate.setHours(0, 0, 0, 0)
const diffDays = Math.ceil((expDate.getTime() - today.getTime()) / (1000 * 60 * 60 * 24))
const certNo = cert?.certNo?.trim()
const certNoText = certNo ? `,证号 ${certNo}` : ''
if (status === 'expired') {
return `${prefix}${requiredName}:已过期,有效期 ${expireDate},已过期 ${Math.abs(diffDays)} 天${certNoText}`
}
if (status === 'expiring') {
return `${prefix}${requiredName}:临期,有效期 ${expireDate},剩余 ${diffDays} 天${certNoText}`
}
return `${prefix}${requiredName}:正常,有效期 ${expireDate}${certNoText}`
}
export function getVehicleCertBadgeStatus(
cert: Pick<CertRow, 'certName' | 'certNo' | 'expireDate' | 'attachmentUrls' | 'remindDays'> | undefined,
requiredName: string
): VehicleCertBadgeStatus {
if (!isVehicleCertUploaded(cert) || !matchVehicleRequiredCertName(cert?.certName, requiredName)) {
return 'missing'
}
const expireDate = cert?.expireDate
if (!expireDate) return 'missing'
const remindDays = cert?.remindDays ?? 30
const expDate = new Date(expireDate)
const today = new Date()
today.setHours(0, 0, 0, 0)
expDate.setHours(0, 0, 0, 0)
const diffDays = Math.ceil((expDate.getTime() - today.getTime()) / (1000 * 60 * 60 * 24))
if (diffDays <= 0) return 'expired'
if (diffDays <= remindDays) return 'expiring'
return 'valid'
}
export function getVehiclePartRequiredCertBadges(options: {
vehicleType: PlVehicleCertCheckType
certList?: CertRow[]
part: VehicleCertPart
partLabel?: string
}): VehicleCertBadgeItem[] {
const { vehicleType, certList = [], part, partLabel = '' } = options
const partCerts =
part === PL_VEHICLE_CERT_PART_TRAILER
? splitVehicleCertsByPart(certList).trailerCerts
: splitVehicleCertsByPart(certList).headCerts
const requiredNames =
part === PL_VEHICLE_CERT_PART_TRAILER
? getVehicleTrailerRequiredCertNames(vehicleType)
: getVehicleHeadRequiredCertNames(vehicleType)
return requiredNames.map(requiredName => {
const matched = partCerts.find(cert => matchVehicleRequiredCertName(cert.certName, requiredName))
const status = getVehicleCertBadgeStatus(matched, requiredName)
const shortLabel = PL_VEHICLE_CERT_SHORT_LABELS[requiredName] || requiredName.slice(0, 1)
return {
requiredName,
shortLabel,
status,
title: formatVehicleCertBadgeTooltip(partLabel, requiredName, status, matched)
}
})
}
+1 -1
View File
@@ -182,7 +182,7 @@
<el-tag v-else-if="row.qualificationComplete === false" type="warning" size="small">
资质不全
</el-tag>
<span v-else>—</span>
<el-tag v-else type="success" size="small">资质齐全</el-tag>
</template>
</el-table-column>
<el-table-column
+17 -2
View File
@@ -114,12 +114,18 @@
<el-table-column
prop="personnelName"
label="姓名"
min-width="100"
min-width="160"
align="center"
header-align="center"
>
<template #default="{ row }">
<el-link type="primary" @click="handleView(row)">{{ row.personnelName }}</el-link>
<div class="personnel-name-cell">
<el-link type="primary" @click="handleView(row)">{{ row.personnelName }}</el-link>
<PlPersonnelCertBadges
:personnel-type="row.personnelType"
:cert-list="row.certList"
/>
</div>
</template>
</el-table-column>
<el-table-column
@@ -357,6 +363,7 @@ import { Check, Close, Delete, Edit, Plus, RefreshLeft, Search, User } from '@el
import { personnelApi, type Personnel, type PersonnelDetail, type CertRow } from '@/api/pl'
import PlCertFormList from '@/components/business/pl-cert-form-list/index.vue'
import PlCertViewList from '@/components/business/pl-cert-view-list/index.vue'
import PlPersonnelCertBadges from '@/components/business/pl-personnel-cert-badges/index.vue'
import SystemViewDialog, {
type ViewSection
} from '@/components/business/system-view-dialog/index.vue'
@@ -824,4 +831,12 @@ onMounted(() => {
.sub-table {
margin-bottom: 8px;
}
.personnel-name-cell {
display: inline-flex;
align-items: center;
justify-content: center;
flex-wrap: wrap;
gap: 6px;
}
</style>
+35 -7
View File
@@ -113,14 +113,21 @@
<el-table-column
prop="licensePlate"
label="车牌号"
min-width="120"
min-width="340"
align="center"
header-align="center"
>
<template #default="{ row }">
<el-link type="primary" @click="handleView(row)">
{{ formatPlVehiclePlateDisplay(row.licensePlate, row.trailerNo) }}
</el-link>
<div class="vehicle-plate-cell">
<el-link type="primary" @click="handleView(row)">
{{ formatPlVehiclePlateDisplay(row.licensePlate, row.trailerNo) }}
</el-link>
<PlVehicleCertBadges
vehicle-type="self"
:cert-list="row.certList"
:trailer-no="row.trailerNo"
/>
</div>
</template>
</el-table-column>
<el-table-column label="车辆类型" min-width="90" align="center" header-align="center" v-if="isColumnVisible('vehicleType')">
@@ -216,7 +223,7 @@
/>
</el-form-item>
<el-form-item label="承运商" prop="carrierId">
<el-select v-model="formData.carrierId" placeholder="请选择承运商(选填)" clearable filterable>
<el-select v-model="formData.carrierId" placeholder="请选择承运商" filterable>
<el-option
v-for="c in carrierList"
:key="c.id"
@@ -390,6 +397,7 @@ import {
} from '@/api/pl'
import PlVehicleCertPartTabs from '@/components/business/pl-vehicle-cert-part-tabs/index.vue'
import PlVehicleCertPersonnelTabs from '@/components/business/pl-vehicle-cert-personnel-tabs/index.vue'
import PlVehicleCertBadges from '@/components/business/pl-vehicle-cert-badges/index.vue'
import type { VehiclePersonnelViewRow } from '@/components/business/pl-vehicle-personnel-view-list/index.vue'
import SystemViewDialog, {
type ViewSection
@@ -414,7 +422,11 @@ import {
PL_VEHICLE_CERT_NAME_OPTIONS,
getSelfVehicleCertMissingSuffix
} from '@/utils/pl-vehicle-cert'
import { validatePersonnelTypeRoleCompat, validatePersonnelAffiliationVehicleCompat } from '@/utils/pl-personnel-cert'
import {
mapPersonnelTypeToVehicleRole,
validatePersonnelTypeRoleCompat,
validatePersonnelAffiliationVehicleCompat
} from '@/utils/pl-personnel-cert'
import { canDeleteByCreator, filterDeletableByCreator, allRowsDeletableByCreator, CREATOR_DELETE_TIP } from '@/utils/creator-delete'
const VEHICLE_TYPE_SELF = 'self'
@@ -487,7 +499,8 @@ const formData = reactive({
const formRules = {
licensePlate: [{ required: true, message: '请输入车牌号', trigger: 'blur' }],
vehicleStatus: [{ required: true, message: '请选择车辆状态', trigger: 'change' }]
vehicleStatus: [{ required: true, message: '请选择车辆状态', trigger: 'change' }],
carrierId: [{ required: true, message: '请选择承运商', trigger: 'change' }]
}
function getStatusTagType(status: string) {
@@ -605,6 +618,7 @@ function handlePersonnelSelect(row: VehiclePersonnelRow, personnelId?: string) {
row.personnelName = ''
row.phoneNo = ''
row.age = null
row.role = ''
return
}
const person = personnelOptions.value.find(p => p.id === personnelId)
@@ -613,6 +627,11 @@ function handlePersonnelSelect(row: VehiclePersonnelRow, personnelId?: string) {
row.personnelName = person.personnelName
row.phoneNo = person.phoneNo || ''
row.age = person.age ?? null
const mappedRole = mapPersonnelTypeToVehicleRole(person.personnelType)
if (mappedRole) {
row.role = mappedRole
handleRoleChange(row, 0)
}
}
function resolvePersonnelRows(rows: VehiclePersonnelRow[]) {
@@ -1002,4 +1021,13 @@ onMounted(() => {
.sub-table {
margin-bottom: 8px;
}
.vehicle-plate-cell {
display: inline-flex;
flex-direction: row;
align-items: center;
justify-content: center;
flex-wrap: nowrap;
gap: 6px;
}
</style>
+35 -7
View File
@@ -121,14 +121,21 @@
<el-table-column
prop="licensePlate"
label="车牌号"
min-width="120"
min-width="340"
align="center"
header-align="center"
>
<template #default="{ row }">
<el-link type="primary" @click="handleView(row)">
{{ formatPlVehiclePlateDisplay(row.licensePlate, row.trailerNo) }}
</el-link>
<div class="vehicle-plate-cell">
<el-link type="primary" @click="handleView(row)">
{{ formatPlVehiclePlateDisplay(row.licensePlate, row.trailerNo) }}
</el-link>
<PlVehicleCertBadges
:vehicle-type="row.vehicleType === 'carrier' ? 'carrier' : 'self'"
:cert-list="row.certList"
:trailer-no="row.trailerNo"
/>
</div>
</template>
</el-table-column>
<el-table-column label="车辆类型" min-width="100" align="center" header-align="center" v-if="isColumnVisible('vehicleType')">
@@ -233,7 +240,7 @@
/>
</el-form-item>
<el-form-item label="承运商" prop="carrierId">
<el-select v-model="formData.carrierId" placeholder="请选择承运商" clearable filterable>
<el-select v-model="formData.carrierId" placeholder="请选择承运商" filterable>
<el-option
v-for="c in carrierList"
:key="c.id"
@@ -412,6 +419,7 @@ import {
} from '@/api/pl'
import PlVehicleCertPartTabs from '@/components/business/pl-vehicle-cert-part-tabs/index.vue'
import PlVehicleCertPersonnelTabs from '@/components/business/pl-vehicle-cert-personnel-tabs/index.vue'
import PlVehicleCertBadges from '@/components/business/pl-vehicle-cert-badges/index.vue'
import type { VehiclePersonnelViewRow } from '@/components/business/pl-vehicle-personnel-view-list/index.vue'
import SystemViewDialog, {
type ViewSection
@@ -432,7 +440,11 @@ import {
getVehicleCertMissingSuffix,
type PlVehicleCertCheckType
} from '@/utils/pl-vehicle-cert'
import { validatePersonnelTypeRoleCompat, validatePersonnelAffiliationVehicleCompat } from '@/utils/pl-personnel-cert'
import {
mapPersonnelTypeToVehicleRole,
validatePersonnelTypeRoleCompat,
validatePersonnelAffiliationVehicleCompat
} from '@/utils/pl-personnel-cert'
import { canDeleteByCreator, filterDeletableByCreator, allRowsDeletableByCreator, CREATOR_DELETE_TIP } from '@/utils/creator-delete'
type CertListItem = CertRow & { _key?: string }
@@ -506,7 +518,8 @@ const formData = reactive({
const formRules = {
licensePlate: [{ required: true, message: '请输入车牌号', trigger: 'blur' }],
vehicleType: [{ required: true, message: '请选择车辆类型', trigger: 'change' }]
vehicleType: [{ required: true, message: '请选择车辆类型', trigger: 'change' }],
carrierId: [{ required: true, message: '请选择承运商', trigger: 'change' }]
}
function getStatusTagType(status: string) {
@@ -671,6 +684,7 @@ function handlePersonnelSelect(row: VehiclePersonnelRow, personnelId?: string) {
row.personnelName = ''
row.phoneNo = ''
row.age = null
row.role = ''
return
}
const person = personnelOptions.value.find(p => p.id === personnelId)
@@ -679,6 +693,11 @@ function handlePersonnelSelect(row: VehiclePersonnelRow, personnelId?: string) {
row.personnelName = person.personnelName
row.phoneNo = person.phoneNo || ''
row.age = person.age ?? null
const mappedRole = mapPersonnelTypeToVehicleRole(person.personnelType)
if (mappedRole) {
row.role = mappedRole
handleRoleChange(row, 0)
}
}
function resolvePersonnelRows(rows: VehiclePersonnelRow[]) {
@@ -1107,4 +1126,13 @@ onMounted(() => {
.sub-table {
margin-bottom: 8px;
}
.vehicle-plate-cell {
display: inline-flex;
flex-direction: row;
align-items: center;
justify-content: center;
flex-wrap: nowrap;
gap: 6px;
}
</style>