MrShi
14 小时以前 44363d47ed8e2bc0a649833692d47740a877b49e
mini-program/pages/select-city/select-city.vue
@@ -1,40 +1,157 @@
<template>
   <view class="box">
      <view class="box-search">
         <u-search placeholder="搜索商品" height="30" searchIconColor="#999999" borderColor="#eeeeee"
            bgColor="#F9F9FB" :showAction="false" v-model="keyword" />
      </view>
      <view class="box-city">
         <view class="box-city-left">
            <image src="/static/logo.png" mode="widthFix"></image>
            <text>合肥</text>
      <view class="head">
         <view class="box-search">
            <u-search placeholder="输入城市名称或拼音" height="30" searchIconColor="#999999" borderColor="#eeeeee" bgColor="#F9F9FB"
               :showAction="false" v-model="name" @search="getCity" />
         </view>
         <view class="box-city-right">重新定位</view>
         <view class="box-city">
            <view class="box-city-left">
               <image src="/static/icon/ic_city@2x.png" mode="widthFix"></image>
               <text>{{cityName}}</text>
            </view>
            <view class="box-city-right" @click="checkLocationAuth">重新定位</view>
         </view>
      </view>
      <view class="list">
         <view class="list-item">
            <view class="list-item-val" style="color: #999;">A</view>
         </view>
         <view class="list-item">
            <view class="list-item-val">阿克苏</view>
         <view class="list-item" :id="'jiedan-' + item.letter" v-for="(item, index) in list" :key="index">
            <view class="list-item-val" style="color: #999;">{{item.letter}}</view>
            <view class="list-item1" v-for="(child, i) in item.children" :key="i" @click="seleCity(child.name)">
               <view class="list-item-val1">{{child.name}}</view>
            </view>
         </view>
      </view>
      <view class="tips">
         <view class="tips-row active">A</view>
         <view class="tips-row">B</view>
         <view class="tips-row">C</view>
         <view class="tips-row">D</view>
         <view class="tips-row">E</view>
         <view :class="index === a ? 'tips-row active' : 'tips-row'" v-for="(item, a) in list" :key="a" @click="gundong(a)">{{item.letter}}</view>
      </view>
   </view>
</template>
<script>
   var QQMapWX = require('@/utils/qqmap-wx-jssdk.js')
   export default {
      data() {
         return {
            keyword: ''
            name: '',
            index: 0,
            list: [],
            cityName: ''
         };
      },
      onLoad() {
         this.getCity()
         this.checkLocationAuth()
      },
      methods: {
         checkLocationAuth() {
             uni.getSetting({
                 success: (res) => {
                     if (!res.authSetting['scope.userLocation']) {
                         uni.authorize({
                             scope: 'scope.userLocation',
                             success: () => {
                                 this.positioning()
                             },
                             fail: () => {
                                 uni.showModal({
                                     title: '提示',
                                     content: '需要获取您的位置信息,请在设置中开启位置权限',
                                     confirmText: '去设置',
                                     success: (res) => {
                                         if (res.confirm) {
                                             this.goToAppSetting();
                                         }
                                     }
                                 });
                             }
                         });
                     } else {
                         this.positioning()
                     }
                 }
             });
         },
         goToAppSetting() {
            var that = this;
             uni.openSetting({
                 success: (res) => {
                  if (res.authSetting['scope.userLocation']) {
                     that.positioning()
                  }
                 }
             });
         },
         // 定位
         positioning() {
            var that = this;
            uni.getLocation({
               type: 'gcj02',
               highAccuracyExpireTime: 3000,
               isHighAccuracy: true,
               success: function (addr) {
                  const locParam = { latitude: addr.latitude, longitude: addr.longitude };
                  const qqmapsdk = new QQMapWX({
                     key: 'HEIBZ-QJLLM-SZ36X-6ZBHI-S6Y2J-S6FND'
                  });
                  qqmapsdk.reverseGeocoder({
                     locParam,
                     success: function(res) {
                        console.log(res.result.ad_info.city);
                        that.cityName = res.result.ad_info.city
                     },
                     fail: (err) => {
                        console.error('获取位置失败===========', err);
                     }
                  });
               }
            });
         },
         seleCity(city) {
            uni.$emit('city', city)
            uni.navigateBack({ delta: 1 });
         },
         gundong(index) {
            this.index = index
            uni.pageScrollTo({
               selector: '#jiedan-' + this.list[index].letter, // 支持 ID 选择器、Class 选择器等 [citation:1]
               duration: 300, // 动画时长,单位毫秒,默认300ms
               offsetTop: -100, // 偏移距离,可以让滚动后元素距离顶部有一段距离 [citation:2]
            });
         },
         getCity() {
            this.$u.api.getCityInfoList({
               type: 1,
               cityName: this.name
            }).then(res => {
               if (res.code === 200) {
                  this.list = this.groupByFirstSpell(res.data)
               }
            })
         },
         groupByFirstSpell(arr) {
            // 使用 Map 来暂存分组结果,键为 firstSpell,值为对象数组
            const map = new Map();
            arr.forEach(item => {
               const key = item.firstSpell;
               if (!map.has(key)) {
                  map.set(key, []);
               }
               map.get(key).push(item);
            });
            // 将 Map 转换为父子结构的数组
            const result = [];
            for (let [key, children] of map.entries()) {
               result.push({
                  letter: key, // 分组字段,可根据实际需求改名
                  children: children
               });
            }
            return result;
         }
      }
   }
