From 92d034e0e124928179f072224e9c2c1ad87fc1b2 Mon Sep 17 00:00:00 2001
From: Tevin <tingquanren@163.com>
Date: Mon, 31 Jul 2023 11:43:45 +0800
Subject: [PATCH] 地址联动组件升级,支持第四级街道,数据采用异步

---
 forms/chinaArea/CChinaArea.vue |  135 ++++++++++++++++++++++++++++++---------------
 1 files changed, 90 insertions(+), 45 deletions(-)

diff --git a/forms/chinaArea/CChinaArea.vue b/forms/chinaArea/CChinaArea.vue
index 8a71fb5..c5e80d7 100644
--- a/forms/chinaArea/CChinaArea.vue
+++ b/forms/chinaArea/CChinaArea.vue
@@ -6,6 +6,7 @@
 <template>
     <view class="c-china-area">
         <picker
+            class="c-china-area-picker"
             mode="multiSelector"
             :range="range"
             :value="current"
@@ -33,10 +34,10 @@
 <script>
 import Taro from '@tarojs/taro';
 import { AtInput, AtIcon } from 'taro-ui-vue';
-import ChinaLocations from './ChinaLocations';
+import { $locations } from '@components/forms/chinaArea/ChinaLocations';
 import './cChinaArea.scss';
 
-const { onReady, getLocationTree, getRegionNames, getRegionCodes } = ChinaLocations;
+const { getRegionNames, getRegionCodes } = $locations;
 
 export default {
     name: 'CChinaArea',
@@ -52,21 +53,26 @@
             type: Boolean,
             default: false,
         },
+        // 联动级别
+        level: {
+            type: Number,
+            default: 3,
+        },
         // 占位提示
         placeholder: String,
     },
     data() {
         return {
             loading: false,
-            range: [[], [], []],
-            current: [0, 0, 0],
+            range: [],
+            current: [],
         };
     },
     computed: {
         selected() {
             const curVal = this.itemRes.formData[this.itemRes.name];
-            if (curVal && curVal.length === 3) {
-                return getRegionNames(curVal).filter(Boolean).join(' / ');
+            if (curVal && (curVal.length === 3 || curVal.length === 4)) {
+                return curVal.join(' / ');
             } else {
                 return '';
             }
@@ -81,7 +87,7 @@
                     return;
                 }
             }
-            const locationTree = getLocationTree();
+            const locationTree = $locations.getLocationTree(this.level);
             const curVal = this.itemRes.formData[this.itemRes.name];
             const range = [
                 locationTree,
@@ -89,6 +95,10 @@
                 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) {
                 // 省
@@ -111,11 +121,20 @@
                             }
                             // 区
                             if (curVal[2]) {
-                                const areaIndex = range[2].findIndex(
-                                    area => area.value === curVal[2]
+                                const distIndex = range[2].findIndex(
+                                    dist => dist.value === curVal[2]
                                 );
-                                if (areaIndex >= 0) {
-                                    current[2] = areaIndex;
+                                if (distIndex >= 0) {
+                                    current[2] = distIndex;
+                                }
+                                // 街
+                                if (this.level === 4 && curVal[3]) {
+                                    const streetIndex = range[3].findIndex(
+                                        street => street.value === curVal[3]
+                                    );
+                                    if (streetIndex >= 0) {
+                                        current[3] = streetIndex;
+                                    }
                                 }
                             }
                         }
@@ -126,34 +145,62 @@
             this.current = current;
         },
         updateColumns(roll) {
-            const locationTree = getLocationTree();
+            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, '');
+                }
             }
             // 第二列滚动
             else if (roll.column === 1) {
-                const areas = locationTree[this.current[0]].children[roll.value].children;
-                this.range = [this.range[0], this.range[1], areas];
+                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 === 3) {
+            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);
             }
         },
         handleChange(detail) {
-            const locationTree = getLocationTree();
-            const codes = [];
+            const locationTree = $locations.getLocationTree(this.level);
+            const names = [];
             const provice = locationTree[detail[0]];
-            codes[0] = provice.value;
-            const city = provice.children[detail[1]] || [];
-            codes[1] = city.value;
-            const area = city.children[detail[2]] || [];
-            codes[2] = area.value;
-            this.itemRes.onChange(codes);
+            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);
         },
         _getGeoLocation() {
             this.loading = true;
@@ -187,31 +234,29 @@
         },
     },
     mounted() {
-        if (process.env.TARO_ENV === 'weapp') {
-            onReady(() => {
-                this.handleOpen();
-            });
-        }
-        // 开启自动定位时,延迟 0.1 秒后发起定位
-        if (this.autoGeo) {
-            if (process.env.TARO_ENV === 'weapp') {
-                setTimeout(() => {
-                    // TODO:小程序中定位
-                }, 100);
-            } else if (process.env.TARO_ENV === 'h5') {
-                if (typeof wx === 'undefined') {
-                    console.warn('无法进行地理位置定位,wx 不存在!');
-                    return;
-                }
-                wx.ready(() => {
-                    if (typeof BMap === 'undefined') {
-                        console.warn('无法进行地理位置定位,BMap 不存在!');
+        $locations.onReady(() => {
+            this.handleOpen();
+            // 开启自动定位时,延迟 0.1 秒后发起定位
+            if (this.autoGeo) {
+                if (process.env.TARO_ENV === 'weapp') {
+                    setTimeout(() => {
+                        // TODO:小程序中定位
+                    }, 100);
+                } else if (process.env.TARO_ENV === 'h5') {
+                    if (typeof wx === 'undefined') {
+                        console.warn('无法进行地理位置定位,wx 不存在!');
                         return;
                     }
-                    this._getGeoLocation();
-                });
+                    wx.ready(() => {
+                        if (typeof BMap === 'undefined') {
+                            console.warn('无法进行地理位置定位,BMap 不存在!');
+                            return;
+                        }
+                        this._getGeoLocation();
+                    });
+                }
             }
-        }
+        });
     },
 };
 </script>
\ No newline at end of file

--
Gitblit v1.9.1