细节优化
This commit is contained in:
27
src/App.vue
27
src/App.vue
@@ -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>
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
@@ -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;
|
||||||
loading.value = true;
|
|
||||||
|
let loadingTimer = null;
|
||||||
|
loadingTimer = setTimeout(() => {
|
||||||
|
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>
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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,7 +188,8 @@ async function onReceiveMessage(messages = []) {
|
|||||||
scores.value.push(msg.target);
|
scores.value.push(msg.target);
|
||||||
power.value = msg.target.battery;
|
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) {
|
if (msg.constructor === MESSAGETYPES.RoundPoint) {
|
||||||
bluePoints.value += msg.blueScore;
|
bluePoints.value += msg.blueScore;
|
||||||
@@ -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>
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
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 = []) {
|
export function renderScores(ctx, arrows = []) {
|
||||||
let rowIndex = 0;
|
let rowIndex = 0;
|
||||||
arrows.forEach((item, i) => {
|
arrows.forEach((item, i) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user