222 lines
6.7 KiB
JavaScript
222 lines
6.7 KiB
JavaScript
// 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()
|