804 lines
21 KiB
Vue
804 lines
21 KiB
Vue
<!-- src/views/Ranking/Overall/Ranking.vue -->
|
||
<template>
|
||
<div class="fullPage" :style="{ backgroundColor }">
|
||
<!-- 预加载状态 -->
|
||
<div v-show="isLoading" class="loading-container">
|
||
<!-- 背景图 -->
|
||
<BackgroundLayer :backgroundImages="[currentBgImage]" />
|
||
|
||
<!-- 加载动画 -->
|
||
<div class="loading-spinner"></div>
|
||
<p>{{ $t('loading') }}...</p>
|
||
</div>
|
||
|
||
<!-- 主要内容 -->
|
||
<div v-show="!isLoading" style="position: relative; z-index: 4">
|
||
<!-- 背景图 -->
|
||
<BackgroundLayer
|
||
:backgroundImages="[currentBgImage]"
|
||
:layerStyle="{
|
||
zIndex: -1,
|
||
}"
|
||
/>
|
||
|
||
<!-- 哨兵元素 -->
|
||
<div ref="sentinel"></div>
|
||
|
||
<!-- 粘性布局贴顶部 -->
|
||
<div
|
||
ref="stickyHeader"
|
||
style="
|
||
position: sticky;
|
||
top: 0;
|
||
z-index: 999;
|
||
border-radius: 0 0 12px 12px;
|
||
transition: all 0.3s;
|
||
"
|
||
>
|
||
<!-- 状态栏占位区域(仅在APP中显示) -->
|
||
<div v-if="isInAppEnvironment" style="height: 60px"></div>
|
||
|
||
<!-- 顶部导航栏 -->
|
||
<div style="padding: 4px 8%">
|
||
<div style="display: flex; justify-content: space-around; position: relative">
|
||
<div
|
||
class="tab"
|
||
@click="changeType('Wealth')"
|
||
style=""
|
||
:style="{ color: rankingType == 'Wealth' ? '#FFB760' : '#fff' }"
|
||
>
|
||
{{ t('ranking_wealth') }}
|
||
</div>
|
||
<div
|
||
class="tab"
|
||
@click="changeType('Charm')"
|
||
style=""
|
||
:style="{ color: rankingType == 'Charm' ? '#60FF83' : '#fff' }"
|
||
>
|
||
{{ t('ranking_charm') }}
|
||
</div>
|
||
<div
|
||
class="tab"
|
||
@click="changeType('Room')"
|
||
style=""
|
||
:style="{ color: rankingType == 'Room' ? '#9B60FF' : '#fff' }"
|
||
>
|
||
{{ t('ranking_room') }}
|
||
</div>
|
||
|
||
<!-- 推出键 -->
|
||
<img
|
||
v-smart-img
|
||
src="../../../assets/icon/arrowBack.png"
|
||
alt=""
|
||
style="position: absolute; left: 0; top: 50%; transform: translateY(-50%)"
|
||
width="6%"
|
||
@click="closePage"
|
||
/>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 排行榜时间选择 -->
|
||
<div
|
||
style="
|
||
margin: 10px 4% 0;
|
||
padding: 4px 16px;
|
||
border-radius: 32px;
|
||
backdrop-filter: blur(32px);
|
||
|
||
display: grid;
|
||
grid-template-columns: repeat(3, 1fr);
|
||
"
|
||
:style="{ border, background }"
|
||
>
|
||
<!-- <div
|
||
class="tag"
|
||
:class="{ tagActive: selectedTimeTab == 'Hourly' }"
|
||
@click="changeDateType('Hourly')"
|
||
>
|
||
{{ t('ranking_hourly') }}
|
||
</div> -->
|
||
<div class="tabItem">
|
||
<div
|
||
class="tag"
|
||
:class="{ tagActive: selectedTimeTab == 'Daily' }"
|
||
@click="changeDateType('Daily')"
|
||
>
|
||
{{ t('ranking_daily') }}
|
||
</div>
|
||
</div>
|
||
|
||
<div class="tabItem">
|
||
<div
|
||
class="tag"
|
||
:class="{ tagActive: selectedTimeTab == 'Weekly' }"
|
||
@click="changeDateType('Weekly')"
|
||
>
|
||
{{ t('ranking_weekly') }}
|
||
</div>
|
||
</div>
|
||
|
||
<div class="tabItem">
|
||
<div
|
||
class="tag"
|
||
:class="{ tagActive: selectedTimeTab == 'Monthly' }"
|
||
@click="changeDateType('Monthly')"
|
||
>
|
||
{{ t('ranking_monthly') }}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 排行榜模块 -->
|
||
<div style="padding: 10px 0">
|
||
<!-- 前3名 -->
|
||
<div style="margin: 3% 10px 0; min-height: 70vw">
|
||
<!-- 第一 -->
|
||
<div style="display: flex; justify-content: center">
|
||
<TopUser
|
||
:Type="rankingType"
|
||
:isTopOne="true"
|
||
:BorderImgUrl="topBorderBg"
|
||
:avatarUrl="RankingTop3[0].avatar || ''"
|
||
:name="RankingTop3[0].nickname || ''"
|
||
:distributionValue="RankingTop3[0].quantityFormat || ''"
|
||
style="width: 40%"
|
||
@click="gotoAppPage(RankingTop3[0].id)"
|
||
/>
|
||
</div>
|
||
<!-- 第二三 -->
|
||
<div style="display: flex; justify-content: space-between; margin-top: -45%">
|
||
<TopUser
|
||
:Type="rankingType"
|
||
:BorderImgUrl="top2BorderBg"
|
||
:avatarUrl="RankingTop3[1].avatar || ''"
|
||
:name="RankingTop3[1].nickname || ''"
|
||
:distributionValue="RankingTop3[1].quantityFormat || ''"
|
||
style="width: 32%"
|
||
@click="gotoAppPage(RankingTop3[1].id)"
|
||
/>
|
||
<TopUser
|
||
:Type="rankingType"
|
||
:BorderImgUrl="top3BorderBg"
|
||
:avatarUrl="RankingTop3[2].avatar || ''"
|
||
:name="RankingTop3[2].nickname || ''"
|
||
:distributionValue="RankingTop3[2].quantityFormat || ''"
|
||
style="width: 32%"
|
||
@click="gotoAppPage(RankingTop3[2].id)"
|
||
/>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 第四名开始 -->
|
||
<div style="padding: 3vw 3vw 0; display: flex; flex-direction: column; gap: 2vw">
|
||
<div
|
||
v-for="(userInfo, index) in RankingFromTop4"
|
||
:key="userInfo.id"
|
||
style="
|
||
border-radius: 12px;
|
||
backdrop-filter: blur(32px);
|
||
padding: 3vw;
|
||
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
gap: 8px;
|
||
"
|
||
:style="{ background: rankItemBackground, border: '1px ' + rankItemBorder }"
|
||
@click="gotoAppPage(userInfo.id)"
|
||
>
|
||
<!-- 基本信息 -->
|
||
<div
|
||
style="
|
||
flex: 1;
|
||
min-width: 0;
|
||
align-self: stretch;
|
||
|
||
display: flex;
|
||
justify-content: space-around;
|
||
align-items: center;
|
||
gap: 8px;
|
||
"
|
||
>
|
||
<!-- 排名 -->
|
||
<div
|
||
style="
|
||
width: auto;
|
||
min-width: 0;
|
||
align-self: stretch;
|
||
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
"
|
||
>
|
||
<div style="font-weight: 700">{{ index + 4 }}</div>
|
||
</div>
|
||
|
||
<!-- 头像 -->
|
||
<img
|
||
v-smart-img
|
||
:src="userInfo.avatar || ''"
|
||
alt=""
|
||
style="
|
||
display: block;
|
||
width: 3em;
|
||
|
||
aspect-ratio: 1/1;
|
||
border-radius: 50%;
|
||
object-fit: cover;
|
||
"
|
||
:style="{ borderRadius: rankingType === 'Room' ? '10%' : '50%' }"
|
||
@error="handleAvatarImageError"
|
||
/>
|
||
|
||
<!-- 名称 -->
|
||
<div
|
||
style="
|
||
flex: 1;
|
||
min-width: 0;
|
||
padding: 0 4px;
|
||
|
||
font-weight: 700;
|
||
overflow: hidden;
|
||
white-space: nowrap;
|
||
text-overflow: ellipsis;
|
||
"
|
||
>
|
||
{{ userInfo.nickname }}
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 贡献值 -->
|
||
<div
|
||
style="
|
||
width: auto;
|
||
min-width: 0;
|
||
align-self: stretch;
|
||
|
||
display: flex;
|
||
align-items: center;
|
||
"
|
||
>
|
||
<img
|
||
v-smart-img
|
||
src="/src/assets/icon/coin.png"
|
||
alt=""
|
||
style="display: block; width: 1.3em; aspect-ratio: 1/1"
|
||
/>
|
||
<div style="font-weight: 500; color: rgba(248, 182, 45, 1)">
|
||
{{ userInfo.quantityFormat }}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 我的排名占位 -->
|
||
<div v-if="!isLoading" style="height: 15vw"></div>
|
||
|
||
<!-- 我的排名 -->
|
||
<div
|
||
v-if="!isLoading"
|
||
style="position: fixed; bottom: 0; z-index: 999; padding: 0 1px; width: 100%"
|
||
:style="{ backgroundColor }"
|
||
>
|
||
<div
|
||
style="
|
||
border-radius: 12px 12px 0 0;
|
||
backdrop-filter: blur(32px);
|
||
padding: 2%;
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
gap: 8px;
|
||
"
|
||
:style="{
|
||
background: rankItemBackground,
|
||
borderTop: '2px ' + rankItemBorder,
|
||
borderLeft: '1px ' + rankItemBorder,
|
||
borderRight: '1px ' + rankItemBorder,
|
||
}"
|
||
>
|
||
<!-- 基本信息 -->
|
||
<div
|
||
style="
|
||
flex: 1;
|
||
min-width: 0;
|
||
align-self: stretch;
|
||
|
||
display: flex;
|
||
justify-content: space-around;
|
||
align-items: center;
|
||
gap: 8px;
|
||
"
|
||
>
|
||
<!-- 排名 -->
|
||
<div
|
||
style="
|
||
width: auto;
|
||
min-width: 0;
|
||
align-self: stretch;
|
||
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
"
|
||
>
|
||
<div style="font-weight: 700">{{ myRanking.rank || 999 }}</div>
|
||
</div>
|
||
|
||
<!-- 头像 -->
|
||
<img
|
||
v-smart-img
|
||
:src="myRanking.avatar || ''"
|
||
alt=""
|
||
style="
|
||
display: block;
|
||
width: 3em;
|
||
aspect-ratio: 1/1;
|
||
border-radius: 50%;
|
||
object-fit: cover;
|
||
"
|
||
:style="{ borderRadius: rankingType === 'Room' ? '10%' : '50%' }"
|
||
@error="handleAvatarImageError"
|
||
/>
|
||
|
||
<!-- 名称 -->
|
||
<div
|
||
style="
|
||
flex: 1;
|
||
min-width: 0;
|
||
font-weight: 700;
|
||
padding: 0 4px;
|
||
|
||
overflow: hidden;
|
||
white-space: nowrap;
|
||
text-overflow: ellipsis;
|
||
"
|
||
>
|
||
{{ myRanking.nickname || '' }}
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 贡献值 -->
|
||
<div
|
||
style="
|
||
width: auto;
|
||
min-width: 0;
|
||
align-self: stretch;
|
||
|
||
display: flex;
|
||
align-items: center;
|
||
"
|
||
>
|
||
<img
|
||
v-smart-img
|
||
src="/src/assets/icon/coin.png"
|
||
alt=""
|
||
style="display: block; width: 1.3em; aspect-ratio: 1/1"
|
||
/>
|
||
<div style="font-weight: 500; color: rgba(248, 182, 45, 1)">
|
||
{{ myRanking.quantityFormat || 0 }}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { computed, onMounted, ref, watch, watchEffect } from 'vue'
|
||
import { useRoute } from 'vue-router'
|
||
import { useI18n } from 'vue-i18n'
|
||
import { isInApp, closePage, viewUserInfo, gotoRoom } from '@/utils/appBridge.js'
|
||
import { connectToApp } from '@/utils/appConnector.js'
|
||
import { preloadImages } from '@/utils/imagePreloader'
|
||
import { getPngUrl } from '@/config/imagePaths.js'
|
||
import { handleAvatarImageError } from '@/utils/imageHandler.js'
|
||
import { useThrottle } from '@/utils/useDebounce'
|
||
|
||
import { getWealthRanking, getCharmRanking, getRoomRanking, getMyRanking } from '@/api/ranking'
|
||
|
||
import BackgroundLayer from '@/components/BackgroundLayer.vue'
|
||
import TopUser from './components/topUser.vue'
|
||
|
||
const route = useRoute()
|
||
const { t, locale } = useI18n()
|
||
|
||
// 获取OSS图片URL的函数
|
||
const imageUrl = (filename) => getPngUrl('Ranking/Overall/', filename)
|
||
|
||
const isInAppEnvironment = ref(false) // 检测是否在APP环境中
|
||
const rankingType = ref(route.query.first || 'Wealth') //榜单类型
|
||
const selectedTimeTab = ref('Daily') //时间标签
|
||
|
||
// 接口参数
|
||
const params_type = ref('GIFTS_SEND') //排行榜类型
|
||
const params_dateType = ref('DAY') //时间类型
|
||
|
||
const totalRanking = ref({})
|
||
const showRanking = ref([])
|
||
const myRanking = ref({}) //我的排名
|
||
|
||
// 预加载状态
|
||
const isLoading = ref(true)
|
||
|
||
const currentBgImage = computed(() => {
|
||
if (rankingType.value == 'Wealth') {
|
||
return imageUrl('bgWealth')
|
||
} else if (rankingType.value == 'Charm') {
|
||
return imageUrl('bgCharm')
|
||
} else if (rankingType.value == 'Room') {
|
||
return imageUrl('bgRoom')
|
||
}
|
||
return '' // 默认返回空字符串
|
||
})
|
||
|
||
// 预加载关键图片
|
||
const preloadCriticalImages = async () => {
|
||
const criticalImages = [
|
||
imageUrl('bgWealth'),
|
||
imageUrl('bgCharm'),
|
||
imageUrl('bgRoom'),
|
||
imageUrl('top1-wealth'),
|
||
imageUrl('top1-charm'),
|
||
imageUrl('top1-room'),
|
||
imageUrl('top2'),
|
||
imageUrl('top3'),
|
||
imageUrl('top2-room'),
|
||
imageUrl('top3-room'),
|
||
]
|
||
|
||
await preloadImages(criticalImages)
|
||
}
|
||
|
||
// 筛选展示榜单
|
||
const updateTimeRanking = () => {
|
||
console.log('updateTimeRanking()//筛选展示榜单')
|
||
|
||
if (selectedTimeTab.value == 'Hourly' && totalRanking.value.hourly) {
|
||
showRanking.value = totalRanking.value.hourly
|
||
console.log('showRanking.value:', showRanking.value)
|
||
} else if (selectedTimeTab.value == 'Daily' && totalRanking.value.daily) {
|
||
showRanking.value = totalRanking.value.daily
|
||
} else if (selectedTimeTab.value == 'Weekly' && totalRanking.value.weekly) {
|
||
showRanking.value = totalRanking.value.weekly
|
||
} else if (selectedTimeTab.value == 'Monthly' && totalRanking.value.monthly) {
|
||
showRanking.value = totalRanking.value.monthly
|
||
}
|
||
}
|
||
const ThrottleChangeType = (type) => {
|
||
if (rankingType.value != type) {
|
||
console.log('改变rankingType')
|
||
rankingType.value = type
|
||
selectedTimeTab.value = 'Daily'
|
||
params_dateType.value = 'DAY'
|
||
|
||
if (type == 'Wealth') {
|
||
params_type.value = 'GIFTS_SEND'
|
||
} else if (type == 'Charm') {
|
||
params_type.value = 'GIFTS_RECEIVED'
|
||
} else if (type == 'Room') {
|
||
params_type.value = 'ROOM_GIFTS'
|
||
}
|
||
|
||
// 清空数据
|
||
totalRanking.value = {}
|
||
showRanking.value = []
|
||
myRanking.value = {}
|
||
|
||
getRanking() // 获取榜单
|
||
getMyRankingInfo() //获取我的排名
|
||
}
|
||
}
|
||
|
||
// 改变排行榜类型
|
||
const changeType = useThrottle(ThrottleChangeType, 1000)
|
||
|
||
// 改变时间类型
|
||
const ThrottleChangeDateType = (dateType) => {
|
||
if (selectedTimeTab.value != dateType) {
|
||
console.log('改变rankingType')
|
||
selectedTimeTab.value = dateType
|
||
|
||
if (dateType == 'Hourly') {
|
||
params_dateType.value = 'HOUR'
|
||
} else if (dateType == 'Daily') {
|
||
params_dateType.value = 'DAY'
|
||
} else if (dateType == 'Weekly') {
|
||
params_dateType.value = 'WEEK'
|
||
} else if (dateType == 'Monthly') {
|
||
params_dateType.value = 'MONTH'
|
||
}
|
||
|
||
// 清空数据
|
||
showRanking.value = []
|
||
myRanking.value = {}
|
||
|
||
updateTimeRanking() //筛选展示榜单
|
||
getMyRankingInfo() //获取我的排名
|
||
}
|
||
}
|
||
|
||
const changeDateType = useThrottle(ThrottleChangeDateType, 500)
|
||
|
||
// 前三名榜单
|
||
const RankingTop3 = computed(() => {
|
||
console.log('刷新RankingTop3')
|
||
|
||
let RankingShow = [...showRanking.value]
|
||
if (showRanking.value.length < 3) {
|
||
let addNullUser = Array.from({ length: 3 - showRanking.value.length }, () => ({
|
||
avatar: '',
|
||
nickname: '',
|
||
quantityFormat: '',
|
||
}))
|
||
RankingShow.push(...addNullUser)
|
||
}
|
||
return RankingShow
|
||
})
|
||
|
||
// 从第四名开始榜单
|
||
const RankingFromTop4 = computed(() => {
|
||
return showRanking.value.filter((_, index) => index >= 3)
|
||
// return []
|
||
})
|
||
|
||
// 动态样式
|
||
const backgroundColor = ref('') //页面样式
|
||
const border = ref('') //时间标签样式
|
||
const background = ref('') //时间标签样式
|
||
const rankItemBackground = ref('') //排名项背景
|
||
const rankItemBorder = ref('') //排名项边框
|
||
|
||
const topBorderBg = ref('') //top1头像框
|
||
const top2BorderBg = ref('') //top2头像框
|
||
const top3BorderBg = ref('') //top3头像框
|
||
|
||
const sentinel = ref(null)
|
||
const stickyHeader = ref(null)
|
||
|
||
watchEffect(() => {
|
||
if (rankingType.value == 'Wealth') {
|
||
backgroundColor.value = '#230F0A'
|
||
topBorderBg.value = imageUrl('top1-wealth')
|
||
top2BorderBg.value = imageUrl('top2')
|
||
top3BorderBg.value = imageUrl('top3')
|
||
border.value = '1px solid rgba(221, 114, 0, 0.39)'
|
||
background.value = 'rgba(252, 194, 147, 0.20)'
|
||
rankItemBackground.value =
|
||
'linear-gradient(97deg, rgba(50, 34, 21, 0.60) 12.03%, rgba(99, 52, 33, 0.60) 100.37%)'
|
||
rankItemBorder.value = 'solid #FFA166'
|
||
|
||
params_type.value = 'GIFTS_SEND'
|
||
}
|
||
if (rankingType.value == 'Charm') {
|
||
backgroundColor.value = '#112C1E'
|
||
topBorderBg.value = imageUrl('top1-charm')
|
||
top2BorderBg.value = imageUrl('top2')
|
||
top3BorderBg.value = imageUrl('top3')
|
||
border.value = '1px solid rgba(0, 221, 74, 0.39)'
|
||
background.value = 'rgba(147, 252, 166, 0.20)'
|
||
rankItemBackground.value =
|
||
'linear-gradient(97deg, rgba(21, 50, 22, 0.60) 12.03%, rgba(33, 99, 40, 0.60) 100.37%)'
|
||
rankItemBorder.value = 'solid #66FF82'
|
||
|
||
params_type.value = 'GIFTS_RECEIVED'
|
||
}
|
||
if (rankingType.value == 'Room') {
|
||
backgroundColor.value = '#211031'
|
||
topBorderBg.value = imageUrl('top1-room')
|
||
top2BorderBg.value = imageUrl('top2-room')
|
||
top3BorderBg.value = imageUrl('top3-room')
|
||
border.value = '1px solid rgba(155, 0, 221, 0.39)'
|
||
background.value = 'rgba(219, 147, 252, 0.20)'
|
||
rankItemBackground.value =
|
||
'linear-gradient(97deg, rgba(33, 21, 50, 0.60) 12.03%, rgba(60, 33, 99, 0.60) 100.37%)'
|
||
rankItemBorder.value = 'solid #A366FF'
|
||
|
||
params_type.value = 'ROOM_GIFTS'
|
||
}
|
||
})
|
||
|
||
const observer = new IntersectionObserver((entries) => {
|
||
entries.forEach((entry) => {
|
||
// 哨兵元素离开视口
|
||
if (!entry.isIntersecting) {
|
||
console.log('哨兵元素离开视口')
|
||
if (stickyHeader.value) {
|
||
stickyHeader.value.classList.add('stuck')
|
||
console.log('添加stuck类')
|
||
} else {
|
||
console.log('元素未找到!')
|
||
}
|
||
} else {
|
||
stickyHeader.value.classList.remove('stuck')
|
||
}
|
||
})
|
||
})
|
||
|
||
// 跳转app
|
||
const gotoAppPage = (id) => {
|
||
if (isInAppEnvironment.value) {
|
||
if (rankingType.value == 'Room') {
|
||
gotoRoom(id)
|
||
} else {
|
||
viewUserInfo(id)
|
||
}
|
||
}
|
||
}
|
||
|
||
// 获取榜单
|
||
const getRanking = async () => {
|
||
console.log('获取榜单')
|
||
|
||
let resRanking = {}
|
||
if (rankingType.value == 'Wealth') {
|
||
resRanking = await getWealthRanking()
|
||
} else if (rankingType.value == 'Charm') {
|
||
resRanking = await getCharmRanking()
|
||
} else if (rankingType.value == 'Room') {
|
||
resRanking = await getRoomRanking()
|
||
}
|
||
if (resRanking.status && resRanking.body) {
|
||
totalRanking.value = resRanking.body
|
||
updateTimeRanking() //筛选展示榜单
|
||
}
|
||
}
|
||
|
||
//获取我的排名
|
||
const getMyRankingInfo = async () => {
|
||
console.log('获取我的排名')
|
||
const resMyRanking = await getMyRanking(params_type.value, params_dateType.value)
|
||
if (resMyRanking.status && resMyRanking.body) {
|
||
myRanking.value = resMyRanking.body
|
||
} else {
|
||
myRanking.value = {}
|
||
}
|
||
}
|
||
|
||
// 刷新页面数据
|
||
const initData = async () => {
|
||
await Promise.all([
|
||
getRanking(), // 获取榜单
|
||
getMyRankingInfo(), //获取我的排名
|
||
])
|
||
}
|
||
|
||
// 完成预加载
|
||
const completePreloading = async () => {
|
||
try {
|
||
// 执行所有初始化操作
|
||
await Promise.all([initData(), preloadCriticalImages()])
|
||
} catch (error) {
|
||
console.error('预加载过程中发生错误:', error)
|
||
} finally {
|
||
// 无论成功或失败都结束加载状态
|
||
isLoading.value = false
|
||
}
|
||
}
|
||
|
||
// 使用工具函数连接APP
|
||
const connectToAppHandler = async () => {
|
||
await connectToApp(() => {
|
||
// 连接成功回调
|
||
completePreloading() // 完成预加载
|
||
})
|
||
}
|
||
|
||
onMounted(() => {
|
||
connectToAppHandler()
|
||
isInAppEnvironment.value = isInApp()
|
||
|
||
observer.observe(sentinel.value)
|
||
})
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
* {
|
||
color: #fff;
|
||
}
|
||
|
||
.fullPage {
|
||
width: 100vw;
|
||
min-height: 100vh;
|
||
background-size: 100% auto;
|
||
background-repeat: no-repeat;
|
||
position: relative;
|
||
}
|
||
|
||
.tab {
|
||
font-weight: 700;
|
||
font-size: 1em;
|
||
}
|
||
|
||
.tabItem {
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
}
|
||
|
||
.tag {
|
||
font-weight: 510;
|
||
padding: 4px 10%;
|
||
}
|
||
|
||
.tagActive {
|
||
color: black;
|
||
border-radius: 32px;
|
||
border: 1px solid #f5f54c;
|
||
box-sizing: border-box;
|
||
background: #fcfc93;
|
||
box-shadow: 0 0 8.6px 3px #fc8b02 inset;
|
||
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
}
|
||
|
||
.stuck {
|
||
background-color: rgba(255, 255, 255, 0.1);
|
||
backdrop-filter: blur(32px);
|
||
}
|
||
|
||
/* 添加加载动画样式 */
|
||
.loading-container {
|
||
width: 100vw;
|
||
height: 100vh;
|
||
display: flex;
|
||
flex-direction: column;
|
||
justify-content: center;
|
||
align-items: center;
|
||
color: #666;
|
||
|
||
overflow: hidden;
|
||
position: relative;
|
||
}
|
||
|
||
.loading-spinner {
|
||
width: 32px;
|
||
height: 32px;
|
||
border: 3px solid #f3f3f3;
|
||
border-top: 3px solid #f59e0b;
|
||
border-radius: 50%;
|
||
animation: spin 1s linear infinite;
|
||
margin-bottom: 12px;
|
||
}
|
||
|
||
@keyframes spin {
|
||
0% {
|
||
transform: rotate(0deg);
|
||
}
|
||
100% {
|
||
transform: rotate(360deg);
|
||
}
|
||
}
|
||
|
||
@media screen and (max-width: 360px) {
|
||
* {
|
||
font-size: 10px;
|
||
}
|
||
}
|
||
|
||
@media screen and (min-width: 360px) {
|
||
* {
|
||
font-size: 14px;
|
||
}
|
||
}
|
||
|
||
@media screen and (min-width: 768px) {
|
||
* {
|
||
font-size: 24px;
|
||
}
|
||
}
|
||
|
||
@media screen and (min-width: 1024px) {
|
||
* {
|
||
font-size: 32px;
|
||
}
|
||
}
|
||
</style>
|