From 6379d7a81d8fb8417977d40031cf587d50f69812 Mon Sep 17 00:00:00 2001
From: Tevin <tingquanren@163.com>
Date: Mon, 31 Jul 2023 17:15:08 +0800
Subject: [PATCH] 地址联动组件再优化,所有方法都改用异步回调

---
 forms/chinaArea/ChinaLocations.js |  211 +++++++++++++------------
 forms/chinaArea/CChinaArea.vue    |  227 +++++++++++++++-------------
 2 files changed, 228 insertions(+), 210 deletions(-)

diff --git a/forms/chinaArea/CChinaArea.vue b/forms/chinaArea/CChinaArea.vue
index c5e80d7..c329e5e 100644
--- a/forms/chinaArea/CChinaArea.vue
+++ b/forms/chinaArea/CChinaArea.vue
@@ -37,8 +37,6 @@
 import { $locations } from '@components/forms/chinaArea/ChinaLocations';
 import './cChinaArea.scss';
 
-const { getRegionNames, getRegionCodes } = $locations;
-
 export default {
     name: 'CChinaArea',
     components: {
@@ -63,7 +61,7 @@
     },
     data() {
         return {
-            loading: false,
+            loading: true,
             range: [],
             current: [],
         };
@@ -87,120 +85,129 @@
                     return;
                 }
             }
