From 500078714411487af00161e01bd7e0b5efdc3414 Mon Sep 17 00:00:00 2001
From: cloudroam <cloudroam>
Date: 星期四, 07 八月 2025 13:32:32 +0800
Subject: [PATCH] add:热门景点
---
sub-pages/hot-city/hot-city-detail.vue | 375 +++++++++++++++++++++++
pages/home/home.vue | 156 +++++++++
static/common/item-films.png | 0
static/common/item-route.png | 0
pages.json | 19 +
sub-pages/hot-city/index.vue | 381 +++++++++++++++++++++++
static/common/item-map.png | 0
7 files changed, 928 insertions(+), 3 deletions(-)
diff --git a/pages.json b/pages.json
index cd1324f..04c7637 100644
--- a/pages.json
+++ b/pages.json
@@ -86,6 +86,25 @@
}
}
]
+ },
+ {
+ "root": "sub-pages/hot-city",
+ "pages": [
+ {
+ "path": "index",
+ "style": {
+ "navigationBarTitleText": "城市",
+ "enablePullDownRefresh": true
+ }
+ }
+ ,{
+ "path": "hot-city-detail",
+ "style": {
+ "navigationBarTitleText": "城市详情",
+ "enablePullDownRefresh": true
+ }
+ }
+ ]
}
,{
"root": "sub-pages/mine",
diff --git a/pages/home/home.vue b/pages/home/home.vue
index 80ed122..353f27b 100644
--- a/pages/home/home.vue
+++ b/pages/home/home.vue
@@ -23,7 +23,7 @@
</view>
<view class="trip-card-swiper">
- <swiper :current="currentPage" @change="onSwiperChange" circular style="min-height: 1850rpx;">
+ <swiper :current="currentPage" @change="onSwiperChange" circular style="min-height: 1650rpx;">
<swiper-item v-for="(group, pageIndex) in pagedTripCards" :key="pageIndex">
<TripCard v-for="(item, index) in group" :key="index" :tag="item.tag" :title="item.coverTitle"
:subtitle="item.coverAlt" :score="item.collectCount" :imageUrl="item.coverUrl"
@@ -32,8 +32,34 @@
</swiper>
</view>
-<!-- <SectionTitle title="全球影视地标" optitle="查看全部" goUrl="/pages/home/home-more" />-->
+ <SectionTitle title="全球影视地标" optitle="查看全部" goUrl="/pages/home/home-more" />
<!-- <GlobalGeo />-->
+ <view class="continent-section">
+ <view class="continent-item all" @click="navigateToAll">全部</view>
+ <view class="continents-container">
+ <view class="continent-row" v-for="(row, index) in continentRows" :key="index">
+ <view
+ class="continent-item continent"
+ v-for="(continent, colIndex) in row"
+ :key="colIndex"
+ @click="navigateToDetail(continent)"
+ >
+ {{ continent.name }}
+ </view>
+ <!-- 添加占位元素保持布局 -->
+ <view
+ v-for="n in (3 - row.length)"
+ :key="'placeholder'+n"
+ class="continent-placeholder"
+ ></view>
+ </view>
+ </view>
+ <view class="continent-item separator"></view>
+ <view class="continent-item nearby" @click="navigateToNearby">
+ <view>附</view>
+ <view>近</view>
+ </view>
+ </view>
<SectionTitle title="场景博物馆" optitle="查看全部" goUrl="/sub-pages/hot-spot/index" />
<SceneMuseumCard v-for="(item, index) in cardList" :key="index" :image="item.image" :title="item.title"
@@ -57,7 +83,6 @@
import HomeMain from './home-main.vue'
import TripCard from './trip-card.vue'
-import GlobalGeo from './global-geo.vue'
import SceneMuseumCard from './scene-museum-card.vue'
import Community from './community.vue'
import { SwiperChangeEvent } from '@dcloudio/uni-app'
@@ -70,6 +95,54 @@
// 主题
const theme = ref('light')
+
+const continents = ref([])
+
+const getContinents = async () => {
+ try {
+ const {code, data} = await $http.request('get', '/api/code/value?type=CONTINENT_TYPE')
+ if (code == 0 && data) {
+ continents.value = data.map(item => (
+ {
+ id: item.id,
+ name: item.label
+ })
+ )
+ }
+
+ } catch (error) {
+ console.log('获取洲数据失败', error)
+ $message.showToast('获取洲数据失败')
+ }
+
+}
+
+const continentRows = computed(() => {
+ const rows = [];
+ const continentsList = [...continents.value];
+
+ // 将洲分成三行
+ for (let i = 0; i < 3; i++) {
+ const start = i * 3;
+ const end = start + 3;
+ rows.push(continentsList.slice(start, end));
+ }
+
+ return rows;
+});
+
+const navigateToDetail = (continent) => {
+ //跳转到具体页面
+ uni.navigateTo({
+ url: `/sub-pages/hot-city/index?continentId=${continent.id}`
+ })
+}
+const navigateToNearby = () => {
+ //附近功能跳转
+ uni.navigateTo({
+ url: '/pages/nearby/nearby'
+ })
+}
// 当前页数
@@ -115,6 +188,7 @@
onMounted(() => {
const localTheme = uni.getStorageSync('theme') || 'light'
theme.value = localTheme
+ getContinents()
})
onShow(() => {
@@ -255,6 +329,82 @@
margin-top: 20rpx;
margin-bottom: 20rpx;
}
+
+.continent-section {
+ display: flex;
+ align-items: stretch;
+ border-top: 1px dashed #ccc;
+ border-bottom: 1px dashed #ccc;
+ padding: 10rpx 0;
+ height: 220rpx; /* 固定高度容纳三行 */
+}
+
+.all, .nearby {
+ flex-shrink: 0;
+ width: 15%;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ font-size: 30rpx;
+ font-weight: bold;
+}
+
+.continents-container {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ justify-content: space-between;
+}
+
+.continent-row {
+ display: flex;
+ justify-content: flex-start; /* 改为左对齐 */
+ height: 33.33%; /* 每行高度占三分之一 */
+ padding: 5rpx 0;
+}
+
+.continent {
+ flex: 0 0 30%; /* 固定宽度30% */
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ text-align: center;
+ font-size: 28rpx;
+ padding: 5rpx 0;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ margin-right: 5%; /* 元素间间距 */
+}
+
+/* 最后一个元素不需要右边距 */
+.continent:last-child {
+ margin-right: 0;
+}
+
+.continent-placeholder {
+ flex: 0 0 30%; /* 占位元素宽度 */
+ margin-right: 5%; /* 保持与正常元素相同的间距 */
+}
+
+/* 最后一个占位元素不需要右边距 */
+.continent-placeholder:last-child {
+ margin-right: 0;
+}
+
+.separator {
+ width: 1px;
+ background-color: #ccc;
+ margin: 0 10rpx;
+ align-self: center;
+ height: 80%; /* 分隔线高度为父容器的80% */
+}
+
+.nearby {
+ flex-direction: column;
+ font-size: 30rpx;
+}
</style>
<style scoped lang="scss">
diff --git a/static/common/item-films.png b/static/common/item-films.png
new file mode 100644
index 0000000..53a3b37
--- /dev/null
+++ b/static/common/item-films.png
Binary files differ
diff --git a/static/common/item-map.png b/static/common/item-map.png
new file mode 100644
index 0000000..57e7456
--- /dev/null
+++ b/static/common/item-map.png
Binary files differ
diff --git a/static/common/item-route.png b/static/common/item-route.png
new file mode 100644
index 0000000..f4cf09f
--- /dev/null
+++ b/static/common/item-route.png
Binary files differ
diff --git a/sub-pages/hot-city/hot-city-detail.vue b/sub-pages/hot-city/hot-city-detail.vue
new file mode 100644
index 0000000..9cc73e4
--- /dev/null
+++ b/sub-pages/hot-city/hot-city-detail.vue
@@ -0,0 +1,375 @@
+<template>
+ <view class="container">
+ <view class="header-info">
+ <image src="/static/common/earth.png" class="earth-icon"></image>
+ <view class="city-info">
+ <text class="city-name">{{cityInfo.cityName}}</text>
+ <text class="city-pinyin">{{cityInfo.cityPinyin}}</text>
+ <text class="city-continent">{{cityInfo.cityCountry}} {{cityInfo.cityContinent}}</text>
+ </view>
+ </view>
+
+ <view class="main-image">
+ <image :src="cityInfo.mainImage" mode="aspectFit" class="main-img" />
+ </view>
+
+ <view class="main-text">
+ <text class="info-title1">{{cityInfo.infoTitle1}}</text>
+ <text class="info-title2">
+ {{cityInfo.infoTitle2}}
+ </text>
+ </view>
+
+ <!-- 添加三个可点击块 -->
+ <view class="tab-container">
+ <view class="tab-item" @click="activeTab = 'films'">
+ <image src="/static/common/item-films.png" class="tab-icon"></image>
+ <text class="tab-text">影片</text>
+ </view>
+ <view class="tab-item" @click="activeTab = 'map'">
+ <image src="/static/common/item-map.png" class="tab-icon"></image>
+ <text class="tab-text">地图</text>
+ </view>
+ <view class="tab-item" @click="activeTab = 'route'">
+ <image src="/static/common/item-route.png" class="tab-icon"></image>
+ <text class="tab-text">路线</text>
+ </view>
+ </view>
+
+ <!-- 根据 activeTab 展示不同内容 -->
+ <view v-if="activeTab === 'films'" class="content-container">
+ <text class="content-title">影片列表</text>
+ <!-- 影片列表内容 -->
+ <view v-for="(film, index) in films" :key="index" class="film-item" @click="goToFilmDetail(film.id)">
+ <image :src="film.coverUrl" class="film-poster"></image>
+ <text class="film-name">{{ film.nameCn }}</text>
+ </view>
+ </view>
+
+ <view v-if="activeTab === 'map'" class="content-container">
+ <text class="content-title">景点列表和地图</text>
+ <!-- 地图内容 -->
+ <map
+ class="map-content"
+ :latitude="mapCenter.latitude"
+ :longitude="mapCenter.longitude"
+ :scale="mapCenter.scale"
+ :markers="mapMarkers"
+ ></map>
+ <view v-for="(spot, index) in spots" :key="index" class="spot-item" @click="goToSpotDetail(spot.id)">
+ <text class="spot-name">{{ spot.locationName }}</text>
+ <text class="spot-desc">{{ spot.landmarkDesc }}</text>
+ </view>
+ </view>
+
+ <view v-if="activeTab === 'route'" class="content-container">
+ <text class="content-title">路线</text>
+ <!-- 路线内容(暂时为空) -->
+ <text>暂无内容</text>
+ </view>
+ </view>
+</template>
+
+<script setup lang="ts">
+import { ref } from 'vue';
+import { onLoad } from '@dcloudio/uni-app'
+import { useGlobal } from '@/composables/useGlobal'
+const { $http, $message } = useGlobal()
+import {FilmWorks,FilmLocationVO} from "@/types/index";
+
+// 定义 activeTab 并设置默认值为 'films'
+const activeTab = ref('films');
+
+const films = ref<FilmWorks[]>();
+const cityInfo = ref({
+ cityName: '北京',
+ cityPinyin: 'Beijing',
+ cityCountry: '中国',
+ cityContinent: 'Asia',
+ mainImage: 'https://ai-public.mastergo.com/ai/img_res/6a226f9e9652c51cd535c3490535dfeb.jpg',
+ infoTitle1: '',
+ infoTitle2: '',
+})
+
+
+onLoad(async (options: any) => {
+ const name = options.name
+ const pinyin = options.pinyin
+ const country = options.country
+ const continent = options.continent
+
+ // 修复后的代码 - 确保所有必需的属性都被设置
+ cityInfo.value = {
+ cityName: name || '北京', // 提供默认值
+ cityPinyin: pinyin || '',
+ cityCountry: country || '中国',
+ cityContinent: continent || 'Asia',
+ mainImage: 'https://ai-public.mastergo.com/ai/img_res/6a226f9e9652c51cd535c3490535dfeb.jpg',
+ infoTitle1: '',
+ infoTitle2: ''
+ }
+
+ if (name) {
+ await getRelatedFilms(name)
+ await getLocations(name)
+ }
+})
+
+const getRelatedFilms = async (name: string) => {
+ const { code, data } = await $http.request('get', '/api/filmLocation/city', {
+ params: { name }
+ })
+ if (code === 0 && Array.isArray(data)) {
+ films.value = data
+ } else {
+ films.value = []
+ }
+}
+
+const getLocations = async (name: string) => {
+ const { code, data } = await $http.request('get', '/api/filmLocation/location', {
+ params: { name }
+ })
+ if (code === 0 && Array.isArray(data)) {
+ spots.value = data
+
+ if (data.length > 0) {
+
+ // 使用第一个景点的数据更新cityInfo
+ const firstSpot = data[0];
+
+ // 更新主图,如果没有locationUrl则使用默认图
+ cityInfo.value.mainImage = firstSpot.locationUrl || cityInfo.value.mainImage;
+
+ // 更新infoTitle1,使用locationName
+ if (firstSpot.locationName) {
+ cityInfo.value.infoTitle1 = firstSpot.locationName;
+ }
+
+ // 更新infoTitle2,组合address、sceneType、classicScene和landmarkDesc
+ let infoTitle2Content = '';
+ if (firstSpot.address) {
+ infoTitle2Content += firstSpot.address;
+ }
+ if (firstSpot.sceneType) {
+ infoTitle2Content += (infoTitle2Content ? ' ' : '') + firstSpot.sceneType;
+ }
+ if (firstSpot.classicScene) {
+ infoTitle2Content += (infoTitle2Content ? ' ' : '') + firstSpot.classicScene;
+ }
+ if (firstSpot.landmarkDesc) {
+ infoTitle2Content += (infoTitle2Content ? ' ' : '') + firstSpot.landmarkDesc;
+ }
+
+ if (infoTitle2Content) {
+ cityInfo.value.infoTitle2 = infoTitle2Content;
+ }
+ // 设置中心点为第一个景点的位置
+ mapCenter.value.latitude = data[0].gpsLat || 39.9042
+ mapCenter.value.longitude = data[0].gpsLng || 116.4074
+ mapCenter.value.scale = 12
+
+ // 创建标记点数组
+ mapMarkers.value = data.map((spot, index) => ({
+ id: index,
+ latitude: spot.gpsLat,
+ longitude: spot.gpsLng,
+ title: spot.locationName,
+ iconPath: '/static/common/marker.png', // 可以替换为实际的标记图标路径
+ width: 30,
+ height: 30
+ })).filter(marker => marker.latitude && marker.longitude) // 过滤掉没有坐标的标记
+ }
+ } else {
+ spots.value = []
+ }
+}
+
+const spots = ref<FilmLocationVO[]>();
+
+// 添加地图中心点和标记数据
+const mapCenter = ref({
+ latitude: 39.9042,
+ longitude: 116.4074,
+ scale: 10
+});
+
+const mapMarkers = ref([]);
+
+
+// 跳转到影片详情页
+const goToFilmDetail = (id: number) => {
+ uni.navigateTo({
+ url: `/sub-pages/film-list/film-detail?id=${id}`
+ });
+};
+
+// 跳转到景点详情页
+const goToSpotDetail = (id: number) => {
+ uni.navigateTo({
+ url: `/sub-pages/hot-spot/spot-detail?id=${id}`
+ });
+};
+</script>
+
+<style scoped>
+.container {
+ padding: 20rpx;
+}
+
+.header-info {
+ display: flex;
+ align-items: center;
+ margin-bottom: 30rpx;
+ padding: 20rpx;
+ background-color: #f8f8f8;
+ border-radius: 16rpx;
+}
+
+.earth-icon{
+ width: 180rpx;
+ height: 180rpx;
+ margin-right: 30rpx;
+}
+
+.city-info {
+ display: flex;
+ flex-direction: column;
+}
+
+.city-name {
+ font-size: 40rpx;
+ font-weight: bold;
+ margin-bottom: 10rpx;
+}
+
+.city-pinyin {
+ font-size: 32rpx;
+ color: #666;
+ margin-bottom: 10rpx;
+}
+
+.city-continent {
+ font-size: 28rpx;
+ color: #999;
+}
+
+.main-image {
+ width: 100%;
+ height: 400rpx;
+ margin-bottom: 30rpx;
+ border-radius: 16rpx;
+ overflow: hidden;
+}
+
+.main-img {
+ width: 100%;
+ height: 100%;
+}
+
+.main-text {
+ padding: 20rpx;
+ margin-bottom: 30rpx;
+ background-color: #f8f8f8;
+ border-radius: 16rpx;
+}
+
+.info-title1 {
+ font-size: 32rpx;
+ font-weight: bold;
+ margin-bottom: 15rpx;
+ display: block;
+}
+
+.info-title2 {
+ font-size: 28rpx;
+ line-height: 1.6;
+ color: #333;
+}
+
+.tab-container {
+ display: flex;
+ justify-content: space-around;
+ padding: 20rpx 0;
+ margin-bottom: 30rpx;
+ border-top: 1rpx solid #eee;
+ border-bottom: 1rpx solid #eee;
+}
+
+.tab-item {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ padding: 20rpx;
+}
+
+.tab-icon {
+ width: 60rpx;
+ height: 60rpx;
+ margin-bottom: 10rpx;
+}
+
+.tab-text {
+ font-size: 28rpx;
+}
+
+.content-container {
+ padding: 20rpx;
+ background-color: #f8f8f8;
+ border-radius: 16rpx;
+ margin-bottom: 20rpx;
+}
+
+.content-title {
+ font-size: 36rpx;
+ font-weight: bold;
+ margin-bottom: 30rpx;
+ display: block;
+}
+
+.film-item {
+ display: flex;
+ align-items: center;
+ margin-bottom: 30rpx;
+ padding: 20rpx;
+ background-color: #fff;
+ border-radius: 12rpx;
+}
+
+.film-poster {
+ width: 120rpx;
+ height: 160rpx;
+ margin-right: 20rpx;
+ border-radius: 8rpx;
+}
+
+.film-name {
+ font-size: 32rpx;
+}
+
+.map-content {
+ width: 100%;
+ height: 400rpx;
+ margin-bottom: 30rpx;
+ border-radius: 16rpx;
+}
+
+.spot-item {
+ margin-bottom: 30rpx;
+ padding: 20rpx;
+ background-color: #fff;
+ border-radius: 12rpx;
+}
+
+.spot-name {
+ font-size: 32rpx;
+ font-weight: bold;
+ margin-bottom: 10rpx;
+ display: block;
+}
+
+.spot-desc {
+ font-size: 28rpx;
+ color: #666;
+}
+</style>
diff --git a/sub-pages/hot-city/index.vue b/sub-pages/hot-city/index.vue
new file mode 100644
index 0000000..3de6160
--- /dev/null
+++ b/sub-pages/hot-city/index.vue
@@ -0,0 +1,381 @@
+<template>
+ <view :class="['app', theme]">
+ <!-- 搜索框部分 -->
+ <view style="padding-top: 10rpx;">
+ <up-search
+ height="70rpx"
+ placeholder="搜索城市"
+ search-icon-size="40rpx"
+ margin="0rpx 30rpx"
+ v-model="search"
+ :show-action="true"
+ @search="onSearch"
+ @custom="onSearch"
+ @click-icon="onSearch"
+ />
+ </view>
+
+ <!-- 标签切换部分 -->
+ <up-tabs :list="tabList" @click="click">
+ <template #right>
+ <view style="padding-left: 4px;" @tap="() => showToast('插槽被点击')">
+ <up-icon name="list" size="40rpx" bold></up-icon>
+ </view>
+ </template>
+ </up-tabs>
+
+ <!-- 城市列表 -->
+ <view class="city-items">
+ <!-- 搜索状态下的列表 -->
+ <template v-if="search">
+ <view
+ class="city-item"
+ v-for="city in displayedCities"
+ :key="city.id"
+ @click="handleCityClick(city)"
+ >
+ {{ city.name }}
+ </view>
+ </template>
+
+ <!-- 非搜索状态下的列表 -->
+ <template v-else>
+ <!-- 热门城市部分 -->
+ <view class="section" v-if="filteredHotCities.length">
+ <view class="section-title">热门城市</view>
+ <view class="hot-city-list">
+ <view
+ class="hot-city-item"
+ v-for="city in filteredHotCities"
+ :key="'hot-'+city.id"
+ @click="handleCityClick(city)"
+ >
+ {{ city.name }}
+ </view>
+ </view>
+ </view>
+
+ <!-- A-Z城市列表 -->
+ <view class="section" v-for="group in groupedCities" :key="group.letter">
+ <view class="section-title">{{ group.letter }}</view>
+ <view
+ class="city-detail-item"
+ v-for="city in group.cities"
+ :key="'az-'+city.id"
+ @click="handleCityClick(city)"
+ >
+ <view class="city-name">{{ city.name }}</view>
+ <view class="city-sub-info">
+ <text class="city-pinyin">{{ city.pinyin }}</text>
+ <text class="city-country"> · {{ city.country }}</text>
+ </view>
+ </view>
+ </view>
+ </template>
+ </view>
+ </view>
+</template>
+
+<script setup lang="ts">
+import { ref, computed, onMounted, watch } from 'vue'
+import { onLoad } from '@dcloudio/uni-app'
+import { useGlobal } from '@/composables/useGlobal'
+const { $http, $message, $store } = useGlobal()
+
+const theme = ref('light')
+const search = ref('')
+
+// 响应式数据
+const tabList = ref([])
+
+const currentTab = ref('Asia')
+
+// 更新热门城市数据结构,添加国家字段
+// const hotCities = ref([
+// { id: 1, name: '北京市', pinyin: 'Beijing', country: '中国', continent: 'asia' },
+// { id: 2, name: '上海市', pinyin: 'Shanghai', country: '中国', continent: 'asia' },
+// { id: 3, name: '纽约', pinyin: 'New York', country: '美国', continent: 'northAmerica' },
+// { id: 4, name: '伦敦', pinyin: 'London', country: '英国', continent: 'europe' },
+// ])
+const hotCities = ref([])
+
+// 更新所有城市数据结构,添加国家字段
+const allCities = ref([])
+
+// 当前洲的热门城市
+const filteredHotCities = computed(() => {
+ if (currentTab.value === 'all') {
+ return hotCities.value;
+ }
+ return hotCities.value.filter(city => city.continent === currentTab.value);
+});
+
+// 当前洲的所有城市(按拼音分组)
+const groupedCities = computed(() => {
+ // 获取当前洲的城市列表
+ let cities = [];
+ if (currentTab.value === 'all') {
+ cities = [...allCities.value];
+ } else {
+ cities = allCities.value.filter(city => city.continent === currentTab.value);
+ }
+
+ // 按拼音首字母分组
+ const groups: Record<string, any[]> = {};
+ cities.forEach(city => {
+ const firstLetter = city.pinyin.charAt(0).toUpperCase();
+ if (!groups[firstLetter]) {
+ groups[firstLetter] = [];
+ }
+ groups[firstLetter].push(city);
+ });
+
+ // 转换为数组并按字母排序
+ return Object.keys(groups)
+ .sort()
+ .map(letter => ({
+ letter,
+ cities: groups[letter].sort((a, b) =>
+ a.pinyin.localeCompare(b.pinyin))
+ }));
+});
+
+// 根据当前标签显示对应的城市(用于搜索状态)
+const displayedCities = computed(() => {
+ let cities = [];
+ if (currentTab.value === 'all') {
+ cities = [...hotCities.value, ...allCities.value];
+ } else {
+ cities = allCities.value.filter(city => city.continent === currentTab.value);
+ }
+
+ // 添加搜索过滤功能
+ if (search.value) {
+ return cities.filter(city =>
+ city.name?.includes(search.value) ||
+ city.pinyin?.toLowerCase().includes(search.value.toLowerCase())
+ )
+ }
+ return cities
+})
+
+// 标签点击事件
+// const click = (item: { name: string; value: string }) => {
+// currentTab.value = item.value
+// console.log('currentTab:', currentTab.value)
+// }
+const click = async (item: { name: string; value: string }) => {
+ currentTab.value = item.value;
+ console.log('currentTab:', currentTab.value);
+
+ // 显示加载状态
+ uni.showLoading({ title: '加载中...' });
+
+ try {
+ await getHotCities();
+ await getAllCities();
+ } finally {
+ uni.hideLoading();
+ }
+};
+
+// 搜索事件
+const onSearch = (value: string) => {
+ const searchValue = typeof value === 'string' ? value : search.value
+ search.value = searchValue
+}
+
+const handleCityClick = (city: any) => {
+ console.log('City clicked:', city)
+ // 实际应用中这里可以添加选择城市后的逻辑
+ uni.navigateTo({
+ url: `/sub-pages/hot-city/hot-city-detail?name=${city.name}`
+ })
+}
+
+const showToast = (msg: string) => {
+ uni.showToast({ title: msg, icon: 'none' })
+}
+
+onLoad(async(options) => {
+ const storedTheme = uni.getStorageSync('theme') || 'light'
+ theme.value = storedTheme
+
+ console.log("options", options)
+
+ if (options && options.continentId) {
+ // 等待获取 tab 列表完成
+ await getTabList()
+
+ const continentId = options.continentId.toString()
+ console.log('continentId:', continentId);
+ console.log("tabList.value", tabList.value)
+
+ const tab = tabList.value.find(t => {
+ console.log(`Comparing "${t.id}" with "${continentId}"`);
+ return t.id.toString() === continentId.toString();
+ });
+ console.log("tab", tab)
+ if (tab) {
+ console.log(' currentTab.value ', currentTab.value )
+ currentTab.value = tab.value
+ console.log(' currentTab.value ', currentTab.value )
+ console.log('Tab found and set:', tab)
+ // 关键:在设置完 currentTab 后,立即获取对应的数据
+ await getHotCities();
+ await getAllCities();
+ } else {
+ console.log('Tab not found for continentId:', options.continentId)
+ console.log('Available tabs:', tabList.value)
+ }
+ } else {
+ // 如果没有传参,正常获取 tab 列表和数据
+ await getTabList()
+ await getHotCities();
+ await getAllCities();
+ }
+})
+
+
+// onMounted(() => {
+// // 初始化数据
+// // getTabList();
+// getHotCities();
+// getAllCities();
+// })
+
+// 监听currentTab变化,重新获取数据
+// 确保 watch 能够深度监听并正确处理异步操作
+watch(currentTab, async (newVal, oldVal) => {
+ console.log('Tab changed from', oldVal, 'to', newVal);
+ await getHotCities();
+ await getAllCities();
+}, { flush: 'post' });
+
+const getAllCities = async () => {
+ // 获取所有城市
+ try{
+ const { code, data } = await $http.request('get', '/api/filmLocation/info',{
+ params: {
+ continent: currentTab.value,
+ }
+ })
+ if (code === 0 && data) {
+ allCities.value = data.map(item => ({
+ id: item.id,
+ name: item.city,
+ pinyin: item.pinyin,
+ country: item.country,
+ continent: item.continent
+ }))
+ }
+ }catch (e) {
+ console.log("获取热门城市失败", e)
+ $message.showToast("获取热门城市失败")
+ }
+}
+
+ const getHotCities = async () => {
+ //获取热门城市
+ try{
+ const { code, data } = await $http.request('get', '/api/filmHotCity/list',{
+ params: {
+ size: 10,
+ continent: currentTab.value=='all'?'':currentTab.value,
+ current: 1
+ }
+ })
+ if (code === 0 && data) {
+ hotCities.value = data.records.map(item => ({
+ id: item.id,
+ name: item.name,
+ country: item.country,
+ continent: item.continent
+ }))
+ }
+ }catch (e) {
+ console.log("获取热门城市失败", e)
+ $message.showToast("获取热门城市失败")
+ }
+}
+
+const getTabList = async () => {
+ // 获取洲列表
+ try {
+ const {code, data} = await $http.request('get', '/api/code/value?type=CONTINENT_TYPE')
+ if (code == 0 && data) {
+ tabList.value = data.map((item: any) => ({
+ id: item.id,
+ name: item.label,
+ value: item.value // 确保这里返回洲的标识符
+ }))
+ }
+ } catch (e) {
+ console.log("获取洲数据失败", e)
+ $message.showToast("获取洲数据失败")
+ }
+}
+</script>
+
+<style scoped>
+.city-items {
+ padding: 0 30rpx;
+}
+
+.section {
+ margin-bottom: 30rpx;
+}
+
+.section-title {
+ font-size: 28rpx;
+ color: #666;
+ padding: 20rpx 0;
+ border-bottom: 1rpx solid #eee;
+ margin-bottom: 15rpx;
+}
+
+.hot-city-list {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 20rpx;
+}
+
+.hot-city-item {
+ background-color: #f5f5f5;
+ padding: 15rpx 25rpx;
+ border-radius: 10rpx;
+ font-size: 28rpx;
+}
+
+.city-detail-item {
+ padding: 25rpx 0;
+ border-bottom: 1rpx solid #f5f5f5;
+}
+
+.city-name {
+ font-size: 32rpx;
+ font-weight: 500;
+ margin-bottom: 8rpx;
+}
+
+.city-sub-info {
+ display: flex;
+ font-size: 26rpx;
+ color: #888;
+}
+
+.city-pinyin {
+ font-style: italic;
+}
+
+.city-country {
+ margin-left: 5rpx;
+}
+
+/* 搜索状态下的简单列表样式 */
+.city-item {
+ padding: 25rpx 0;
+ border-bottom: 1rpx solid #f5f5f5;
+ font-size: 32rpx;
+}
+</style>
\ No newline at end of file
--
Gitblit v1.9.3