diff --git a/src/components/Header.vue b/src/components/Header.vue index a1692c5..828b0a8 100644 --- a/src/components/Header.vue +++ b/src/components/Header.vue @@ -57,7 +57,6 @@ const signin = () => { const loading = ref(false); const pointBook = ref(null); -const showProgress = ref(false); const heat = ref(0); /** 房间号按钮动态定位样式(position: fixed,根据胶囊真实位置计算,脱离 flex 流避免挤压标题) */ const battleRoomBtnStyle = ref({}); @@ -82,9 +81,6 @@ onMounted(() => { pointBook.value = uni.getStorageSync("last-point-book"); } } - if (currentPage.route === "pages/team-battle") { - showProgress.value = true; - } // 仅在对战房间页获取胶囊位置,按钮用 fixed 定位精确贴靠胶囊左侧(脱离 flex 流,不挤压标题) if (currentPage.route === "pages/battle-room") { try { @@ -189,7 +185,7 @@ onBeforeUnmount(() => { }} - + diff --git a/src/components/HeaderProgress.vue b/src/components/HeaderProgress.vue index 887afc9..f735806 100644 --- a/src/components/HeaderProgress.vue +++ b/src/components/HeaderProgress.vue @@ -33,8 +33,8 @@ watch( newVal.includes("你") ? "轮到你了" : newVal.includes("红队") - ? "请红方射箭" - : "请蓝方射箭" + ? "请红方射箭" + : "请蓝方射箭" ); audioManager.play(key, false); currentRoundEnded.value = false; @@ -93,20 +93,22 @@ const onUpdateTips = (newVal) => { tips.value = newVal; }; -const onUpdateTotalShot = (newVal) => { - currentShot.value = newVal.currentShot; - totalShot.value = newVal.totalShot; -}; +// 监听 Pinia store 中 totalShot 变化,用于比赛恢复时同步箭数(替代 uni.$emit 避免时序问题) +// 使用 immediate: true 确保组件创建时立即读取 store 当前值(解决重入时 totalShot 值不变 watch 不触发的问题) +watch(() => store.game.totalShot, (newVal) => { + if (newVal > 0) { + totalShot.value = newVal; + currentShot.value = store.game.currentShot; + } +}, { immediate: true }); onMounted(() => { - uni.$on("update-shot", onUpdateTotalShot); uni.$on("update-tips", onUpdateTips); uni.$on("socket-inbox", onReceiveMessage); uni.$on("play-sound", playSound); }); onBeforeUnmount(() => { - uni.$off("update-shot", onUpdateTotalShot); uni.$off("socket-inbox", onReceiveMessage); uni.$off("play-sound", playSound); if (timer.value) clearInterval(timer.value); @@ -118,10 +120,7 @@ onBeforeUnmount(() => { {{ (tips || "").replace(/你/g, "").replace(/重回/g, "") }} ({{ currentShot }}/{{ totalShot }}) @@ -135,11 +134,13 @@ onBeforeUnmount(() => { justify-content: center; font-weight: 500; } -.container > button:last-child { + +.container>button:last-child { width: 36px; height: 36px; } -.container > button:last-child > image { + +.container>button:last-child>image { width: 36px; min-height: 36px; } diff --git a/src/pages/team-battle.vue b/src/pages/team-battle.vue index 21bb3ad..e4e565a 100644 --- a/src/pages/team-battle.vue +++ b/src/pages/team-battle.vue @@ -176,7 +176,7 @@ function onNewRound(msg, prevRound) { isFinalShoot.value = msg.current.goldRound; // 决金箭轮每人只射一箭,重置箭数显示为 (0/1) if (msg.current.goldRound) { - uni.$emit("update-shot", { currentShot: 0, totalShot: 1 }); + store.updateShotInfo(0, 1); } // 用传入的 prevRound(捕获时刻的旧轮次)展示结算 Tip,与进度条 currentRound 解耦 roundTipRound.value = prevRound; @@ -228,6 +228,8 @@ async function onReceiveMessage(msg) { onLoad(async (options) => { if (options.battleId) battleId.value = options.battleId; + // 重置箭数,防止因 Pinia 保留上一场比赛的旧值而错误展示 + store.updateShotInfo(0, 0); // uni.enableAlertBeforeUnload({ // message: "离开比赛可能导致比赛失败,是否继续?", // success: (res) => { @@ -263,9 +265,15 @@ onShow(async () => { url: `/pages/friend-battle-result?battleId=${result.matchId}`, }); } else { - // shootNumber 来自后端,恢复状态时同步 totalShot,防止 BattleStart 不重新推送导致显示错误 - if (result.shootNumber) { - uni.$emit("update-shot", { currentShot: 0, totalShot: result.shootNumber }); + if (result.status !== 0) { + // 比赛进行中,从后端恢复箭数(测距阶段不展示) + if (result.shootNumber) { + // current.index 为 0 基的当前箭序号(0=第一箭),+1 后作为 currentShot 展示 + store.updateShotInfo((result.current?.index ?? 0) + 1, result.shootNumber); + } + } else { + // 测距阶段重置箭数,防止 ImmediateWatcher 读取 Pinia 保留的旧值 + store.updateShotInfo(0, 0); } recoverData(result, {force: true}); } diff --git a/src/store.js b/src/store.js index b53daef..2ab1868 100644 --- a/src/store.js +++ b/src/store.js @@ -80,6 +80,8 @@ export default defineStore("store", { roomID: "", inBattle: false, roomNumber: "", // 当前房间号,供 Header 展示房号胶囊 + currentShot: 0, // 当前已射箭数(用于 HeaderProgress 恢复状态) + totalShot: 0, // 轮次总箭数(用于 HeaderProgress 恢复状态) }, }), @@ -136,6 +138,11 @@ export default defineStore("store", { this.game.roomID = roomID; this.game.inBattle = inBattle; }, + /** 更新当前射箭进度(用于 HeaderProgress 恢复状态,替代 uni.$emit 避免时序问题) */ + updateShotInfo(currentShot = 0, totalShot = 0) { + this.game.currentShot = currentShot; + this.game.totalShot = totalShot; + }, /** 更新当前房间号,供 Header 组件展示房号胶囊 */ updateRoomNumber(number) { this.game.roomNumber = number;