-            const locationTree = $locations.getLocationTree(this.level);
-            const curVal = this.itemRes.formData[this.itemRes.name];
-            const range = [
-                locationTree,
-                locationTree[0].children,
-                locationTree[0].children[0].children,
-            ];
-            const current = [0, 0, 0];
-            if (this.level === 4) {
-                range[3] = locationTree[0].children[0].children[0].children;
-                current[3] = '';
-            }
-            // 有值
-            if (curVal && curVal.length > 0) {
-                // 省
-                if (curVal[0]) {
-                    const proviceIndex = locationTree.findIndex(
-                        provice => provice.value === curVal[0]
-                    );
-                    if (proviceIndex >= 0) {
-                        range[1] = locationTree[proviceIndex].children;
-                        range[2] = locationTree[proviceIndex].children[0].children;
-                        current[0] = proviceIndex;
-                        // 市
-                        if (curVal[1]) {
-                            const cityIndex = range[1].findIndex(
-                                city => city.value === curVal[1]
+            $locations.getLocationTree(this.level, locationTree => {
+                const curVal = this.itemRes.formData[this.itemRes.name];
+                const range2 = (locationTree[0] || {}).children || [];
+                const range3 = (range2[0] || {}).children || [];
+                const range = [locationTree, range2, range3];
+                const current = [0, 0, 0];
+                if (this.level === 4) {
+                    const range4 = (range3[0] || {}).children || [];
+                    range[3] = range4;
+                    current[3] = '';
+                }
+                // 有值
+                if (curVal && curVal.length > 0) {
+                    $locations.getRegionCodes(curVal, codes => {
+                        // 省
+                        if (codes[0]) {
+                            const proviceIndex = locationTree.findIndex(
+                                provice => provice.value === codes[0]
                             );
-                            if (cityIndex >= 0) {
-                                range[2] = range[1][cityIndex].children;
-                                current[1] = cityIndex;
-                            }
-                            // 区
-                            if (curVal[2]) {
-                                const distIndex = range[2].findIndex(
-                                    dist => dist.value === curVal[2]
-                                );
-                                if (distIndex >= 0) {
-                                    current[2] = distIndex;
-                                }
-                                // 街
-                                if (this.level === 4 && curVal[3]) {
-                                    const streetIndex = range[3].findIndex(
-                                        street => street.value === curVal[3]
+                            if (proviceIndex >= 0) {
+                                range[1] = locationTree[proviceIndex].children;
+                                range[2] =
+                                    locationTree[proviceIndex].children[0].children;
+                                current[0] = proviceIndex;
+                                // 市
+                                if (codes[1]) {
+                                    const cityIndex = range[1].findIndex(
+                                        city => city.value === codes[1]
                                     );
-                                    if (streetIndex >= 0) {
-                                        current[3] = streetIndex;
+                                    if (cityIndex >= 0) {
+                                        range[2] = range[1][cityIndex].children;
+                                        current[1] = cityIndex;
+                                    }
+                                    // 区
+                                    if (codes[2]) {
+                                        const distIndex = range[2].findIndex(
+                                            dist => dist.value === codes[2]
+                                        );
+                                        if (distIndex >= 0) {
+                                            current[2] = distIndex;
+                                        }
+                                        // 街
+                                        if (this.level === 4 && codes[3]) {
+                                            if (distIndex >= 0) {
+                                                range[3] =
+                                                    range[2][distIndex].children || [];
+                                                const streetIndex = range[3].findIndex(
+                                                    street => street.value === codes[3]
+                                                );
+                                                if (streetIndex >= 0) {
+                                                    current[3] = streetIndex;
+                                                }
+                                            }
+                                        }
                                     }
                                 }
                             }
                         }
-                    }
+                    });
                 }
-            }
-            this.range = range;
-            this.current = current;
+                this.range = range;
+                this.current = current;
+            });
         },
         updateColumns(roll) {
-            const locationTree = $locations.getLocationTree(this.level);
-            // 第一列滚动
-            if (roll.column === 0) {
-                const cities = locationTree[roll.value].children;
-                this.range = [this.range[0], cities, cities[0].children];
-                this.current = [roll.value, 0, 0];
-                if (this.level === 4) {
-                    const range3 = (cities[0].children[0] || {}).children || [];
-                    this.range.splice(3, 1, range3);
-                    this.current.splice(3, 1, '');
+            $locations.getLocationTree(this.level, locationTree => {
+                // 第一列滚动
+                if (roll.column === 0) {
+                    const cities = locationTree[roll.value].children;
+                    this.range = [this.range[0], cities, cities[0].children];
+                    this.current = [roll.value, 0, 0];
+                    if (this.level === 4) {
+                        const range3 = (cities[0].children[0] || {}).children || [];
+                        this.range.splice(3, 1, range3);
+                        this.current.splice(3, 1, '');
+                    }
                 }
-            }
-            // 第二列滚动
-            else if (roll.column === 1) {
-                const dists = locationTree[this.current[0]].children[roll.value].children;
-                this.range = [this.range[0], this.range[1], dists];
-                this.current = [this.current[0], roll.value, 0];
-                if (this.level === 4) {
-                    const range3 = dists[0].children || [];
-                    this.range.splice(3, 1, range3);
-                    this.current.splice(3, 1, '');
+                // 第二列滚动
+                else if (roll.column === 1) {
+                    const dists =
+                        locationTree[this.current[0]].children[roll.value].children;
+                    this.range = [this.range[0], this.range[1], dists];
+                    this.current = [this.current[0], roll.value, 0];
+                    if (this.level === 4) {
+                        const range3 = dists[0].children || [];
+                        this.range.splice(3, 1, range3);
+                        this.current.splice(3, 1, '');
+                    }
                 }
-            }
-            // 第三列滚动
-            else if (roll.column === 2) {
-                this.current.splice(2, 1, roll.value);
-                if (this.level === 4) {
-                    const streets =
-                        locationTree[this.current[0]].children[this.current[1]].children[
-                            roll.value
-                        ].children || [];
-                    this.range.splice(3, 1, streets);
-                    this.current.splice(3, 1, '');
+                // 第三列滚动
+                else if (roll.column === 2) {
+                    this.current.splice(2, 1, roll.value);
+                    if (this.level === 4) {
+                        const streets =
+                            locationTree[this.current[0]].children[this.current[1]]
+                                .children[roll.value].children || [];
+                        this.range.splice(3, 1, streets);
+                        this.current.splice(3, 1, '');
+                    }
                 }
-            }
-            // 第四列滚动
-            else if (roll.column === 3) {
-                this.current.splice(3, 1, roll.value);
-            }
+                // 第四列滚动
+                else if (roll.column === 3) {
+                    this.current.splice(3, 1, roll.value);
+                }
+            });
         },
         handleChange(detail) {
-            const locationTree = $locations.getLocationTree(this.level);
-            const names = [];
-            const provice = locationTree[detail[0]];
-            names[0] = provice.label;
-            const city = provice.children[detail[1]] || {};
-            names[1] = city.label;
-            const dist = city.children[detail[2]] || {};
-            names[2] = dist.label;
-            if (this.level === 4) {
-                const street = (dist.children || [])[detail[3]] || {};
-                if (street.value) {
-                    names[3] = street.label;
+            $locations.getLocationTree(this.level, locationTree => {
+                const names = [];
+                const provice = locationTree[detail[0]];
+                names[0] = provice.label;
+                const city = provice.children[detail[1]] || {};
+                names[1] = city.label;
+                const dist = city.children[detail[2]] || {};
+                names[2] = dist.label;
+                if (this.level === 4) {
+                    const street = (dist.children || [])[detail[3]] || {};
+                    if (street.value) {
+                        names[3] = street.label;
+                    }
                 }
-            }
-            this.itemRes.onChange(names);
+                this.itemRes.onChange(names);
+            });
         },
         _getGeoLocation() {
             this.loading = true;
@@ -217,14 +224,19 @@
                             return;
                         }
                         const address = result.addressComponents;
-                        const codes = getRegionCodes([
+                        const regions = [
                             address.province.replace(/省|市|自治区|特别行政区/g, ''),
                             address.city,
                             address.district,
-                        ]);
-                        if (codes && codes.length > 0) {
-                            this.itemRes.onChange(codes);
-                        }
+                            address.street,
+                        ];
+                        $locations.getRegionCodes(regions, codes => {
+                            if (codes && codes.length > 0) {
+                                $locations.getRegionNames(codes, names => {
+                                    this.itemRes.onChange(names);
+                                });
+                            }
+                        });
                         this.loading = false;
                     });
                 },
@@ -235,6 +247,7 @@
     },
     mounted() {
         $locations.onReady(() => {
+            this.loading = false;
             this.handleOpen();
             // 开启自动定位时,延迟 0.1 秒后发起定位
             if (this.autoGeo) {
diff --git a/forms/chinaArea/ChinaLocations.js b/forms/chinaArea/ChinaLocations.js
index b2e6c4e..ff1efb2 100644
--- a/forms/chinaArea/ChinaLocations.js
+++ b/forms/chinaArea/ChinaLocations.js
@@ -11,7 +11,7 @@
 let locationTreeLv3 = [];
 let locationTreeLv4 = [];
 let locationRes = {};
-let readyCallback = () => { };
+let readyCallbacks = [];
 
 Taro.request({
     url: $hostBoot.getHost() + project.host.assetsPath + '/datas/ChinaLocations.lv4.min.json',
@@ -26,7 +26,7 @@
     method: 'GET',
     success: response => {
         locationRes = response.data;
-        readyCallback();
+        readyCallbacks.forEach(callback => callback());
     }
 });
 
@@ -34,7 +34,7 @@
 
     onReady(callback) {
         if (Tools.isEmptyObject(locationRes)) {
-            readyCallback = callback;
+            readyCallbacks.push(callback);
         } else {
             callback();
         }
@@ -100,138 +100,143 @@
         return treeDatas;
     }
 
-    getLocationTree(level) {
-        if (level === 3) {
-            if (locationTreeLv3.length === 0) {
-                locationTreeLv3 = this._createLocationTree(3);
+    getLocationTree(level, callback) {
+        this.onReady(() => {
+            if (level === 3) {
+                if (locationTreeLv3.length === 0) {
+                    locationTreeLv3 = this._createLocationTree(3);
+                }
+                callback(locationTreeLv3);
+            } else if (level === 4) {
+                if (locationTreeLv4.length === 0) {
+                    locationTreeLv4 = this._createLocationTree(4);
+                }
+                callback(locationTreeLv4);
             }
-            return locationTreeLv3;
-        } else if (level === 4) {
-            if (locationTreeLv4.length === 0) {
-                locationTreeLv4 = this._createLocationTree(4);
-            }
-            return locationTreeLv4;
-        }
+        });
     }
 
     // 获取省市区拼合文本
     getRegionText(regions, callback) {
-        if (regions.length === 0) {
-            return '';
-        }
-        let address = '';
-        let tempLocationData = locationRes;
-        regions.forEach((code) => {
-            if (!code || !tempLocationData[code]) {
-                address.push('');
-                tempLocationData = [];
-            } else {
-                if (typeof tempLocationData[code].name === 'string') {
-                    address += tempLocationData[code].name;
-                } else {
-                    address += tempLocationData[code];
-                }
-                tempLocationData = tempLocationData[code].children;
-            }
+        this.getRegionNames(regions, address => {
+            callback(address.join(''));
         });
-        return address;
     }
 
     // 省市区名称
     getRegionNames(regions, callback) {
-        if (typeof regions === 'string') {
-            regions = regions.split(',');
-        }
-        if (!regions || regions.length === 0 || !regions[0]) {
-            return [];
-        }
-        let address = [];
-        let tempLocationData = locationRes;
-        regions.forEach((code) => {
-            if (!code || !tempLocationData[code]) {
-                address.push('');
-                tempLocationData = [];
-            } else {
-                if (typeof tempLocationData[code].name === 'string') {
-                    address.push(tempLocationData[code].name);
-                } else {
-                    address.push(tempLocationData[code]);
-                }
-                tempLocationData = tempLocationData[code].children;
+        this.onReady(() => {
+            if (typeof regions === 'string') {
+                regions = regions.split(',');
             }
+            if (!regions || regions.length === 0 || !regions[0]) {
+                callback([]);
+            }
+            let address = [];
+            let tempLocationData = locationRes;
+            regions.forEach((code) => {
+                if (!code || !tempLocationData[code]) {
+                    address.push('');
+                    tempLocationData = [];
+                } else {
+                    if (typeof tempLocationData[code].name === 'string') {
+                        address.push(tempLocationData[code].name);
+                    } else {
+                        address.push(tempLocationData[code]);
+                    }
+                    tempLocationData = tempLocationData[code].children;
+                }
+            });
+            callback(address);
         });
-        return address;
     }
 
     // 省市区文本转code
     getRegionCodes(regions, callback) {
-        if (typeof regions === 'string') {
-            regions = regions.split(',');
-        }
-        if (!regions || regions.length === 0 || !regions[0]) {
-            return '';
-        }
-        const codes = [];
-        // 省
-        for (let provinceCode in locationRes) {
-            if (locationRes.hasOwnProperty(provinceCode)) {
-                if (locationRes[provinceCode].name === regions[0]) {
-                    codes[0] = provinceCode;
-                    // 市
-                    const provinceChildren = locationRes[provinceCode].children;
-                    for (let cityCode in provinceChildren) {
-                        if (provinceChildren.hasOwnProperty(cityCode)) {
-                            if (provinceChildren[cityCode].name === regions[1]) {
-                                codes[1] = cityCode;
-                                // 区
-                                const areaChildren = provinceChildren[cityCode].children || [];
-                                for (let areaCode in areaChildren) {
-                                    if (areaChildren.hasOwnProperty(areaCode)) {
-                                        if (areaChildren[areaCode] === regions[2]) {
-                                            codes[2] = areaCode;
-                                            break;
+        this.onReady(() => {
+            if (typeof regions === 'string') {
+                regions = regions.split(',');
+            }
+            if (!regions || regions.length === 0 || !regions[0]) {
+                callback([]);
+            }
+            const codes = [];
+            // 省
+            for (let provinceCode in locationRes) {
+                if (locationRes.hasOwnProperty(provinceCode)) {
+                    if (locationRes[provinceCode].name === regions[0]) {
+                        codes[0] = provinceCode;
+                        // 市
+                        const provinceContainer = locationRes[provinceCode].children;
+                        for (let cityCode in provinceContainer) {
+                            if (provinceContainer.hasOwnProperty(cityCode)) {
+                                if (provinceContainer[cityCode].name === regions[1]) {
+                                    codes[1] = cityCode;
+                                    // 区
+                                    const distContainer = provinceContainer[cityCode].children;
+                                    for (let distCode in distContainer) {
+                                        if (distContainer.hasOwnProperty(distCode)) {
+                                            if (distContainer[distCode] === regions[2]) {
+                                                codes[2] = distCode;
+                                                break;
+                                            }
+                                            if (distContainer[distCode].name === regions[2]) {
+                                                codes[2] = distCode;
+                                                // 如果存在街道,继续转街道
+                                                if (regions[3]) {
+                                                    const streetContainer = distContainer[distCode].children;
+                                                    Object.keys(streetContainer).forEach(streetCode => {
+                                                        if (streetContainer[streetCode] === regions[3]) {
+                                                            codes[3] = streetCode;
+                                                        }
+                                                    });
+                                                }
+                                                break;
+                                            }
                                         }
                                     }
+                                    break;
                                 }
-                                break;
                             }
                         }
+                        break;
                     }
-                    break;
                 }
             }
-        }
-        return codes;
+            callback(codes);
+        });
     }
 
     // 电话区码
-    getRegionsArea(regions) {
-        if (typeof regions === 'string') {
-            regions = regions.split(',');
-        }
-        if (!regions || regions.length === 0 || !regions[0]) {
-            return '';
-        }
-        let area = '';
-        // 省
-        for (let provinceCode in locationRes) {
-            if (locationRes.hasOwnProperty(provinceCode)) {
-                if (provinceCode === regions[0]) {
-                    // 市
-                    const provinceChildren = locationRes[provinceCode].children;
-                    for (let cityCode in provinceChildren) {
-                        if (provinceChildren.hasOwnProperty(cityCode)) {
-                            if (cityCode === regions[1]) {
-                                area = provinceChildren[cityCode].area;
-                                break;
+    getRegionsArea(regions, callback) {
+        this.onReady(() => {
+            if (typeof regions === 'string') {
+                regions = regions.split(',');
+            }
+            if (!regions || regions.length === 0 || !regions[0]) {
+                callback('');
+            }
+            let area = '';
+            // 省
+            for (let provinceCode in locationRes) {
+                if (locationRes.hasOwnProperty(provinceCode)) {
+                    if (provinceCode === regions[0]) {
+                        // 市
+                        const provinceChildren = locationRes[provinceCode].children;
+                        for (let cityCode in provinceChildren) {
+                            if (provinceChildren.hasOwnProperty(cityCode)) {
+                                if (cityCode === regions[1]) {
+                                    area = provinceChildren[cityCode].area;
+                                    break;
+                                }
                             }
                         }
+                        break;
                     }
-                    break;
                 }
             }
-        }
-        return area;
+            callback(area);
+        });
     }
 };
 

--
Gitblit v1.9.1