</script>
@@ -42,18 +159,21 @@
<style lang="scss" scoped>
   .box {
      width: 100%;
      padding: 30rpx;
      padding: 0 30rpx 30rpx 30rpx;
      box-sizing: border-box;
      .tips {
         position: fixed;
         right: 20rpx;
         top: 50%;
         transform: translate(-50%, 0);
         transform: translate(0, -50%);
         display: flex;
         flex-direction: column;
         .active {
            color: #004096 !important;
         }
         .tips-row {
            font-weight: 400;
            font-size: 22rpx;
@@ -61,54 +181,85 @@
            margin-bottom: 10rpx;
         }
      }
      .list {
         width: 100%;
         margin-top: 54rpx;
         margin-top: 20rpx;
         .list-item {
            width: 100%;
            height: 100rpx;
            display: flex;
            align-items: center;
            border-bottom: 1rpx solid #E5E5E5;
            flex-direction: column;
            .list-item-val {
               font-weight: 400;
               font-size: 30rpx;
               color: #333333;
               height: 100rpx;
               line-height: 100rpx;
               border-bottom: 1rpx solid #E5E5E5;
            }
            .list-item1 {
               width: 100%;
               height: 100rpx;
               line-height: 100rpx;
               display: flex;
               flex-direction: column;
               border-bottom: 1rpx solid #E5E5E5;
               .list-item-val1 {
                  font-weight: 400;
                  font-size: 30rpx;
                  color: #333333;
               }
            }
         }
      }
      .box-search {
      .head {
         width: 100%;
         padding: 30rpx 0;
         box-sizing: border-box;
         position: sticky;
         top: 0;
         left: 0;
         z-index: 999;
         background-color: #ffffff;
      }
      .box-city {
         width: 100%;
         display: flex;
         align-items: center;
         justify-content: space-between;
         margin-top: 40rpx;
         .box-city-left {
         .box-search {
            width: 100%;
         }
         .box-city {
            width: 100%;
            display: flex;
            align-items: center;
            image {
               width: 28rpx;
               height: 28rpx;
               margin-right: 20rpx;
            justify-content: space-between;
            margin-top: 40rpx;
            .box-city-left {
               display: flex;
               align-items: center;
               image {
                  width: 36rpx;
                  height: 36rpx;
                  margin-right: 20rpx;
               }
               text {
                  font-weight: 500;
                  font-size: 30rpx;
                  color: #222222;
               }
            }
            text {
               font-weight: 500;
               font-size: 30rpx;
               color: #222222;
            .box-city-right {
               font-weight: 400;
               font-size: 28rpx;
               color: #004096;
            }
         }
         .box-city-right {
            font-weight: 400;
            font-size: 28rpx;
            color: #004096;
         }
      }
   }