WebApp【公共组件库】@前端(For Git Submodule)
Tevin
2022-04-22 a580cafe59a8f067cc6f011193952367beadcb2f
地址组件,增加智能地址识别功能
1 files added
1 files modified
230 ■■■■■ changed files
forms/chinaArea/SmartAddress.js 226 ●●●●● patch | view | raw | blame | history
forms/chinaArea/index.js 4 ●●● patch | view | raw | blame | history
forms/chinaArea/SmartAddress.js
New file
@@ -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;
        }
    }
}
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,
}
    SmartAddress,
};