feat(新页面): 排行榜

This commit is contained in:
hzj 2025-09-29 20:56:10 +08:00
parent 9e82f2c93d
commit f2c71c1597
2 changed files with 197 additions and 70 deletions

37
src/api/ranking.js Normal file
View File

@ -0,0 +1,37 @@
import { get, post } from '../utils/http.js'
// 获取财富榜
export const getWealthRanking = async () => {
try {
const response = await get(`/activity/leaderboard/gifts-send`)
return response
} catch (error) {
console.error('Failed to fetch get wealth ranking:', error)
console.error('error:' + error.response.errorMsg)
throw error
}
}
// 获取魅力榜
export const getCharmRanking = async () => {
try {
const response = await get(`/activity/leaderboard/gifts-received`)
return response
} catch (error) {
console.error('Failed to fetch get charm ranking:', error)
console.error('error:' + error.response.errorMsg)
throw error
}
}
// 获取房间榜
export const getRoomRanking = async () => {
try {
const response = await get(`/activity/leaderboard/room-gifts`)
return response
} catch (error) {
console.error('Failed to fetch get room ranking:', error)
console.error('error:' + error.response.errorMsg)
throw error
}
}

View File

@ -1,7 +1,7 @@
<template> <template>
<div class="fullPage" :style="{ backgroundColor, backgroundImage }"> <div class="fullPage" :style="{ backgroundColor, backgroundImage }">
<div ref="sentinel"></div>
<!-- 哨兵元素 --> <!-- 哨兵元素 -->
<div ref="sentinel"></div>
<!-- 粘性布局贴顶部 --> <!-- 粘性布局贴顶部 -->
<div <div
@ -102,7 +102,7 @@
</div> </div>
<!-- 排行榜模块 --> <!-- 排行榜模块 -->
<div> <div style="padding: 10px 0">
<!-- 前3名 --> <!-- 前3名 -->
<div style="margin: 3% 10px 0"> <div style="margin: 3% 10px 0">
<!-- 第一 --> <!-- 第一 -->
@ -111,9 +111,9 @@
:isRoom="rankingType === 'Room'" :isRoom="rankingType === 'Room'"
:isTopOne="true" :isTopOne="true"
:BorderImgUrl="topBorderBg" :BorderImgUrl="topBorderBg"
avatarUrl="" :avatarUrl="RankingTop3[0].avatar || ''"
name="aaaa" :name="RankingTop3[0].nickname || ''"
distributionValue="11111" :distributionValue="RankingTop3[0].quantityFormat || ''"
style="width: 40%" style="width: 40%"
/> />
</div> </div>
@ -122,17 +122,17 @@
<TopUser <TopUser
:isRoom="rankingType === 'Room'" :isRoom="rankingType === 'Room'"
:BorderImgUrl="top2BorderBg" :BorderImgUrl="top2BorderBg"
avatarUrl="" :avatarUrl="RankingTop3[1].avatar || ''"
name="aaaa" :name="RankingTop3[1].nickname || ''"
distributionValue="11111" :distributionValue="RankingTop3[1].quantityFormat || ''"
style="width: 30%" style="width: 30%"
/> />
<TopUser <TopUser
:isRoom="rankingType === 'Room'" :isRoom="rankingType === 'Room'"
:BorderImgUrl="top3BorderBg" :BorderImgUrl="top3BorderBg"
avatarUrl="" :avatarUrl="RankingTop3[2].avatar || ''"
name="aaaa" :name="RankingTop3[2].nickname || ''"
distributionValue="11111" :distributionValue="RankingTop3[2].quantityFormat || ''"
style="width: 30%" style="width: 30%"
/> />
</div> </div>
@ -141,7 +141,8 @@
<!-- 第四名开始 --> <!-- 第四名开始 -->
<div style="margin: 3% 10px 0"> <div style="margin: 3% 10px 0">
<div <div
v-for="value in 9" v-for="(userInfo, index) in RankingFromTop4"
:key="userInfo.id"
style=" style="
border-radius: 12px; border-radius: 12px;
backdrop-filter: blur(32px); backdrop-filter: blur(32px);
@ -154,12 +155,18 @@
:style="{ background: rankItemBackground, border: '1px ' + rankItemBorder }" :style="{ background: rankItemBackground, border: '1px ' + rankItemBorder }"
> >
<div style="display: flex; align-items: center; width: 70%"> <div style="display: flex; align-items: center; width: 70%">
<div style="font-weight: 700">999</div> <div style="font-weight: 700">{{ index + 4 }}</div>
<img <img
src="" :src="userInfo.avatar"
alt="" alt=""
width="20%" width="20%"
style="display: block; aspect-ratio: 1/1; margin: 0 4px" style="
display: block;
border-radius: 50%;
object-fit: cover;
aspect-ratio: 1/1;
margin: 0 4px;
"
:style="{ borderRadius: rankingType === 'Room' ? '0' : '50%' }" :style="{ borderRadius: rankingType === 'Room' ? '0' : '50%' }"
@error="defaultAvatarUrl" @error="defaultAvatarUrl"
/> />
@ -171,7 +178,7 @@
text-overflow: ellipsis; text-overflow: ellipsis;
" "
> >
aaaaaaaaaaaa {{ userInfo.nickname }}
</div> </div>
</div> </div>
<div style="display: flex; align-items: center; width: 30%"> <div style="display: flex; align-items: center; width: 30%">
@ -190,67 +197,70 @@
text-overflow: ellipsis; text-overflow: ellipsis;
" "
> >
123456789 {{ userInfo.quantityFormat }}
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div>
<!-- 我的排名 --> <!-- 我的排名 -->
<div style="position: sticky; bottom: 0; z-index: 999; padding: 0 1px; width: 100%"> <div
<div style="position: sticky; bottom: 0; z-index: 999; padding: 0 1px; width: 100%"
style=" :style="{ backgroundColor }"
border-radius: 12px 12px 0 0; >
border-top: 2px solid #ffa166; <div
border-right: 1px solid #ffa166; style="
border-left: 1px solid #ffa166; border-radius: 12px 12px 0 0;
backdrop-filter: blur(32px); border-top: 2px solid #ffa166;
padding: 12px; border-right: 1px solid #ffa166;
display: flex; border-left: 1px solid #ffa166;
justify-content: space-between; backdrop-filter: blur(32px);
align-items: center; padding: 12px;
" display: flex;
:style="{ justify-content: space-between;
background: rankItemBackground, align-items: center;
borderTop: '2px ' + rankItemBorder, "
borderLeft: '1px ' + rankItemBorder, :style="{
borderRight: '1px ' + rankItemBorder, background: rankItemBackground,
}" borderTop: '2px ' + rankItemBorder,
> borderLeft: '1px ' + rankItemBorder,
<div style="display: flex; align-items: center; width: 70%"> borderRight: '1px ' + rankItemBorder,
<div style="font-weight: 700">999</div> }"
<img >
src="" <div style="display: flex; align-items: center; width: 70%">
alt="" <div style="font-weight: 700">999</div>
width="20%" <img
style="display: block; aspect-ratio: 1/1; margin: 0 4px" src=""
@error="defaultAvatarUrl" alt=""
/> width="20%"
<div style="display: block; aspect-ratio: 1/1; margin: 0 4px"
style="font-weight: 700; overflow: hidden; white-space: nowrap; text-overflow: ellipsis" @error="defaultAvatarUrl"
> />
aaaaaaaaaaaa <div
</div> style="font-weight: 700; overflow: hidden; white-space: nowrap; text-overflow: ellipsis"
>
aaaaaaaaaaaa
</div> </div>
<div style="display: flex; align-items: center; width: 30%"> </div>
<img <div style="display: flex; align-items: center; width: 30%">
src="/src/assets/icon/coin.png" <img
alt="" src="/src/assets/icon/coin.png"
width="20%" alt=""
style="display: block; aspect-ratio: 1/1" width="20%"
/> style="display: block; aspect-ratio: 1/1"
<div />
style=" <div
font-weight: 500; style="
color: rgba(248, 182, 45, 1); font-weight: 500;
overflow: hidden; color: rgba(248, 182, 45, 1);
white-space: nowrap; overflow: hidden;
text-overflow: ellipsis; white-space: nowrap;
" text-overflow: ellipsis;
> "
123456789 >
</div> 123456789
</div> </div>
</div> </div>
</div> </div>
@ -261,6 +271,7 @@
import { isInApp, closePage } from '@/utils/appBridge.js' import { isInApp, closePage } from '@/utils/appBridge.js'
import { computed, onMounted, ref, watch, watchEffect } from 'vue' import { computed, onMounted, ref, watch, watchEffect } from 'vue'
import TopUser from '@/components/Ranking/topUser.vue' import TopUser from '@/components/Ranking/topUser.vue'
import { getWealthRanking, getCharmRanking, getRoomRanking } from '@/api/ranking'
//vite //vite
const imageModules = import.meta.glob('@/assets/images/Ranking/*.{png,jpg,svg}', { eager: true }) const imageModules = import.meta.glob('@/assets/images/Ranking/*.{png,jpg,svg}', { eager: true })
@ -276,6 +287,65 @@ const isInAppEnvironment = ref(false) // 检测是否在APP环境中
const rankingType = ref('Wealth') // const rankingType = ref('Wealth') //
const selectedTimeTab = ref('Hourly') // const selectedTimeTab = ref('Hourly') //
const totalRanking = ref({})
const showRanking = ref([])
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
}
}
watch(
() => rankingType.value,
() => {
console.log('监听到rankingType.value变化')
totalRanking.value = {}
showRanking.value = []
//
getRanking()
}
)
watch(
() => selectedTimeTab.value,
() => {
console.log('监听到selectedTimeTab.value变化')
showRanking.value = []
updateTimeRanking() //
}
)
//
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)
})
// //
const backgroundColor = ref('') // const backgroundColor = ref('') //
const backgroundImage = ref('') // const backgroundImage = ref('') //
@ -351,10 +421,30 @@ const observer = new IntersectionObserver((entries) => {
}) })
}) })
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()
}
}
onMounted(() => { onMounted(() => {
isInAppEnvironment.value = isInApp() isInAppEnvironment.value = isInApp()
observer.observe(sentinel.value) observer.observe(sentinel.value)
//
getRanking()
}) })
</script> </script>