Преглед на файлове

feat: implement address parsing functionality in order form to extract province, city, and area from user input

Yannay преди 2 месеца
родител
ревизия
15f4627c68
променени са 1 файла, в които са добавени 168 реда и са изтрити 1 реда
  1. 168 1
      pages/orderForm/index.vue

+ 168 - 1
pages/orderForm/index.vue

@@ -126,6 +126,7 @@ import orderFileUpload from '@/components/order-file-upload/order-file-upload.vu
126 126
 import dateTimePicker from "@/components/dateTimePicker/dateTimePicker.vue"
127 127
 import ldSelect from "@/components/ld-select/ld-select.vue"
128 128
 import BrandSelect from "@/components/brand-select/brand-select.vue"
129
+const CHINA_REGIONS = require('@/components/pick-regions/regions.json')
129 130
 export default {
130 131
 	components: {
131 132
 		orderFileUpload,
@@ -289,7 +290,173 @@ export default {
289 290
 		},
290 291
 
291 292
 		// 地址失焦时自动解析地址信息
292
-		handleAddressBlur() {
293
+		async handleAddressBlur() {
294
+			if (!this.form.address || !this.form.address.trim()) {
295
+				return;
296
+			}
297
+			
298
+			const address = this.form.address.trim();
299
+			const parsedRegion = this.parseAddress(address);
300
+			
301
+			if (parsedRegion && parsedRegion.province) {
302
+				this.form.province = parsedRegion.province;
303
+				this.form.city = parsedRegion.city || '';
304
+				this.form.area = parsedRegion.area || '';
305
+				// 更新 defaultRegion,用于更新 pick-regions 组件的显示
306
+				this.defaultRegion = [
307
+					parsedRegion.province,
308
+					parsedRegion.city || '',
309
+					parsedRegion.area || ''
310
+				];
311
+			}
312
+		},
313
+		
314
+		// 基于地址字典解析地址,提取省市区信息
315
+		parseAddress(address) {
316
+			if (!address || !CHINA_REGIONS || CHINA_REGIONS.length === 0) {
317
+				return null;
318
+			}
319
+			
320
+			let bestMatch = null;
321
+			let bestMatchScore = 0; // 匹配分数:完整匹配得分更高
322
+			
323
+			// 遍历所有省份
324
+			for (const province of CHINA_REGIONS) {
325
+				const provinceName = province.name;
326
+				// 移除可能的"省"、"市"、"自治区"、"特别行政区"等后缀进行匹配
327
+				const provinceNameShort = provinceName.replace(/省|市|自治区|特别行政区|壮族自治区|维吾尔自治区|回族自治区/g, '');
328
+				
329
+				// 检查地址中是否包含省份名称
330
+				const hasProvinceFull = address.includes(provinceName);
331
+				const hasProvinceShort = address.includes(provinceNameShort);
332
+				
333
+				if (hasProvinceFull || hasProvinceShort) {
334
+					// 找到省份在地址中的位置
335
+					const provinceIndex = hasProvinceFull 
336
+						? address.indexOf(provinceName) 
337
+						: address.indexOf(provinceNameShort);
338
+					
339
+					if (provinceIndex === -1) continue;
340
+					
341
+					// 获取省份后的剩余地址
342
+					const provinceMatchLength = hasProvinceFull ? provinceName.length : provinceNameShort.length;
343
+					const remainingAfterProvince = address.substring(provinceIndex + provinceMatchLength);
344
+					
345
+					// 直辖市特殊处理
346
+					const municipalities = ['北京市', '上海市', '天津市', '重庆市'];
347
+					if (municipalities.includes(provinceName)) {
348
+						// 直辖市:市名就是省名,直接查找区/县
349
+						const cityName = provinceName;
350
+						let matchedArea = null;
351
+						let maxAreaLength = 0;
352
+						
353
+						// 遍历该省份下的所有市(通常是"市辖区")
354
+						if (province.childs && province.childs.length > 0) {
355
+							for (const city of province.childs) {
356
+								// 遍历该市下的所有区/县
357
+								if (city.childs && city.childs.length > 0) {
358
+									for (const area of city.childs) {
359
+										const areaName = area.name;
360
+										// 检查剩余地址中是否包含区/县名称
361
+										if (remainingAfterProvince.includes(areaName)) {
362
+											// 找到最长的匹配(更准确)
363
+											if (areaName.length > maxAreaLength) {
364
+												maxAreaLength = areaName.length;
365
+												matchedArea = areaName;
366
+											}
367
+										}
368
+									}
369
+								}
370
+							}
371
+						}
372
+						
373
+						// 计算匹配分数:有区/县得3分,只有省市区得2分
374
+						const matchScore = matchedArea ? 3 : 2;
375
+						if (matchScore > bestMatchScore) {
376
+							bestMatchScore = matchScore;
377
+							bestMatch = {
378
+								province: provinceName,
379
+								city: cityName,
380
+								area: matchedArea || ''
381
+							};
382
+							// 如果找到了完整的省市区,可以提前返回
383
+							if (matchedArea) {
384
+								return bestMatch;
385
+							}
386
+						}
387
+						continue;
388
+					}
389
+					
390
+					// 非直辖市:查找市
391
+					if (province.childs && province.childs.length > 0) {
392
+						for (const city of province.childs) {
393
+							const cityName = city.name;
394
+							// 移除可能的"市"、"州"、"盟"、"地区"、"自治州"等后缀
395
+							const cityNameShort = cityName.replace(/市|州|盟|地区|自治州/g, '');
396
+							
397
+							// 检查剩余地址中是否包含市名称
398
+							const hasCityFull = remainingAfterProvince.includes(cityName);
399
+							const hasCityShort = remainingAfterProvince.includes(cityNameShort);
400
+							
401
+							if (hasCityFull || hasCityShort) {
402
+								const cityIndex = hasCityFull
403
+									? remainingAfterProvince.indexOf(cityName)
404
+									: remainingAfterProvince.indexOf(cityNameShort);
405
+								
406
+								if (cityIndex === -1) continue;
407
+								
408
+								// 获取市后的剩余地址
409
+								const cityMatchLength = hasCityFull ? cityName.length : cityNameShort.length;
410
+								const remainingAfterCity = remainingAfterProvince.substring(cityIndex + cityMatchLength);
411
+								
412
+								// 查找区/县
413
+								let matchedArea = null;
414
+								let maxAreaLength = 0;
415
+								if (city.childs && city.childs.length > 0) {
416
+									for (const area of city.childs) {
417
+										const areaName = area.name;
418
+										// 检查剩余地址中是否包含区/县名称
419
+										if (remainingAfterCity.includes(areaName)) {
420
+											// 找到最长的匹配(更准确)
421
+											if (areaName.length > maxAreaLength) {
422
+												maxAreaLength = areaName.length;
423
+												matchedArea = areaName;
424
+											}
425
+										}
426
+									}
427
+								}
428
+								
429
+								// 计算匹配分数:完整省市区得3分,只有省市得2分
430
+								const matchScore = matchedArea ? 3 : 2;
431
+								if (matchScore > bestMatchScore) {
432
+									bestMatchScore = matchScore;
433
+									bestMatch = {
434
+										province: provinceName,
435
+										city: cityName,
436
+										area: matchedArea || ''
437
+									};
438
+									// 如果找到了完整的省市区,可以提前返回
439
+									if (matchedArea) {
440
+										return bestMatch;
441
+									}
442
+								}
443
+							}
444
+						}
445
+					}
446
+					
447
+					// 如果只找到了省份,也记录(得分1分)
448
+					if (!bestMatch || bestMatchScore < 1) {
449
+						bestMatch = {
450
+							province: provinceName,
451
+							city: '',
452
+							area: ''
453
+						};
454
+						bestMatchScore = 1;
455
+					}
456
+				}
457
+			}
458
+			
459
+			return bestMatch;
293 460
 		},
294 461
 
295 462
 		// 更新各类附件