update:优化比赛结束
This commit is contained in:
@@ -27,6 +27,8 @@ const data = ref({});
|
||||
const showOverlay = ref(false);
|
||||
/** 自动关闭覆盖层的计时器 */
|
||||
const overlayTimer = ref(null);
|
||||
const overlayDelayTimer = ref(null);
|
||||
let loadGeneration = 0;
|
||||
/** 控制经验条是否执行进场动画(弹窗关闭后才置 true,避免动画被遮挡) */
|
||||
const showExpAnim = ref(false);
|
||||
|
||||
@@ -175,9 +177,11 @@ function getMeleeAvatarBorderColor(rank) {
|
||||
// ---- 生命周期 ----
|
||||
|
||||
onLoad(async (options) => {
|
||||
const currentLoadId = ++loadGeneration;
|
||||
if (!options.battleId) return;
|
||||
|
||||
const result = await getBattleAPI(options.battleId);
|
||||
if (currentLoadId !== loadGeneration) return;
|
||||
data.value = result;
|
||||
|
||||
// 从 teams 各队伍的 players 中找到当前用户,解析经验进度条所需字段
|
||||
@@ -219,7 +223,8 @@ onLoad(async (options) => {
|
||||
}
|
||||
|
||||
// 数据加载完成后延迟 1 秒再显示激励弹窗,避免进场时画面太杂
|
||||
setTimeout(() => {
|
||||
overlayDelayTimer.value = setTimeout(() => {
|
||||
overlayDelayTimer.value = null;
|
||||
showOverlay.value = true;
|
||||
// 弹窗显示后 2.5 秒自动关闭
|
||||
overlayTimer.value = setTimeout(() => {
|
||||
@@ -229,7 +234,15 @@ onLoad(async (options) => {
|
||||
});
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
if (overlayTimer.value) clearTimeout(overlayTimer.value);
|
||||
loadGeneration += 1;
|
||||
if (overlayDelayTimer.value) {
|
||||
clearTimeout(overlayDelayTimer.value);
|
||||
overlayDelayTimer.value = null;
|
||||
}
|
||||
if (overlayTimer.value) {
|
||||
clearTimeout(overlayTimer.value);
|
||||
overlayTimer.value = null;
|
||||
}
|
||||
});
|
||||
|
||||
// ---- 方法 ----
|
||||
|
||||
@@ -105,6 +105,8 @@ let restoreLoadingTimer = null;
|
||||
let pendingRoundAudio = false;
|
||||
// 一旦收到 BattleEnd,后续普通消息就不再进入队列。
|
||||
let battleEnded = false;
|
||||
let battleEndTaskRunning = false;
|
||||
let resultNavigationPending = false;
|
||||
let skipNextRestoreOnShow = false;
|
||||
let pendingReturnSnapshot = null;
|
||||
const handledMessageKeys = new Set();
|
||||
@@ -1094,8 +1096,38 @@ async function runNewRoundTask(task, runId) {
|
||||
pendingRoundAudio = true;
|
||||
}
|
||||
|
||||
function navigateToBattleResultOnce(matchId) {
|
||||
const targetMatchId = matchId || battleId.value;
|
||||
if (!targetMatchId || resultNavigationPending) return false;
|
||||
|
||||
resultNavigationPending = true;
|
||||
battleEnded = true;
|
||||
restoreGeneration += 1;
|
||||
if (pendingRestoreTimer) {
|
||||
clearTimeout(pendingRestoreTimer);
|
||||
pendingRestoreTimer = null;
|
||||
}
|
||||
hideRestoreLoading();
|
||||
|
||||
uni.redirectTo({
|
||||
url: `/pages/friend-battle-result?battleId=${targetMatchId}`,
|
||||
fail: (err) => {
|
||||
resultNavigationPending = false;
|
||||
console.log("navigate to battle result failed:", err);
|
||||
},
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
// 终局任务:播放结束语音后,根据状态跳结果页或返回上一页。
|
||||
async function runBattleEndTask(task, runId) {
|
||||
if (resultNavigationPending) {
|
||||
notifyMatchAudioAck(task);
|
||||
return;
|
||||
}
|
||||
|
||||
battleEndTaskRunning = true;
|
||||
try {
|
||||
const battleInfo = task.message;
|
||||
applyBattleBase(battleInfo);
|
||||
battleEnded = true;
|
||||
@@ -1113,9 +1145,7 @@ async function runBattleEndTask(task, runId) {
|
||||
if (!isQueueAlive(runId)) return;
|
||||
|
||||
if (matchStatus.value === 2) {
|
||||
uni.redirectTo({
|
||||
url: `/pages/friend-battle-result?battleId=${battleId.value}`,
|
||||
});
|
||||
navigateToBattleResultOnce(battleId.value);
|
||||
} else if (matchStatus.value === 4) {
|
||||
const roomNumber = battleInfo.roomId || store.game.roomNumber || store.game.roomID;
|
||||
setTimeout(() => {
|
||||
@@ -1128,6 +1158,9 @@ async function runBattleEndTask(task, runId) {
|
||||
}
|
||||
}, BATTLE_CANCEL_RETURN_DELAY);
|
||||
}
|
||||
} finally {
|
||||
battleEndTaskRunning = false;
|
||||
}
|
||||
}
|
||||
|
||||
// 无效射击任务:弹 toast 并播报无效射击,不修改比赛主状态。
|
||||
@@ -1143,7 +1176,7 @@ async function runInvalidShotTask(task, runId) {
|
||||
|
||||
// 回前台恢复入口:拉取服务端快照,处理结束态,然后继续消费增量队列。
|
||||
async function restoreLatestBattle() {
|
||||
if (!battleId.value) return;
|
||||
if (!battleId.value || resultNavigationPending) return;
|
||||
const currentRestoreId = ++restoreGeneration;
|
||||
showRestoreLoading();
|
||||
|
||||
@@ -1175,9 +1208,8 @@ async function restoreLatestBattle() {
|
||||
if (result.status === 2) {
|
||||
clearXRingStreaks();
|
||||
hideRestoreLoading();
|
||||
uni.redirectTo({
|
||||
url: `/pages/friend-battle-result?battleId=${result.matchId}`,
|
||||
});
|
||||
battleEnded = true;
|
||||
if (!battleEndTaskRunning) navigateToBattleResultOnce(result.matchId);
|
||||
return;
|
||||
}
|
||||
if (result.status === 4) {
|
||||
@@ -1284,6 +1316,8 @@ onLoad((options) => {
|
||||
restoreGeneration += 1;
|
||||
pendingRoundAudio = false;
|
||||
battleEnded = false;
|
||||
battleEndTaskRunning = false;
|
||||
resultNavigationPending = false;
|
||||
handledMessageKeys.clear();
|
||||
handledMessageKeyOrder.length = 0;
|
||||
queuedMessageKeys.clear();
|
||||
@@ -1328,6 +1362,8 @@ onMounted(async () => {
|
||||
|
||||
// 离开页面时清理监听、停止音频,并让当前队列整体失效。
|
||||
onBeforeUnmount(() => {
|
||||
restoreGeneration += 1;
|
||||
battleEndTaskRunning = false;
|
||||
uni.setKeepScreenOn({
|
||||
keepScreenOn: false,
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user