540 lines
13 KiB
Vue
540 lines
13 KiB
Vue
<script setup>
|
|
import { ref, computed, onMounted } from "vue";
|
|
import { onLoad } from "@dcloudio/uni-app";
|
|
import Avatar from "@/components/Avatar.vue";
|
|
import UserUpgrade from "@/components/UserUpgrade.vue";
|
|
import { getBattleAPI } from "@/apis";
|
|
import { topThreeColors, getBattleResultTips } from "@/constants";
|
|
import audioManager from "@/audioManager";
|
|
import useStore from "@/store";
|
|
import { storeToRefs } from "pinia";
|
|
const store = useStore();
|
|
const { user } = storeToRefs(store);
|
|
const { getLvlName } = store;
|
|
|
|
const ifWin = ref(false);
|
|
const data = ref({});
|
|
const totalPoints = ref(0);
|
|
const rank = ref(0);
|
|
const players = ref([]);
|
|
|
|
function exit() {
|
|
if (data.value.roomId) {
|
|
uni.redirectTo({
|
|
url: `/pages/battle-room?roomNumber=${data.value.roomId}`,
|
|
});
|
|
} else {
|
|
uni.navigateBack();
|
|
}
|
|
}
|
|
|
|
onLoad(async (options) => {
|
|
if (!options.battleId) return;
|
|
const myId = user.value.id;
|
|
const result = await getBattleAPI(options.battleId || "60049406950510592");
|
|
data.value = result;
|
|
if (result.winTeam) {
|
|
ifWin.value = result.teams[result.winTeam].players.some(
|
|
(p) => p.id === myId
|
|
);
|
|
}
|
|
if (result.mode <= 3) {
|
|
audioManager.play(ifWin.value ? "胜利" : "失败");
|
|
} else {
|
|
players.value = result.resultList.map((item, index) => {
|
|
const plist = result.teams[0] ? result.teams[0].players : [];
|
|
const p = plist.find((p) => p.id === item.userId);
|
|
if (p.id === user.value.id) {
|
|
totalPoints.value = p.score;
|
|
rank.value = index + 1;
|
|
}
|
|
return {
|
|
...item,
|
|
rank: index + 1,
|
|
name: p.name,
|
|
avatar: p.avatar || "",
|
|
};
|
|
});
|
|
if (rank.value <= players.value * 0.3) {
|
|
audioManager.play("胜利");
|
|
} else {
|
|
audioManager.play("胜利");
|
|
}
|
|
}
|
|
});
|
|
|
|
const myTeam = computed(() => {
|
|
const teams = data.value.teams;
|
|
if (teams && teams.length) {
|
|
if (teams[1].players.some((p) => p.id === user.value.id)) return 1;
|
|
}
|
|
return 2;
|
|
});
|
|
|
|
const checkBowData = () => {
|
|
uni.navigateTo({
|
|
url: `/pages/match-detail?battleId=${data.value.matchId}`,
|
|
});
|
|
};
|
|
</script>
|
|
|
|
<template>
|
|
<view class="container">
|
|
<block v-if="data.mode <= 3">
|
|
<view class="header-team" :style="{ marginTop: '25%' }">
|
|
<image src="../static/battle-result.png" mode="widthFix" />
|
|
<view class="header-solo" v-if="data.mode === 1">
|
|
<text
|
|
:style="{
|
|
background:
|
|
data.winTeam === 1
|
|
? 'linear-gradient(270deg, #3597ff 0%, rgba(0,0,0,0) 100%);'
|
|
: 'linear-gradient(270deg, #fd4444 0%, rgba(0, 0, 0, 0) 100%)',
|
|
}"
|
|
>{{ data.winTeam === 1 ? "蓝队" : "红队" }}获胜</text
|
|
>
|
|
<Avatar
|
|
:size="32"
|
|
:src="
|
|
data.winTeam === 1
|
|
? data.teams[1].players[0].avatar
|
|
: data.teams[2].players[0].avatar
|
|
"
|
|
:borderColor="data.winTeam === 1 ? '#5FADFF' : '#FF5656'"
|
|
mode="widthFix"
|
|
/>
|
|
</view>
|
|
</view>
|
|
<view class="header-mvp" v-if="data.mode === 2 || data.mode === 3">
|
|
<image
|
|
:src="`../static/${data.winTeam === 1 ? 'blue' : 'red'}-team-win.png`"
|
|
mode="widthFix"
|
|
/>
|
|
<view
|
|
:style="{
|
|
transform: `translateY(50px) rotate(-${
|
|
5 + (data.mvp || []).length
|
|
}deg)`,
|
|
}"
|
|
>
|
|
<view v-if="data.mvp && data.mvp.totalRings">
|
|
<image src="../static/title-mvp.png" mode="widthFix" />
|
|
<text
|
|
>斩获<text
|
|
:style="{
|
|
color: '#fed847',
|
|
fontSize: '18px',
|
|
margin: '0 3px',
|
|
fontWeight: '600',
|
|
}"
|
|
>{{ data.mvp.totalRings }}</text
|
|
>环</text
|
|
>
|
|
</view>
|
|
<view v-if="data.mvp && data.mvp.length">
|
|
<view v-for="(player, index) in data.mvp" :key="index">
|
|
<view class="team-avatar">
|
|
<Avatar
|
|
:src="player.avatar"
|
|
:size="40"
|
|
:borderColor="myTeam === 1 ? '#5fadff' : '#ff6060'"
|
|
/>
|
|
<text
|
|
v-if="player.id === user.id"
|
|
:style="{
|
|
backgroundColor: myTeam === 1 ? '#5fadff' : '#ff6060',
|
|
}"
|
|
>自己</text
|
|
>
|
|
</view>
|
|
<text class="truncate">{{ player.name }}</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
<view class="battle-winner">
|
|
<image src="../static/shining-bg.png" mode="widthFix" />
|
|
<image
|
|
:src="ifWin ? '../static/you-win.png' : '../static/you-lost.png'"
|
|
mode="widthFix"
|
|
class="scale-in"
|
|
/>
|
|
<image
|
|
:src="
|
|
getBattleResultTips(data.way, data.mode, {
|
|
win: ifWin,
|
|
})
|
|
"
|
|
class="scale-in"
|
|
mode="widthFix"
|
|
/>
|
|
</view>
|
|
</block>
|
|
<block v-else>
|
|
<view class="header-melee">
|
|
<view />
|
|
<image src="../static/battle-result.png" mode="widthFix" />
|
|
<view />
|
|
</view>
|
|
<view
|
|
class="players"
|
|
:style="{
|
|
height: `${Math.max(players.length > 5 ? '330' : '300')}px`,
|
|
}"
|
|
>
|
|
<view
|
|
v-for="(player, index) in players"
|
|
:key="index"
|
|
:style="{
|
|
border: player.id === user.id ? '1px solid #B04630' : 'none',
|
|
}"
|
|
>
|
|
<image
|
|
v-if="player.rank === 1"
|
|
class="player-bg"
|
|
src="../static/melee-player-bg1.png"
|
|
mode="aspectFill"
|
|
/>
|
|
<image
|
|
v-if="player.rank === 2"
|
|
class="player-bg"
|
|
src="../static/melee-player-bg2.png"
|
|
mode="aspectFill"
|
|
/>
|
|
<image
|
|
v-if="player.rank === 3"
|
|
class="player-bg"
|
|
src="../static/melee-player-bg3.png"
|
|
mode="aspectFill"
|
|
/>
|
|
<image
|
|
v-if="player.rank === 1"
|
|
class="player-crown"
|
|
src="../static/champ1.png"
|
|
mode="widthFix"
|
|
/>
|
|
<image
|
|
v-if="player.rank === 2"
|
|
class="player-crown"
|
|
src="../static/champ2.png"
|
|
mode="widthFix"
|
|
/>
|
|
<image
|
|
v-if="player.rank === 3"
|
|
class="player-crown"
|
|
src="../static/champ3.png"
|
|
mode="widthFix"
|
|
/>
|
|
<view v-if="player.rank > 3" class="view-crown">{{
|
|
player.rank
|
|
}}</view>
|
|
<Avatar
|
|
:src="player.avatar"
|
|
:size="36"
|
|
:borderColor="topThreeColors[index] || ''"
|
|
/>
|
|
<view class="player-title">
|
|
<text class="truncate">{{ player.name }}</text>
|
|
<text>{{ getLvlName(player.rank_lvl) }}</text>
|
|
</view>
|
|
<text
|
|
><text :style="{ color: '#fff' }">{{ player.totalRing }}</text>
|
|
环</text
|
|
>
|
|
</view>
|
|
</view>
|
|
</block>
|
|
<view
|
|
class="battle-e"
|
|
:style="{ marginTop: data.mode > 3 ? '20px' : '20vw' }"
|
|
>
|
|
<image src="../static/row-yellow-bg.png" mode="widthFix" />
|
|
<view class="team-avatar">
|
|
<Avatar
|
|
:src="user.avatar"
|
|
:size="40"
|
|
:borderColor="myTeam === 1 ? '#5fadff' : '#ff6060'"
|
|
/>
|
|
<text
|
|
:style="{ backgroundColor: '#5fadff' }"
|
|
v-if="data.mode <= 3 && myTeam === 1"
|
|
>蓝队</text
|
|
>
|
|
<text
|
|
:style="{ backgroundColor: '#ff6060' }"
|
|
v-if="data.mode <= 3 && myTeam === 2"
|
|
>红队</text
|
|
>
|
|
</view>
|
|
<text v-if="data.way === 1">
|
|
你的经验 {{ totalPoints > 0 ? "+" + totalPoints : totalPoints }}
|
|
</text>
|
|
<text v-if="data.way === 2">
|
|
你的积分 {{ totalPoints > 0 ? "+" + totalPoints : totalPoints }}
|
|
</text>
|
|
</view>
|
|
<text v-if="data.mode > 3" class="description">
|
|
{{
|
|
getBattleResultTips(data.way, data.mode, {
|
|
win: ifWin,
|
|
score: totalPoints,
|
|
rank,
|
|
})
|
|
}}
|
|
</text>
|
|
<view class="op-btn">
|
|
<view @click="checkBowData">查看成绩</view>
|
|
<view @click="exit">返回</view>
|
|
</view>
|
|
<UserUpgrade />
|
|
</view>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.container {
|
|
width: 100vw;
|
|
height: 100vh;
|
|
background-color: #292929;
|
|
position: relative;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: flex-start;
|
|
}
|
|
.tag {
|
|
position: absolute;
|
|
width: 32vw;
|
|
top: 0;
|
|
right: 0;
|
|
}
|
|
.container > view {
|
|
position: relative;
|
|
}
|
|
.header-team {
|
|
width: 82%;
|
|
margin: 10px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
color: #fff;
|
|
}
|
|
.header-team > image {
|
|
width: 20vw;
|
|
}
|
|
.header-solo {
|
|
font-size: 14px;
|
|
display: flex;
|
|
align-items: flex-end;
|
|
}
|
|
.header-solo > text {
|
|
padding: 5px 20px;
|
|
padding-left: 24px;
|
|
transform: translateX(15px);
|
|
}
|
|
.battle-winner {
|
|
width: 100%;
|
|
height: 38%;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: flex-end;
|
|
color: #fff9;
|
|
font-size: 14px;
|
|
}
|
|
.battle-winner > image {
|
|
position: absolute;
|
|
width: 100vw;
|
|
top: 0;
|
|
left: 0;
|
|
}
|
|
.battle-winner > image:first-child {
|
|
animation: rotate 10s linear infinite;
|
|
}
|
|
.battle-winner > image:nth-child(2) {
|
|
top: 10%;
|
|
}
|
|
.battle-winner > image:nth-child(3) {
|
|
top: 75%;
|
|
}
|
|
.battle-e {
|
|
width: 100%;
|
|
height: 60px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
.battle-e > image {
|
|
position: absolute;
|
|
width: 100vw;
|
|
}
|
|
.battle-e > text {
|
|
position: relative;
|
|
font-size: 30px;
|
|
color: #fff;
|
|
margin-left: 10px;
|
|
}
|
|
.description {
|
|
margin-top: 50px;
|
|
font-size: 14px;
|
|
color: #fed847;
|
|
width: 100%;
|
|
text-align: center;
|
|
margin-bottom: 10px;
|
|
}
|
|
.op-btn {
|
|
width: 100%;
|
|
display: flex;
|
|
justify-content: center;
|
|
margin-top: 30px;
|
|
}
|
|
.op-btn > view {
|
|
width: 36%;
|
|
margin: 0 10px;
|
|
background-color: #fed847;
|
|
border-radius: 20px;
|
|
padding: 10px 0;
|
|
text-align: center;
|
|
color: #000;
|
|
}
|
|
.op-btn > view:last-child {
|
|
color: #fff;
|
|
background-color: #757575;
|
|
}
|
|
.header-melee {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: 100%;
|
|
margin-bottom: 30px;
|
|
margin-top: 25%;
|
|
}
|
|
.header-melee > view {
|
|
height: 1px;
|
|
background-color: #fff3;
|
|
width: 18%;
|
|
}
|
|
.header-melee > image {
|
|
width: 27%;
|
|
margin: 0 20px;
|
|
}
|
|
.players {
|
|
display: flex;
|
|
flex-direction: column;
|
|
overflow: auto;
|
|
width: calc(100% - 60px);
|
|
color: #fff6;
|
|
margin: 0 30px;
|
|
}
|
|
.players > view {
|
|
width: 100%;
|
|
height: 60px;
|
|
flex: 0 0 auto;
|
|
overflow: hidden;
|
|
position: relative;
|
|
background-color: #ffffff1a;
|
|
display: flex;
|
|
align-items: center;
|
|
box-sizing: border-box;
|
|
}
|
|
.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;
|
|
}
|
|
.player-title {
|
|
position: relative;
|
|
display: flex;
|
|
flex-direction: column;
|
|
margin-left: 15px;
|
|
width: calc(100% - 160px);
|
|
}
|
|
.player-title > text:first-child {
|
|
color: #fff;
|
|
margin-bottom: 3px;
|
|
width: 40vw;
|
|
}
|
|
.player-title > text:last-child {
|
|
font-size: 13px;
|
|
}
|
|
.team-avatar {
|
|
position: relative;
|
|
overflow: hidden;
|
|
width: 40px;
|
|
height: 40px;
|
|
box-sizing: border-box;
|
|
border-radius: 50%;
|
|
}
|
|
.team-avatar > text {
|
|
font-size: 7px;
|
|
text-align: center;
|
|
width: 100%;
|
|
position: absolute;
|
|
left: 0;
|
|
bottom: 0;
|
|
color: #fff;
|
|
padding-bottom: 1px;
|
|
}
|
|
.header-mvp {
|
|
position: relative;
|
|
width: 100%;
|
|
}
|
|
.header-mvp > image:first-child {
|
|
position: absolute;
|
|
width: 100%;
|
|
}
|
|
.header-mvp > view {
|
|
display: flex;
|
|
justify-content: center;
|
|
}
|
|
.header-mvp > view > view:first-child {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
}
|
|
.header-mvp > view > view:first-child > image {
|
|
width: 24vw;
|
|
}
|
|
.header-mvp > view > view:first-child > text {
|
|
color: #fff;
|
|
font-size: 14px;
|
|
transform: skewX(-10deg);
|
|
}
|
|
.header-mvp > view > view:last-child {
|
|
display: flex;
|
|
align-items: center;
|
|
color: #fff;
|
|
font-size: 9px;
|
|
text-align: center;
|
|
transform: translateY(-4px);
|
|
}
|
|
.header-mvp > view > view:last-child > view {
|
|
margin-left: 4vw;
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
.header-mvp > view > view:last-child > view > text {
|
|
margin-top: 4px;
|
|
width: 40px;
|
|
transform: skewX(-10deg) translateX(-3px);
|
|
}
|
|
</style>
|