提交
This commit is contained in:
1 parent
c2cba3e668
commit
2142b33cfa
24 files changed
+4834
-3684
No files matched your search
@@ -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)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
})
|
||||
}
|
||||
Reference in new issue
Block a user