<template>
|
<view class="box">
|
<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">
|
<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" :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="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 {
|
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>
|
|
<style lang="scss" scoped>
|
.box {
|
width: 100%;
|
padding: 0 30rpx 30rpx 30rpx;
|
box-sizing: border-box;
|
|
.tips {
|
position: fixed;
|
right: 20rpx;
|
top: 50%;
|
transform: translate(0, -50%);
|
display: flex;
|
flex-direction: column;
|
|
.active {
|
color: #004096 !important;
|
}
|
|
.tips-row {
|
font-weight: 400;
|
font-size: 22rpx;
|
color: #333333;
|
margin-bottom: 10rpx;
|
}
|
}
|
|
.list {
|
width: 100%;
|
margin-top: 20rpx;
|
|
.list-item {
|
width: 100%;
|
display: flex;
|
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;
|
}
|
}
|
}
|
}
|
|
.head {
|
width: 100%;
|
padding: 30rpx 0;
|
box-sizing: border-box;
|
position: sticky;
|
top: 0;
|
left: 0;
|
z-index: 999;
|
background-color: #ffffff;
|
|
.box-search {
|
width: 100%;
|
}
|
|
.box-city {
|
width: 100%;
|
display: flex;
|
align-items: center;
|
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;
|
}
|
}
|
|
.box-city-right {
|
font-weight: 400;
|
font-size: 28rpx;
|
color: #004096;
|
}
|
}
|
}
|
}
|
</style>
|