Files
shoot-miniprograms/src/pages/rank-list.vue
2025-09-25 16:04:37 +08:00

404 lines
9.6 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<script setup>
import { ref, onMounted } from "vue";
import Avatar from "@/components/Avatar.vue";
import useStore from "@/store";
import { storeToRefs } from "pinia";
const store = useStore();
const { user, rankData } = storeToRefs(store);
const { getLvlName } = store;
const capsuleHeight = ref(0);
const selectedIndex = ref(0);
const currentList = ref([]);
const myData = ref({});
const addBg = ref("");
onMounted(async () => {
const menuBtnInfo = uni.getMenuButtonBoundingClientRect();
capsuleHeight.value = menuBtnInfo.top - 9;
handleSelect(0);
});
const handleSelect = (index) => {
selectedIndex.value = index;
myData.value = {};
currentList.value = [];
if (index === 0) {
currentList.value = rankData.value.rank;
} else if (index === 1) {
currentList.value = rankData.value.mvpRank;
} else if (index === 2) {
currentList.value = rankData.value.ringRank;
}
if (user.value.id) {
currentList.value.some((item) => {
if (item.userId === user.value.id) {
myData.value = item;
return true;
}
return false;
});
if (!myData.value.userId) {
myData.value = {
userId: user.value.id,
TotalGames: 0,
totalScore: 0,
mvpCount: 0,
TenRings: 0,
};
}
}
};
const onScrollView = (e) => {
addBg.value = e.detail.scrollTop > 100;
};
const subTitles = ["排位赛积分", "MVP次数", "十环次数"];
</script>
<template>
<view class="container">
<view
class="header"
:style="{
paddingTop: capsuleHeight + 'px',
}"
>
<image
v-if="addBg"
class="bg-image"
src="../static/app-bg.png"
mode="widthFix"
/>
<navigator open-type="navigateBack">
<image class="header-back" src="../static/back.png" mode="widthFix" />
</navigator>
<text
:style="{ opacity: addBg ? 1 : 0, color: '#fff', fontWeight: 'bold' }"
>
本赛季排行榜
</text>
</view>
<scroll-view
scroll-y
@scroll="onScrollView"
:style="{ height: myData.userId ? '90vh' : '100vh' }"
>
<image
src="https://static.shelingxingqiu.com/attachment/2025-09-25/dd1p9b3wcrwnlnghiq.png"
mode="widthFix"
class="header-bg"
/>
<view class="rank-tabs">
<view
v-for="(rankType, index) in ['积分榜', 'MVP榜', '十环榜']"
:key="index"
:style="{
fontSize: index === selectedIndex ? '16px' : '14px',
color: index === selectedIndex ? '#000' : '#fff',
backgroundColor: index === selectedIndex ? '#FFD947' : '#383737',
}"
@tap="handleSelect(index)"
>
{{ rankType }}
</view>
</view>
<view class="rank-list">
<view class="rank-list-header">
<text>排名</text>
<text>用户ID</text>
<text>{{ subTitles[selectedIndex] }}</text>
</view>
<view
v-for="(item, index) in currentList"
:key="index"
class="rank-list-item"
:style="{
backgroundColor: index % 2 === 0 ? '#9898981f' : 'transparent',
}"
>
<image
v-if="index === 0"
class="player-bg"
src="../static/melee-player-bg1.png"
mode="aspectFill"
/>
<image
v-if="index === 1"
class="player-bg"
src="../static/melee-player-bg2.png"
mode="aspectFill"
/>
<image
v-if="index === 2"
class="player-bg"
src="../static/melee-player-bg3.png"
mode="aspectFill"
/>
<image
v-if="index === 0"
class="player-crown"
src="../static/champ1.png"
mode="widthFix"
/>
<image
v-if="index === 1"
class="player-crown"
src="../static/champ2.png"
mode="widthFix"
/>
<image
v-if="index === 2"
class="player-crown"
src="../static/champ3.png"
mode="widthFix"
/>
<view v-if="index > 2" class="view-crown">{{ index + 1 }}</view>
<Avatar :src="item.avatar" />
<view class="rank-item-content">
<text class="truncate">{{ item.name }}</text>
<text
>{{ getLvlName(item.totalScore) }}{{ item.TotalGames }}</text
>
</view>
<text class="rank-item-integral" v-if="selectedIndex === 0">
<text
:style="{ fontSize: '14px', color: '#fff', marginRight: '5px' }"
>{{ item.totalScore }} </text
>
</text>
<text class="rank-item-integral" v-if="selectedIndex === 1">
<text
:style="{ fontSize: '14px', color: '#fff', marginRight: '5px' }"
>{{ item.mvpCount }} </text
>
</text>
<text class="rank-item-integral" v-if="selectedIndex === 2">
<text
:style="{ fontSize: '14px', color: '#fff', marginRight: '5px' }"
>{{ item.TenRings }} </text
>
</text>
</view>
<view v-if="!currentList.length" class="no-data">
<text>筹备中...</text>
</view>
</view>
</scroll-view>
<view class="my-rank-data" v-if="myData.userId">
<image
src="https://static.shelingxingqiu.com/attachment/2025-08-05/dbuaf19pf7qd8ps0uh.png"
mode="widthFix"
/>
<text>{{ myData.rank }}</text>
<Avatar :src="user.avatar" />
<view class="rank-item-content">
<text class="truncate">{{ user.nickName }}</text>
<text>{{ user.lvlName }}{{ myData.TotalGames }}</text>
</view>
<text class="rank-item-integral" v-if="selectedIndex === 0">
<text
:style="{ fontSize: '14px', color: '#fff', marginRight: '5px' }"
>{{ myData.totalScore || 0 }}</text
></text
>
<text class="rank-item-integral" v-if="selectedIndex === 1">
<text
:style="{ fontSize: '14px', color: '#fff', marginRight: '5px' }"
>{{ myData.mvpCount || 0 }}</text
></text
>
<text class="rank-item-integral" v-if="selectedIndex === 2">
<text
:style="{ fontSize: '14px', color: '#fff', marginRight: '5px' }"
>{{ myData.TenRings || 0 }}</text
></text
>
</view>
</view>
</template>
<style scoped>
.container {
width: 100%;
}
.header-bg {
width: 100%;
}
.header {
width: 100%;
height: 50px;
display: flex;
align-items: center;
position: fixed;
top: 0;
transition: all 0.3s ease;
z-index: 10;
overflow: hidden;
}
.header text {
transition: all 0.3s ease;
line-height: 50px;
position: relative;
}
.rank-tabs {
width: calc(100% - 20px);
display: flex;
justify-content: space-around;
padding: 0 10px;
margin-top: -15px;
}
.rank-tabs > view {
width: 25%;
padding: 10px;
text-align: center;
border-radius: 20px;
}
.rank-list {
display: flex;
flex-direction: column;
align-items: center;
width: calc(100% - 20px);
color: #fff9;
font-size: 12px;
margin: 10px;
border: 1px solid rgb(255 217 71 / 0.2);
border-radius: 10px;
background-color: #313131;
}
.rank-list > view {
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
overflow: hidden;
position: relative;
}
.rank-list-header {
width: calc(100% - 20px) !important;
padding: 10px;
}
.rank-list-header > text:nth-child(2) {
width: 14%;
}
.rank-list-header > text:last-child {
width: 30%;
text-align: right;
}
.rank-list-item {
padding: 10px 0;
}
.player-bg {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
}
.player-crown {
position: relative;
width: 27px;
height: 27px;
margin: 0 15px;
}
.view-crown {
width: 27px;
height: 27px;
line-height: 27px;
text-align: center;
border-radius: 50%;
margin: 0 15px;
color: #fff;
background-color: #676767;
position: relative;
}
.rank-item-content {
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: center;
width: 50%;
position: relative;
padding-left: 10px;
}
.rank-item-content > text:first-child {
color: #fff;
font-size: 14px;
margin-bottom: 3px;
width: 120px;
}
.rank-list-item > text:last-child {
margin-right: 10px;
width: 56px;
text-align: right;
}
.my-rank-data {
width: calc(100% - 30px);
padding: 15px;
display: flex;
align-items: center;
justify-content: space-between;
color: #fff9;
font-size: 12px;
height: calc(10vh - 30px);
position: relative;
overflow: hidden;
border-radius: 10px;
}
.my-rank-data > image:first-child {
position: absolute;
width: 100%;
left: 0;
top: -5px;
}
.my-rank-data > text:nth-child(2) {
background-color: #c1a434;
position: relative;
color: #fff;
padding: 3px 5px;
border-radius: 20px;
margin: 10px;
font-size: 14px;
min-width: 15px;
text-align: center;
}
.my-rank-data > text:last-child {
position: relative;
margin-right: 10px;
width: 65px;
text-align: right;
}
.my-rank-data > .rank-item-content > text:first-child {
color: #fed847;
}
.my-rank-data > .rank-item-integral {
color: #fff9;
font-size: 12px;
margin-right: 0 !important;
}
.no-data {
width: 100%;
height: 400px;
display: flex;
justify-content: center !important;
align-items: center;
color: #fff9;
font-size: 14px;
}
.header-back {
width: 22px;
height: 22px;
margin: 0px 15px;
margin-top: 5px;
position: relative;
}
.bg-image {
width: 100vw;
height: 100vh;
position: absolute;
top: 0;
left: 0;
}
</style>