297 lines
7.2 KiB
Vue
297 lines
7.2 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/area.js";
|
|
import { request } from "../../utils/index.js";
|
|
|
|
export default {
|
|
data() {
|
|
return {
|
|
location: {},
|
|
searchValue: "",
|
|
hotCities: [
|
|
"上海",
|
|
"北京",
|
|
"广州",
|
|
"杭州",
|
|
"成都",
|
|
"深圳",
|
|
"苏州",
|
|
"南京",
|
|
"重庆",
|
|
"西安",
|
|
"长沙",
|
|
"天津",
|
|
"三亚",
|
|
"厦门",
|
|
"武汉",
|
|
"无锡",
|
|
],
|
|
// 右侧字母列表
|
|
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",
|
|
],
|
|
activeId: "", // 当前高亮的字母区域 ID
|
|
activeLetter: "", // 当前高亮的字母
|
|
searchRes: [
|
|
{
|
|
name: "河北,石家庄",
|
|
},
|
|
{
|
|
name: "河北,廊坊",
|
|
},
|
|
{
|
|
name: "河北,保定",
|
|
},
|
|
{
|
|
name: "河北,衡水",
|
|
},
|
|
{
|
|
name: "河北,沧州",
|
|
},
|
|
{
|
|
name: "河北,唐山",
|
|
},
|
|
],
|
|
|
|
cityList: [], // 接口请求返回参数信息
|
|
groupedData: [], // 分组后的数据
|
|
|
|
};
|
|
},
|
|
onLoad() {
|
|
this.location = uni.getStorageSync("location");
|
|
this.init();
|
|
},
|
|
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.cityList.forEach((item) => {
|
|
if (map[item.letters]) {
|
|
map[item.letters].list.push(item);
|
|
}
|
|
});
|
|
|
|
// 过滤掉没有数据的字母
|
|
this.groupedData = Object.values(map).filter(
|
|
(group) => group.list.length > 0
|
|
);
|
|
},
|
|
|
|
// 点击字母滚动到对应区域
|
|
scrollToLetter(letter) {
|
|
this.$nextTick(() => {
|
|
this.activeId = "group-" + letter;
|
|
this.activeLetter = letter;
|
|
});
|
|
},
|
|
|
|
|
|
async init() {
|
|
const res = await request(apiArr.getRegionList, 'POST', {
|
|
page_num: 1,
|
|
page_size: 100,
|
|
});
|
|
console.log('111111', res);
|
|
this.cityList = res.rows;
|
|
const hotsList = res.rows.filter((item) => item.hot === 2);
|
|
console.log('热门城市信息', hotsList);
|
|
|
|
await this.groupData();
|
|
},
|
|
|
|
// 滚动时监听当前位置
|
|
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;
|
|
}
|
|
},
|
|
},
|
|
};
|
|
</script>
|
|
|
|
<style>
|
|
@import url("./index.css");
|
|
</style>
|