细节优化

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; top: -1000px;
left: 0; 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> </style>

View File

@@ -18,7 +18,7 @@ const tabs = [
]; ];
function handleTabClick(index) { function handleTabClick(index) {
if (index !== 2 && !user.value.id) return props.signin(); if (index !== 0 && !user.value.id) return props.signin();
if (index === 0) { if (index === 0) {
uni.navigateTo({ uni.navigateTo({
url: "/pages/be-vip", url: "/pages/be-vip",

View File

@@ -1,5 +1,6 @@
<script setup> <script setup>
import { ref } from "vue"; import { ref } from "vue";
import { debounce } from "@/util";
const props = defineProps({ const props = defineProps({
width: { width: {
type: String, type: String,
@@ -28,15 +29,23 @@ const props = defineProps({
}); });
const loading = ref(false); const loading = ref(false);
const onBtnClick = async () => { const timer = ref(null);
const onBtnClick = debounce(async () => {
if (props.disabled || loading.value) return; if (props.disabled || loading.value) return;
let loadingTimer = null;
loadingTimer = setTimeout(() => {
loading.value = true; loading.value = true;
}, 300);
try { try {
await props.onClick(); await props.onClick();
} finally { } finally {
clearTimeout(loadingTimer);
loading.value = false; loading.value = false;
} }
}; });
</script> </script>
<template> <template>

View File

@@ -50,9 +50,8 @@ const handleChange = (e) => {
<style scoped> <style scoped>
.swiper-container { .swiper-container {
width: calc(100% - 20px); width: 100%;
margin: 10px; height: 570px;
height: 560px;
position: relative; position: relative;
border-radius: 10px; border-radius: 10px;
overflow: hidden; overflow: hidden;
@@ -64,12 +63,13 @@ const handleChange = (e) => {
} }
.swiper-container image { .swiper-container image {
width: 100%; width: calc(100% - 20px);
margin: 10px;
} }
.dots { .dots {
position: absolute; position: absolute;
bottom: 14%; bottom: 13%;
left: 50%; left: 50%;
transform: translateX(-50%); transform: translateX(-50%);
display: flex; display: flex;

View File

@@ -9,6 +9,7 @@ export const MESSAGETYPES = {
ToSomeoneShoot: parseInt("0x077ACD1A"), // 125488410 ToSomeoneShoot: parseInt("0x077ACD1A"), // 125488410
SomeGuyIsReady: parseInt("0xAEE8C236"), // 2934489654 SomeGuyIsReady: parseInt("0xAEE8C236"), // 2934489654
MatchOver: parseInt("0xB7815EEF"), // 3078708975 MatchOver: parseInt("0xB7815EEF"), // 3078708975
StartCount: parseInt("0xD7B0DD2F"), // 3618692399
RoundPoint: 4061248646, RoundPoint: 4061248646,
UserEnterRoom: 2133805521, UserEnterRoom: 2133805521,
UserExitRoom: 3896523333, UserExitRoom: 3896523333,

View File

@@ -13,8 +13,9 @@ import BowPower from "@/components/BowPower.vue";
import ShootProgress from "@/components/ShootProgress.vue"; import ShootProgress from "@/components/ShootProgress.vue";
import PlayersRow from "@/components/PlayersRow.vue"; import PlayersRow from "@/components/PlayersRow.vue";
import SModal from "@/components/SModal.vue"; import SModal from "@/components/SModal.vue";
import ScreenHint from "@/components/ScreenHint.vue";
import { getRoomAPI, destroyRoomAPI, exitRoomAPI, startRoomAPI } from "@/apis"; import { getRoomAPI, destroyRoomAPI, exitRoomAPI, startRoomAPI } from "@/apis";
import { MESSAGETYPES, roundsName } from "@/constants"; import { MESSAGETYPES, roundsName, getMessageTypeName } from "@/constants";
import useStore from "@/store"; import useStore from "@/store";
import { storeToRefs } from "pinia"; import { storeToRefs } from "pinia";
const store = useStore(); const store = useStore();
@@ -40,6 +41,9 @@ const tips = ref("即将开始...");
const roundResults = ref([]); const roundResults = ref([]);
const redPoints = ref(0); const redPoints = ref(0);
const bluePoints = ref(0); const bluePoints = ref(0);
const currentRedPoint = ref(0);
const currentBluePoint = ref(0);
const showRoundTip = ref(false);
const playersScores = ref({}); const playersScores = ref({});
const showModal = ref(false); const showModal = ref(false);
onLoad(async (options) => { onLoad(async (options) => {
@@ -98,7 +102,7 @@ async function onReceiveMessage(messages = []) {
(battleId.value && msg.id === battleId.value) || (battleId.value && msg.id === battleId.value) ||
msg.constructor === MESSAGETYPES.WaitForAllReady msg.constructor === MESSAGETYPES.WaitForAllReady
) { ) {
console.log("收到消息:", msg); console.log("收到消息:", getMessageTypeName(msg.constructor), msg);
} }
if (!start.value && msg.constructor === MESSAGETYPES.ShootSyncMeArrowID) { if (!start.value && msg.constructor === MESSAGETYPES.ShootSyncMeArrowID) {
scores.value.push(msg.target); scores.value.push(msg.target);
@@ -184,6 +188,7 @@ async function onReceiveMessage(messages = []) {
scores.value.push(msg.target); scores.value.push(msg.target);
power.value = msg.target.battery; power.value = msg.target.battery;
} }
if (playersScores.value[msg.userId])
playersScores.value[msg.userId].push(msg.target); playersScores.value[msg.userId].push(msg.target);
} }
if (msg.constructor === MESSAGETYPES.RoundPoint) { if (msg.constructor === MESSAGETYPES.RoundPoint) {
@@ -194,6 +199,9 @@ async function onReceiveMessage(messages = []) {
const result = msg.preRoundResult; const result = msg.preRoundResult;
scores.value = []; scores.value = [];
currentShooterId.value = 0; currentShooterId.value = 0;
currentBluePoint.value = result.blueScore;
currentRedPoint.value = result.redScore;
showRoundTip.value = true;
if ( if (
result.currentRound > 0 && result.currentRound > 0 &&
result.currentRound < totalRounds.value result.currentRound < totalRounds.value
@@ -221,7 +229,7 @@ const onLeaveRoom = () => {
}; };
const destroyRoom = async () => { const destroyRoom = async () => {
await destroyRoomAPI(roomNumber.value); if (roomNumber.value) await destroyRoomAPI(roomNumber.value);
}; };
const exitRoom = async () => { const exitRoom = async () => {
@@ -349,10 +357,27 @@ onUnmounted(() => {
/> />
</view> </view>
<Timer :seq="timerSeq" /> <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)"> <SModal :show="showModal" :onClose="() => (showModal = false)">
<view class="btns"> <view class="btns">
<button @click="exitRoom">暂时离开</button> <SButton :onClick="exitRoom" width="200px" :rounded="20">
<button @click="destroyRoom">解散房间</button> 暂时离开
</SButton>
<view :style="{ height: '20px' }"></view>
<SButton :onClick="destroyRoom" width="200px" :rounded="20">
解散房间
</SButton>
</view> </view>
</SModal> </SModal>
</Container> </Container>
@@ -450,7 +475,7 @@ onUnmounted(() => {
align-items: center; align-items: center;
justify-content: center; justify-content: center;
} }
.btns > button { /* .btns > button {
color: #000; color: #000;
background-color: #fed847; background-color: #fed847;
padding: 10px; padding: 10px;
@@ -458,5 +483,5 @@ onUnmounted(() => {
border-radius: 20px; border-radius: 20px;
font-size: 14px; font-size: 14px;
margin: 10px; margin: 10px;
} } */
</style> </style>

View File

@@ -6,14 +6,12 @@ import SButton from "@/components/SButton.vue";
import useStore from "@/store"; import useStore from "@/store";
import { storeToRefs } from "pinia"; import { storeToRefs } from "pinia";
const store = useStore(); const store = useStore();
const { user } = storeToRefs(store); const { user, config } = storeToRefs(store);
const vipChoosen = ref(0); const selectedVIP = ref(0);
const vips = [1, 3, 6, 12];
const chooseVip = (index) => { const chooseVip = (index) => {
vipChoosen.value = index; selectedVIP.value = index;
}; };
const onPay = () => { const onPay = () => {
@@ -61,19 +59,19 @@ const onPay = () => {
</view> </view>
<view class="vip-items"> <view class="vip-items">
<view <view
v-for="(item, index) in vips" v-for="(item, index) in config.vipMenus || []"
:key="index" :key="index"
:style="{ :style="{
color: vipChoosen === index ? '#fff' : '#333333', color: selectedVIP === index ? '#fff' : '#333333',
borderColor: vipChoosen === index ? '#FF7D57' : '#eee', borderColor: selectedVIP === index ? '#FF7D57' : '#eee',
background: background:
vipChoosen === index selectedVIP === index
? '#FF7D57' ? '#FF7D57'
: 'linear-gradient(180deg, #fbfbfb 0%, #f5f5f5 100%)', : 'linear-gradient(180deg, #fbfbfb 0%, #f5f5f5 100%)',
}" }"
@click="chooseVip(index)" @click="chooseVip(index)"
> >
{{ item }}个月会员 {{ item.name }}
</view> </view>
</view> </view>
</view> </view>
@@ -140,15 +138,15 @@ const onPay = () => {
} }
.vip-items { .vip-items {
width: 100%; width: 100%;
display: flex; display: grid;
align-items: center; grid-template-columns: repeat(4, 23.5%);
justify-content: space-between;
padding: 10px; padding: 10px;
row-gap: 5%;
column-gap: 2%;
} }
.vip-items > view { .vip-items > view {
border: 1px solid #eee; border: 1px solid #eee;
padding: 12px 0; padding: 12px 0;
width: 23%;
border-radius: 10px; border-radius: 10px;
text-align: center; text-align: center;
} }

View File

@@ -11,12 +11,13 @@ import useStore from "@/store";
import { storeToRefs } from "pinia"; import { storeToRefs } from "pinia";
const store = useStore(); const store = useStore();
const { user } = storeToRefs(store); const { user } = storeToRefs(store);
import { debounce } from "@/util";
const showModal = ref(false); const showModal = ref(false);
const warnning = ref(""); const warnning = ref("");
const roomNumber = ref(""); const roomNumber = ref("");
const enterRoom = async () => { const enterRoom = debounce(async () => {
if (!roomNumber.value) { if (!roomNumber.value) {
warnning.value = "请输入房间号"; warnning.value = "请输入房间号";
showModal.value = true; showModal.value = true;
@@ -28,6 +29,7 @@ const enterRoom = async () => {
); );
if (!alreadyIn) await joinRoomAPI(roomNumber.value); if (!alreadyIn) await joinRoomAPI(roomNumber.value);
roomNumber.value = ""; roomNumber.value = "";
showModal.value = false;
uni.navigateTo({ uni.navigateTo({
url: `/pages/battle-room?roomNumber=${room.number}`, url: `/pages/battle-room?roomNumber=${room.number}`,
}); });
@@ -36,8 +38,8 @@ const enterRoom = async () => {
showModal.value = true; showModal.value = true;
} }
} }
}; });
const createRoom = () => { const onCreateRoom = () => {
warnning.value = ""; warnning.value = "";
showModal.value = true; showModal.value = true;
}; };
@@ -74,7 +76,7 @@ const createRoom = () => {
</view> </view>
</view> </view>
<view> <view>
<SButton width="70%" :rounded="30" :onClick="createRoom"> <SButton width="70%" :rounded="30" :onClick="onCreateRoom">
创建约战房 创建约战房
</SButton> </SButton>
</view> </view>

View File

@@ -42,7 +42,7 @@ const handleScan = () => {
}; };
const confirmBind = async () => { const confirmBind = async () => {
if (addDevice.value.id) { if (!justBind.value && addDevice.value.id) {
await bindDeviceAPI(addDevice.value); await bindDeviceAPI(addDevice.value);
updateDevice(addDevice.value.id, addDevice.value.name); updateDevice(addDevice.value.id, addDevice.value.name);
confirmBindTip.value = false; confirmBindTip.value = false;

View File

@@ -216,31 +216,4 @@ onUnmounted(() => {
.container { .container {
width: 100%; 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> </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 = []) { export function renderScores(ctx, arrows = []) {
let rowIndex = 0; let rowIndex = 0;
arrows.forEach((item, i) => { arrows.forEach((item, i) => {