Просмотр исходного кода

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

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

Co-authored-by: Cursor <cursoragent@cursor.com>
zlwu 3 месяцев назад
Родитель
Сommit
b1e788e856
1 измененных файлов с 120 добавлено и 0 удалено
  1. 120 0
      web-admin/src/utils/pl-paste-recognize.ts

+ 120 - 0
web-admin/src/utils/pl-paste-recognize.ts

@@ -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 }
+}