317 lines
7.8 KiB
Vue
317 lines
7.8 KiB
Vue
<script setup>
|
||
import { ref } from "vue";
|
||
import { onShow } from "@dcloudio/uni-app";
|
||
import Container from "@/components/Container.vue";
|
||
import Guide from "@/components/Guide.vue";
|
||
import SButton from "@/components/SButton.vue";
|
||
import SModal from "@/components/SModal.vue";
|
||
import CreateRoom from "@/components/CreateRoom.vue";
|
||
import Avatar from "@/components/Avatar.vue";
|
||
import { getRoomAPI, joinRoomAPI, isGamingAPI, getBattleDataAPI } from "@/apis";
|
||
import useStore from "@/store";
|
||
import { storeToRefs } from "pinia";
|
||
const store = useStore();
|
||
const { user } = storeToRefs(store);
|
||
import { debounce } from "@/util";
|
||
|
||
const showModal = ref(false);
|
||
const warnning = ref("");
|
||
const roomNumber = ref("");
|
||
const data = ref({});
|
||
|
||
const enterRoom = debounce(async () => {
|
||
const isGaming = await isGamingAPI();
|
||
if (isGaming) {
|
||
uni.$showHint(1);
|
||
return;
|
||
}
|
||
if (!roomNumber.value) {
|
||
warnning.value = "请输入房间号";
|
||
showModal.value = true;
|
||
} else {
|
||
const room = await getRoomAPI(roomNumber.value);
|
||
if (room.number) {
|
||
const alreadyIn = room.members.find(
|
||
(item) => item.userInfo.id === user.value.id
|
||
);
|
||
if (!alreadyIn) {
|
||
const result = await joinRoomAPI(roomNumber.value);
|
||
if (result.full) {
|
||
warnning.value = "房间已满员";
|
||
showModal.value = true;
|
||
return;
|
||
}
|
||
}
|
||
roomNumber.value = "";
|
||
showModal.value = false;
|
||
uni.navigateTo({
|
||
url: `/pages/battle-room?roomNumber=${room.number}`,
|
||
});
|
||
} else {
|
||
warnning.value = room.started ? "该房间对战已开始,无法加入" : "查无此房";
|
||
showModal.value = true;
|
||
}
|
||
}
|
||
});
|
||
const onCreateRoom = async () => {
|
||
const isGaming = await isGamingAPI();
|
||
if (isGaming) {
|
||
uni.$showHint(1);
|
||
return;
|
||
}
|
||
warnning.value = "";
|
||
showModal.value = true;
|
||
};
|
||
onShow(async () => {
|
||
const result = await getBattleDataAPI();
|
||
data.value = result;
|
||
});
|
||
</script>
|
||
|
||
<template>
|
||
<Container title="好友约战" :showBackToGame="true">
|
||
<view :style="{ width: '100%' }">
|
||
<Guide>
|
||
<view class="guide-tips">
|
||
<text>约上朋友开几局,欢乐多,不寂寞</text>
|
||
<text>一起练升级更快,早日加入全国排位赛!</text>
|
||
</view>
|
||
</Guide>
|
||
<view class="my-data">
|
||
<view>
|
||
<Avatar :rankLvl="user.rankLvl" :src="user.avatar" :size="30" />
|
||
<text class="truncate">{{ user.nickName }}</text>
|
||
</view>
|
||
<view>
|
||
<view>
|
||
<view>
|
||
<text>{{ data.TotalBattle }}</text>
|
||
<text>局</text>
|
||
</view>
|
||
<text>约战数量</text>
|
||
</view>
|
||
<view>
|
||
<view>
|
||
<text>{{ data.totalArrow }}</text>
|
||
<text>箭</text>
|
||
</view>
|
||
<text>射箭量</text>
|
||
</view>
|
||
<view>
|
||
<view class="stars">
|
||
<block v-for="i in 5" :key="i">
|
||
<image
|
||
v-if="data.totalWinningRate >= i * 0.2"
|
||
src="../static/star-full.png"
|
||
mode="widthFix"
|
||
/>
|
||
<image
|
||
v-else-if="data.totalWinningRate >= (i - 1) * 0.2 + 0.1"
|
||
src="../static/star-half.png"
|
||
mode="widthFix"
|
||
/>
|
||
<image v-else src="../static/star-empty.png" mode="widthFix" />
|
||
</block>
|
||
</view>
|
||
<text>挑战难度</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="founded-room">
|
||
<image src="../static/founded-room.png" mode="widthFix" />
|
||
<view>
|
||
<input
|
||
placeholder="输入房间号"
|
||
v-model="roomNumber"
|
||
placeholder-style="color: #ccc"
|
||
/>
|
||
<view @click="enterRoom">进入房间</view>
|
||
</view>
|
||
</view>
|
||
<view class="create-room">
|
||
<image
|
||
src="https://static.shelingxingqiu.com/attachment/2025-07-15/dbcejys872iyun92h6.png"
|
||
mode="widthFix"
|
||
/>
|
||
<image src="../static/room-notfound-title.png" mode="widthFix" />
|
||
<view>
|
||
<image :src="user.avatar" mode="widthFix" />
|
||
<image src="../static/versus.png" mode="widthFix" />
|
||
<view>
|
||
<image src="../static/question-mark.png" mode="widthFix" />
|
||
</view>
|
||
</view>
|
||
<view>
|
||
<SButton width="80%" :rounded="30" :onClick="onCreateRoom">
|
||
创建约战房
|
||
</SButton>
|
||
</view>
|
||
</view>
|
||
<SModal :show="showModal" :onClose="() => (showModal = false)">
|
||
<view v-if="warnning" class="warnning">
|
||
{{ warnning }}
|
||
</view>
|
||
<CreateRoom v-if="!warnning" :onConfirm="() => (showModal = false)" />
|
||
</SModal>
|
||
</view>
|
||
</Container>
|
||
</template>
|
||
|
||
<style scoped>
|
||
.founded-room {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: flex-start;
|
||
background-color: #54431d33;
|
||
border: 1px solid #54431d;
|
||
margin: 15px;
|
||
border-radius: 10px;
|
||
padding: 15px;
|
||
}
|
||
.founded-room > image {
|
||
width: 16vw;
|
||
}
|
||
.founded-room > view {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
margin-top: 15px;
|
||
background-color: #fff;
|
||
border-radius: 30px;
|
||
width: 100%;
|
||
overflow: hidden;
|
||
}
|
||
.founded-room > view > input {
|
||
width: 70%;
|
||
text-align: center;
|
||
font-size: 14px;
|
||
height: 40px;
|
||
}
|
||
.founded-room > view > view {
|
||
background-color: #fed847;
|
||
width: 30%;
|
||
line-height: 40px;
|
||
border-radius: 30px;
|
||
font-size: 14px;
|
||
padding: 3px 0;
|
||
font-weight: bold;
|
||
color: #000;
|
||
text-align: center;
|
||
}
|
||
.create-room {
|
||
position: relative;
|
||
margin: 15px;
|
||
height: 50vw;
|
||
}
|
||
.create-room > image:first-of-type {
|
||
position: absolute;
|
||
width: 100%;
|
||
}
|
||
.create-room > image:nth-of-type(2) {
|
||
padding: 15px;
|
||
width: 25vw;
|
||
position: relative;
|
||
}
|
||
.create-room > view:nth-child(3) {
|
||
margin: 12vw auto;
|
||
position: relative;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
.create-room > view > image:first-child {
|
||
width: 19vw;
|
||
transform: translateY(-60%);
|
||
border-radius: 50%;
|
||
position: relative;
|
||
}
|
||
.create-room > view > image:nth-child(2) {
|
||
width: 37vw;
|
||
position: relative;
|
||
}
|
||
.create-room > view > view:nth-child(3) {
|
||
position: relative;
|
||
width: 19vw;
|
||
height: 19vw;
|
||
border-radius: 50%;
|
||
background-color: #ccc;
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
transform: translateY(60%);
|
||
}
|
||
.create-room > view > view:nth-child(3) > image {
|
||
width: 20px;
|
||
margin-right: 2px;
|
||
}
|
||
.warnning {
|
||
width: 100%;
|
||
height: 100%;
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
color: #fff9;
|
||
}
|
||
.my-data {
|
||
width: calc(100% - 30px);
|
||
margin: 15px;
|
||
margin-top: 0;
|
||
border-radius: 10px;
|
||
border: 1px solid #54431d;
|
||
overflow: hidden;
|
||
background-color: #54431d33;
|
||
}
|
||
.my-data > view {
|
||
width: 100%;
|
||
display: flex;
|
||
color: #fff9;
|
||
}
|
||
.my-data > view:first-child {
|
||
width: calc(100% - 30px);
|
||
align-items: flex-end;
|
||
padding-bottom: 15px;
|
||
border-bottom: 1px solid #48494e;
|
||
margin: 15px;
|
||
margin-bottom: 0;
|
||
}
|
||
.my-data > view:first-child > text {
|
||
color: #fff;
|
||
font-size: 17px;
|
||
margin-left: 10px;
|
||
width: 120px;
|
||
}
|
||
.my-data > view:last-child {
|
||
margin-bottom: 15px;
|
||
}
|
||
.my-data > view:last-child > view {
|
||
width: 33%;
|
||
margin-top: 15px;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
font-size: 12px;
|
||
}
|
||
.my-data > view:last-child > view > view {
|
||
margin-bottom: 5px;
|
||
}
|
||
.my-data > view:last-child > view > view > text:first-child {
|
||
color: #fff;
|
||
font-size: 20px;
|
||
margin-right: 5px;
|
||
transform: translateY(4px);
|
||
}
|
||
.my-data > view:last-child > view:nth-child(2) {
|
||
border-left: 1px solid #48494e;
|
||
border-right: 1px solid #48494e;
|
||
}
|
||
.my-data > view:last-child > view > view {
|
||
display: flex;
|
||
align-items: flex-end;
|
||
height: 20px;
|
||
}
|
||
.stars > image {
|
||
width: 4vw;
|
||
margin: 0 1px;
|
||
}
|
||
</style>
|