Files
shoot-miniprograms/src/pages/my-growth.vue
2025-08-22 11:51:52 +08:00

201 lines
5.2 KiB
Vue

<script setup>
import { onMounted } from "vue";
import Container from "@/components/Container.vue";
import Avatar from "@/components/Avatar.vue";
import BowData from "@/components/BowData.vue";
import BattleHeader from "@/components/BattleHeader.vue";
import ScrollList from "@/components/ScrollList.vue";
import { getBattleListAPI, getPractiseResultListAPI } from "@/apis";
import { meleeAvatarColors } from "@/constants";
import { ref } from "vue";
const selectedIndex = ref(0);
const matchList = ref([]);
const battleList = ref([]);
const practiseList = ref([]);
const toMatchDetail = (id) => {
uni.navigateTo({
url: `/pages/match-detail?id=${id}`,
});
};
const getPractiseDetail = async (id) => {
uni.navigateTo({
url: `/pages/mine-bow-data?id=${id}`,
});
};
const onMatchLoading = async (page) => {
const result = await getBattleListAPI(page, 2);
if (page === 1) {
matchList.value = result;
} else {
matchList.value = matchList.value.concat(result);
}
return result.length;
};
const onBattleLoading = async (page) => {
const result = await getBattleListAPI(page, 1);
if (page === 1) {
battleList.value = result;
} else {
battleList.value = battleList.value.concat(result);
}
return result.length;
};
const onPractiseLoading = async (page) => {
const result = await getPractiseResultListAPI(page);
if (page === 1) {
practiseList.value = result;
} else {
practiseList.value = practiseList.value.concat(result);
}
return result.length;
};
</script>
<template>
<Container title="我的成长脚印" overflow="hidden">
<view class="tabs">
<view
v-for="(rankType, index) in ['排位赛', '好友约战', '个人练习']"
:key="index"
:style="{
color: index === selectedIndex ? '#000' : '#fff',
backgroundColor: index === selectedIndex ? '#FFD947' : 'transparent',
}"
@tap="() => (selectedIndex = index)"
>
{{ rankType }}
</view>
</view>
<view class="contents">
<ScrollList :show="selectedIndex === 0" :onLoading="onMatchLoading">
<view
v-for="(item, index) in matchList"
:key="index"
@click="() => toMatchDetail(item.battleId)"
>
<view class="contest-header">
<text>{{ item.name }}</text>
<text>{{ item.createdAt }}</text>
<image src="../static/back.png" mode="widthFix" />
</view>
<BattleHeader
:players="item.mode === 1 ? [] : item.players"
:blueTeam="item.bluePlayers"
:redTeam="item.redPlayers"
:winner="item.winner"
:showRank="item.mode === 2"
:showHeader="false"
/>
</view>
</ScrollList>
<ScrollList :show="selectedIndex === 1" :onLoading="onBattleLoading">
<view
v-for="(item, index) in battleList"
:key="index"
@click="() => toMatchDetail(item.battleId)"
>
<view class="contest-header">
<text>{{ item.name }}</text>
<text>{{ item.createdAt }}</text>
<image src="../static/back.png" mode="widthFix" />
</view>
<BattleHeader
:players="item.mode === 1 ? [] : item.players"
:blueTeam="item.bluePlayers"
:redTeam="item.redPlayers"
:winner="item.winner"
:showRank="item.mode === 2"
:showHeader="false"
/>
</view>
</ScrollList>
<ScrollList
:show="selectedIndex === 2"
:onLoading="onPractiseLoading"
:pageSize="15"
>
<view
v-for="(item, index) in practiseList"
:key="index"
class="practice-record"
@click="() => getPractiseDetail(item.id)"
>
<text
>{{ item.completed_arrows === 36 ? "耐力挑战" : "单组练习" }}
{{ item.createdAt }}</text
>
<image src="../static/back.png" mode="widthFix" />
</view>
</ScrollList>
</view>
</Container>
</template>
<style scoped>
.container {
width: 100%;
}
.tabs {
width: calc(100% - 30px);
display: flex;
justify-content: space-around;
font-size: 15px;
padding: 15px;
padding-top: 0;
}
.tabs > view {
width: 33.3%;
padding: 7px 10px;
text-align: center;
border-radius: 20px;
}
.contents {
width: 100%;
height: calc(100% - 50px);
}
.contents > scroll-view {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
}
.contest-header {
display: flex;
justify-content: space-between;
padding: 7px 12px;
font-size: 12px;
background: linear-gradient(180deg, #323845 0%, #2e2e39 100%);
position: relative;
}
.contest-header > text:first-child {
color: #ffd947;
font-size: 14px;
}
.contest-header > text:nth-child(2) {
color: #fff9;
margin-right: 20px;
}
.contest-header > image {
position: absolute;
top: 8px;
right: 10px;
width: 15px;
transform: rotate(180deg);
}
.practice-record {
color: #fff9;
border-bottom: 1px solid #fff9;
padding: 15px;
display: flex;
align-items: center;
justify-content: space-between;
}
.practice-record > image {
width: 15px;
transform: rotate(180deg);
}
</style>