// src/utils/versionChecker.js // 版本检查工具 import { imageCacheManager } from '@/utils/imageCacheManager' const PERSISTENT_KEYS = [ 'preferred-language', // 语言设置 'userProfile', // 用户资料 'teamInfo', // 团队信息 'lastImgUrl', // 最后图片URL 'applyInfo', // 申请资料 'gamesKing', // 游戏王每日弹窗查看状态 ] export class VersionChecker { constructor() { this.currentVersion = import.meta.env.VITE_APP_VERSION || Date.now().toString() //app版本号 this.storageKey = 'h5_app_version' //本地存储的版本号key this.serverVersionKey = 'app_server_version' //服务器版本号key this.enableCheck = import.meta.env.VITE_ENABLE_VERSION_CHECK === 'true' //是否开启检测app版本号 } // 检查版本(开发环境:本地.env文件;生产环境:构建脚本生成的version.json文件) async checkServerVersion() { if (!this.enableCheck) { return false } try { let versionInfo //版本更新信息 // 开发环境:使用本地.env文件环境变量 if (import.meta.env.MODE === 'development') { versionInfo = { version: import.meta.env.VITE_APP_VERSION, type: import.meta.env.VITE_VERSION_TYPE || 'patch', } } // 生产环境:从服务器获取version.json文件 else { const response = await fetch(`/version.json?t=${Date.now()}`) if (!response.ok) { console.warn('无法获取服务器版本信息') return false } const contentType = response.headers.get('content-type') if (!contentType || !contentType.includes('application/json')) { console.warn('服务器返回的不是JSON格式') return false } versionInfo = await response.json() //获取服务器版本信息 } const serverVersion = versionInfo.version //最新生成的服务器版本号 const versionType = versionInfo.type || 'patch' // 版本更新类型 const storedServerVersion = localStorage.getItem(this.serverVersionKey) //网页缓存的版本号 // 更新服务器版本信息 localStorage.setItem(this.serverVersionKey, serverVersion) // 比较版本 if (storedServerVersion && storedServerVersion !== serverVersion) { console.log(`检测到${versionType}版本更新: ${storedServerVersion} -> ${serverVersion}`) // 返回版本类型信息 return { shouldUpdate: true, versionType: versionType, } } return { shouldUpdate: false } } catch (error) { console.warn('版本检查失败:', error.message) return { shouldUpdate: false } } } // 初始化网页首次检查版本 async checkVersion() { // 获取最新版本信息 const versionResult = await this.checkServerVersion() // 判断是否需要更新 if (versionResult.shouldUpdate) { await this.handleVersionUpdate(versionResult.versionType) return true } // 检查本地版本是否匹配 const storedLocalVersion = localStorage.getItem(this.storageKey) if (storedLocalVersion !== this.currentVersion) { // 本地版本变化,可能是首次加载或本地版本升级 localStorage.setItem(this.storageKey, this.currentVersion) console.log(`本地版本更新到: ${this.currentVersion}`) } return false } // 处理版本更新 async handleVersionUpdate(updateType = 'major') { console.log(`检测到${updateType}版本更新,正在清理缓存...`) // 根据更新类型决定清除策略 switch (updateType) { case 'major': // 重大更新:清除所有缓存(不管图片版本号是否更新) await this.clearCache() break case 'minor': case 'patch': // minor或patch更新:检查图片版本号是否更新 // 如果图片版本号更新,则按imageCacheVersion中的cacheType清除缓存 // 如果图片版本号未更新,则不做任何缓存清除处理 await imageCacheManager.checkVersionAndUpdate() this.clearSessionData() // 清除 session 数据 break default: // 默认:清除所有缓存 await this.clearCache() } localStorage.setItem(this.storageKey, this.currentVersion) localStorage.setItem(this.serverVersionKey, this.currentVersion) // 直接刷新页面 this.forceReload() } // 清除所有会话存储数据sessionStorage clearSessionData() { try { // localStorage和Cache API不受影响 const preservedData = {} PERSISTENT_KEYS.forEach((key) => { const value = localStorage.getItem(key) if (value !== null) { preservedData[key] = value } }) // 清除 sessionStorage sessionStorage.clear() // 恢复保留的数据 Object.keys(preservedData).forEach((key) => { localStorage.setItem(key, preservedData[key]) }) } catch (error) { console.warn('清理 session 数据失败:', error) } } async clearCache() { // 清除范围: // localStorage:所有本地存储数据 // sessionStorage:所有会话存储数据 // Cache API:所有缓存(包括非图片缓存) // Service Worker:注销所有注册 // 保留数据:保留 PERSISTENT_KEYS 中定义的白名单数据 try { // 保存需要保留的数据 const preservedData = {} PERSISTENT_KEYS.forEach((key) => { const value = localStorage.getItem(key) if (value !== null) { preservedData[key] = value } }) // 清除所有localStorage localStorage.clear() // 恢复保留的数据 Object.keys(preservedData).forEach((key) => { localStorage.setItem(key, preservedData[key]) }) // 清除sessionStorage sessionStorage.clear() // 清除所有缓存 if ('caches' in window) { const cacheNames = await caches.keys() await Promise.all(cacheNames.map((name) => caches.delete(name))) } // 注销Service Worker(如果存在) if ('serviceWorker' in navigator) { const registrations = await navigator.serviceWorker.getRegistrations() await Promise.all(registrations.map((reg) => reg.unregister())) } } catch (error) { console.warn('清除缓存失败:', error) } } // 强制刷新页面 forceReload() { // 直接刷新当前页面,不跳转到其他页面 try { window.location.reload(true) } catch (error) { // 备用方案 window.location.href = window.location.href } } // 获取当前版本 getCurrentVersion() { return this.currentVersion } } // 导出单例 export const versionChecker = new VersionChecker()