mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-06-07 16:49:52 +08:00
优化排名展示效果
This commit is contained in:
@@ -84,6 +84,25 @@ function getPodiumStatStyle() {
|
||||
}
|
||||
}
|
||||
|
||||
// 获取前三名区域背景样式
|
||||
function getPodiumAreaBackgroundStyle() {
|
||||
const isDark = theme.global.current.value.dark
|
||||
return {
|
||||
background: isDark
|
||||
? 'linear-gradient(135deg, rgba(255, 215, 0, 0.25) 0%, rgba(255, 69, 0, 0.2) 25%, rgba(255, 20, 147, 0.15) 50%, rgba(138, 43, 226, 0.1) 75%, rgba(0, 191, 255, 0.08) 100%), linear-gradient(to bottom, transparent 0%, transparent 70%, rgba(255, 215, 0, 0.1) 85%, transparent 100%)'
|
||||
: 'linear-gradient(135deg, rgba(255, 215, 0, 0.2) 0%, rgba(255, 69, 0, 0.15) 25%, rgba(255, 20, 147, 0.12) 50%, rgba(138, 43, 226, 0.08) 75%, rgba(0, 191, 255, 0.05) 100%), linear-gradient(to bottom, transparent 0%, transparent 70%, rgba(255, 215, 0, 0.08) 85%, transparent 100%)',
|
||||
border: 'none',
|
||||
borderRadius: '0',
|
||||
padding: '32px 24px 48px 24px',
|
||||
margin: '0 -24px 0 -',
|
||||
boxShadow: isDark
|
||||
? '0 16px 48px rgba(255, 215, 0, 0.2), inset 0 1px 0 rgba(255, 255, 255, 0.1)'
|
||||
: '0 16px 48px rgba(255, 215, 0, 0.15), inset 0 1px 0 rgba(255, 255, 255, 0.3)',
|
||||
position: 'relative' as const,
|
||||
overflow: 'hidden',
|
||||
}
|
||||
}
|
||||
|
||||
// 获取排名图标
|
||||
function getRankIcon(rank: number) {
|
||||
if (rank === 1) return 'mdi-trophy'
|
||||
@@ -109,18 +128,25 @@ onMounted(() => {
|
||||
</VCardItem>
|
||||
<VDialogCloseBtn @click="emit('close')" />
|
||||
<VDivider />
|
||||
<VCardText>
|
||||
<VCardText class="pa-0">
|
||||
<LoadingBanner v-if="loading" class="mt-4" />
|
||||
<div v-else-if="rankedStatistics.length === 0" class="text-center py-8">
|
||||
<VIcon icon="mdi-chart-line" size="64" color="grey" class="mb-4" />
|
||||
<div class="text-h6 text-grey">{{ t('subscribe.noStatisticsData') }}</div>
|
||||
</div>
|
||||
|
||||
<div v-else class="mt-4">
|
||||
<div v-else>
|
||||
<!-- 前三名特殊展示 -->
|
||||
<div class="mb-6">
|
||||
<div class="text-h6 mb-4 text-center">{{ t('subscribe.ranking') }}</div>
|
||||
<div class="d-flex justify-center align-center gap-4 flex-wrap">
|
||||
<div class="podium-area" :style="getPodiumAreaBackgroundStyle()">
|
||||
<!-- 装饰性背景元素 -->
|
||||
<div class="podium-decoration">
|
||||
<div class="decoration-circle decoration-1"></div>
|
||||
<div class="decoration-circle decoration-2"></div>
|
||||
<div class="decoration-circle decoration-3"></div>
|
||||
</div>
|
||||
<div class="text-h6 mb-4 text-center podium-title">{{ t('subscribe.ranking') }}</div>
|
||||
<!-- 大屏幕横向排列 -->
|
||||
<div class="d-none d-md-flex justify-center align-center gap-4 flex-wrap">
|
||||
<!-- 第二名 -->
|
||||
<div v-if="rankedStatistics[1]" class="text-center">
|
||||
<div class="rank-circle mb-2" :style="getRankStyle(2)">
|
||||
@@ -193,24 +219,86 @@ onMounted(() => {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 小屏幕垂直排列 -->
|
||||
<div class="d-flex d-md-none flex-column align-center gap-4">
|
||||
<!-- 第一名 -->
|
||||
<div v-if="rankedStatistics[0]" class="text-center">
|
||||
<div class="rank-circle mb-2 first-place" :style="getRankStyle(1)">
|
||||
<VIcon :icon="getRankIcon(1)" size="32" />
|
||||
</div>
|
||||
<div class="text-h5 font-weight-bold" :style="{ color: getPodiumTextColor() }">
|
||||
{{ rankedStatistics[0].share_user || '未知' }}
|
||||
</div>
|
||||
<div class="d-flex align-center justify-center gap-3 mt-1">
|
||||
<div class="d-flex align-center podium-stat" :style="getPodiumStatStyle()">
|
||||
<VIcon icon="mdi-share-outline" size="14" :color="getPodiumTextColor()" class="mr-1" />
|
||||
<span :style="{ color: getPodiumTextColor() }">{{ rankedStatistics[0].share_count || 0 }}</span>
|
||||
</div>
|
||||
<div class="d-flex align-center podium-stat" :style="getPodiumStatStyle()">
|
||||
<VIcon icon="mdi-fire" size="14" :color="getPodiumTextColor()" class="mr-1" />
|
||||
<span :style="{ color: getPodiumTextColor() }">{{
|
||||
rankedStatistics[0].total_reuse_count || 0
|
||||
}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 第二名 -->
|
||||
<div v-if="rankedStatistics[1]" class="text-center">
|
||||
<div class="rank-circle mb-2" :style="getRankStyle(2)">
|
||||
<VIcon :icon="getRankIcon(2)" size="24" />
|
||||
</div>
|
||||
<div class="text-h6 font-weight-bold" :style="{ color: getPodiumTextColor() }">
|
||||
{{ rankedStatistics[1].share_user || '未知' }}
|
||||
</div>
|
||||
<div class="d-flex align-center justify-center gap-2 mt-1">
|
||||
<div class="d-flex align-center podium-stat" :style="getPodiumStatStyle()">
|
||||
<VIcon icon="mdi-share-outline" size="14" :color="getPodiumTextColor()" class="mr-1" />
|
||||
<span :style="{ color: getPodiumTextColor() }">{{ rankedStatistics[1].share_count || 0 }}</span>
|
||||
</div>
|
||||
<div class="d-flex align-center podium-stat" :style="getPodiumStatStyle()">
|
||||
<VIcon icon="mdi-fire" size="14" :color="getPodiumTextColor()" class="mr-1" />
|
||||
<span :style="{ color: getPodiumTextColor() }">{{
|
||||
rankedStatistics[1].total_reuse_count || 0
|
||||
}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 第三名 -->
|
||||
<div v-if="rankedStatistics[2]" class="text-center">
|
||||
<div class="rank-circle mb-2" :style="getRankStyle(3)">
|
||||
<VIcon :icon="getRankIcon(3)" size="24" />
|
||||
</div>
|
||||
<div class="text-h6 font-weight-bold" :style="{ color: getPodiumTextColor() }">
|
||||
{{ rankedStatistics[2].share_user || '未知' }}
|
||||
</div>
|
||||
<div class="d-flex align-center justify-center gap-2 mt-1">
|
||||
<div class="d-flex align-center podium-stat" :style="getPodiumStatStyle()">
|
||||
<VIcon icon="mdi-share-outline" size="14" :color="getPodiumTextColor()" class="mr-1" />
|
||||
<span :style="{ color: getPodiumTextColor() }">
|
||||
{{ rankedStatistics[2].share_count || 0 }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="d-flex align-center podium-stat" :style="getPodiumStatStyle()">
|
||||
<VIcon icon="mdi-fire" size="14" :color="getPodiumTextColor()" class="mr-1" />
|
||||
<span :style="{ color: getPodiumTextColor() }">
|
||||
{{ rankedStatistics[2].total_reuse_count || 0 }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 完整排行榜 -->
|
||||
<VDivider class="mb-4" />
|
||||
<div class="text-h6 mb-4">{{ t('subscribe.ranking') }}</div>
|
||||
<VList class="bg-transparent">
|
||||
<VList class="bg-transparent px-3">
|
||||
<VListItem
|
||||
v-for="item in rankedStatistics"
|
||||
v-for="item in rankedStatistics.filter(item => item.rank > 3)"
|
||||
:key="item.share_user"
|
||||
class="mb-2 rounded-lg"
|
||||
:class="item.rank <= 3 ? 'elevation-1 pb-3' : ''"
|
||||
>
|
||||
<template #prepend>
|
||||
<div class="rank-badge mr-3" :style="getRankStyle(item.rank)">
|
||||
<VIcon :icon="getRankIcon(item.rank)" size="16" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<VListItemTitle class="font-weight-bold text-h6 mb-1">
|
||||
{{ item.share_user || '未知' }}
|
||||
</VListItemTitle>
|
||||
@@ -303,4 +391,87 @@ onMounted(() => {
|
||||
.podium-stat:hover {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
/* 前三名区域样式 */
|
||||
.podium-area {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.podium-title {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
color: #fff !important;
|
||||
font-weight: bold;
|
||||
text-shadow: 0 2px 4px rgba(0, 0, 0, 30%);
|
||||
}
|
||||
|
||||
/* 装饰性元素 */
|
||||
.podium-decoration {
|
||||
position: absolute;
|
||||
z-index: 0;
|
||||
inset: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.decoration-circle {
|
||||
position: absolute;
|
||||
border-radius: 50%;
|
||||
animation: float 6s ease-in-out infinite;
|
||||
background: radial-gradient(circle, rgba(255, 255, 255, 10%) 0%, transparent 70%);
|
||||
}
|
||||
|
||||
.decoration-1 {
|
||||
animation-delay: 0s;
|
||||
block-size: 80px;
|
||||
inline-size: 80px;
|
||||
inset-block-start: 10%;
|
||||
inset-inline-start: 10%;
|
||||
}
|
||||
|
||||
.decoration-2 {
|
||||
animation-delay: 2s;
|
||||
block-size: 60px;
|
||||
inline-size: 60px;
|
||||
inset-block-start: 20%;
|
||||
inset-inline-end: 15%;
|
||||
}
|
||||
|
||||
.decoration-3 {
|
||||
animation-delay: 4s;
|
||||
block-size: 40px;
|
||||
inline-size: 40px;
|
||||
inset-block-end: 20%;
|
||||
inset-inline-start: 20%;
|
||||
}
|
||||
|
||||
@keyframes float {
|
||||
0%,
|
||||
100% {
|
||||
opacity: 0.6;
|
||||
transform: translateY(0) rotate(0deg);
|
||||
}
|
||||
|
||||
50% {
|
||||
opacity: 1;
|
||||
transform: translateY(-10px) rotate(180deg);
|
||||
}
|
||||
}
|
||||
|
||||
/* 增强前三名文字效果 */
|
||||
.podium-area .text-h6,
|
||||
.podium-area .text-h5 {
|
||||
font-weight: bold;
|
||||
text-shadow: 0 2px 4px rgba(0, 0, 0, 30%);
|
||||
}
|
||||
|
||||
.podium-area .rank-circle {
|
||||
border: 2px solid rgba(255, 255, 255, 20%);
|
||||
box-shadow: 0 8px 24px rgba(0, 0, 0, 30%);
|
||||
}
|
||||
|
||||
.podium-area .first-place {
|
||||
border: 3px solid rgba(255, 215, 0, 50%);
|
||||
box-shadow: 0 12px 32px rgba(255, 215, 0, 40%);
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user