细节优化

This commit is contained in:
kron
2025-06-22 15:04:10 +08:00
parent bd438e7b62
commit 1e681b46c7
11 changed files with 115 additions and 63 deletions

View File

@@ -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>

View File

@@ -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",

View File

@@ -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>

View File

@@ -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;

View File

@@ -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,

View File

@@ -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>

View File

@@ -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;
}

View File

@@ -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>

View File

@@ -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;

View File

@@ -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>

View File

@@ -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) => {