Files
shoot-miniprograms/src/pages/my-growth.vue

232 lines
6.5 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 { onMounted } from "vue";
import { onLoad } from "@dcloudio/uni-app";
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?battleId=${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;
};
const getName = (battle) => {
if (battle.mode <= 3) return `${battle.mode}V${battle.mode}`;
// 排位赛大乱斗mode 数字与实际人数不一致,使用固定映射
if (battle.way === 2) {
if (battle.mode === 4) return "5人大乱斗";
if (battle.mode === 5) return "10人大乱斗";
}
// 好友约战大乱斗:从 teams[0].players 取实际参与人数动态展示
const count = battle.teams?.[0]?.players?.length;
return count ? `${count}人大乱斗` : "大乱斗";
};
/**
* 支持通过 URL 参数指定初始 tab
* @example /pages/my-growth?tab=1 跳转到「好友约战」tab
*/
onLoad((options) => {
if (options && options.tab !== undefined) {
const tabIndex = parseInt(options.tab, 10);
if (!isNaN(tabIndex)) selectedIndex.value = tabIndex;
}
});
</script>
<template>
<Container title="我的成长脚印" :scroll="false">
<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">
<swiper
:current="selectedIndex"
@change="(e) => (selectedIndex = e.detail.current)"
:style="{ height: '100%' }"
>
<swiper-item>
<ScrollList :onLoading="onMatchLoading">
<view
v-for="(item, index) in matchList"
:key="index"
@click="() => toMatchDetail(item.id)"
>
<view class="contest-header">
<text>{{ getName(item) }}</text>
<text>{{ item.createTime }}</text>
<image src="../static/back.png" mode="widthFix" />
</view>
<BattleHeader
:players="item.teams[0] ? item.teams[0].players : []"
:blueTeam="item.teams[1] ? item.teams[1].players : []"
:redTeam="item.teams[2] ? item.teams[2].players : []"
:winner="item.winTeam"
:showRank="item.teams[0]"
:showHeader="false"
/>
</view>
</ScrollList>
</swiper-item>
<swiper-item>
<ScrollList :onLoading="onBattleLoading">
<view
v-for="(item, index) in battleList"
:key="index"
@click="() => toMatchDetail(item.id)"
>
<view class="contest-header">
<text>{{ getName(item) }}</text>
<text>{{ item.createTime }}</text>
<image src="../static/back.png" mode="widthFix" />
</view>
<BattleHeader
:players="item.teams[0] ? item.teams[0].players : []"
:blueTeam="item.teams[1] ? item.teams[1].players : []"
:redTeam="item.teams[2] ? item.teams[2].players : []"
:winner="item.winTeam"
:showRank="item.teams[0]"
:showHeader="false"
/>
</view>
</ScrollList>
</swiper-item>
<swiper-item>
<ScrollList :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.createTime }}</text
>
<image src="../static/back.png" mode="widthFix" />
</view>
</ScrollList>
</swiper-item>
</swiper>
</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>