Files
shoot-miniprograms/src/pages/rank-list.vue

360 lines
8.3 KiB
Vue
Raw Normal View History

2025-06-17 12:01:44 +08:00
<script setup>
import { ref, onMounted } from "vue";
import Avatar from "@/components/Avatar.vue";
2025-06-28 12:03:33 +08:00
import useStore from "@/store";
import { storeToRefs } from "pinia";
const store = useStore();
const { user, rankData } = storeToRefs(store);
2025-07-01 10:57:49 +08:00
const { getLvlName } = store;
2025-06-26 23:41:23 +08:00
2025-06-17 12:01:44 +08:00
const isIos = ref(true);
2025-06-26 23:41:23 +08:00
const selectedIndex = ref(0);
2025-07-01 10:57:49 +08:00
const currentList = ref([]);
2025-07-03 11:40:03 +08:00
const myData = ref(null);
2025-07-13 13:28:21 +08:00
const addBg = ref("");
2025-06-17 12:01:44 +08:00
2025-06-26 23:41:23 +08:00
onMounted(async () => {
2025-06-17 12:01:44 +08:00
const deviceInfo = uni.getDeviceInfo();
isIos.value = deviceInfo.osName === "ios";
2025-07-01 10:57:49 +08:00
currentList.value = rankData.value.rank;
2025-07-03 11:40:03 +08:00
myData.value = rankData.value.rank.find(
(item) => item.userId === user.value.id
);
2025-06-17 12:01:44 +08:00
});
const handleSelect = (index) => {
selectedIndex.value = index;
2025-07-03 11:40:03 +08:00
myData.value = null;
2025-07-01 10:57:49 +08:00
if (index === 0) {
currentList.value = rankData.value.rank;
} else if (index === 2) {
currentList.value = rankData.value.ringRank;
} else {
currentList.value = [];
}
2025-07-03 11:40:03 +08:00
myData.value = rankData.value.rank.find(
(item) => item.userId === user.value.id
);
2025-06-17 12:01:44 +08:00
};
2025-07-10 15:34:00 +08:00
const onScrollView = (e) => {
2025-07-13 13:28:21 +08:00
addBg.value = e.detail.scrollTop > 100;
2025-07-10 15:34:00 +08:00
};
2025-06-17 12:01:44 +08:00
const subTitles = ["排位赛积分", "本周MVP次数", "本周十环次数"];
</script>
<template>
2025-07-10 15:34:00 +08:00
<scroll-view class="container" scroll-y @scroll="onScrollView">
<view
class="header"
:style="{
paddingTop: isIos ? '38px' : '25px',
}"
2025-06-17 12:01:44 +08:00
>
2025-07-13 13:28:21 +08:00
<image
v-if="addBg"
class="bg-image"
src="../static/app-bg.png"
mode="widthFix"
/>
2025-07-10 15:34:00 +08:00
<navigator open-type="navigateBack">
2025-07-13 13:28:21 +08:00
<image class="header-back" src="../static/back.png" mode="widthFix" />
2025-07-10 15:34:00 +08:00
</navigator>
2025-07-13 13:28:21 +08:00
<text :style="{ opacity: addBg ? 1 : 0, color: '#fff' }">
本赛季排行榜
</text>
2025-07-10 15:34:00 +08:00
</view>
2025-06-17 12:01:44 +08:00
<image src="../static/rankbg.png" mode="widthFix" class="header-bg" />
<view class="rank-tabs">
<view
2025-07-10 19:55:30 +08:00
v-for="(rankType, index) in ['积分榜', 'MVP榜', '十环榜']"
2025-06-17 12:01:44 +08:00
: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
2025-07-01 10:57:49 +08:00
v-for="(item, index) in currentList"
2025-06-17 12:01:44 +08:00
: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>
2025-07-01 10:57:49 +08:00
<Avatar :src="item.avatar" />
2025-06-17 12:01:44 +08:00
<view class="rank-item-content">
2025-07-01 10:57:49 +08:00
<text>{{ item.name }}</text>
<text
>{{ getLvlName(item.totalScore) }}{{ item.TotalGames }}</text
>
2025-06-17 12:01:44 +08:00
</view>
2025-07-17 09:57:08 +08:00
<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 === 2">
<text :style="{ fontSize: '14px', color: '#fff', marginRight: '5px' }"
>{{ item.TenRings }} </text
>
</text>
2025-06-17 12:01:44 +08:00
</view>
2025-07-11 00:56:39 +08:00
<view v-if="!currentList.length" class="no-data">
<text>筹备中...</text>
</view>
2025-06-17 12:01:44 +08:00
</view>
2025-07-03 11:40:03 +08:00
<view class="my-rank-data" v-if="myData">
2025-06-17 12:01:44 +08:00
<image src="../static/modal-content-bg.png" mode="widthFix" />
2025-07-03 11:40:03 +08:00
<text>{{ myData.rank }}</text>
2025-06-28 12:03:33 +08:00
<Avatar :src="user.avatar" />
2025-06-17 12:01:44 +08:00
<view class="rank-item-content">
2025-06-28 12:03:33 +08:00
<text class="truncate">{{ user.nickName }}</text>
2025-07-03 11:40:03 +08:00
<text>{{ user.lvlName }}{{ myData.TotalGames }}</text>
2025-06-17 12:01:44 +08:00
</view>
2025-07-17 15:50:49 +08:00
<text class="rank-item-integral" v-if="selectedIndex === 2"
><text
:style="{ fontSize: '14px', color: '#fff', marginRight: '5px' }"
>{{ myData.TenRings }}</text
></text
>
<text class="rank-item-integral" v-else
2025-06-28 12:03:33 +08:00
><text
:style="{ fontSize: '14px', color: '#fff', marginRight: '5px' }"
2025-07-03 11:40:03 +08:00
>{{ myData.totalScore }}</text
2025-06-17 12:01:44 +08:00
></text
>
</view>
2025-07-10 15:34:00 +08:00
</scroll-view>
2025-06-17 12:01:44 +08:00
</template>
<style scoped>
.container {
2025-07-10 15:34:00 +08:00
width: 100%;
height: 100vh;
2025-06-17 12:01:44 +08:00
padding-bottom: 100px;
}
.header-bg {
width: 100%;
}
2025-07-10 15:34:00 +08:00
.header {
width: 100%;
height: 60px;
2025-06-17 12:01:44 +08:00
display: flex;
2025-07-10 15:34:00 +08:00
align-items: flex-center;
position: fixed;
top: 0;
transition: all 0.3s ease;
z-index: 10;
2025-07-13 13:28:21 +08:00
overflow: hidden;
2025-07-10 15:34:00 +08:00
}
.header text {
transition: all 0.3s ease;
line-height: 60px;
2025-07-13 13:28:21 +08:00
position: relative;
2025-06-17 12:01:44 +08:00
}
.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;
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;
2025-06-28 12:03:33 +08:00
width: 120px;
2025-06-17 12:01:44 +08:00
}
.rank-list-item > text:last-child {
margin-right: 10px;
2025-07-17 09:57:08 +08:00
width: 56px;
text-align: right;
2025-06-17 12:01:44 +08:00
}
.my-rank-data {
position: fixed;
bottom: 0;
left: 0;
width: calc(100% - 30px);
padding: 15px;
padding-bottom: 30px;
display: flex;
align-items: center;
justify-content: space-between;
color: #fff9;
font-size: 12px;
}
.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;
2025-07-17 09:57:08 +08:00
margin: 10px;
2025-06-17 12:01:44 +08:00
font-size: 14px;
}
.my-rank-data > text:last-child {
position: relative;
margin-right: 10px;
2025-07-17 09:57:08 +08:00
width: 56px;
text-align: right;
2025-06-17 12:01:44 +08:00
}
.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;
}
2025-07-11 00:56:39 +08:00
.no-data {
width: 100%;
height: 400px;
display: flex;
justify-content: center !important;
align-items: center;
color: #fff9;
font-size: 14px;
}
2025-07-13 13:28:21 +08:00
.header-back {
width: 22px;
height: 22px;
margin: 20px 15px;
position: relative;
}
.bg-image {
width: 100vw;
height: 100vh;
position: absolute;
top: 0;
left: 0;
}
2025-06-17 12:01:44 +08:00
</style>