页面完善

This commit is contained in:
kron
2025-07-13 13:28:21 +08:00
parent 12a24464c2
commit b6d78d6070
4 changed files with 155 additions and 62 deletions

View File

@@ -57,8 +57,8 @@ export const getAppConfig = () => {
return request("GET", "/index/appConfig");
};
export const getHomeData = () => {
return request("GET", "/user/myHome");
export const getHomeData = (seasonId) => {
return request("GET", `/user/myHome?seasonId=${seasonId}`);
};
export const getProvinceData = () => {

View File

@@ -33,7 +33,7 @@ const props = defineProps({
});
const avatarFrame = ref("");
watch(
() => config.value,
() => [config.value, props.score],
() => {
if (props.score !== undefined) {
avatarFrame.value = getLvlImage(props.score);

View File

@@ -11,7 +11,7 @@ const isIos = ref(true);
const selectedIndex = ref(0);
const currentList = ref([]);
const myData = ref(null);
const headerColor = ref("");
const addBg = ref("");
onMounted(async () => {
const deviceInfo = uni.getDeviceInfo();
@@ -38,7 +38,7 @@ const handleSelect = (index) => {
};
const onScrollView = (e) => {
headerColor.value = e.detail.scrollTop > 100 ? "orange" : "";
addBg.value = e.detail.scrollTop > 100;
};
const subTitles = ["排位赛积分", "本周MVP次数", "本周十环次数"];
@@ -50,13 +50,20 @@ const subTitles = ["排位赛积分", "本周MVP次数", "本周十环次数"];
class="header"
:style="{
paddingTop: isIos ? '38px' : '25px',
backgroundColor: headerColor,
}"
>
<image
v-if="addBg"
class="bg-image"
src="../static/app-bg.png"
mode="widthFix"
/>
<navigator open-type="navigateBack">
<image src="../static/back.png" mode="widthFix" />
<image class="header-back" src="../static/back.png" mode="widthFix" />
</navigator>
<text :style="{ opacity: headerColor ? 1 : 0 }">本赛季排行榜</text>
<text :style="{ opacity: addBg ? 1 : 0, color: '#fff' }">
本赛季排行榜
</text>
</view>
<image src="../static/rankbg.png" mode="widthFix" class="header-bg" />
<view class="rank-tabs">
@@ -178,15 +185,12 @@ const subTitles = ["排位赛积分", "本周MVP次数", "本周十环次数"];
top: 0;
transition: all 0.3s ease;
z-index: 10;
}
.header image {
width: 22px;
height: 22px;
margin: 20px 15px;
overflow: hidden;
}
.header text {
transition: all 0.3s ease;
line-height: 60px;
position: relative;
}
.rank-tabs {
width: calc(100% - 20px);
@@ -325,4 +329,17 @@ const subTitles = ["排位赛积分", "本周MVP次数", "本周十环次数"];
color: #fff9;
font-size: 14px;
}
.header-back {
width: 22px;
height: 22px;
margin: 20px 15px;
position: relative;
}
.bg-image {
width: 100vw;
height: 100vh;
position: absolute;
top: 0;
left: 0;
}
</style>

View File

@@ -1,5 +1,6 @@
<script setup>
import { ref, onMounted } from "vue";
import { onHide } from "@dcloudio/uni-app";
import Container from "@/components/Container.vue";
import Avatar from "@/components/Avatar.vue";
import { getRankListAPI, isGamingAPI } from "@/apis";
@@ -8,24 +9,28 @@ import { getHomeData } from "@/apis";
import useStore from "@/store";
import { storeToRefs } from "pinia";
const store = useStore();
const { user, device, rankData } = storeToRefs(store);
const { user, device } = storeToRefs(store);
const { getLvlName } = store;
const defaultSeasonData = {
"1v1": { totalGames: 0, winCount: 0, winRate: 0 },
"5m": { totalGames: 0, winCount: 0, winRate: 0 },
"10m": { totalGames: 0, winCount: 0, winRate: 0 },
};
const selectedIndex = ref(0);
const currentList = ref([]);
const seasonName = ref("");
const seasonData = ref([]);
const currentSeasonData = ref({
"1v1": { totalGames: 0, winCount: 0, winRate: 0 },
"5m": { totalGames: 0, winCount: 0, winRate: 0 },
"10m": { totalGames: 0, winCount: 0, winRate: 0 },
});
const rankData = ref({ user: {} });
const showSeasonList = ref(false);
const currentSeasonData = ref(defaultSeasonData);
const handleSelect = (index) => {
selectedIndex.value = index;
if (index === 0) {
if (index === 0 && rankData.value.rank) {
currentList.value = rankData.value.rank.slice(0, 10);
} else if (index === 2) {
} else if (index === 2 && rankData.value.ringRank) {
currentList.value = rankData.value.ringRank.slice(0, 10);
} else {
currentList.value = [];
@@ -33,37 +38,12 @@ const handleSelect = (index) => {
};
onMounted(async () => {
currentList.value = rankData.value.rank;
const { userGameStats, seasonList } = await getHomeData();
const result = await getHomeData();
currentList.value = result.rank;
rankData.value = result;
const { userGameStats, seasonList } = result;
seasonData.value = seasonList;
if (
userGameStats &&
userGameStats.stats_list &&
userGameStats.stats_list.length
) {
userGameStats.stats_list.forEach((item) => {
if (seasonList.length) {
seasonList.some((s) => {
if (s.seasonId === item.seasonId) {
seasonName.value = s.seasonName;
return true;
}
return false;
});
}
let keyName = "";
if (item.gameType === 1 && item.teamSize === 2) keyName = "1v1";
if (item.gameType === 2 && item.teamSize === 5) keyName = "5m";
if (item.gameType === 2 && item.teamSize === 10) keyName = "10m";
if (keyName) {
currentSeasonData.value[keyName] = {
totalGames: item.totalGames,
winCount: item.winCount,
winRate: Number(((item.winCount / item.totalGames) * 100).toFixed(2)),
};
}
});
}
updateData();
});
const toTeamMatchPage = async (gameType, teamSize) => {
@@ -115,41 +95,112 @@ const toRankListPage = () => {
url: "/pages/rank-list",
});
};
const onChangeSeason = async (seasonId, name) => {
if (name !== seasonName.value) {
const result = await getHomeData(seasonId);
rankData.value = result;
seasonName.value = name;
handleSelect(selectedIndex.value);
updateData();
}
showSeasonList.value = false;
};
const updateData = () => {
const { userGameStats, seasonList } = rankData.value;
currentSeasonData.value = { ...defaultSeasonData };
if (
userGameStats &&
userGameStats.stats_list &&
userGameStats.stats_list.length
) {
userGameStats.stats_list.forEach((item) => {
if (seasonList.length) {
seasonList.some((s) => {
if (s.seasonId === item.seasonId) {
seasonName.value = s.seasonName;
return true;
}
return false;
});
}
let keyName = "";
if (item.gameType === 1 && item.teamSize === 2) keyName = "1v1";
if (item.gameType === 2 && item.teamSize === 5) keyName = "5m";
if (item.gameType === 2 && item.teamSize === 10) keyName = "10m";
if (keyName) {
currentSeasonData.value[keyName] = {
totalGames: item.totalGames,
winCount: item.winCount,
winRate: Number(((item.winCount / item.totalGames) * 100).toFixed(2)),
};
}
});
}
};
onHide(() => {
showSeasonList.value = false;
});
</script>
<template>
<Container title="排行赛">
<view class="container">
<view class="container" @click="() => (showSeasonList = false)">
<view class="ranking-my-data" v-if="user.id">
<view>
<view class="user-info">
<Avatar :src="user.avatar" :score="user.scores" :size="30" />
<Avatar
:src="user.avatar"
:score="rankData.user.scores"
:size="30"
/>
<text>{{ user.nickName }}</text>
</view>
<view class="ranking-season" v-if="seasonData.length">
<view
class="ranking-season"
v-if="seasonData.length"
@click.stop="() => (showSeasonList = true)"
>
<text>{{ seasonName }}</text>
<image
v-if="seasonData.length > 1"
src="../static/triangle.png"
mode="widthFix"
/>
<view class="season-list" v-if="showSeasonList">
<view
v-for="(item, index) in seasonData"
:key="index"
@click.stop="
() => onChangeSeason(item.seasonId, item.seasonName)
"
>
<text>{{ item.seasonName }}</text>
<image
v-if="item.seasonName === seasonName"
src="../static/triangle.png"
mode="widthFix"
/>
</view>
</view>
</view>
</view>
<view class="my-data">
<view>
<text>段位</text>
<text :style="{ color: '#83CDFF' }">{{ user.lvlName || "-" }}</text>
<text :style="{ color: '#83CDFF' }">{{
getLvlName(rankData.user.scores) || "-"
}}</text>
</view>
<view>
<text>赛季平均环数</text>
<text :style="{ color: '#FFD947' }">{{
user.avg_ring ? user.avg_ring + "环" : "-"
rankData.user.avg_ring ? rankData.user.avg_ring + "环" : "-"
}}</text>
</view>
<view>
<text>赛季胜率</text>
<text :style="{ color: '#FF507E' }">{{
user.avg_win ? user.avg_win + "%" : "-"
rankData.user.avg_win ? rankData.user.avg_win + "%" : "-"
}}</text>
</view>
</view>
@@ -157,17 +208,17 @@ const toRankListPage = () => {
<image
src="../static/battle1v1.png"
mode="widthFix"
@click="() => toTeamMatchPage(1, 2)"
@click.stop="() => toTeamMatchPage(1, 2)"
/>
<image
src="../static/battle5.png"
mode="widthFix"
@click="() => toMeleeMatchPage(2, 5)"
@click.stop="() => toMeleeMatchPage(2, 5)"
/>
<image
src="../static/battle10.png"
mode="widthFix"
@click="() => toMeleeMatchPage(2, 10)"
@click.stop="() => toMeleeMatchPage(2, 10)"
/>
</view>
<view class="data-progress">
@@ -215,7 +266,7 @@ const toRankListPage = () => {
/>
</view>
</view>
<view @click="toMyGrowthPage">查看我的比赛记录</view>
<view @click.stop="toMyGrowthPage">查看我的比赛记录</view>
</view>
<view class="ranking-data">
<view>
@@ -277,7 +328,7 @@ const toRankListPage = () => {
<view v-if="!currentList.length" class="no-data">
<text>筹备中...</text>
</view>
<view class="see-more" @click="toRankListPage">点击查看更多</view>
<view class="see-more" @click.stop="toRankListPage">点击查看更多</view>
</view>
</view>
</Container>
@@ -328,6 +379,7 @@ const toRankListPage = () => {
display: flex;
justify-content: center;
align-items: center;
position: relative;
}
.ranking-season > image {
width: 12px;
@@ -479,4 +531,28 @@ const toRankListPage = () => {
align-items: center;
color: #fff9;
}
.season-list {
background-color: #000c;
border-radius: 15px;
color: #fff;
display: flex;
flex-direction: column;
justify-content: center;
font-size: 12px;
padding: 5px 0;
position: absolute;
width: 220rpx;
top: -44rpx;
right: -30rpx;
letter-spacing: 2px;
}
.season-list > view {
display: flex;
align-items: center;
padding: 10px 20px;
}
.season-list > view > image {
width: 12px;
margin-left: 10px;
}
</style>