<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>
|