<template>
|
<view :class="['app', theme]">
|
<TopTabBar />
|
<view class="main-content">
|
<!-- 主要内容展示 -->
|
<HomeMain />
|
|
<view class="section">
|
<up-row>
|
<up-col span="6">
|
<view class="row">
|
<text class="theme-text left-text">内容精选</text>
|
</view>
|
</up-col>
|
<up-col span="3"></up-col>
|
<up-col span="3">
|
<view class="row-right">
|
<up-icon name="/static/common/left-arrow-dark.png" size="80rpx" @click="prevPage" />
|
<up-icon name="/static/common/right-arrow-dark.png" size="80rpx" @click="nextPage" />
|
</view>
|
</up-col>
|
</up-row>
|
</view>
|
|
<view class="trip-card-swiper">
|
<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"
|
:detailUrl="`${detailUrl}?id=${item.id}`" />
|
</swiper-item>
|
</swiper>
|
</view>
|
|
<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"
|
:subtitle="item.subtitle" :readTime="item.readTime" />
|
|
<SectionTitle title="光影天地" optitle="加入光影" goUrl="/sub-pages/community/index" />
|
<Community v-for="(item, index) in communitys" :key="index" :detailUrl="`${detailUrl}?id=${item.id}`" :avatar="item.avatar" :nickname="item.nickname"
|
:time="formatRelativeTime(item.createTime)" :image="item.coverUrl" :content="item.coverAlt"
|
:likeCount="item.likeCount" :commentCount="item.commentCount" />
|
<up-loadmore :status="communityStatus" :line="true" />
|
<view style="height: 300rpx;"></view>
|
</view>
|
|
<CommonFooter flg="0" />
|
</view>
|
</template>
|
|
<script setup lang="ts">
|
import { ref, computed, onMounted } from 'vue'
|
import { onShow, onPullDownRefresh, onReachBottom } from '@dcloudio/uni-app'
|
|
import HomeMain from './home-main.vue'
|
import TripCard from './trip-card.vue'
|
import SceneMuseumCard from './scene-museum-card.vue'
|
import Community from './community.vue'
|
import { SwiperChangeEvent } from '@dcloudio/uni-app'
|
import { useGlobal } from '@/composables/useGlobal'
|
const { $http, $message, $store } = useGlobal()
|
import { FilmWorks } from '@/types/index'
|
import { formatRelativeTime } from '@/utils/time'
|
import { FilmWorksCategory } from '@/enums/dict'
|
|
|
// 主题
|
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'
|
})
|
}
|
|
|
// 当前页数
|
const currentPage = ref(0)
|
// 每页显示条数
|
const pageSize = 3
|
|
|
// 旅行卡片数据
|
const detailUrl = '/sub-pages/film-list/film-detail'
|
const tripCardList = ref<FilmWorks[]>([])
|
|
// 分页后的数组,每页3条
|
const pagedTripCards = computed(() => {
|
const pages: FilmWorks[][] = []
|
const list = tripCardList.value || [] // 安全兜底
|
for (let i = 0; i < list.length; i += pageSize) {
|
pages.push(list.slice(i, i + pageSize))
|
}
|
return pages
|
})
|
|
// 总页数
|
const totalPages = computed(() => {
|
const list = tripCardList.value || [] // 安全兜底
|
return Math.ceil(list.length / pageSize)
|
})
|
|
// 场景博物馆卡片数据
|
// 场景博物馆卡片数据
|
const cardList = ref<Array<{
|
image: string
|
title: string
|
subtitle: string
|
readTime: string
|
}>>([])
|
|
// 数据
|
const communitys = ref<FilmWorks[]>([])
|
|
|
// 生命周期
|
onMounted(() => {
|
const localTheme = uni.getStorageSync('theme') || 'light'
|
theme.value = localTheme
|
getContinents()
|
})
|
|
onShow(() => {
|
|
// 内容精选
|
getContentSelected()
|
|
// 光影
|
getCommunitys()
|
|
// 场景博物馆
|
getSceneMuseumData()
|
});
|
|
|
onPullDownRefresh(async () => {
|
console.log('用户下拉刷新了')
|
// 内容精选
|
getContentSelected()
|
// 光影
|
communityPage.value = 1
|
getCommunitys()
|
uni.stopPullDownRefresh() // 停止下拉刷新动画
|
})
|
|
onReachBottom(() => {
|
console.log('用户触底了')
|
getCommunitys()
|
})
|
|
const getContentSelected = async () => {
|
tripCardList.value = await getFilmWorks(FilmWorksCategory.CONTENT_SELECTED, 20, 1);
|
}
|
|
|
const communityPage = ref(1)
|
const communitySize = 10
|
const communityStatus = ref('loading')
|
const getCommunitys = async () => {
|
if (communityStatus.value === 'nomore') return
|
|
communityStatus.value = 'loading'
|
|
const records = await getFilmWorks(FilmWorksCategory.COMMUNITY, communitySize, communityPage.value)
|
|
if (records && records.length > 0) {
|
// 使用 Set 进行去重
|
const existingIds = new Set(communitys.value.map(item => item.id))
|
const uniqueRecords = records.filter(item => !existingIds.has(item.id))
|
|
communitys.value = [...communitys.value, ...uniqueRecords]
|
|
// 如果返回的记录数少于请求的 size,说明没有更多数据
|
if (records.length < communitySize) {
|
communityStatus.value = 'noMore'
|
}
|
|
communityPage.value++
|
} else {
|
communityStatus.value = 'noMore'
|
}
|
}
|
|
|
// 获取场景博物馆数据
|
const getSceneMuseumData = async () => {
|
try {
|
const { code, data } = await $http.request('get', '/api/filmLocation/getTop3')
|
if (code === 0 && data) {
|
cardList.value = data.map(item => ({
|
image: item.locationUrl,
|
title: item.locationName,
|
subtitle: item.address,
|
readTime: `${item.locationWeight}热度`
|
}))
|
}
|
} catch (error) {
|
console.error('获取场景博物馆数据失败:', error)
|
$message.showToast('获取场景博物馆数据失败')
|
}
|
}
|
// 内容精选
|
const getFilmWorks = async (type: String, pageSize: Number, currentPage: Number) => {
|
const {
|
code, data
|
} = await $http.request('get', '/api/filmWorks/list', {
|
params: {
|
classify: type,
|
size: pageSize,
|
status: 'published',
|
current: currentPage
|
}
|
})
|
if (code == 0) {
|
return data.records
|
} else {
|
$message.showToast('系统异常,无法获取数据')
|
return null;
|
}
|
}
|
|
// 下一页
|
const nextPage = () => {
|
if (currentPage.value < totalPages.value - 1) {
|
currentPage.value++
|
}
|
}
|
|
// 上一页
|
const prevPage = () => {
|
if (currentPage.value > 0) {
|
currentPage.value--
|
}
|
}
|
|
// swiper 改变时触发
|
const onSwiperChange = (e: SwiperChangeEvent) => {
|
currentPage.value = e.detail.current
|
}
|
</script>
|
|
<style scoped>
|
.app.light {
|
background-color: #fff;
|
color: #000;
|
}
|
|
/* 其他样式保持不变或根据需要调整 */
|
</style>
|
<style scoped>
|
.main-content {
|
margin: 30rpx;
|
}
|
|
.row {
|
display: flex;
|
align-items: center;
|
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">
|
.section {
|
// margin-top: 30rpx;
|
|
.space-between {
|
justify-content: space-between;
|
}
|
|
.row {
|
display: flex;
|
align-items: center;
|
padding: 10rpx 0;
|
}
|
|
.row-right {
|
display: flex;
|
align-items: center;
|
padding: 20rpx 0;
|
// justify-content: end;
|
justify-content: space-between;
|
}
|
|
.left-text {
|
font-size: 40rpx;
|
font-weight: bold;
|
color: var(--icon-color);
|
letter-spacing: 5rpx;
|
}
|
|
.right-text {
|
font-size: 25rpx;
|
margin-right: 10rpx;
|
}
|
|
.theme-text {
|
margin-left: 10rpx;
|
}
|
}
|
</style>
|