fix:修复了扫雷不弹出结算窗口
This commit is contained in:
parent
3a1d4857dd
commit
3d37bbc8d3
@ -520,12 +520,47 @@ function cleanAvatar(avatar) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const MATCHING_GAME_CACHE_KEY = 'matching_game_cache_v1'
|
const MATCHING_GAME_CACHE_KEY = 'matching_game_cache_v1'
|
||||||
|
const MATCHING_GAME_TIMESTAMP_KEY = 'matching_game_last_timestamp' // 对对碰最后获取卡片数据的时间
|
||||||
|
|
||||||
function getMatchingGameCache() {
|
function getMatchingGameCache() {
|
||||||
const obj = uni.getStorageSync(MATCHING_GAME_CACHE_KEY) || {}
|
const obj = uni.getStorageSync(MATCHING_GAME_CACHE_KEY) || {}
|
||||||
return typeof obj === 'object' && obj ? obj : {}
|
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) {
|
function findLatestMatchingGameCacheEntry(aid) {
|
||||||
const activityKey = String(aid || '')
|
const activityKey = String(aid || '')
|
||||||
if (!activityKey) return null
|
if (!activityKey) return null
|
||||||
@ -550,6 +585,17 @@ function findLatestMatchingGameCacheEntry(aid) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function syncResumeGame(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)
|
const latest = findLatestMatchingGameCacheEntry(aid)
|
||||||
if (!latest || !latest.entry || !latest.entry.game_id) {
|
if (!latest || !latest.entry || !latest.entry.game_id) {
|
||||||
resumeIssueId.value = ''
|
resumeIssueId.value = ''
|
||||||
@ -1414,6 +1460,9 @@ async function doDraw() {
|
|||||||
const cardsRes = await getMatchingGameCards(gameId)
|
const cardsRes = await getMatchingGameCards(gameId)
|
||||||
if (!cardsRes) throw new Error('获取游戏数据失败')
|
if (!cardsRes) throw new Error('获取游戏数据失败')
|
||||||
|
|
||||||
|
// 成功获取卡片数据后,记录时间戳
|
||||||
|
recordMatchingGameCardsTimestamp()
|
||||||
|
|
||||||
const allCards = normalizeAllCards(cardsRes.all_cards || cardsRes.data?.all_cards || [])
|
const allCards = normalizeAllCards(cardsRes.all_cards || cardsRes.data?.all_cards || [])
|
||||||
if (!allCards.length) throw new Error('游戏数据为空')
|
if (!allCards.length) throw new Error('游戏数据为空')
|
||||||
|
|
||||||
|
|||||||
@ -1242,6 +1242,22 @@
|
|||||||
font-size: 40rpx;
|
font-size: 40rpx;
|
||||||
font-weight: 900;
|
font-weight: 900;
|
||||||
color: $text-dark-main;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// =====================================
|
// =====================================
|
||||||
|
|||||||
@ -81,7 +81,7 @@
|
|||||||
<view v-else class="game-screen">
|
<view v-else class="game-screen">
|
||||||
<!-- 顶部状态栏 -->
|
<!-- 顶部状态栏 -->
|
||||||
<view class="game-header">
|
<view class="game-header">
|
||||||
<view class="round-badge">Round {{ gameState.round }}</view>
|
<view class="round-badge">Round {{ gameState.globalTurnCount || gameState.round || 0 }}</view>
|
||||||
<text class="header-title">动物扫雷</text>
|
<text class="header-title">动物扫雷</text>
|
||||||
<view class="header-actions">
|
<view class="header-actions">
|
||||||
<view class="btn-icon" @tap="showGuide = true">📜</view>
|
<view class="btn-icon" @tap="showGuide = true">📜</view>
|
||||||
@ -232,10 +232,13 @@
|
|||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 结算弹窗 -->
|
<!-- 结算弹窗 -->
|
||||||
<view v-if="!gameState?.gameStarted && gameState?.winnerId" class="modal-overlay">
|
<view v-if="shouldShowResultModal" class="modal-overlay">
|
||||||
<view class="modal-content glass-card">
|
<view class="modal-content glass-card">
|
||||||
<text class="modal-emoji">{{ gameState.winnerId === myUserId ? '🏆' : '💀' }}</text>
|
<text class="modal-emoji">{{ gameState.winnerId === myUserId ? '🏆' : '💀' }}</text>
|
||||||
<text class="modal-title">{{ gameState.winnerId === myUserId ? '胜利!' : '很遗憾失败了' }}</text>
|
<text class="modal-title">{{ gameState.winnerId === myUserId ? '胜利!' : '很遗憾失败了' }}</text>
|
||||||
|
<view class="result-details" v-if="gameState.players">
|
||||||
|
<text class="detail-text">{{ getResultMessage() }}</text>
|
||||||
|
</view>
|
||||||
<view
|
<view
|
||||||
class="btn-primary"
|
class="btn-primary"
|
||||||
:class="{ disabled: isRefreshing }"
|
:class="{ disabled: isRefreshing }"
|
||||||
@ -352,6 +355,27 @@ export default {
|
|||||||
},
|
},
|
||||||
globalLabels() {
|
globalLabels() {
|
||||||
return this.floatingLabels.filter(l => l.cellIndex === undefined && l.targetUserId === undefined);
|
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: {
|
watch: {
|
||||||
@ -602,12 +626,41 @@ export default {
|
|||||||
} else if (opCode === 5) {
|
} else if (opCode === 5) {
|
||||||
this.handleEvent(data);
|
this.handleEvent(data);
|
||||||
} else if (opCode === 6) {
|
} else if (opCode === 6) {
|
||||||
|
// 游戏结束 - 确保正确设置游戏状态
|
||||||
|
console.log('[游戏结束] 接收到游戏结束数据:', data);
|
||||||
|
|
||||||
if (data.gameState) {
|
if (data.gameState) {
|
||||||
this.gameState = data.gameState;
|
// 更新游戏状态并标记为已结束
|
||||||
|
this.gameState = {
|
||||||
|
...data.gameState,
|
||||||
|
gameStarted: false, // 明确标记游戏已结束
|
||||||
|
winnerId: data.winnerId || data.gameState.winnerId
|
||||||
|
};
|
||||||
} else {
|
} 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) {
|
handleEvent(event) {
|
||||||
@ -737,6 +790,20 @@ export default {
|
|||||||
100: '请求游戏状态'
|
100: '请求游戏状态'
|
||||||
};
|
};
|
||||||
return map[code] || '未知';
|
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)} 获得了胜利,下次好运!`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
const REWARD_CACHE_KEY = 'reward_cache_v2' // v2: 修复概率精度问题
|
const REWARD_CACHE_KEY = 'reward_cache_v2' // v2: 修复概率精度问题
|
||||||
const MATCHING_GAME_CACHE_KEY = 'matching_game_cache_v1'
|
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
|
if (!bestEntry) return null
|
||||||
return { issue_id: bestIssueId, entry: bestEntry }
|
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] 已清除所有对对碰缓存')
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user