feat(rankIng): 添加排行榜弹窗

This commit is contained in:
woody 2025-09-25 11:18:52 +08:00
parent 3c2b8f7475
commit f066a7aab9
10 changed files with 920 additions and 37 deletions

670
components/RankingPopup.vue Normal file
View File

@ -0,0 +1,670 @@
<template>
<view>
<!-- 直推人数排行榜弹窗 -->
<u-popup
class="ranking-popup"
mode="center"
:show="showPeopleRanking"
:closeOnClickOverlay="false"
border-radius="20"
>
<view style="width: 90vw; height: 85vh" class="popup-container">
<!-- 弹窗头部 -->
<view class="popup-header">
<view class="header-title">直推人数排行榜</view>
</view>
<!-- 前三名特殊展示区域 -->
<view class="top-three-section">
<view class="podium-container">
<!-- 第二名 -->
<view class="podium-item second-place" v-if="peopleTopThree[1]">
<view class="player-area">
<view class="rank-number">
<img src="@/static/images/rank-2.svg" alt="" />
</view>
<view
class="member-name"
:class="{ highlight: peopleTopThree[1].isLoginMember == 1 }"
>
{{ peopleTopThree[1].memberName }}
</view>
<view class="member-code">{{
peopleTopThree[1].memberCode
}}</view>
<view class="score">{{ peopleTopThree[1].count }}</view>
</view>
</view>
<!-- 第一名 -->
<view class="podium-item first-place" v-if="peopleTopThree[0]">
<view class="player-area">
<view class="rank-number">
<img src="@/static/images/rank-1.svg" alt="" />
</view>
<view
class="member-name"
:class="{ highlight: peopleTopThree[0].isLoginMember == 1 }"
>
{{ peopleTopThree[0].memberName }}
</view>
<view class="member-code">{{
peopleTopThree[0].memberCode
}}</view>
<view class="score">{{ peopleTopThree[0].count }}</view>
</view>
</view>
<!-- 第三名 -->
<view class="podium-item third-place" v-if="peopleTopThree[2]">
<view class="player-area">
<view class="rank-number">
<img src="@/static/images/rank-3.svg" alt="" />
</view>
<view
class="member-name"
:class="{ highlight: peopleTopThree[2].isLoginMember == 1 }"
>
{{ peopleTopThree[2].memberName }}
</view>
<view class="member-code">{{
peopleTopThree[2].memberCode
}}</view>
<view class="score">{{ peopleTopThree[2].count }}</view>
</view>
</view>
</view>
</view>
<!-- 4-30名滚动列表 -->
<view class="ranking-list">
<view class="list-header">
<text class="list-title">完整排行榜</text>
</view>
<scroll-view
class="scroll-container"
scroll-y="true"
:show-scrollbar="false"
>
<view
class="list-item"
v-for="(item, index) in peopleRemainingList"
:key="index"
>
<view class="item-rank">{{ index + 4 }}</view>
<view class="item-info">
<view
class="item-name"
:class="{ highlight: item.isLoginMember == 1 }"
>
{{ item.memberName }}
</view>
<view class="item-code">{{ item.memberCode }}</view>
</view>
<view class="item-score">{{ item.count }}</view>
</view>
<view class="list-footer" v-if="peopleRemainingList.length === 0">
<text class="empty-text">暂无更多数据</text>
</view>
</scroll-view>
</view>
<!-- 底部关闭按钮 -->
<view class="popup-footer">
<view class="close-text-btn" @click="closePeopleRanking">
</view>
</view>
</view>
</u-popup>
<!-- 直推金额排行榜弹窗 -->
<u-popup
class="ranking-popup"
width="85%"
height="85%"
mode="center"
:show="showAmountRanking"
:closeOnClickOverlay="false"
border-radius="20"
>
<view style="width: 90vw; height: 85vh" class="popup-container">
<!-- 弹窗头部 -->
<view class="popup-header">
<view class="header-title">直推金额排行榜</view>
</view>
<!-- 前三名特殊展示区域 -->
<view class="top-three-section">
<view class="podium-container">
<!-- 第二名 -->
<view class="podium-item second-place" v-if="amountTopThree[1]">
<view class="player-area">
<view class="rank-number">
<img src="@/static/images/rank-2.svg" alt="" />
</view>
<view
class="member-name"
:class="{ highlight: amountTopThree[1].isLoginMember == 1 }"
>
{{ amountTopThree[1].memberName }}
</view>
<view class="member-code">{{
amountTopThree[1].memberCode
}}</view>
<view class="score">{{
formatAmount(amountTopThree[1].amount)
}}</view>
</view>
</view>
<!-- 第一名 -->
<view class="podium-item first-place" v-if="amountTopThree[0]">
<view class="player-area">
<view class="rank-number">
<img src="@/static/images/rank-1.svg" alt="" />
</view>
<view
class="member-name"
:class="{ highlight: amountTopThree[0].isLoginMember == 1 }"
>
{{ amountTopThree[0].memberName }}
</view>
<view class="member-code">{{
amountTopThree[0].memberCode
}}</view>
<view class="score">{{
formatAmount(amountTopThree[0].amount)
}}</view>
</view>
</view>
<!-- 第三名 -->
<view class="podium-item third-place" v-if="amountTopThree[2]">
<view class="player-area">
<view class="rank-number">
<img src="@/static/images/rank-3.svg" alt="" />
</view>
<view
class="member-name"
:class="{ highlight: amountTopThree[2].isLoginMember == 1 }"
>
{{ amountTopThree[2].memberName }}
</view>
<view class="member-code">{{
amountTopThree[2].memberCode
}}</view>
<view class="score">{{
formatAmount(amountTopThree[2].amount)
}}</view>
</view>
</view>
</view>
</view>
<!-- 4-30名滚动列表 -->
<view class="ranking-list">
<view class="list-header">
<text class="list-title">完整排行榜</text>
</view>
<scroll-view
class="scroll-container"
scroll-y="true"
:show-scrollbar="false"
>
<view
class="list-item"
v-for="(item, index) in amountRemainingList"
:key="index"
>
<view class="item-rank">{{ index + 4 }}</view>
<view class="item-info">
<view
class="item-name"
:class="{ highlight: item.isLoginMember == 1 }"
>
{{ item.memberName }}
</view>
<view class="item-code">{{ item.memberCode }}</view>
</view>
<view class="item-score">{{ formatAmount(item.amount) }}</view>
</view>
<view class="list-footer" v-if="amountRemainingList.length === 0">
<text class="empty-text">暂无更多数据</text>
</view>
</scroll-view>
</view>
<!-- 底部关闭按钮 -->
<view class="popup-footer">
<view class="close-text-btn" @click="closeAmountRanking">
</view>
</view>
</view>
</u-popup>
<!-- 加载状态 -->
<u-loading-page
:loading="loading"
loading-text="加载中..."
></u-loading-page>
</view>
</template>
<script>
import * as api from '@/config/index.js'
export default {
name: 'RankingPopup',
data() {
return {
//
showPeopleRanking: false,
showAmountRanking: false,
loading: false,
//
peopleRankingList: [],
peopleTopThree: [],
peopleRemainingList: [],
//
amountRankingList: [],
amountTopThree: [],
amountRemainingList: [],
//
userInfo: uni.getStorageSync('User') || {},
}
},
methods: {
//
async showRankingPopups() {
this.loading = true
try {
//
await Promise.all([this.loadPeopleRanking(), this.loadAmountRanking()])
//
this.showPeopleRanking = true
} catch (error) {
console.error('加载排行榜数据失败:', error)
uni.showToast({
title: '加载失败',
icon: 'error',
})
} finally {
this.loading = false
}
},
//
getCurrentYearMonth() {
const now = new Date()
const year = now.getFullYear()
const month = String(now.getMonth() + 1).padStart(2, '0') // 0
return { year, month }
},
//
async loadPeopleRanking() {
try {
const { year, month } = this.getCurrentYearMonth()
const params = {
year,
month,
faker: true,
}
const res = await api.getTopPeople(params)
if (res.code === 200 && res.data) {
//
const mappedData = res.data.map(item => ({
...item,
memberName: item.memberName,
memberCode: item.memberCode,
count: item.numberOfPeople, //
isLoginMember: item.memberId === this.userInfo.memberId ? 1 : 0, //
}))
this.peopleRankingList = mappedData.slice(0, 30) // 30
this.peopleTopThree = this.peopleRankingList.slice(0, 3)
this.peopleRemainingList = this.peopleRankingList.slice(3)
}
} catch (error) {
console.error('加载人数排行榜失败:', error)
throw error
}
},
//
async loadAmountRanking() {
try {
const { year, month } = this.getCurrentYearMonth()
const params = {
year,
month,
faker: true,
}
const res = await api.getTopAmount(params)
if (res.code === 200 && res.data) {
//
const mappedData = res.data.map(item => ({
...item,
memberName: item.memberName,
memberCode: item.memberCode,
amount: item.numberOfAmount, //
isLoginMember: item.memberId === this.userInfo.memberId ? 1 : 0, //
}))
this.amountRankingList = mappedData.slice(0, 30) // 30
this.amountTopThree = this.amountRankingList.slice(0, 3)
this.amountRemainingList = this.amountRankingList.slice(3)
}
} catch (error) {
console.error('加载金额排行榜失败:', error)
throw error
}
},
//
closePeopleRanking() {
this.showPeopleRanking = false
//
setTimeout(() => {
this.showAmountRanking = true
}, 300)
},
//
closeAmountRanking() {
this.showAmountRanking = false
//
this.$emit('onRankingComplete')
},
//
formatAmount(amount) {
return amount
},
},
}
</script>
<style lang="scss" scoped>
::v-deep .u-popup__content {
background-color: rgba(0, 0, 0, 0);
}
.popup-container {
width: 100%;
height: 100%;
background: linear-gradient(135deg, #005bac 0%, #0077cc 50%, #003d7a 100%);
border-radius: 20rpx;
display: flex;
flex-direction: column;
overflow: hidden;
}
.popup-header {
padding: 30rpx 40rpx 20rpx;
flex-shrink: 0;
.header-title {
font-size: 36rpx;
font-weight: bold;
color: #fff;
text-shadow: 0 2rpx 4rpx rgba(0, 0, 0, 0.3);
text-align: center;
}
}
.top-three-section {
padding: 40rpx 20rpx;
flex-shrink: 0;
background: linear-gradient(
180deg,
rgba(255, 255, 255, 0.05) 0%,
transparent 100%
);
}
.podium-container {
display: flex;
justify-content: center;
align-items: center;
// height: 320rpx;
position: relative;
// padding: 30rpx 20rpx;
// background: rgba(255, 255, 255, 0.05);
border-radius: 25rpx;
margin: 0 10rpx;
.second-place {
}
}
.podium-item {
display: flex;
flex-direction: column;
align-items: center;
margin: 0 15rpx;
position: relative;
.player-area {
border-radius: 20rpx;
// padding: 25rpx 18rpx;
min-width: 140rpx;
text-align: center;
transition: all 0.3s ease;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.crown {
position: absolute;
top: -25rpx;
font-size: 50rpx;
z-index: 10;
filter: drop-shadow(0 4rpx 12rpx rgba(255, 215, 0, 0.4));
animation: crown-bounce 2s ease-in-out infinite;
}
.rank-number {
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 26rpx;
font-weight: bold;
color: #fff;
margin-bottom: 15rpx;
img {
height: 60rpx;
width: 60rpx;
}
}
.member-name {
font-size: 26rpx;
color: #fff;
text-align: center;
margin-bottom: 8rpx;
font-weight: bold;
text-shadow: 0 2rpx 6rpx rgba(0, 0, 0, 0.4);
max-width: 120rpx;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
&.highlight {
color: #ffd700;
text-shadow: 0 2rpx 8rpx rgba(255, 215, 0, 0.6);
}
}
.member-code {
color: rgba(255, 255, 255, 0.8);
text-align: center;
margin-bottom: 10rpx;
font-size: 24rpx;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.score {
font-size: 22rpx;
color: #fff;
background: linear-gradient(
135deg,
rgba(255, 255, 255, 0.25) 0%,
rgba(255, 255, 255, 0.15) 100%
);
padding: 8rpx 16rpx;
border-radius: 20rpx;
font-weight: bold;
border: 1rpx solid rgba(255, 255, 255, 0.3);
text-shadow: 0 1rpx 3rpx rgba(0, 0, 0, 0.3);
}
}
.first-place {
.score {
background: linear-gradient(
135deg,
rgba(255, 215, 0, 0.3) 0%,
rgba(255, 215, 0, 0.15) 100%
);
border-color: rgba(255, 215, 0, 0.4);
color: #ffd700;
}
}
@keyframes crown-bounce {
0%,
100% {
transform: translateY(0);
}
50% {
transform: translateY(-8rpx);
}
}
.ranking-list {
flex: 1;
background: rgba(255, 255, 255, 0.95);
margin: 20rpx 20rpx 0 20rpx;
border-radius: 20rpx 20rpx 0 0;
overflow: hidden;
backdrop-filter: blur(10rpx);
display: flex;
flex-direction: column;
}
.list-header {
padding: 30rpx 40rpx 20rpx;
border-bottom: 2rpx solid #f0f0f0;
flex-shrink: 0;
.list-title {
font-size: 28rpx;
font-weight: bold;
color: #333;
}
}
.scroll-container {
flex: 1;
height: 0; /* 关键在flex布局中scroll-view需要明确高度 */
}
.list-item {
display: flex;
align-items: center;
padding: 20rpx 40rpx;
border-bottom: 1rpx solid #f5f5f5;
&:last-child {
border-bottom: none;
}
.item-rank {
width: 80rpx;
font-size: 24rpx;
font-weight: bold;
color: #666;
text-align: center;
margin-right: 20rpx;
}
.item-info {
flex: 1;
display: flex;
flex-direction: column;
}
.item-name {
font-size: 26rpx;
color: #333;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
margin-bottom: 4rpx;
&.highlight {
color: #005bac;
font-weight: bold;
}
}
.item-code {
font-size: 20rpx;
color: #999;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.item-score {
font-size: 24rpx;
color: #666;
font-weight: bold;
min-width: 100rpx;
text-align: right;
}
}
.list-footer {
padding: 40rpx;
text-align: center;
.empty-text {
font-size: 24rpx;
color: #999;
}
}
.popup-footer {
padding: 20rpx 40rpx 30rpx;
flex-shrink: 0;
.close-text-btn {
background: rgba(255, 255, 255, 0.9);
color: #005bac;
text-align: center;
padding: 24rpx 40rpx;
border-radius: 50rpx;
font-size: 28rpx;
font-weight: bold;
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
transition: all 0.3s ease;
&:active {
transform: scale(0.98);
background: rgba(255, 255, 255, 0.8);
}
}
}
</style>

View File

@ -0,0 +1,127 @@
<template>
<view class="example-page">
<view class="header">
<text class="title">排行榜弹窗组件示例</text>
</view>
<view class="content">
<view class="button-group">
<u-button
type="primary"
size="large"
@click="showRanking"
:loading="loading"
>
显示排行榜
</u-button>
</view>
<view class="info-section">
<text class="info-title">使用说明</text>
<text class="info-text"
>1. 点击按钮将依次显示直推人数和直推金额排行榜</text
>
<text class="info-text">2. 前三名会特殊展示在顶部</text>
<text class="info-text">3. 4-30名可在下方滚动查看</text>
<text class="info-text">4. 关闭人数排行后自动显示金额排行</text>
</view>
</view>
<!-- 排行榜弹窗组件 -->
<RankingPopup ref="rankingPopup" @onRankingComplete="onRankingComplete" />
</view>
</template>
<script>
import RankingPopup from './RankingPopup.vue'
export default {
name: 'RankingPopupExample',
components: {
RankingPopup,
},
data() {
return {
loading: false,
}
},
methods: {
//
async showRanking() {
this.loading = true
try {
await this.$refs.rankingPopup.showRankingPopups()
} catch (error) {
console.error('显示排行榜失败:', error)
} finally {
this.loading = false
}
},
//
onRankingComplete() {
console.log('排行榜展示完成')
uni.showToast({
title: '排行榜展示完成',
icon: 'success',
})
},
},
}
</script>
<style lang="scss" scoped>
.example-page {
min-height: 100vh;
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
padding: 40rpx;
}
.header {
text-align: center;
margin-bottom: 60rpx;
.title {
font-size: 36rpx;
font-weight: bold;
color: #333;
}
}
.content {
max-width: 600rpx;
margin: 0 auto;
}
.button-group {
text-align: center;
margin-bottom: 60rpx;
}
.info-section {
background: rgba(255, 255, 255, 0.9);
padding: 40rpx;
border-radius: 20rpx;
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
.info-title {
display: block;
font-size: 28rpx;
font-weight: bold;
color: #333;
margin-bottom: 20rpx;
}
.info-text {
display: block;
font-size: 24rpx;
color: #666;
line-height: 1.6;
margin-bottom: 12rpx;
&:last-child {
margin-bottom: 0;
}
}
}
</style>

View File

@ -19,7 +19,6 @@
<u-icon name="close"></u-icon>
</div>
<div class="img-auto" v-html="content.content"></div>
</u-popup>
</template>
@ -42,12 +41,12 @@ export default {
}
},
mounted() {
this.getUserTc()
// this.getUserTc()
},
methods: {
closeTap() {
this.noticeFlag = false
// this.$emit("getTree");
this.$emit('close')
},
getUserTc(data) {
api
@ -63,6 +62,8 @@ export default {
if (items == this.publishLocationIndex) {
this.noticeFlag = true
this.content = res.data[0]
} else {
this.$emit('close')
}
})
}

View File

@ -101,20 +101,24 @@ export default {
if (!this.autoTrigger) {
return
}
uni.showLoading({
title: '加载中...',
})
this.getRegionSelect()
.then(selectedList => {
this.selectedList = selectedList
const area = selectedList.shift()
this.open(area)
})
.catch(() => {
uni.hideLoading()
})
this.init()
},
methods: {
init() {
uni.showLoading({
title: '加载中...',
})
this.getRegionSelect()
.then(selectedList => {
this.selectedList = selectedList
const area = selectedList.shift()
this.open(area)
})
.catch(() => {
this.$emit('success')
uni.hideLoading()
})
},
async getRegionSelect() {
return new Promise(async (resolve, reject) => {
try {
@ -125,7 +129,6 @@ export default {
.filter(key => res.data[key])
.filter(key => !res.data?.data?.[`${key}Data`])
.reverse()
console.log(needSelected, 'needSelected')
if (
needSelected?.length &&
Object.keys(res.data?.data || {}).length < needSelected?.length
@ -274,6 +277,7 @@ export default {
throw new Error(res.message || 'Failed to set region')
}
} catch (error) {
this.$emit('success')
console.error('Failed to set region:', error)
}
},

View File

@ -1,19 +1,30 @@
const http = uni.$u.http
//首页
export const userIndex = (params) => http.get('/sale/api/wares/get-app-index', { params })
export const userIndex = params =>
http.get('/sale/api/wares/get-app-index', { params })
//修改头像
export const updateHead = (data) => http.post('/member/api/member/update-head', data)
export const updateHead = data =>
http.post('/member/api/member/update-head', data)
//提货记录列表
export const pickList = (params) => http.get('/activity/api/pick/list', { params })
export const pickList = params =>
http.get('/activity/api/pick/list', { params })
//提货专区列表
export const pickLogList = (params) => http.get('/activity/api/pick/pick-log', { params })
export const pickLogList = params =>
http.get('/activity/api/pick/pick-log', { params })
//植树活动
export const queryTreeActivity = (params) => http.get('/activity/api/sa-tree-order/queryTreeActivity', { params })
export const queryTreeActivity = params =>
http.get('/activity/api/sa-tree-order/queryTreeActivity', { params })
//创客空间列表
export const marketList = (params) => http.get('/member/api/maker-space/list', { params })
export const marketList = params =>
http.get('/member/api/maker-space/list', { params })
export const getTopPeople = params =>
http.post('/member/api/member-statistics/topPeople', params)
export const getTopAmount = params =>
http.post('/member/api/member-statistics/topAmount', params)

View File

@ -19,7 +19,7 @@ module.exports = vm => {
//#ifdef DEV_SERVER
console.log('DEV_SERVER')
config.baseURL = 'http://192.168.0.86:8080'
config.baseURL = 'https://t-app.beida666.com/prod-api'
//#endif
//#ifdef QA_SERVER

View File

@ -27,6 +27,7 @@
</swiper>
</view>
</view>
<view class="goods-sort">
<view v-if="!newShareMember" class="goods-flexs">
<view v-for="(item, index) in recommendSpecialAreaList" :key="index">
@ -54,7 +55,7 @@
<div>
<!-- 公告弹窗 -->
<notice-popup
@getTree="getTree"
@close="noticePopupHandleClose"
:userInfo="userInfo"
ref="child"
:publishLocationIndex="10"
@ -67,11 +68,11 @@
ref="child2"
@childMethodTrigger="callChildMethod"
></znNewsPopup>
<!-- 直推排行弹窗
<directrank-popup
@callznMethodTrigger="callznMethod"
></directrank-popup>
-->
<!-- 直推排行弹窗 -->
<RankingPopup
ref="rankingPopup"
@onRankingComplete="handleRankingComplete"
/>
<u-modal
:show="promptFlag"
@ -87,7 +88,11 @@
></u-modal>
</div>
</view>
<RegionSelect v-if="userInfo.memberCode != 'BD68880628'" />
<RegionSelect
:autoTrigger="false"
ref="regionSelect"
@success="regionSelectSuccess"
/>
</view>
</template>
@ -107,6 +112,7 @@ import { mapGetters } from 'vuex'
import RegionSelect from '@/components/region-select/index.vue'
import RaisedTabbar from '@/components/raised-tabbar.vue'
import GoodsList from '@/components/goods-list.vue'
import RankingPopup from '@/components/RankingPopup.vue'
export default {
components: {
noticePopup,
@ -116,6 +122,7 @@ export default {
areaProductList,
RegionSelect,
GoodsList,
RankingPopup,
},
filters: {
seles(value) {
@ -128,6 +135,7 @@ export default {
},
data() {
return {
rankingComplete: false,
newShareMember: false,
promptFlag: false,
promptMsg: '',
@ -353,6 +361,7 @@ export default {
// this.getLanguage();
this.getService()
// this.showRankingPopups()
},
onShow() {
this.$store.dispatch('getCarLength')
@ -360,6 +369,10 @@ export default {
this.user = uni.getStorageSync('User')
this.getAreaGoods()
this.newShareMember = this.user?.loginType !== 0
if (this.user.memberCode !== 'BD68880628') {
console.log('init')
this.$refs.regionSelect.init()
}
})
},
onPullDownRefresh() {
@ -379,6 +392,33 @@ export default {
}
},
//
async showRankingPopups() {
try {
this.$nextTick(async () => {
await this.$refs.rankingPopup.showRankingPopups()
})
} catch (error) {
console.error('显示排行榜失败:', error)
uni.showToast({
title: '加载排行榜失败',
icon: 'error',
})
}
},
//
handleRankingComplete() {
this.rankingComplete = true
this.$refs.child.getUserTc()
},
regionSelectSuccess() {
if (this.rankingComplete) {
return
}
this.showRankingPopups()
},
goAreaUrl() {
ban.agreementName().then(res => {
if (res.data == 0) {
@ -450,15 +490,11 @@ export default {
}
})
},
callChildMethod() {
this.$refs.child.getUserTc()
},
callznMethod() {
this.$refs.child2.getUserTc2()
},
//
getTree() {
this.$refs.tree.getData()
noticePopupHandleClose() {
// this.$refs.regionSelect.getRegionSelect()
},
isEmpty(v) {
switch (typeof v) {
@ -619,6 +655,37 @@ export default {
height: 100%;
}
}
//
.ranking-entry {
padding: 20rpx 30rpx;
.ranking-btn {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
border-radius: 25rpx;
padding: 20rpx 30rpx;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 4rpx 12rpx rgba(102, 126, 234, 0.3);
.ranking-icon {
font-size: 32rpx;
margin-right: 12rpx;
}
.ranking-text {
color: #fff;
font-size: 28rpx;
font-weight: bold;
}
&:active {
transform: scale(0.98);
transition: transform 0.1s ease;
}
}
}
.content1 {
background: url('~@/static/images/fBgd.jpg') no-repeat;
background-size: 100% 100%;

1
static/images/rank-1.svg Normal file
View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1758763283426" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1585" xmlns:xlink="http://www.w3.org/1999/xlink" width="256" height="256"><path d="M144.304 429.375A371.701 371.701 0 1 0 516.006 57.553a371.701 371.701 0 0 0-371.702 371.701z" fill="#FFFFFF" p-id="1586"></path><path d="M284.347 509.666L57.057 889.589l138.988 27.798 92.67 106.553 227.29-379.953zM895.96 745.962l-138.99-236.296-236.295 129.743 227.02 379.923 92.639-106.553 138.989-27.798z m0 0" fill="#D9403C" p-id="1587"></path><path d="M284.347 509.666L163.88 708.888a473.616 473.616 0 0 0 231.658 138.99l125.106-208.5z m472.593 0L520.644 639.409l125.105 208.498a473.646 473.646 0 0 0 231.658-138.989z m0 0" fill="#B91C22" p-id="1588"></path><path d="M923.877 472.592a68.998 68.998 0 0 0 18.522-41.711 45.175 45.175 0 0 0-18.522-41.712 20.389 20.389 0 0 1-4.638-23.16 53.126 53.126 0 0 0 4.638-46.32 72.04 72.04 0 0 0-27.798-37.073c-4.638 0-9.276-9.276-4.638-18.522a80.11 80.11 0 0 0-4.638-46.32 72.07 72.07 0 0 0-37.074-27.797c-9.276 0-13.914-9.276-13.914-18.522a50.295 50.295 0 0 0-18.521-41.712 56.59 56.59 0 0 0-41.712-18.522c-9.276 0-13.914-4.638-18.522-13.914a72.04 72.04 0 0 0-27.798-37.073 54.813 54.813 0 0 0-46.32-4.638c-9.275 0-18.521 0-23.16-9.276a57.553 57.553 0 0 0-37.073-27.798 80.11 80.11 0 0 0-46.32 4.638c-9.275 4.638-18.521 4.638-23.16-4.638A68.998 68.998 0 0 0 511.278 0a258.673 258.673 0 0 0-37.074 23.16c-4.638 9.276-13.913 9.276-23.16 4.638a53.126 53.126 0 0 0-46.319-4.638 72.04 72.04 0 0 0-37.074 27.798 24.093 24.093 0 0 1-18.521 9.276 54.813 54.813 0 0 0-46.32 4.638 72.04 72.04 0 0 0-27.798 37.073c0 9.276-9.276 13.914-18.522 13.914a74.72 74.72 0 0 0-41.711 13.914 53.728 53.728 0 0 0-18.522 46.32c0 9.276-4.638 13.914-13.914 18.522a34.845 34.845 0 0 0-32.436 23.16 54.813 54.813 0 0 0-4.638 46.319c0 9.276 0 18.522-9.276 23.16a52.975 52.975 0 0 0-32.436 37.073 80.11 80.11 0 0 0 4.638 46.32c4.638 9.276 4.638 18.522-4.638 23.16a69.058 69.058 0 0 0-13.913 37.074 45.175 45.175 0 0 0 18.521 41.711 20.389 20.389 0 0 1 4.638 23.16 57.222 57.222 0 0 0-9.276 46.32 72.07 72.07 0 0 0 27.798 37.073c9.276 4.638 9.276 13.914 9.276 23.16a54.813 54.813 0 0 0 4.759 46.41 72.04 72.04 0 0 0 37.073 27.798c9.276 0 13.914 9.276 13.914 18.522a50.295 50.295 0 0 0 18.522 41.711 56.59 56.59 0 0 0 41.712 18.522c9.276 0 13.914 4.638 18.522 13.914a72.04 72.04 0 0 0 27.797 37.074 54.813 54.813 0 0 0 46.32 4.638c9.276 0 18.522 0 23.16 9.276a57.553 57.553 0 0 0 37.073 27.798 80.11 80.11 0 0 0 46.32-4.638 11.474 11.474 0 0 1 18.522-4.638 68.998 68.998 0 0 0 41.712 18.521 45.175 45.175 0 0 0 41.711-18.521 20.389 20.389 0 0 1 23.16-4.638 53.126 53.126 0 0 0 46.32 4.638 72.07 72.07 0 0 0 37.073-27.798c4.638-9.276 13.914-9.276 23.16-9.276a54.813 54.813 0 0 0 46.32-4.638 72.07 72.07 0 0 0 27.797-37.074c0-9.276 9.276-13.914 18.522-13.914a50.295 50.295 0 0 0 41.712-18.522 56.59 56.59 0 0 0 18.522-41.711c0-9.276 4.638-13.914 13.914-18.522a72.07 72.07 0 0 0 37.073-27.798 54.813 54.813 0 0 0 4.638-46.32c0-9.275 0-18.521 9.276-23.16a57.553 57.553 0 0 0 27.798-37.073 80.11 80.11 0 0 0-4.638-46.32c-13.914 4.638-9.276-4.638-4.638-13.914z m-361.401 138.99h-69.6v-250.18h-88.031v-46.32c23.16 0 37.073-4.638 46.32-4.638a93.121 93.121 0 0 0 37.073-18.522 75.292 75.292 0 0 0 13.914-27.798c0-4.638 4.638-9.276 4.638-13.914h60.233v361.401z m0 0" fill="#EEB317" p-id="1589"></path><path d="M516.036 55.355a363.54 363.54 0 0 1 264.094 111.19A371.49 371.49 0 0 1 891.32 430.64a363.54 363.54 0 0 1-111.19 264.093 371.49 371.49 0 0 1-264.094 111.192 363.54 363.54 0 0 1-264.094-111.192A371.49 371.49 0 0 1 140.75 430.64 379.742 379.742 0 0 1 516.036 55.355z m245.572 129.984a346.343 346.343 0 0 0-491.144-0.272 340.32 340.32 0 0 0-101.946 245.814 331.616 331.616 0 0 0 101.946 245.572 339.235 339.235 0 0 0 245.572 101.945 331.616 331.616 0 0 0 245.572-101.945 346.764 346.764 0 0 0 0-491.145z m0 0" fill="#FFFFFF" p-id="1590"></path></svg>

After

Width:  |  Height:  |  Size: 4.0 KiB

1
static/images/rank-2.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 4.9 KiB

1
static/images/rank-3.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 5.2 KiB