305 lines
7.6 KiB
Vue
305 lines
7.6 KiB
Vue
<template>
|
|
<view class="city-select-page">
|
|
<view class="white_container padding_bottom40">
|
|
<!-- 搜索框 -->
|
|
<u-search placeholder="输入城市进行搜索" :value="searchValue" @search="handleSearch" @change="handleSearch"
|
|
:showAction=false height="70" searchIconSize="40" shape="round"></u-search>
|
|
<view v-if="searchValue" class="search_popup">
|
|
<view v-for="(item, index) in searchRes" :key="index"
|
|
:class="['list-item', index === searchRes.length - 1 && 'no_border']"
|
|
@click="headerSelectMapClick(item)">
|
|
{{ item.name }}
|
|
</view>
|
|
</view>
|
|
<view v-if="!searchValue">
|
|
<!-- 当前定位城市 -->
|
|
<view class="current-city">
|
|
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/Index_add.png" mode="widthFix" />
|
|
<text>当前定位城市 {{ location.cityName }}</text>
|
|
</view>
|
|
|
|
<!-- 国内热门城市 -->
|
|
<view class="hot-cities">
|
|
<text class="title">国内热门城市</text>
|
|
<view class="city-list">
|
|
<view v-for="(item, index) in hotCities" class="city_name" :key="index"
|
|
@click="headerSelectMapClick(item)">{{ item }}</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
</view>
|
|
|
|
|
|
|
|
<view v-if="!searchValue" class="container">
|
|
<!-- 左侧列表 -->
|
|
<scroll-view class="list-scroll" scroll-y :scroll-into-view="activeId" @scroll="handleScroll">
|
|
<view v-for="(group, index) in groupedData" :key="index" class="white_container"
|
|
:id="'group-' + group.letter">
|
|
<!-- 字母标题 -->
|
|
<view class="letter-title">{{ group.letter }}</view>
|
|
<!-- 列表项 -->
|
|
<view v-for="(item, ind) in group.list" :key="item.id"
|
|
:class="['list-item', ind === group.list.length - 1 && 'no_border']"
|
|
@click="headerSelectMapClick(item)">
|
|
{{ item.name }}
|
|
</view>
|
|
</view>
|
|
</scroll-view>
|
|
|
|
<!-- 右侧索引栏 -->
|
|
<view class="index-bar">
|
|
<view v-for="(letter, index) in letters" :key="index" class="index-item" @tap="scrollToLetter(letter)">
|
|
{{ letter }}
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
</view>
|
|
</template>
|
|
|
|
|
|
|
|
<script>
|
|
import {
|
|
apiArr
|
|
} from '../../api/community.js';
|
|
import { apiArr as areaApi } from '../../api/area.js';
|
|
import {
|
|
util,
|
|
picUrl,
|
|
request,
|
|
menuButtonInfo
|
|
} from '../../utils/index.js';
|
|
|
|
import {pinyin} from 'pinyin-pro';
|
|
console.log(pinyin('汉语拼音'),'zz');
|
|
|
|
|
|
export default {
|
|
data() {
|
|
return {
|
|
location: {},
|
|
searchValue: '',
|
|
currentCity: '衡水',
|
|
hotCities: ['上海', '北京', '广州', '杭州', '成都', '深圳', '苏州', '南京', '重庆', '西安', '长沙', '天津', '三亚', '厦门', '武汉', '无锡'],
|
|
rawData: [{
|
|
id: 1,
|
|
name: '阿巴嘎旗',
|
|
letters: 'A',
|
|
lat: '39.908823',
|
|
long: '116.39747',
|
|
},
|
|
{
|
|
id: 2,
|
|
name: '阿坝',
|
|
letters: 'A',
|
|
lat: '31.196322',
|
|
long: '121.339841'
|
|
},
|
|
{
|
|
id: 3,
|
|
name: '阿坝县',
|
|
letters: 'A',
|
|
},
|
|
{
|
|
id: 4,
|
|
name: '阿城区',
|
|
letters: 'A',
|
|
},
|
|
{
|
|
id: 5,
|
|
name: '阿尔山市',
|
|
letters: 'B',
|
|
},
|
|
{
|
|
id: 6,
|
|
name: '阿合奇县',
|
|
letters: 'B',
|
|
},
|
|
{
|
|
id: 7,
|
|
name: '阿克塞哈萨克族自治县',
|
|
letters: 'B',
|
|
},
|
|
{
|
|
id: 8,
|
|
name: '阿克苏地区',
|
|
letters: 'C',
|
|
},
|
|
{
|
|
id: 9,
|
|
name: '阿克苏市',
|
|
letters: 'D',
|
|
},
|
|
{
|
|
id: 10,
|
|
name: '阿拉尔',
|
|
letters: 'E',
|
|
},
|
|
],
|
|
letters: ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
|
|
'U', 'V', 'W', 'X', 'Y', 'Z'
|
|
],
|
|
groupedData: [], // 分组后的数据
|
|
activeId: '', // 当前高亮的字母区域 ID
|
|
activeLetter: '',// 当前高亮的字母
|
|
searchRes: [
|
|
{
|
|
name: '河北,石家庄'
|
|
},
|
|
{
|
|
name: '河北,廊坊'
|
|
},
|
|
{
|
|
name: '河北,保定'
|
|
},
|
|
{
|
|
name: '河北,衡水'
|
|
},
|
|
{
|
|
name: '河北,沧州'
|
|
},
|
|
{
|
|
name: '河北,唐山'
|
|
},
|
|
],
|
|
|
|
proviceList: [],
|
|
cityList: []
|
|
}
|
|
},
|
|
onLoad(options) {
|
|
this.location = uni.getStorageSync('location');
|
|
this.getArea()
|
|
},
|
|
methods: {
|
|
headerSelectMapClick(item) {
|
|
console.log('地图选点', item);
|
|
const lat = Number(item.lat);
|
|
const long = Number(item.long);
|
|
uni.chooseLocation({
|
|
latitude: lat,
|
|
longitude: long,
|
|
success: (res) => {
|
|
console.log('打开地图选择商铺名称', res);
|
|
if (!res.name) {
|
|
uni.showToast({
|
|
title: '请选择具体城市信息',
|
|
icon: 'none'
|
|
});
|
|
return;
|
|
}
|
|
// 更新页面数据,如标记点等
|
|
const selectLocation = {
|
|
cityName: res.address.match(/(.*?(?:省|自治区)|^)(.*?)(?:市|地区|盟|州|县|区)?$/)[2].match(/(.*市)/)[1],
|
|
district: res.address.match(/市(.*)/)[1],
|
|
lat: res.latitude,
|
|
lng: res.longitude
|
|
};
|
|
uni.setStorageSync('location', selectLocation); // 缓存数据信息
|
|
// uni.setStorageSync('city', selectLocation.cityName); // 缓存数据信息
|
|
console.log('location', selectLocation);
|
|
uni.navigateBack({
|
|
delta: 1
|
|
});
|
|
},
|
|
fail: (err) => {
|
|
console.log('选择位置失败', err);
|
|
}
|
|
});
|
|
},
|
|
handleSearch(e) {
|
|
// 搜索逻辑,可以在这里根据 searchValue 过滤城市数据
|
|
this.searchValue = e;
|
|
console.log('搜ee索:', e);
|
|
},
|
|
groupData() {
|
|
const map = {};
|
|
this.letters.forEach(letter => {
|
|
map[letter] = {
|
|
letter,
|
|
list: []
|
|
};
|
|
});
|
|
|
|
this.rawData.forEach(item => {
|
|
if (map[item.letters]) {
|
|
map[item.letters].list.push(item);
|
|
}
|
|
});
|
|
console.log('112312313', Object.values(map).filter(group => group.list.length > 0))
|
|
// 过滤掉没有数据的字母
|
|
this.groupedData = Object.values(map).filter(group => group.list.length > 0);
|
|
},
|
|
// 点击字母滚动到对应区域
|
|
scrollToLetter(letter) {
|
|
this.$nextTick(() => {
|
|
this.activeId = 'group-' + letter;
|
|
this.activeLetter = letter;
|
|
});
|
|
},
|
|
// 滚动时监听当前位置
|
|
handleScroll(e) {
|
|
const query = uni.createSelectorQuery().in(this);
|
|
let activeLetter = '';
|
|
|
|
// 遍历每个字母区域,检查是否在可视范围内
|
|
this.letters.some(letter => {
|
|
query.select(`#group-${letter}`).boundingClientRect(rect => {
|
|
if (rect && rect.top <= 100 && rect.bottom >= 0) {
|
|
activeLetter = letter;
|
|
}
|
|
}).exec();
|
|
return activeLetter; // 找到第一个符合条件的字母后退出循环
|
|
});
|
|
if (activeLetter && activeLetter !== this.activeLetter) {
|
|
this.activeLetter = activeLetter;
|
|
}
|
|
},
|
|
|
|
getArea() {
|
|
let that = this
|
|
request(areaApi.getArea, "POST", {}).then(res => {
|
|
this.proviceList = res.rows
|
|
this.proviceList.forEach(item => {
|
|
that.getCity(item.ad_code)
|
|
})
|
|
})
|
|
},
|
|
|
|
getCity(e) {
|
|
request(areaApi.getArea, "POST", { parent_ad_code: e }).then(res => {
|
|
const citiesWithLetters = res.rows.map(city => {
|
|
const firstChar = city.ad_name.charAt(0);
|
|
// 检查是否是英文字母
|
|
if (/^[A-Za-z]$/.test(firstChar)) {
|
|
return { ...city, letters: firstChar.toUpperCase() };
|
|
}
|
|
// 使用 pinyin-pro 获取首个拼音并转为大写
|
|
const firstPinyin = pinyin(firstChar, { pattern: 'first', type: 'array',toneType:"none" });
|
|
const firstPinyinChar = firstPinyin[0] ? firstPinyin[0].toUpperCase() : '#';
|
|
// 验证转换结果是否为有效字母,无效则标记为 '#'
|
|
|
|
const letter = /^[A-Z]$/.test(firstPinyinChar) ? firstPinyinChar : '#';
|
|
if (letter === '#') {
|
|
console.log('当前城市', city.short_name);
|
|
}
|
|
return { ...city, letters: letter };
|
|
});
|
|
this.cityList = this.cityList.concat(citiesWithLetters);
|
|
});
|
|
},
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
}
|
|
</script>
|
|
|
|
<style>
|
|
@import url("./index.css");
|
|
</style> |