From 6db2142cf654546794e5ad3ce43998166b476f82 Mon Sep 17 00:00:00 2001 From: chenlimao Date: Wed, 13 May 2026 15:40:12 +0800 Subject: [PATCH 1/2] =?UTF-8?q?fix=EF=BC=9A=E4=BF=AE=E5=A4=8D=E6=B5=8B?= =?UTF-8?q?=E8=B7=9D=E9=A1=B5=E9=9D=A2=E6=A0=87=E9=A2=98=E5=B1=95=E7=A4=BA?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/HeaderProgress.vue | 3 ++- src/pages/team-battle.vue | 5 ++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/components/HeaderProgress.vue b/src/components/HeaderProgress.vue index c06c1d3..da96697 100644 --- a/src/components/HeaderProgress.vue +++ b/src/components/HeaderProgress.vue @@ -105,8 +105,9 @@ watch(() => store.game.totalShot, (newVal) => { // 监听 Pinia store 中 tips 变化,用于比赛恢复时同步提示文案(替代 uni.$emit 避免时序问题) // 使用 immediate: true 确保组件创建时立即读取 store 当前值(解决 onShow 早于 onMounted 导致 uni.$emit 事件丢失的问题) +// 注意:使用 != null 而非 if(newVal),确保空字符串 "" 也能触发清空(避免重新开赛时旧文案残留) watch(() => store.game.tips, (newVal) => { - if (newVal) { + if (newVal != null) { tips.value = newVal; } }, { immediate: true }); diff --git a/src/pages/team-battle.vue b/src/pages/team-battle.vue index 06750f9..34802a4 100644 --- a/src/pages/team-battle.vue +++ b/src/pages/team-battle.vue @@ -295,8 +295,11 @@ onShow(async () => { store.updateShotInfo(result.current?.indexMap?.[user.value.id] ?? 0, result.shootNumber); } } else { - // 测距阶段重置箭数,防止 ImmediateWatcher 读取 Pinia 保留的旧值 + // 测距阶段重置箭数和提示文案,防止 ImmediateWatcher 读取 Pinia 保留的旧值 store.updateShotInfo(0, 0); + // 同步清空 Pinia tips 与本地 tips,避免重新开赛时 HeaderProgress 展示上一场旧文案 + store.updateTips(""); + tips.value = ""; } recoverData(result, {force: true}); } From 9d45abd693e6664790d9e4f5a0a2e9a52778da4d Mon Sep 17 00:00:00 2001 From: chenlimao Date: Wed, 13 May 2026 16:33:59 +0800 Subject: [PATCH 2/2] =?UTF-8?q?fix=EF=BC=9A=E5=B0=84=E7=AE=AD=E6=8A=A5?= =?UTF-8?q?=E7=8E=AF=E7=9A=84=E6=97=B6=E5=80=99=E8=BF=9B=E5=BA=A6=E6=9D=A1?= =?UTF-8?q?=E6=9A=82=E5=81=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/team-battle.vue | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/src/pages/team-battle.vue b/src/pages/team-battle.vue index 34802a4..3f5d273 100644 --- a/src/pages/team-battle.vue +++ b/src/pages/team-battle.vue @@ -47,6 +47,10 @@ const battleWay = ref(0); const lastToSomeoneShootKey = ref(""); /** 控制设备离线提示弹窗的显示状态 */ const showOfflineModal = ref(false); +/** 待延迟发出的进度条重置队伍(ShootResult 报环期间暂缓切换,报环音频结束后再发 reset) */ +const pendingProgressTeam = ref(null); +/** 报环序列的最后一个音频类型('hasAdjust' = 最后 key 为方向调整,'noAdjust' = 最后 key 为环数/未上靶) */ +const pendingTriggerKey = ref(null); /** * 监听设备在线状态,比赛进行中设备离线时弹窗提示用户 @@ -144,7 +148,8 @@ const recoverData = (battleInfo, {force = false, arrowOnly = false} = {}) => { }, 100); }); } else { - uni.$emit("update-remain", {reset: true, value: 15, team: targetTeam}); + // 报环语音播放期间暂缓切换进度条:存储目标队伍,待报环音频结束后由 onAudioEnded 发出 reset + pendingProgressTeam.value = targetTeam; updateRemainSecond.value = battleInfo.readyTime; } } else { @@ -165,6 +170,20 @@ const recoverData = (battleInfo, {force = false, arrowOnly = false} = {}) => { }; function onAudioEnded(s) { + // 报环序列最后一个音频结束后,切换进度条到下一玩家满值 + // pendingTriggerKey 标记最后一个 key 类型:hasAdjust 则等"调整"音频结束,noAdjust 则等"环"/"靶"音频结束 + if ( + pendingProgressTeam.value !== null && + pendingTriggerKey.value !== null && + ( + (pendingTriggerKey.value === 'hasAdjust' && s.includes('调整')) || + (pendingTriggerKey.value === 'noAdjust' && (s.includes('环') || s.includes('靶'))) + ) + ) { + uni.$emit("update-remain", {reset: true, value: 15, team: pendingProgressTeam.value}); + pendingProgressTeam.value = null; + pendingTriggerKey.value = null; + } // "请红方射箭"/"请蓝方射箭":队友或对手轮次;"轮到你了":用户本人轮次(HeaderProgress特殊分支) // 三者音频结束后均需启动倒计时进度条 if (s.indexOf('请红方射箭') >= 0 || s.indexOf('请蓝方射箭') >= 0 || s.indexOf('轮到你了') >= 0) { @@ -172,6 +191,12 @@ function onAudioEnded(s) { if (s.indexOf('请红方射箭') >= 0) team = 'red'; else if (s.indexOf('请蓝方射箭') >= 0) team = 'blue'; else team = tips.value.includes('红队') ? 'red' : 'blue'; // 轮到你了:从当前tips判断用户所在队伍 + // 兜底:无报环音频时(如首次 ToSomeoneShoot 无前置 ShootResult),在此清空 pending 并发出 reset + if (pendingProgressTeam.value !== null) { + uni.$emit("update-remain", {reset: true, value: 15, team: pendingProgressTeam.value}); + pendingProgressTeam.value = null; + pendingTriggerKey.value = null; + } uni.$emit("update-remain", {stop: false, value: updateRemainSecond.value, team: team}); } if (s.indexOf("比赛结束") >= 0) { @@ -229,6 +254,11 @@ async function onReceiveMessage(msg) { uni.$emit("update-remain", {stop: true}) showRoundTip.value = false; recoverData(msg, {arrowOnly: true}); + // 根据 shootData.angle 预判报环序列最后一个 key: + // 有 angle 则最后 key 为"向X调整"(hasAdjust),否则为"环"/"未上靶"(noAdjust) + if (msg.shootData) { + pendingTriggerKey.value = (msg.shootData.angle !== null) ? 'hasAdjust' : 'noAdjust'; + } } else if (msg.type === MESSAGETYPESV2.NewRound) { // 在进入延迟前先捕获当前轮次,供 onNewRound 使用,防止 800ms 内 ToSomeoneShoot 提前更新 currentRound 造成 Tip 展示错轮 const prevRound = currentRound.value;