/** * 地址解析工具 - 使用关键词匹配方式解析省市区地址 * 思路:通过省市区关键词截取,去两边留中间 */ /** * 解析连续文本格式的地址 * @param {string} fullAddress 完整地址字符串,如:山西省太原市迎泽区庙前街道劲松北路9号院 * @returns {Object|null} 解析后的地址信息 */ export const parseAddress = (fullAddress) => { if (!fullAddress || typeof fullAddress !== 'string') { console.warn('地址不能为空且必须为字符串'); return null; } // 定义省市区关键词 const provinceKeywords = /省|自治区|特别行政区/; const cityKeywords = /市|自治州|地区|盟/; const districtKeywords = /区|县|旗|自治县|自治旗|特区|林区/; // 1. 解析省份 const provinceEndIndex = fullAddress.search(provinceKeywords); if (provinceEndIndex === -1) { // 处理直辖市情况 const cityStartIndex = fullAddress.search(cityKeywords); if (cityStartIndex === -1) { console.warn('无法识别省份或城市'); return null; } // 直辖市情况:如北京市海淀区 const province = fullAddress.substring(0, cityStartIndex + 1); const city = province; // 解析区县 const districtEndIndex = fullAddress.search(districtKeywords); if (districtEndIndex === -1) { console.warn('无法识别区县'); return null; } const district = fullAddress.substring(city.length, districtEndIndex + 1); const street = fullAddress.substring(districtEndIndex + 1).trim(); return { province, city, district, street: street || undefined }; } // 2. 解析城市 const province = fullAddress.substring(0, provinceEndIndex + 1); const remainingAfterProvince = fullAddress.substring(provinceEndIndex + 1); const cityEndIndex = remainingAfterProvince.search(cityKeywords); if (cityEndIndex === -1) { console.warn('无法识别城市'); return null; } const city = remainingAfterProvince.substring(0, cityEndIndex + 1); const remainingAfterCity = remainingAfterProvince.substring(cityEndIndex + 1); // 3. 解析区县 const districtEndIndex = remainingAfterCity.search(districtKeywords); if (districtEndIndex === -1) { console.warn('无法识别区县'); return null; } const district = remainingAfterCity.substring(0, districtEndIndex + 1); const street = remainingAfterCity.substring(districtEndIndex + 1).trim(); return { province, city, district, street: street || undefined }; }; /** * 仅获取省份名称 * @param {string} fullAddress 完整地址字符串 * @returns {string|null} 省份名称 */ export const getProvince = (fullAddress) => { const result = parseAddress(fullAddress); return result?.province || null; }; /** * 仅获取城市名称 * @param {string} fullAddress 完整地址字符串 * @returns {string|null} 城市名称 */ export const getCity = (fullAddress) => { const result = parseAddress(fullAddress); return result?.city || null; }; /** * 仅获取区县名称 * @param {string} fullAddress 完整地址字符串 * @returns {string|null} 区县名称 */ export const getDistrict = (fullAddress) => { const result = parseAddress(fullAddress); return result?.district || null; }; /** * 获取解析后的省市区数组(用于回显) * @param {string} fullAddress 完整地址字符串 * @returns {Array} 省市区数组 */ export const getAddressTree = (fullAddress) => { const result = parseAddress(fullAddress); if (!result) return []; return [result.province, result.city, result.district]; }; /** * 递归查找城市名称对应的areaCode * @param {string} cityName 城市名称 * @param {Array} areaTree 省市区联级列表数据 * @returns {string} 匹配到的areaCode,匹配不到返回空字符串 */ export const findCityCodeByCname = (cityName, areaTree) => { // 边界条件检查 if (!cityName || !areaTree || !Array.isArray(areaTree)) { return ''; } // 遍历当前层级 for (const area of areaTree) { // 匹配到城市名称,返回areaCode if (area.areaCname == cityName) { return area.areaCode; } // 如果有子节点,递归查找 if (area.children && area.children.length > 0) { const foundCode = findCityCodeByCname(cityName, area.children); if (foundCode) { return foundCode; } } } // 所有节点都遍历完,没有匹配到 return ''; }; // Vue 2 插件形式 const AddressParserPlugin = { install(Vue) { Vue.prototype.$parseAddress = parseAddress; Vue.prototype.$getProvince = getProvince; Vue.prototype.$getCity = getCity; Vue.prototype.$getDistrict = getDistrict; Vue.prototype.$getAddressTree = getAddressTree; Vue.prototype.$findCityCodeByCname = findCityCodeByCname; } }; // 如果是在浏览器环境下直接使用 if (typeof window !== 'undefined' && window.Vue) { window.Vue.use(AddressParserPlugin); } // 导出插件形式 export default AddressParserPlugin;