From 3d37bbc8d3b0b9286c7a174bfceef444dfc43264 Mon Sep 17 00:00:00 2001 From: tsui110 Date: Sat, 3 Jan 2026 16:38:41 +0800 Subject: [PATCH] =?UTF-8?q?fix=EF=BC=9A=E4=BF=AE=E5=A4=8D=E4=BA=86?= =?UTF-8?q?=E6=89=AB=E9=9B=B7=E4=B8=8D=E5=BC=B9=E5=87=BA=E7=BB=93=E7=AE=97?= =?UTF-8?q?=E7=AA=97=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pages-activity/activity/duiduipeng/index.vue | 51 +++++++++++- pages-game/game/minesweeper/play.scss | 16 ++++ pages-game/game/minesweeper/play.vue | 81 ++++++++++++++++++-- utils/cache.js | 44 +++++++++++ 4 files changed, 184 insertions(+), 8 deletions(-) diff --git a/pages-activity/activity/duiduipeng/index.vue b/pages-activity/activity/duiduipeng/index.vue index ca99538..c12032b 100644 --- a/pages-activity/activity/duiduipeng/index.vue +++ b/pages-activity/activity/duiduipeng/index.vue @@ -520,12 +520,47 @@ function cleanAvatar(avatar) { } const MATCHING_GAME_CACHE_KEY = 'matching_game_cache_v1' +const MATCHING_GAME_TIMESTAMP_KEY = 'matching_game_last_timestamp' // 对对碰最后获取卡片数据的时间 function getMatchingGameCache() { const obj = uni.getStorageSync(MATCHING_GAME_CACHE_KEY) || {} return typeof obj === 'object' && obj ? obj : {} } +/** + * 记录对对碰游戏卡片获取时间戳 + * 当成功调用 /api/app/matching/cards 接口时调用 + */ +function recordMatchingGameCardsTimestamp() { + const timestamp = Date.now() + uni.setStorageSync(MATCHING_GAME_TIMESTAMP_KEY, timestamp) + console.log('[MatchingGame] 记录卡片获取时间戳:', new Date(timestamp).toISOString()) +} + +/** + * 检查对对碰游戏缓存是否过期 + * @param {number} maxAgeSeconds - 最大有效期(秒),默认100秒 + * @returns {boolean} true表示未过期,false表示已过期 + */ +function isMatchingGameCacheValid(maxAgeSeconds = 100) { + const timestamp = uni.getStorageSync(MATCHING_GAME_TIMESTAMP_KEY) + if (!timestamp) return false + + const now = Date.now() + const ageSeconds = (now - timestamp) / 1000 + const isValid = ageSeconds < maxAgeSeconds + + console.log('[MatchingGame] 检查缓存有效期:', { + timestamp: new Date(timestamp).toISOString(), + now: new Date(now).toISOString(), + ageSeconds: ageSeconds.toFixed(2), + maxAgeSeconds, + isValid + }) + + return isValid +} + function findLatestMatchingGameCacheEntry(aid) { const activityKey = String(aid || '') if (!activityKey) return null @@ -550,6 +585,17 @@ function findLatestMatchingGameCacheEntry(aid) { } function syncResumeGame(aid) { + // 检查缓存是否过期(超过100秒) + if (!isMatchingGameCacheValid(100)) { + console.log('[MatchingGame] 缓存已过期,清除所有缓存') + // 清除缓存和时间戳 + uni.removeStorageSync(MATCHING_GAME_CACHE_KEY) + uni.removeStorageSync(MATCHING_GAME_TIMESTAMP_KEY) + resumeIssueId.value = '' + resumeGame.value = null + return null + } + const latest = findLatestMatchingGameCacheEntry(aid) if (!latest || !latest.entry || !latest.entry.game_id) { resumeIssueId.value = '' @@ -1413,7 +1459,10 @@ async function doDraw() { // 4. 获取游戏数据 const cardsRes = await getMatchingGameCards(gameId) if (!cardsRes) throw new Error('获取游戏数据失败') - + + // 成功获取卡片数据后,记录时间戳 + recordMatchingGameCardsTimestamp() + const allCards = normalizeAllCards(cardsRes.all_cards || cardsRes.data?.all_cards || []) if (!allCards.length) throw new Error('游戏数据为空') diff --git a/pages-game/game/minesweeper/play.scss b/pages-game/game/minesweeper/play.scss index 2d44489..f5b359c 100644 --- a/pages-game/game/minesweeper/play.scss +++ b/pages-game/game/minesweeper/play.scss @@ -1242,6 +1242,22 @@ font-size: 40rpx; font-weight: 900; color: $text-dark-main; + margin-top: $spacing-md; + } + + .result-details { + margin: $spacing-lg 0; + padding: $spacing-md; + background: rgba($bg-dark-card, 0.5); + border-radius: $radius-md; + width: 100%; + + .detail-text { + font-size: $font-md; + color: $text-dark-sub; + text-align: center; + line-height: 1.6; + } } // ===================================== diff --git a/pages-game/game/minesweeper/play.vue b/pages-game/game/minesweeper/play.vue index f621d36..911bfcd 100644 --- a/pages-game/game/minesweeper/play.vue +++ b/pages-game/game/minesweeper/play.vue @@ -81,7 +81,7 @@ - Round {{ gameState.round }} + Round {{ gameState.globalTurnCount || gameState.round || 0 }} 动物扫雷 📜 @@ -232,12 +232,15 @@ - + {{ gameState.winnerId === myUserId ? '🏆' : '💀' }} {{ gameState.winnerId === myUserId ? '胜利!' : '很遗憾失败了' }} - + {{ getResultMessage() }} + + @@ -352,6 +355,27 @@ export default { }, globalLabels() { return this.floatingLabels.filter(l => l.cellIndex === undefined && l.targetUserId === undefined); + }, + // 判断是否应该显示结算弹窗 + shouldShowResultModal() { + // 有游戏状态且游戏已结束且有获胜者 + if (!this.gameState) return false; + + // 检查 gameStarted 是否为 false(游戏已结束) + const isGameOver = this.gameState.gameStarted === false; + + // 检查是否有获胜者 + const hasWinner = !!this.gameState.winnerId; + + console.log('[shouldShowResultModal] 检查弹窗显示条件:', { + isGameOver, + hasWinner, + winnerId: this.gameState.winnerId, + myUserId: this.myUserId, + shouldShow: isGameOver && hasWinner + }); + + return isGameOver && hasWinner; } }, watch: { @@ -602,12 +626,41 @@ export default { } else if (opCode === 5) { this.handleEvent(data); } else if (opCode === 6) { + // 游戏结束 - 确保正确设置游戏状态 + console.log('[游戏结束] 接收到游戏结束数据:', data); + if (data.gameState) { - this.gameState = data.gameState; + // 更新游戏状态并标记为已结束 + this.gameState = { + ...data.gameState, + gameStarted: false, // 明确标记游戏已结束 + winnerId: data.winnerId || data.gameState.winnerId + }; } else { - this.gameState = data; + this.gameState = { + ...data, + gameStarted: false // 明确标记游戏已结束 + }; + } + + // 确保 winnerId 存在 + if (!this.gameState.winnerId && data.winnerId) { + this.gameState.winnerId = data.winnerId; + } + + console.log('[游戏结束] 最终游戏状态:', this.gameState); + console.log('[游戏结束] winnerId:', this.gameState.winnerId); + console.log('[游戏结束] gameStarted:', this.gameState.gameStarted); + console.log('[游戏结束] 是否显示弹窗:', !this.gameState.gameStarted && !!this.gameState.winnerId); + + this.addLog('system', `战局结束:${this.gameState.winnerId === this.myUserId ? '🎉 您获得了胜利!' : '💀 很遗憾失败了'}`); + + // 添加震动反馈 + if (this.gameState.winnerId === this.myUserId) { + uni.vibrateShort({ type: 'success' }); + } else { + uni.vibrateShort({ type: 'fail' }); } - this.addLog('system', `战局结束:${data.winnerId === this.myUserId ? '您获得了胜利!' : '很遗憾失败了'}`); } }, handleEvent(event) { @@ -737,6 +790,20 @@ export default { 100: '请求游戏状态' }; return map[code] || '未知'; + }, + // 获取结算详情信息 + getResultMessage() { + if (!this.gameState || !this.gameState.players) return ''; + + const winnerId = this.gameState.winnerId; + const winner = this.gameState.players[winnerId]; + const winnerName = winner ? (winner.username || '对手') : '未知'; + + if (winnerId === this.myUserId) { + return '恭喜您战胜了所有对手,获得胜利!'; + } else { + return `${winnerName.substring(0, 10)} 获得了胜利,下次好运!`; + } } } } diff --git a/utils/cache.js b/utils/cache.js index 9def0ed..5f62ed1 100644 --- a/utils/cache.js +++ b/utils/cache.js @@ -4,6 +4,7 @@ const REWARD_CACHE_KEY = 'reward_cache_v2' // v2: 修复概率精度问题 const MATCHING_GAME_CACHE_KEY = 'matching_game_cache_v1' +const MATCHING_GAME_TIMESTAMP_KEY = 'matching_game_last_timestamp' // 对对碰最后获取卡片数据的时间 /** * 判断缓存是否新鲜 @@ -171,3 +172,46 @@ export function findLatestMatchingGameCacheEntry(activityId) { if (!bestEntry) return null return { issue_id: bestIssueId, entry: bestEntry } } + +/** + * 记录对对碰游戏卡片获取时间戳 + * 当成功调用 /api/app/matching/cards 接口时调用 + */ +export function recordMatchingGameCardsTimestamp() { + const timestamp = Date.now() + uni.setStorageSync(MATCHING_GAME_TIMESTAMP_KEY, timestamp) + console.log('[MatchingGame] 记录卡片获取时间戳:', new Date(timestamp).toISOString()) +} + +/** + * 检查对对碰游戏缓存是否过期 + * @param {number} maxAgeSeconds - 最大有效期(秒),默认100秒 + * @returns {boolean} true表示未过期,false表示已过期 + */ +export function isMatchingGameCacheValid(maxAgeSeconds = 100) { + const timestamp = uni.getStorageSync(MATCHING_GAME_TIMESTAMP_KEY) + if (!timestamp) return false + + const now = Date.now() + const ageSeconds = (now - timestamp) / 1000 + const isValid = ageSeconds < maxAgeSeconds + + console.log('[MatchingGame] 检查缓存有效期:', { + timestamp: new Date(timestamp).toISOString(), + now: new Date(now).toISOString(), + ageSeconds: ageSeconds.toFixed(2), + maxAgeSeconds, + isValid + }) + + return isValid +} + +/** + * 清除对对碰游戏缓存和时间戳 + */ +export function clearMatchingGameAllCache() { + uni.removeStorageSync(MATCHING_GAME_CACHE_KEY) + uni.removeStorageSync(MATCHING_GAME_TIMESTAMP_KEY) + console.log('[MatchingGame] 已清除所有对对碰缓存') +}