id-scanner-lib 1.3.2 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. package/README.md +55 -460
  2. package/dist/id-scanner-lib.esm.js +4641 -0
  3. package/dist/id-scanner-lib.esm.js.map +1 -0
  4. package/dist/id-scanner-lib.js +14755 -0
  5. package/dist/id-scanner-lib.js.map +1 -0
  6. package/dist/types/core/base-module.d.ts +44 -0
  7. package/dist/types/core/camera-manager.d.ts +258 -0
  8. package/dist/types/core/config.d.ts +88 -0
  9. package/dist/types/core/errors.d.ts +111 -0
  10. package/dist/types/core/event-emitter.d.ts +55 -0
  11. package/dist/types/core/logger.d.ts +277 -0
  12. package/dist/types/core/module-manager.d.ts +78 -0
  13. package/dist/types/core/plugin-manager.d.ts +158 -0
  14. package/dist/types/core/resource-manager.d.ts +246 -0
  15. package/dist/types/core/result.d.ts +83 -0
  16. package/dist/types/core/scanner-factory.d.ts +93 -0
  17. package/dist/types/index.bundle.d.ts +1303 -0
  18. package/dist/types/index.d.ts +86 -0
  19. package/dist/types/interfaces/external-types.d.ts +174 -0
  20. package/dist/types/interfaces/face-detection.d.ts +293 -0
  21. package/dist/types/interfaces/scanner-module.d.ts +280 -0
  22. package/dist/types/modules/face/face-detector.d.ts +170 -0
  23. package/dist/types/modules/face/index.d.ts +56 -0
  24. package/dist/types/modules/face/liveness-detector.d.ts +177 -0
  25. package/dist/types/modules/face/types.d.ts +136 -0
  26. package/dist/types/modules/id-card/anti-fake-detector.d.ts +170 -0
  27. package/dist/types/modules/id-card/id-card-detector.d.ts +131 -0
  28. package/dist/types/modules/id-card/index.d.ts +89 -0
  29. package/dist/types/modules/id-card/ocr-processor.d.ts +110 -0
  30. package/dist/types/modules/id-card/ocr-worker.d.ts +31 -0
  31. package/dist/types/modules/id-card/types.d.ts +181 -0
  32. package/dist/types/modules/qrcode/index.d.ts +51 -0
  33. package/dist/types/modules/qrcode/qr-code-scanner.d.ts +64 -0
  34. package/dist/types/modules/qrcode/types.d.ts +67 -0
  35. package/dist/types/utils/camera.d.ts +81 -0
  36. package/dist/types/utils/image-processing.d.ts +176 -0
  37. package/dist/types/utils/index.d.ts +175 -0
  38. package/dist/types/utils/performance.d.ts +81 -0
  39. package/dist/types/utils/resource-manager.d.ts +53 -0
  40. package/dist/types/utils/types.d.ts +166 -0
  41. package/dist/types/utils/worker.d.ts +52 -0
  42. package/dist/types/version.d.ts +7 -0
  43. package/package.json +76 -77
  44. package/src/core/base-module.ts +78 -0
  45. package/src/core/camera-manager.ts +798 -0
  46. package/src/core/config.ts +268 -0
  47. package/src/core/errors.ts +174 -0
  48. package/src/core/event-emitter.ts +110 -0
  49. package/src/core/logger.ts +549 -0
  50. package/src/core/module-manager.ts +165 -0
  51. package/src/core/plugin-manager.ts +429 -0
  52. package/src/core/resource-manager.ts +762 -0
  53. package/src/core/result.ts +163 -0
  54. package/src/core/scanner-factory.ts +237 -0
  55. package/src/index.ts +113 -936
  56. package/src/interfaces/external-types.ts +200 -0
  57. package/src/interfaces/face-detection.ts +309 -0
  58. package/src/interfaces/scanner-module.ts +384 -0
  59. package/src/modules/face/face-detector.ts +931 -0
  60. package/src/modules/face/index.ts +208 -0
  61. package/src/modules/face/liveness-detector.ts +908 -0
  62. package/src/modules/face/types.ts +133 -0
  63. package/src/modules/id-card/anti-fake-detector.ts +732 -0
  64. package/src/modules/id-card/id-card-detector.ts +474 -0
  65. package/src/modules/id-card/index.ts +425 -0
  66. package/src/modules/id-card/ocr-processor.ts +538 -0
  67. package/src/modules/id-card/ocr-worker.ts +259 -0
  68. package/src/modules/id-card/types.ts +178 -0
  69. package/src/modules/qrcode/index.ts +175 -0
  70. package/src/modules/qrcode/qr-code-scanner.ts +230 -0
  71. package/src/modules/qrcode/types.ts +65 -0
  72. package/src/types/browser-image-compression.d.ts +19 -0
  73. package/src/types/tesseract.d.ts +280 -0
  74. package/src/utils/image-processing.ts +432 -49
  75. package/src/utils/index.ts +426 -0
  76. package/src/utils/performance.ts +168 -131
  77. package/src/utils/resource-manager.ts +65 -146
  78. package/src/utils/types.ts +90 -2
  79. package/src/utils/worker.ts +123 -84
  80. package/src/version.ts +11 -0
  81. package/tools/scaffold.js +543 -0
  82. package/dist/id-scanner-core.esm.js +0 -11076
  83. package/dist/id-scanner-core.esm.js.map +0 -1
  84. package/dist/id-scanner-core.js +0 -11088
  85. package/dist/id-scanner-core.js.map +0 -1
  86. package/dist/id-scanner-core.min.js +0 -1
  87. package/dist/id-scanner-core.min.js.map +0 -1
  88. package/dist/id-scanner-ocr.esm.js +0 -1802
  89. package/dist/id-scanner-ocr.esm.js.map +0 -1
  90. package/dist/id-scanner-ocr.js +0 -1811
  91. package/dist/id-scanner-ocr.js.map +0 -1
  92. package/dist/id-scanner-ocr.min.js +0 -1
  93. package/dist/id-scanner-ocr.min.js.map +0 -1
  94. package/dist/id-scanner-qr.esm.js +0 -1023
  95. package/dist/id-scanner-qr.esm.js.map +0 -1
  96. package/dist/id-scanner-qr.js +0 -1032
  97. package/dist/id-scanner-qr.js.map +0 -1
  98. package/dist/id-scanner-qr.min.js +0 -1
  99. package/dist/id-scanner-qr.min.js.map +0 -1
  100. package/dist/id-scanner.js +0 -3740
  101. package/dist/id-scanner.js.map +0 -1
  102. package/dist/id-scanner.min.js +0 -1
  103. package/dist/id-scanner.min.js.map +0 -1
  104. package/src/core.ts +0 -138
  105. package/src/demo/demo.ts +0 -204
  106. package/src/id-recognition/anti-fake-detector.ts +0 -317
  107. package/src/id-recognition/data-extractor.ts +0 -262
  108. package/src/id-recognition/id-detector.ts +0 -363
  109. package/src/id-recognition/ocr-processor.ts +0 -334
  110. package/src/id-recognition/ocr-worker.ts +0 -156
  111. package/src/index-umd.ts +0 -477
  112. package/src/ocr-module.ts +0 -187
  113. package/src/qr-module.ts +0 -179
  114. package/src/scanner/barcode-scanner.ts +0 -251
  115. package/src/scanner/qr-scanner.ts +0 -167
