/** * 缓存管理工具 */ 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' // 对对碰最后获取卡片数据的时间 /** * 判断缓存是否新鲜 * @param {number} timestamp - 缓存时间戳 * @param {number} ttl - 有效期(毫秒),默认24小时 * @returns {boolean} */ export function isFresh(timestamp, ttl = 24 * 60 * 60 * 1000) { const now = Date.now() const v = Number(timestamp || 0) return now - v < ttl } /** * 获取奖励缓存 * @returns {Object} */ export function getRewardCache() { const obj = uni.getStorageSync(REWARD_CACHE_KEY) || {} return typeof obj === 'object' && obj ? obj : {} } /** * 设置奖励缓存 * @param {string} activityId - 活动ID * @param {string} issueId - 期ID * @param {any} value - 缓存值 */ export function setRewardCache(activityId, issueId, value) { const cache = getRewardCache() const act = cache[activityId] || {} act[issueId] = { value, ts: Date.now() } cache[activityId] = act uni.setStorageSync(REWARD_CACHE_KEY, cache) } /** * 获取奖励缓存项 * @param {string} activityId - 活动ID * @param {string} issueId - 期ID * @returns {any|null} */ export function getRewardCacheItem(activityId, issueId) { const cache = getRewardCache() const act = cache[activityId] || {} const c = act[issueId] if (c && isFresh(c.ts) && Array.isArray(c.value)) { return c.value } return null } /** * 获取对对碰游戏缓存 * @returns {Object} */ export function getMatchingGameCache() { const obj = uni.getStorageSync(MATCHING_GAME_CACHE_KEY) || {} return typeof obj === 'object' && obj ? obj : {} } /** * 读取对对碰游戏缓存项 * @param {string} activityId - 活动ID * @param {string} issueId - 期ID * @returns {Object|null} */ export function readMatchingGameCacheEntry(activityId, issueId) { const activityKey = String(activityId || '') const issueKey = String(issueId || '') if (!activityKey || !issueKey) return null const cache = getMatchingGameCache() const act = cache[activityKey] || {} const entry = act && act[issueKey] const ok = entry && typeof entry === 'object' && entry.game_id return ok ? entry : null } /** * 写入对对碰游戏缓存项 * @param {string} activityId - 活动ID * @param {string} issueId - 期ID * @param {Object} entry - 缓存数据 */ export function writeMatchingGameCacheEntry(activityId, issueId, entry) { const activityKey = String(activityId || '') const issueKey = String(issueId || '') if (!activityKey || !issueKey) return const cache = getMatchingGameCache() // 清理超过170秒的缓存记录 const now = Date.now() const TTL = 170 * 1000 // 170秒 // 遍历所有活动的所有期,删除过期的缓存 for (const actKey in cache) { const act = cache[actKey] if (!act || typeof act !== 'object') continue for (const issKey in act) { const entry = act[issKey] if (!entry || typeof entry !== 'object') continue const ts = Number(entry.ts || 0) if (now - ts >= TTL) { // 超过170秒,删除此缓存记录 delete act[issKey] } } // 如果该活动下没有任何期了,删除活动 if (Object.keys(act).length === 0) { delete cache[actKey] } } // 写入新的缓存 const act = (cache[activityKey] && typeof cache[activityKey] === 'object') ? cache[activityKey] : {} act[issueKey] = entry cache[activityKey] = act uni.setStorageSync(MATCHING_GAME_CACHE_KEY, cache) } /** * 清除对对碰游戏缓存项 * @param {string} activityId - 活动ID * @param {string} issueId - 期ID */ export function clearMatchingGameCacheEntry(activityId, issueId) { const activityKey = String(activityId || '') const issueKey = String(issueId || '') const cache = getMatchingGameCache() const act = cache[activityKey] if (!act || typeof act !== 'object') return if (act[issueKey] !== undefined) delete act[issueKey] if (Object.keys(act).length === 0) delete cache[activityKey] else cache[activityKey] = act uni.setStorageSync(MATCHING_GAME_CACHE_KEY, cache) } /** * 查找最新的对对碰游戏缓存 * @param {string} activityId - 活动ID * @returns {Object|null} */ export function findLatestMatchingGameCacheEntry(activityId) { const activityKey = String(activityId || '') if (!activityKey) return null const cache = getMatchingGameCache() const act = cache[activityKey] if (!act || typeof act !== 'object') return null let bestIssueId = '' let bestEntry = null let bestTs = -Infinity Object.keys(act).forEach(issueId => { const entry = act[issueId] if (!entry || typeof entry !== 'object' || !entry.game_id) return const ts = Number(entry.ts || 0) if (!bestEntry || ts > bestTs) { bestTs = ts bestIssueId = issueId bestEntry = entry } }) 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] 已清除所有对对碰缓存') }