323 lines
8.3 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="city-select-page" v-if="loading">
<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-if="searchRes.length === 0" class="list-item">暂无搜索结果</view>
<view
v-else
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 hotCityList"
class="city_name"
:key="index"
@click="headerSelectMapClick(item)"
>{{ item.name }}</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>
<!-- 列表项 -->
<!-- TODO: 小程序编译避坑指南 -->
<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, debounce } 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: [],
loading: false,
hotCityList: [], // 接口请求返回参数信息
groupedData: [], // 实际展示数据
};
},
onLoad() {
this.location = uni.getStorageSync("location");
this.init();
},
methods: {
headerSelectMapClick(item) {
console.log('1111 this', this);
console.log("地图选点", item);
const lat = Number(item.lat) || 0;
const long = Number(item.long) || 0;
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,
region: res.address.match(/^(.*?省.*?(?:市|自治州|盟).*?(?:县|区|旗))/)[1], // 省市区
};
uni.setStorageSync("location", selectLocation); // 缓存数据信息
// uni.setStorageSync('city', selectLocation.cityName); // 缓存数据信息
console.log("location", selectLocation);
uni.navigateBack({
delta: 1,
});
},
fail: (err) => {
console.log("选择位置失败", err);
},
});
},
handleSearch: debounce(function(keyword) {
if(keyword === '') {
this.searchValue = '';
this.searchRes = [];
return;
}
uni.showLoading({
title: '加载中',
mask: true
})
request(apiArr.getRegionList, 'POST', {
short_name: keyword,
ad_level: 2,
}, { silent: false }).then((res) => {
console.log('搜索结果', res);
this.searchValue = keyword;
this.searchRes = res.rows || [];
uni.hideLoading();
})
}, 500),
groupData(item) {
console.log('123. item', item);
const map = {};
this.letters.forEach((letter) => {
map[letter] = {
letter,
list: [],
};
});
item.forEach((items) => {
if (map[items.letters]) {
map[items.letters].list.push(items);
}
});
console.log('11111111', map)
// 过滤掉没有数据的字母
this.groupedData = Object.values(map).filter(
(group) => group.list.length > 0
);
uni.hideLoading();
this.loading = true;
},
// 点击字母滚动到对应区域
scrollToLetter(letter) {
this.$nextTick(() => {
this.activeId = "group-" + letter;
this.activeLetter = letter;
});
},
async init() {
uni.showLoading({
title: '加载中',
mask: true
})
const params = {
ad_level:2
}
const res = await request(apiArr.getRegionList, 'POST', params, { silent: false });
// TODO: 数据量返回过于庞大,只获取所需信息,其他内容舍弃
const newRes = res.rows.map((item) => {
return {
lat: item.lat,
letters: item.letters,
long: item.long,
name: item.name,
}
})
console.log('111', newRes)
// this.cityList = newRes;
const hotsList = res.rows.filter((item) => item.hot === 2).map((item) => {
return {
lat: item.lat,
long: item.long,
name: item.name,
};
});
console.log('热门城市信息', hotsList);
this.hotCityList = hotsList;
await this.groupData(newRes);
},
// 滚动时监听当前位置
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>