feat(web-admin): 三方车辆客户文本粘贴解析工具

为三方车辆/人员粘贴识别提供规则解析纯函数。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
zlwuandCursor committed 2026-07-25 10:58:52 +08:00
1 parent fd62043f71
commit b1e788e856
1 file changed
+120
+120
View File
@@ -0,0 +1,120 @@
/**
* 三方车辆/人员客户文本粘贴解析
* 示例:
* 皖LB1405 皖LP359
* 核载:34 吨
* 驾驶员:徐孝军
* 手机号:18956652137
* 身份证:342921198602020031
* 押运员:汪海明
* 电话:13955522828
* 身份证:342829197009084019
*/
export interface PlPastePersonnelDraft {
personnelName: string
phoneNo?: string
idCardNo?: string
personnelType: 'driver' | 'escort'
}
export interface PlPasteVehicleDraft {
licensePlate: string
trailerNo?: string
loadCapacity?: number
}
export interface PlPasteRecognizeResult {
vehicle?: PlPasteVehicleDraft
driver?: PlPastePersonnelDraft
escort?: PlPastePersonnelDraft
warnings: string[]
}
const PLATE_LINE =
/^[\u4e00-\u9fa5A-Z]{1,2}[A-Z0-9]+(?:\s+[\u4e00-\u9fa5A-Z]{1,2}[A-Z0-9]+)?$/i
export function parsePlCustomerVehicleText(raw: string): PlPasteRecognizeResult {
const warnings: string[] = []
const lines = raw
.split(/\r?\n/)
.map(l => l.trim())
.filter(Boolean)
let vehicle: PlPasteVehicleDraft | undefined
let driver: PlPastePersonnelDraft | undefined
let escort: PlPastePersonnelDraft | undefined
let section: 'none' | 'driver' | 'escort' = 'none'
for (const line of lines) {
const normalizedPlateLine = line.replace(/\s+/g, ' ')
if (!vehicle && PLATE_LINE.test(normalizedPlateLine)) {
const parts = normalizedPlateLine.split(/\s+/).filter(Boolean)
vehicle = {
licensePlate: parts[0] || '',
trailerNo: parts[1] || undefined
}
continue
}
const load = line.match(/核载[::]?\s*([\d.]+)\s*吨?/)
if (load) {
if (!vehicle) {
vehicle = { licensePlate: '' }
}
vehicle.loadCapacity = Number(load[1])
continue
}
if (/^驾驶员[::]/.test(line)) {
section = 'driver'
driver = {
personnelName: line.replace(/^驾驶员[::]\s*/, '').trim(),
personnelType: 'driver'
}
continue
}
if (/^押运员[::]/.test(line)) {
section = 'escort'
escort = {
personnelName: line.replace(/^押运员[::]\s*/, '').trim(),
personnelType: 'escort'
}
continue
}
const phone = line.match(/^(?:手机号|电话)[::]?\s*(\d{11})$/)
if (phone) {
if (section === 'driver' && driver) {
driver.phoneNo = phone[1]
continue
}
if (section === 'escort' && escort) {
escort.phoneNo = phone[1]
continue
}
}
const idCard = line.match(/^身份证[::]?\s*([0-9Xx]{15,18})$/)
if (idCard) {
const no = idCard[1].toUpperCase()
if (section === 'driver' && driver) {
driver.idCardNo = no
continue
}
if (section === 'escort' && escort) {
escort.idCardNo = no
continue
}
}
warnings.push(`未识别行:${line}`)
}
if (vehicle && !vehicle.licensePlate.trim()) {
warnings.push('未识别到主车车牌')
}
return { vehicle, driver, escort, warnings }
}