From a580cafe59a8f067cc6f011193952367beadcb2f Mon Sep 17 00:00:00 2001 From: Tevin <tingquanren@163.com> Date: Fri, 22 Apr 2022 18:16:06 +0800 Subject: [PATCH] 地址组件,增加智能地址识别功能 --- forms/chinaArea/SmartAddress.js | 226 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ forms/chinaArea/index.js | 4 2 files changed, 229 insertions(+), 1 deletions(-) diff --git a/forms/chinaArea/SmartAddress.js b/forms/chinaArea/SmartAddress.js new file mode 100644 index 0000000..750a6ac --- /dev/null +++ b/forms/chinaArea/SmartAddress.js @@ -0,0 +1,226 @@ +/** + * SmartAddress + * @author Tevin + */ + +import ChinaLocations from '@components/forms/chinaArea/ChinaLocations'; +import { Tools } from '@components/common/Tools'; + +export class SmartAddress { + constructor() { + this.wordData = {}; + } + + parseWord(word, callback) { + if (!this._checkLength(word)) { + callback(false); + return; + } + this.wordData = {}; + const wordArr = this._splitWord(word); + ChinaLocations.onReady(() => { + this._checkPhone(wordArr); + this._checkCompany(wordArr); + this._checkUser(wordArr); + this._checkAddress(wordArr); + if (Tools.isEmptyObject(this.wordData)) { + callback(false); + } else { + callback({ ...this.wordData }); + } + }); + } + + _checkLength(word) { + if (!word || typeof word !== 'string') { + return false; + } else if (word.length < 8) { + return false; + } else if (word.length > 150) { + return false; + } + return true; + } + + _splitWord(word) { + word = word.replace(/([::]) */g, '$1'); // 带类型名模式预处理 + const splitReg = /[ \n\r…,.;?!'"()\[\],。;?!‘’“”()【】—|]/g; + const array = word.split(splitReg).filter(Boolean); + return array.map(item => { + const nextItem = { label: '', content: '' }; + if (/[::]/.test(item)) { + const [label, content] = item.split(/[::]/g).filter(Boolean); + nextItem.label = label; + nextItem.content = content; + } else { + nextItem.content = item; + } + return nextItem; + }); + } + + _checkPhone(list) { + const phoneLabelReg = /^电话|联系电话|手机|手机号码$/; + const phoneReg = /^1[3456789]\d{9}$/; + const telReg = /\d{3.4}-\d{8}/; + for (let i = 0, item; (item = list[i]); i++) { + if (!item.content) { + continue; + } + if (item.label) { + if (phoneLabelReg.test(item.label)) { + this.wordData.phone = item.content; + if (this.wordData.phone.length === 13) { + this.wordData.phone = this.wordData.phone.replace(/-/g, ''); + } + list.splice(i, 1); + break; + } + } else { + const phone = item.content.replace(/-/g, ''); + if (phoneReg.test(phone)) { + this.wordData.phone = phone; + list.splice(i, 1); + break; + } else if (telReg.test(item.content)) { + this.wordData.phone = phone; + list.splice(i, 1); + break; + } + } + } + } + + _checkCompany(list) { + const companyLabelReg = /公司|公司名称|客户|客户名称/; + const companyNameReg = /公司|厂|站|气|部$/; + for (let i = 0, item; (item = list[i]); i++) { + if (!item.content) { + continue; + } + if (item.label) { + if (companyLabelReg.test(item.label)) { + this.wordData.company = item.content; + list.splice(i, 1); + break; + } + } else { + if (item.content.length > 5 && companyNameReg.test(item.content)) { + this.wordData.company = item.content; + list.splice(i, 1); + break; + } + } + } + } + + _checkUser(list) { + const userLabelReg = /姓名|联系人|收货人|收件人/; + const userReg = /^[\u4e00-\u9fa5]{2,3}$/; + for (let i = 0, item; (item = list[i]); i++) { + if (!item.content) { + continue; + } + if (item.label) { + if (userLabelReg.test(item.label)) { + this.wordData.user = item.content; + list.splice(i, 1); + break; + } + } else { + if (userReg.test(item.content)) { + this.wordData.user = item.content; + list.splice(i, 1); + break; + } + } + } + } + + _checkAddress(list) { + const adrLabelReg = /地址|详细地址|公司地址|联系地址|地区|所在地区/; + for (let i = 0, item; (item = list[i]); i++) { + if (!item.content) { + continue; + } + if (item.label) { + if (adrLabelReg.test(item.label)) { + this._parseAddress(item.content); + list.splice(i, 1); + break; + } + } else { + if (this._isAddress(item.content)) { + this._parseAddress(item.content); + list.splice(i, 1); + break; + } + } + } + } + + _isAddress(content) { + content = content.replace('中国', ''); + const provinceNames = ChinaLocations.getLocationTree() + .map(lv1 => lv1.label.replace('特别行政区', '').replace('省', '')); + for (let province of provinceNames) { + if (content.indexOf(province) >= 0) { + return true; + } + } + return false; + } + + _parseAddress(content) { + content = content.replace('中国', ''); + const chinaTree = ChinaLocations.getLocationTree(); + // 省份处理 --- + const provinceTailReg = /特别行政区|自治区|省|市$/; + for (let province of chinaTree) { + const provinceStr = province.label.replace(provinceTailReg, ''); + // 省份匹配 + if (content.indexOf(provinceStr) === 0) { + // 保存省 + this.wordData.province = province.label; + this.wordData.provinceCode = province.value; + // 移除省份 + const provinceNameReg = new RegExp('^' + provinceStr + '(特别行政区|自治区|省|市)?'); + content = content.replace(provinceNameReg, ''); + // 市级处理 --- + const cityTailReg = /市|区|县|自治县|自治州|地区$/; + for (let city of province.children) { + const cityStr = city.label.replace(cityTailReg, ''); + // 市级匹配 + if (content.indexOf(cityStr) === 0) { + // 保存市级 + this.wordData.city = city.label; + this.wordData.cityCode = city.value; + // 移除市级 + const cityNameReg = new RegExp('^' + cityStr + '(市|区|县|自治县|自治州|地区)?'); + content = content.replace(cityNameReg, ''); + // 区级处理 --- + const distTailReg = /市|区|县|镇|乡|自治县|开发区|新区|矿区|旗|自治旗$/; + for (let dist of city.children) { + const distStr = dist.label.replace(distTailReg, ''); + // 区级匹配 + if (content.indexOf(distStr) === 0) { + // 保存区级 + this.wordData.dist = dist.label; + this.wordData.distCode = dist.value; + // 移除区级 + const distNameReg = new RegExp('^' + distStr + '(市|区|县|镇|乡|自治县|开发区|新区|矿区|旗|自治旗)?'); + content = content.replace(distNameReg, ''); + } + } + } + } + } + } + // 省市区都匹配上了,剩下的为街道 + if (this.wordData.province && this.wordData.city && this.wordData.dist) { + this.wordData.street = content; + } + } + + +} \ No newline at end of file diff --git a/forms/chinaArea/index.js b/forms/chinaArea/index.js index d673bb1..0d63f1e 100644 --- a/forms/chinaArea/index.js +++ b/forms/chinaArea/index.js @@ -5,8 +5,10 @@ import CChinaArea from '@components/forms/chinaArea/CChinaArea.vue'; import ChinaLocations from '@components/forms/chinaArea/ChinaLocations'; +import { SmartAddress } from '@components/forms/chinaArea/SmartAddress'; export { CChinaArea, ChinaLocations, -} \ No newline at end of file + SmartAddress, +}; \ No newline at end of file -- Gitblit v1.9.1