uniapp-ZHSQ/pages/shopcity/shopcity.vue
2025-06-30 11:04:41 +08:00

396 lines
9.9 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 { 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.cityList.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;
}
},
async getArea() {
let that = this;
const res = await request(apiArr.getRegionList, 'POST', {
page_num: 1,
page_size: 100,
});
console.log('111111', res);
this.cityList = res.rows;
await this.groupData();
return
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);
console.log(
"this.cityList.concat(citiesWithLetters);this.cityList.concat(citiesWithLetters);",
this.cityList.concat(citiesWithLetters)
);
});
},
},
};
</script>
<style>
@import url("./index.css");
</style>