@@ -1,334 +0,0 @@
1
- /**
2
- * @file OCR处理模块
3
- * @description 提供身份证文字识别和信息提取功能
4
- * @module OCRProcessor
5
- */
6
-
7
- import { createWorker } from "tesseract.js"
8
- import { IDCardInfo } from "../utils/types"
9
- import { ImageProcessor } from "../utils/image-processing"
10
- import { LRUCache, calculateImageFingerprint } from "../utils/performance"
11
- import {
12
- isWorkerSupported,
13
- createWorker as createCustomWorker,
14
- } from "../utils/worker"
15
- import { processOCRInWorker, OCRProcessInput } from "./ocr-worker"
16
- import { Disposable } from "../utils/resource-manager"
17
-
18
- /**
19
- * OCR处理器选项接口
20
- */
21
- export interface OCRProcessorOptions {
22
- language?: string
23
- useWorker?: boolean
24
- maxImageDimension?: number
25
- timeout?: number
26
- brightness?: number // 新增亮度参数
27
- contrast?: number // 新增对比度参数
28
- onProgress?: (progress: number) => void
29
- enableCache?: boolean // 添加启用缓存选项
30
- cacheSize?: number // 添加缓存大小选项
31
- logger?: (message: any) => void // 添加日志记录器选项
32
- }
33
-
34
- /**
35
- * OCR处理器类
36
- *
37
- * 使用Tesseract.js实现对身份证图像的OCR文字识别和信息提取功能
38
- *
39
- * @example
40
- * ```typescript
41
- * // 创建OCR处理器
42
- * const ocrProcessor = new OCRProcessor();
43
- *
44
- * // 初始化OCR引擎
45
- * await ocrProcessor.initialize();
46
- *
47
- * // 处理身份证图像
48
- * const idInfo = await ocrProcessor.processIDCard(idCardImageData);
49
- * console.log('识别到的身份证信息:', idInfo);
50
- *
51
- * // 使用结束后释放资源
52
- * await ocrProcessor.terminate();
53
- * ```
54
- */
55
- export class OCRProcessor implements Disposable {
56
- private worker: any = null
57
- private ocrWorker: ReturnType<
58
- typeof createCustomWorker<
59
- OCRProcessInput,
60
- { idCardInfo: IDCardInfo; processingTime: number }
61
- >
62
- > | null = null
63
- private initialized: boolean = false
64
- private resultCache: LRUCache<string, IDCardInfo>
65
- private options: OCRProcessorOptions
66
-
67
- /**
68
- * 创建OCR处理器实例
69
- *
70
- * @param options OCR处理器选项
71
- */
72
- constructor(options: OCRProcessorOptions = {}) {
73
- this.options = {
74
- useWorker: isWorkerSupported(),
75
- enableCache: true,
76
- cacheSize: 50,
77
- maxImageDimension: 1000,
78
- logger: console.log,
79
- ...options,
80
- }
81
-
82
- // 初始化缓存
83
- this.resultCache = new LRUCache<string, IDCardInfo>(this.options.cacheSize)
84
- }
85
-
86
- /**
87
- * 初始化OCR引擎
88
- *
89
- * 加载Tesseract OCR引擎和中文简体语言包,并设置适合身份证识别的参数
90
- *
91
- * @returns {Promise<void>} 初始化完成的Promise
92
- */
93
- async initialize(): Promise<void> {
94
- if (this.initialized) return
95
-
96
- if (this.options.useWorker) {
97
- // 使用自定义Worker线程处理OCR
98
- this.ocrWorker = createCustomWorker<
99
- OCRProcessInput,
100
- { idCardInfo: IDCardInfo; processingTime: number }
101
- >(processOCRInWorker)
102
- this.initialized = true
103
- this.options.logger?.("OCR Worker 初始化完成")
104
- } else {
105
- // 使用主线程处理OCR
106
- this.worker = createWorker({
107
- logger: this.options.logger,
108
- } as any)
109
-
110
- await this.worker.load()
111
- await this.worker.loadLanguage("chi_sim")
112
- await this.worker.initialize("chi_sim")
113
- await this.worker.setParameters({
114
- tessedit_char_whitelist:
115
- "0123456789X-年月日一二三四五六七八九十零壹贰叁肆伍陆柒捌玖拾ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz民族汉族满族回族维吾尔族藏族苗族彝族壮族朝鲜族侗族瑶族白族土家族哈尼族哈萨克族傣族黎族傈僳族佤族高山族拉祜族水族东乡族钠西族景颇族柯尔克孜族士族达斡尔族仫佬族羌族布朗族撒拉族毛南族仡佬族锡伯族阿昌族普米族塔吉克族怒族乌孜别克族俄罗斯族鄂温克族德昂族保安族裕固族京族塔塔尔族独龙族鄂伦春族赫哲族门巴族珞巴族基诺族男女性别住址出生公民身份号码签发机关有效期",
116
- })
117
-
118
- this.initialized = true
119
- this.options.logger?.("OCR引擎初始化完成")
120
- }
121
- }
122
-
123
- /**
124
- * 处理身份证图像并提取信息
125
- * @param imageData 要处理的身份证图像数据
126
- * @returns 提取的身份证信息
127
- */
128
- async processIDCard(imageData: ImageData): Promise<IDCardInfo> {
129
- if (!this.initialized) {
130
- await this.initialize()
131
- }
132
-
133
- // 计算图像指纹,用于缓存查找
134
- if (this.options.enableCache) {
135
- const fingerprint = calculateImageFingerprint(imageData)
136
-
137
- // 检查缓存中是否有结果
138
- const cachedResult = this.resultCache.get(fingerprint)
139
- if (cachedResult) {
140
- this.options.logger?.("使用缓存的OCR结果")
141
- return cachedResult
142
- }
143
- }
144
-
145
- // 调整图像大小以提高性能和准确性
146
- const downsampledImage = ImageProcessor.resizeImage(
147
- imageData,
148
- this.options.maxImageDimension || 1000,
149
- this.options.maxImageDimension || 1000,
150
- true // 保持宽高比
151
- )
152
-
153
- // 提高图像质量以获得更好的OCR结果
154
- const enhancedImage = ImageProcessor.batchProcess(downsampledImage, {
155
- brightness: this.options.brightness || 15,
156
- contrast: this.options.contrast || 25,
157
- sharpen: true,
158
- })
159
-
160
- // 转换为base64供Tesseract处理
161
- // 创建一个canvas元素
162
- const canvas = document.createElement("canvas")
163
- canvas.width = enhancedImage.width
164
- canvas.height = enhancedImage.height
165
- const ctx = canvas.getContext("2d")
166
-
167
- if (!ctx) {
168
- throw new Error("无法创建canvas上下文")
169
- }
170
-
171
- // 将ImageData绘制到canvas
172
- ctx.putImageData(enhancedImage, 0, 0)
173
-
174
- // 转换为Base64
175
- const base64Image = canvas.toDataURL("image/jpeg", 0.7)
176
-
177
- // OCR识别
178
- try {
179
- let idCardInfo: IDCardInfo
180
-
181
- if (this.options.useWorker && this.ocrWorker) {
182
- // 使用Worker线程处理
183
- const result = await this.ocrWorker.postMessage({
184
- imageBase64: base64Image,
185
- tessWorkerOptions: {
186
- logger: this.options.logger,
187
- },
188
- })
189
-
190
- idCardInfo = result.idCardInfo
191
- this.options.logger?.(
192
- `OCR处理完成,用时: ${result.processingTime.toFixed(2)}ms`
193
- )
194
- } else {
195
- // 使用主线程处理
196
- const startTime = performance.now()
197
-
198
- // 转换ImageData为Canvas
199
- const canvas = ImageProcessor.imageDataToCanvas(enhancedImage)
200
-
201
- const { data } = await this.worker.recognize(canvas)
202
-
203
- // 解析身份证信息
204
- idCardInfo = this.parseIDCardText(data.text)
205
-
206
- const processingTime = performance.now() - startTime
207
- this.options.logger?.(
208
- `OCR处理完成,用时: ${processingTime.toFixed(2)}ms`
209
- )
210
- }
211
-
212
- // 缓存结果
213
- if (this.options.enableCache) {
214
- const fingerprint = calculateImageFingerprint(imageData)
215
- this.resultCache.set(fingerprint, idCardInfo)
216
- }
217
-
218
- return idCardInfo
219
- } catch (error) {
220
- this.options.logger?.(`OCR识别错误: ${error}`)
221
- return {} as IDCardInfo
222
- }
223
- }
224
-
225
- /**
226
- * 解析身份证文本信息
227
- *
228
- * 从OCR识别到的文本中提取结构化的身份证信息
229
- *
230
- * @private
231
- * @param {string} text - OCR识别到的文本
232
- * @returns {IDCardInfo} 提取到的身份证信息对象
233
- */
234
- private parseIDCardText(text: string): IDCardInfo {
235
- const info: IDCardInfo = {}
236
-
237
- // 拆分为行
238
- const lines = text.split("\n").filter((line) => line.trim())
239
-
240
- // 解析身份证号码(最容易识别的部分)
241
- const idNumberRegex = /(\d{17}[\dX])/
242
- const idNumberMatch = text.match(idNumberRegex)
243
- if (idNumberMatch) {
244
- info.idNumber = idNumberMatch[1]
245
- }
246
-
247
- // 解析姓名
248
- for (const line of lines) {
249
- if (
250
- line.includes("姓名") ||
251
- (line.length < 10 && line.length > 1 && !/\d/.test(line))
252
- ) {
253
- info.name = line.replace("姓名", "").trim()
254
- break
255
- }
256
- }
257
-
258
- // 解析性别和民族
259
- const genderNationalityRegex = /(男|女).*(族)/
260
- const genderMatch = text.match(genderNationalityRegex)
261
- if (genderMatch) {
262
- info.gender = genderMatch[1]
263
- const nationalityText = genderMatch[0]
264
- info.nationality = nationalityText
265
- .substring(nationalityText.indexOf(genderMatch[1]) + 1)
266
- .trim()
267
- }
268
-
269
- // 解析出生日期
270
- const birthDateRegex = /(\d{4})年(\d{1,2})月(\d{1,2})日/
271
- const birthDateMatch = text.match(birthDateRegex)
272
- if (birthDateMatch) {
273
- info.birthDate = `${birthDateMatch[1]}-${birthDateMatch[2]}-${birthDateMatch[3]}`
274
- }
275
-
276
- // 解析地址
277
- const addressRegex = /住址([\s\S]*?)公民身份号码/
278
- const addressMatch = text.match(addressRegex)
279
- if (addressMatch) {
280
- info.address = addressMatch[1].replace(/\n/g, "").trim()
281
- }
282
-
283
- // 解析签发机关
284
- const authorityRegex = /签发机关([\s\S]*?)有效期/
285
- const authorityMatch = text.match(authorityRegex)
286
- if (authorityMatch) {
287
- info.issuingAuthority = authorityMatch[1].replace(/\n/g, "").trim()
288
- }
289
-
290
- // 解析有效期限
291
- const validPeriodRegex = /有效期限([\s\S]*?)(-|至)/
292
- const validPeriodMatch = text.match(validPeriodRegex)
293
- if (validPeriodMatch) {
294
- info.validPeriod = validPeriodMatch[0].replace("有效期限", "").trim()
295
- }
296
-
297
- return info
298
- }
299
-
300
- /**
301
- * 清除结果缓存
302
- */
303
- clearCache(): void {
304
- this.resultCache.clear()
305
- this.options.logger?.("OCR结果缓存已清除")
306
- }
307
-
308
- /**
309
- * 终止OCR引擎并释放资源
310
- *
311
- * @returns {Promise<void>} 终止完成的Promise
312
- */
313
- async terminate(): Promise<void> {
314
- if (this.worker) {
315
- await this.worker.terminate()
316
- this.worker = null
317
- }
318
-
319
- if (this.ocrWorker) {
320
- this.ocrWorker.terminate()
321
- this.ocrWorker = null
322
- }
323
-
324
- this.initialized = false
325
- this.options.logger?.("OCR引擎已终止")
326
- }
327
-
328
- /**
329
- * 释放资源
330
- */
331
- dispose(): Promise<void> {
332
- return this.terminate()
333
- }
334
- }
@@ -1,156 +0,0 @@
1
- /**
2
- * @file OCR Worker处理模块
3
- * @description 用于在Web Worker中执行OCR处理
4
- * @module OCRWorker
5
- */
6
-
7
- import type { IDCardInfo } from "../utils/types"
8
-
9
- /**
10
- * OCR处理输入接口
11
- */
12
- export interface OCRProcessInput {
13
- imageBase64: string
14
- tessWorkerOptions?: any
15
- }
16
-
17
- /**
18
- * OCR处理输出接口
19
- */
20
- export interface OCRProcessOutput {
21
- idCardInfo: IDCardInfo
22
- processingTime: number
23
- }
24
-
25
- /**
26
- * 在Web Worker中执行OCR处理的函数
27
- *
28
- * 该函数用于在使用 createWorker 创建的 Worker 中执行
29
- *
30
- * @param input OCR处理输入数据
31
- * @returns OCR处理结果
32
- */
33
- export async function processOCRInWorker(
34
- input: OCRProcessInput
35
- ): Promise<OCRProcessOutput> {
36
- // 计时开始
37
- const startTime = performance.now()
38
-
39
- // 加载Tesseract.js (Worker 环境下动态导入)
40
- const { createWorker } = await import("tesseract.js")
41
-
42
- // 创建OCR Worker
43
- const worker = (await createWorker(
44
- input.tessWorkerOptions || {
45
- logger: (m: any) => console.log(m),
46
- }
47
- )) as any // 添加类型断言,避免TypeScript错误
48
-
49
- try {
50
- // 初始化OCR引擎
51
- await worker.load()
52
- await worker.loadLanguage("chi_sim")
53
- await worker.initialize("chi_sim")
54
- await worker.setParameters({
55
- tessedit_char_whitelist:
56
- "0123456789X-年月日一二三四五六七八九十零壹贰叁肆伍陆柒捌玖拾ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz民族汉族满族回族维吾尔族藏族苗族彝族壮族朝鲜族侗族瑶族白族土家族哈尼族哈萨克族傣族黎族傈僳族佤族高山族拉祜族水族东乡族钠西族景颇族柯尔克孜族士族达斡尔族仫佬族羌族布朗族撒拉族毛南族仡佬族锡伯族阿昌族普米族塔吉克族怒族乌孜别克族俄罗斯族鄂温克族德昂族保安族裕固族京族塔塔尔族独龙族鄂伦春族赫哲族门巴族珞巴族基诺族男女性别住址出生公民身份号码签发机关有效期",
57
- })
58
-
59
- // 识别图像
60
- const { data } = await worker.recognize(input.imageBase64)
61
-
62
- // 解析识别结果
63
- const idCardInfo = parseIDCardText(data.text)
64
-
65
- // 处理完成后终止worker
66
- await worker.terminate()
67
-
68
- // 计算处理时间
69
- const processingTime = performance.now() - startTime
70
-
71
- // 返回处理结果
72
- return {
73
- idCardInfo,
74
- processingTime,
75
- }
76
- } catch (error) {
77
- // 确保资源被释放
78
- await worker.terminate()
79
- throw error
80
- }
81
- }
82
-
83
- /**
84
- * 解析身份证文本信息
85
- *
86
- * 从OCR识别到的文本中提取结构化的身份证信息
87
- *
88
- * @private
89
- * @param {string} text - OCR识别到的文本
90
- * @returns {IDCardInfo} 提取到的身份证信息对象
91
- */
92
- function parseIDCardText(text: string): IDCardInfo {
93
- const info: IDCardInfo = {}
94
-
95
- // 拆分为行
96
- const lines = text.split("\n").filter((line) => line.trim())
97
-
98
- // 解析身份证号码(最容易识别的部分)
99
- const idNumberRegex = /(\d{17}[\dX])/
100
- const idNumberMatch = text.match(idNumberRegex)
101
- if (idNumberMatch) {
102
- info.idNumber = idNumberMatch[1]
103
- }
104
-
105
- // 解析姓名
106
- for (const line of lines) {
107
- if (
108
- line.includes("姓名") ||
109
- (line.length < 10 && line.length > 1 && !/\d/.test(line))
110
- ) {
111
- info.name = line.replace("姓名", "").trim()
112
- break
113
- }
114
- }
115
-
116
- // 解析性别和民族
117
- const genderNationalityRegex = /(男|女).*(族)/
118
- const genderMatch = text.match(genderNationalityRegex)
119
- if (genderMatch) {
120
- info.gender = genderMatch[1]
121
- const nationalityText = genderMatch[0]
122
- info.nationality = nationalityText
123
- .substring(nationalityText.indexOf(genderMatch[1]) + 1)
124
- .trim()
125
- }
126
-
127
- // 解析出生日期
128
- const birthDateRegex = /(\d{4})年(\d{1,2})月(\d{1,2})日/
129
- const birthDateMatch = text.match(birthDateRegex)
130
- if (birthDateMatch) {
131
- info.birthDate = `${birthDateMatch[1]}-${birthDateMatch[2]}-${birthDateMatch[3]}`
132
- }
133
-
134
- // 解析地址
135
- const addressRegex = /住址([\s\S]*?)公民身份号码/
136
- const addressMatch = text.match(addressRegex)
137
- if (addressMatch) {
138
- info.address = addressMatch[1].replace(/\n/g, "").trim()
139
- }
140
-
141
- // 解析签发机关
142
- const authorityRegex = /签发机关([\s\S]*?)有效期/
143
- const authorityMatch = text.match(authorityRegex)
144
- if (authorityMatch) {
145
- info.issuingAuthority = authorityMatch[1].replace(/\n/g, "").trim()
146
- }
147
-
148
- // 解析有效期限
149
- const validPeriodRegex = /有效期限([\s\S]*?)(-|至)/
150
- const validPeriodMatch = text.match(validPeriodRegex)
151
- if (validPeriodMatch) {
152
- info.validPeriod = validPeriodMatch[0].replace("有效期限", "").trim()
153
- }
154
-
155
- return info
156
- }