细节优化
This commit is contained in:
27
src/App.vue
27
src/App.vue
@@ -167,4 +167,31 @@ button::after {
|
||||
top: -1000px;
|
||||
left: 0;
|
||||
}
|
||||
.round-end-tip {
|
||||
width: 100%;
|
||||
color: #fff;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
.round-end-tip > view:nth-child(2) {
|
||||
margin: 15px 0;
|
||||
font-size: 24px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.round-end-tip > view:nth-child(2) > text:nth-child(2),
|
||||
.round-end-tip > view:nth-child(2) > text:nth-child(4) {
|
||||
color: #fed847;
|
||||
width: 30px;
|
||||
text-align: center;
|
||||
font-size: 30px;
|
||||
}
|
||||
.round-end-tip > text:nth-child(3),
|
||||
.round-end-tip > text:nth-child(4) {
|
||||
color: #fff9;
|
||||
font-size: 14px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -18,7 +18,7 @@ const tabs = [
|
||||
];
|
||||
|
||||
function handleTabClick(index) {
|
||||
if (index !== 2 && !user.value.id) return props.signin();
|
||||
if (index !== 0 && !user.value.id) return props.signin();
|
||||
if (index === 0) {
|
||||
uni.navigateTo({
|
||||
url: "/pages/be-vip",
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { debounce } from "@/util";
|
||||
const props = defineProps({
|
||||
width: {
|
||||
type: String,
|
||||
@@ -28,15 +29,23 @@ const props = defineProps({
|
||||
});
|
||||
|
||||
const loading = ref(false);
|
||||
const onBtnClick = async () => {
|
||||
const timer = ref(null);
|
||||
|
||||
const onBtnClick = debounce(async () => {
|
||||
if (props.disabled || loading.value) return;
|
||||
loading.value = true;
|
||||
|
||||
let loadingTimer = null;
|
||||
loadingTimer = setTimeout(() => {
|
||||
loading.value = true;
|
||||
}, 300);
|
||||
|
||||
try {
|
||||
await props.onClick();
|
||||
} finally {
|
||||
clearTimeout(loadingTimer);
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
@@ -50,9 +50,8 @@ const handleChange = (e) => {
|
||||
|
||||
<style scoped>
|
||||
.swiper-container {
|
||||
width: calc(100% - 20px);
|
||||
margin: 10px;
|
||||
height: 560px;
|
||||
width: 100%;
|
||||
height: 570px;
|
||||
position: relative;
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
@@ -64,12 +63,13 @@ const handleChange = (e) => {
|
||||
}
|
||||
|
||||
.swiper-container image {
|
||||
width: 100%;
|
||||
width: calc(100% - 20px);
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
.dots {
|
||||
position: absolute;
|
||||
bottom: 14%;
|
||||
bottom: 13%;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
display: flex;
|
||||
|
||||
@@ -9,6 +9,7 @@ export const MESSAGETYPES = {
|
||||
ToSomeoneShoot: parseInt("0x077ACD1A"), // 125488410
|
||||
SomeGuyIsReady: parseInt("0xAEE8C236"), // 2934489654
|
||||
MatchOver: parseInt("0xB7815EEF"), // 3078708975
|
||||
StartCount: parseInt("0xD7B0DD2F"), // 3618692399
|
||||
RoundPoint: 4061248646,
|
||||
UserEnterRoom: 2133805521,
|
||||
UserExitRoom: 3896523333,
|
||||
|
||||
@@ -13,8 +13,9 @@ import BowPower from "@/components/BowPower.vue";
|
||||
import ShootProgress from "@/components/ShootProgress.vue";
|
||||
import PlayersRow from "@/components/PlayersRow.vue";
|
||||
import SModal from "@/components/SModal.vue";
|
||||
import ScreenHint from "@/components/ScreenHint.vue";
|
||||
import { getRoomAPI, destroyRoomAPI, exitRoomAPI, startRoomAPI } from "@/apis";
|
||||
import { MESSAGETYPES, roundsName } from "@/constants";
|
||||
import { MESSAGETYPES, roundsName, getMessageTypeName } from "@/constants";
|
||||
import useStore from "@/store";
|
||||
import { storeToRefs } from "pinia";
|
||||
const store = useStore();
|
||||
@@ -40,6 +41,9 @@ const tips = ref("即将开始...");
|
||||
const roundResults = ref([]);
|
||||
const redPoints = ref(0);
|
||||
const bluePoints = ref(0);
|
||||
const currentRedPoint = ref(0);
|
||||
const currentBluePoint = ref(0);
|
||||
const showRoundTip = ref(false);
|
||||
const playersScores = ref({});
|
||||
const showModal = ref(false);
|
||||
onLoad(async (options) => {
|
||||
@@ -98,7 +102,7 @@ async function onReceiveMessage(messages = []) {
|
||||
(battleId.value && msg.id === battleId.value) ||
|
||||
msg.constructor === MESSAGETYPES.WaitForAllReady
|
||||
) {
|
||||
console.log("收到消息:", msg);
|
||||
console.log("收到消息:", getMessageTypeName(msg.constructor), msg);
|
||||
}
|
||||
if (!start.value && msg.constructor === MESSAGETYPES.ShootSyncMeArrowID) {
|
||||
scores.value.push(msg.target);
|
||||
@@ -184,7 +188,8 @@ async function onReceiveMessage(messages = []) {
|
||||
scores.value.push(msg.target);
|
||||
power.value = msg.target.battery;
|
||||
}
|
||||
playersScores.value[msg.userId].push(msg.target);
|
||||
if (playersScores.value[msg.userId])
|
||||
playersScores.value[msg.userId].push(msg.target);
|
||||
}
|
||||
if (msg.constructor === MESSAGETYPES.RoundPoint) {
|
||||
bluePoints.value += msg.blueScore;
|
||||
@@ -194,6 +199,9 @@ async function onReceiveMessage(messages = []) {
|
||||
const result = msg.preRoundResult;
|
||||
scores.value = [];
|
||||
currentShooterId.value = 0;
|
||||
currentBluePoint.value = result.blueScore;
|
||||
currentRedPoint.value = result.redScore;
|
||||
showRoundTip.value = true;
|
||||
if (
|
||||
result.currentRound > 0 &&
|
||||
result.currentRound < totalRounds.value
|
||||
@@ -221,7 +229,7 @@ const onLeaveRoom = () => {
|
||||
};
|
||||
|
||||
const destroyRoom = async () => {
|
||||
await destroyRoomAPI(roomNumber.value);
|
||||
if (roomNumber.value) await destroyRoomAPI(roomNumber.value);
|
||||
};
|
||||
|
||||
const exitRoom = async () => {
|
||||
@@ -349,10 +357,27 @@ onUnmounted(() => {
|
||||
/>
|
||||
</view>
|
||||
<Timer :seq="timerSeq" />
|
||||
<ScreenHint :show="showRoundTip" :onClose="() => (showRoundTip = false)">
|
||||
<view class="round-end-tip">
|
||||
<text>第{{ currentRound - 1 }}轮射击结束</text>
|
||||
<view>
|
||||
<text>蓝队</text>
|
||||
<text>{{ currentBluePoint }}</text>
|
||||
<text>分,红队</text>
|
||||
<text>{{ currentRedPoint }}</text>
|
||||
<text>分</text>
|
||||
</view>
|
||||
</view>
|
||||
</ScreenHint>
|
||||
<SModal :show="showModal" :onClose="() => (showModal = false)">
|
||||
<view class="btns">
|
||||
<button @click="exitRoom">暂时离开</button>
|
||||
<button @click="destroyRoom">解散房间</button>
|
||||
<SButton :onClick="exitRoom" width="200px" :rounded="20">
|
||||
暂时离开
|
||||
</SButton>
|
||||
<view :style="{ height: '20px' }"></view>
|
||||
<SButton :onClick="destroyRoom" width="200px" :rounded="20">
|
||||
解散房间
|
||||
</SButton>
|
||||
</view>
|
||||
</SModal>
|
||||
</Container>
|
||||
@@ -450,7 +475,7 @@ onUnmounted(() => {
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.btns > button {
|
||||
/* .btns > button {
|
||||
color: #000;
|
||||
background-color: #fed847;
|
||||
padding: 10px;
|
||||
@@ -458,5 +483,5 @@ onUnmounted(() => {
|
||||
border-radius: 20px;
|
||||
font-size: 14px;
|
||||
margin: 10px;
|
||||
}
|
||||
} */
|
||||
</style>
|
||||
|
||||
@@ -6,14 +6,12 @@ import SButton from "@/components/SButton.vue";
|
||||
import useStore from "@/store";
|
||||
import { storeToRefs } from "pinia";
|
||||
const store = useStore();
|
||||
const { user } = storeToRefs(store);
|
||||
const { user, config } = storeToRefs(store);
|
||||
|
||||
const vipChoosen = ref(0);
|
||||
|
||||
const vips = [1, 3, 6, 12];
|
||||
const selectedVIP = ref(0);
|
||||
|
||||
const chooseVip = (index) => {
|
||||
vipChoosen.value = index;
|
||||
selectedVIP.value = index;
|
||||
};
|
||||
|
||||
const onPay = () => {
|
||||
@@ -61,19 +59,19 @@ const onPay = () => {
|
||||
</view>
|
||||
<view class="vip-items">
|
||||
<view
|
||||
v-for="(item, index) in vips"
|
||||
v-for="(item, index) in config.vipMenus || []"
|
||||
:key="index"
|
||||
:style="{
|
||||
color: vipChoosen === index ? '#fff' : '#333333',
|
||||
borderColor: vipChoosen === index ? '#FF7D57' : '#eee',
|
||||
color: selectedVIP === index ? '#fff' : '#333333',
|
||||
borderColor: selectedVIP === index ? '#FF7D57' : '#eee',
|
||||
background:
|
||||
vipChoosen === index
|
||||
selectedVIP === index
|
||||
? '#FF7D57'
|
||||
: 'linear-gradient(180deg, #fbfbfb 0%, #f5f5f5 100%)',
|
||||
}"
|
||||
@click="chooseVip(index)"
|
||||
>
|
||||
{{ item }}个月会员
|
||||
{{ item.name }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -140,15 +138,15 @@ const onPay = () => {
|
||||
}
|
||||
.vip-items {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 23.5%);
|
||||
padding: 10px;
|
||||
row-gap: 5%;
|
||||
column-gap: 2%;
|
||||
}
|
||||
.vip-items > view {
|
||||
border: 1px solid #eee;
|
||||
padding: 12px 0;
|
||||
width: 23%;
|
||||
border-radius: 10px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@@ -11,12 +11,13 @@ 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 enterRoom = async () => {
|
||||
const enterRoom = debounce(async () => {
|
||||
if (!roomNumber.value) {
|
||||
warnning.value = "请输入房间号";
|
||||
showModal.value = true;
|
||||
@@ -28,6 +29,7 @@ const enterRoom = async () => {
|
||||
);
|
||||
if (!alreadyIn) await joinRoomAPI(roomNumber.value);
|
||||
roomNumber.value = "";
|
||||
showModal.value = false;
|
||||
uni.navigateTo({
|
||||
url: `/pages/battle-room?roomNumber=${room.number}`,
|
||||
});
|
||||
@@ -36,8 +38,8 @@ const enterRoom = async () => {
|
||||
showModal.value = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
const createRoom = () => {
|
||||
});
|
||||
const onCreateRoom = () => {
|
||||
warnning.value = "";
|
||||
showModal.value = true;
|
||||
};
|
||||
@@ -74,7 +76,7 @@ const createRoom = () => {
|
||||
</view>
|
||||
</view>
|
||||
<view>
|
||||
<SButton width="70%" :rounded="30" :onClick="createRoom">
|
||||
<SButton width="70%" :rounded="30" :onClick="onCreateRoom">
|
||||
创建约战房
|
||||
</SButton>
|
||||
</view>
|
||||
|
||||
@@ -42,7 +42,7 @@ const handleScan = () => {
|
||||
};
|
||||
|
||||
const confirmBind = async () => {
|
||||
if (addDevice.value.id) {
|
||||
if (!justBind.value && addDevice.value.id) {
|
||||
await bindDeviceAPI(addDevice.value);
|
||||
updateDevice(addDevice.value.id, addDevice.value.name);
|
||||
confirmBindTip.value = false;
|
||||
|
||||
@@ -216,31 +216,4 @@ onUnmounted(() => {
|
||||
.container {
|
||||
width: 100%;
|
||||
}
|
||||
.round-end-tip {
|
||||
width: 100%;
|
||||
color: #fff;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
.round-end-tip > view:nth-child(2) {
|
||||
margin: 15px 0;
|
||||
font-size: 24px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.round-end-tip > view:nth-child(2) > text:nth-child(2),
|
||||
.round-end-tip > view:nth-child(2) > text:nth-child(4) {
|
||||
color: #fed847;
|
||||
width: 30px;
|
||||
text-align: center;
|
||||
font-size: 30px;
|
||||
}
|
||||
.round-end-tip > text:nth-child(3),
|
||||
.round-end-tip > text:nth-child(4) {
|
||||
color: #fff9;
|
||||
font-size: 14px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
</style>
|
||||
|
||||
17
src/util.js
17
src/util.js
@@ -1,3 +1,20 @@
|
||||
export const debounce = (fn, delay = 300) => {
|
||||
let timer = null;
|
||||
return async (...args) => {
|
||||
if (timer) clearTimeout(timer);
|
||||
return new Promise((resolve) => {
|
||||
timer = setTimeout(async () => {
|
||||
try {
|
||||
const result = await fn(...args);
|
||||
resolve(result);
|
||||
} finally {
|
||||
timer = null;
|
||||
}
|
||||
}, delay);
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
export function renderScores(ctx, arrows = []) {
|
||||
let rowIndex = 0;
|
||||
arrows.forEach((item, i) => {
|
||||
|
||||
Reference in New Issue
Block a user