fix(缓存): 修复页面缓存导致打不开或者图片打不开的问题

This commit is contained in:
hzj 2025-11-18 11:40:42 +08:00
parent 21930313f5
commit 2e9db00056
4 changed files with 197 additions and 47 deletions

View File

@ -10,10 +10,10 @@
"dev": "vite --mode development --host",
"dev:test": "vite --mode test --host",
"dev:prod": "vite --mode production --host",
"build": "vite build --mode production",
"build:dev": "vite build --mode development",
"build:test": "vite build --mode test",
"build:prod": "vite build --mode production",
"build": "vite build --mode production && node scripts/generate-version.js",
"build:dev": "vite build --mode development && node scripts/generate-version.js",
"build:test": "vite build --mode test && node scripts/generate-version.js",
"build:prod": "vite build --mode production && node scripts/generate-version.js",
"preview": "vite preview",
"lint": "eslint . --fix"
},

View File

@ -0,0 +1,43 @@
// scripts/generate-version.js
import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs'
import { resolve, dirname } from 'path'
import { fileURLToPath } from 'url'
// 获取当前目录
const __filename = fileURLToPath(import.meta.url)
const __dirname = dirname(__filename)
// 读取 .env 文件获取版本号
const envPath = resolve(__dirname, '../.env')
let version = '1.0.0'
try {
if (existsSync(envPath)) {
const envContent = readFileSync(envPath, 'utf-8')
const versionMatch = envContent.match(/VITE_APP_VERSION=([^\r\n]+)/)
if (versionMatch && versionMatch[1]) {
version = versionMatch[1].replace(/['"]/g, '')
}
}
} catch (error) {
console.warn('无法读取 .env 文件,使用默认版本号:', error.message)
}
// 生成版本信息
const versionInfo = {
version: version,
buildTime: new Date().toISOString(),
timestamp: Date.now(),
}
// 确保 dist 目录存在
const distDir = resolve(__dirname, '../dist')
if (!existsSync(distDir)) {
mkdirSync(distDir, { recursive: true })
}
// 写入 version.json
const outputPath = resolve(distDir, 'version.json')
writeFileSync(outputPath, JSON.stringify(versionInfo, null, 2))
console.log(`✅ 版本文件已生成: ${versionInfo.version} (${versionInfo.buildTime})`)

View File

@ -13,13 +13,12 @@ import { useLangStore } from '@/stores/lang' // 移动到顶部
logEnvInfo()
// 版本检查
if (versionChecker.checkVersion()) {
console.log('检测到新版本,正在更新...')
// 可以选择显示一个更新提示
// if (confirm('检测到新版本,是否立即更新?')) {
// versionChecker.forceReload()
// }
}
versionChecker.checkVersion().then((hasUpdate) => {
if (hasUpdate) {
console.log('检测到新版本,正在更新...')
versionChecker.showUpdatePrompt()
}
})
// 初始化权限系统
console.debug('🔐 Permission system initialized')
@ -38,3 +37,13 @@ initI18n(langStore)
app.use(i18n)
app.mount('#app')
// 定期检查版本更新每5分钟
if (versionChecker.enableCheck) {
setInterval(async () => {
const hasUpdate = await versionChecker.checkServerVersion()
if (hasUpdate) {
versionChecker.showUpdatePrompt()
}
}, 5 * 60 * 1000)
}

View File

@ -3,61 +3,159 @@ export class VersionChecker {
constructor() {
this.currentVersion = import.meta.env.VITE_APP_VERSION || Date.now().toString()
this.storageKey = 'h5_app_version'
this.serverVersionKey = 'app_server_version'
this.enableCheck = import.meta.env.VITE_ENABLE_VERSION_CHECK === 'true'
}
// 检查版本更新
checkVersion() {
const storedVersion = localStorage.getItem(this.storageKey)
if (storedVersion !== this.currentVersion) {
// 版本不匹配,清除缓存并刷新
this.clearCache()
localStorage.setItem(this.storageKey, this.currentVersion)
// 延迟刷新,确保缓存清理完成
setTimeout(() => {
this.forceReload()
}, 100)
return true // 需要刷新
// 检查服务器版本
async checkServerVersion() {
if (!this.enableCheck) {
return false
}
return false // 不需要刷新
try {
// 强制从服务器获取最新版本信息,避免缓存
const response = await fetch(`/version.json?t=${Date.now()}`, {
cache: 'no-cache',
headers: {
'Cache-Control': 'no-cache',
Pragma: 'no-cache',
},
})
if (!response.ok) {
console.warn('无法获取服务器版本信息')
return false
}
const versionInfo = await response.json()
const serverVersion = versionInfo.version
const storedServerVersion = localStorage.getItem(this.serverVersionKey)
// 更新服务器版本信息
localStorage.setItem(this.serverVersionKey, serverVersion)
// 比较版本
if (storedServerVersion && storedServerVersion !== serverVersion) {
console.log(`检测到服务器版本更新: ${storedServerVersion} -> ${serverVersion}`)
return true
}
return false
} catch (error) {
console.warn('版本检查失败:', error)
return false
}
}
// 检查版本更新(综合方法)
async checkVersion() {
// 首先检查服务器版本
const hasServerUpdate = await this.checkServerVersion()
if (hasServerUpdate) {
this.handleVersionUpdate()
return true
}
// 检查本地版本是否匹配
const storedLocalVersion = localStorage.getItem(this.storageKey)
if (storedLocalVersion !== this.currentVersion) {
// 本地版本变化,可能是首次加载或本地版本升级
localStorage.setItem(this.storageKey, this.currentVersion)
console.log(`本地版本更新到: ${this.currentVersion}`)
}
return false
}
// 处理版本更新
handleVersionUpdate() {
console.log('检测到新版本,正在清理缓存...')
this.clearCache()
localStorage.setItem(this.storageKey, this.currentVersion)
localStorage.setItem(this.serverVersionKey, this.currentVersion)
}
// 清除应用缓存
clearCache() {
// 清除localStorage保留必要的数据
const keysToKeep = ['user_token', 'user_info'] // 保留的关键数据
const allKeys = Object.keys(localStorage)
allKeys.forEach(key => {
if (!keysToKeep.includes(key)) {
localStorage.removeItem(key)
// 保存需要保留的数据
const preservedData = {}
const keysToPreserve = ['user_token', 'user_info', 'lang']
keysToPreserve.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()
// 如果支持Service Worker清除SW缓存
if ('serviceWorker' in navigator) {
caches.keys().then(names => {
names.forEach(name => {
caches.delete(name)
// 清除所有缓存
if ('caches' in window) {
caches
.keys()
.then((names) => {
names.forEach((name) => {
caches.delete(name)
})
})
.catch((err) => {
console.warn('清除缓存失败:', err)
})
}
// 注销Service Worker如果存在
if ('serviceWorker' in navigator) {
navigator.serviceWorker
.getRegistrations()
.then((registrations) => {
registrations.forEach((registration) => {
registration.unregister()
})
})
.catch((err) => {
console.warn('注销Service Worker失败:', err)
})
})
}
}
// 强制刷新页面
forceReload() {
// 尝试硬刷新(清除缓存)
if (window.location.reload) {
window.location.reload(true)
} else {
// 备用方案:重新加载页面
window.location.href = window.location.href + '?t=' + Date.now()
// 尝试多种刷新方式确保生效
try {
// 方法1: 强制重新加载
if (window.location.reload) {
window.location.reload(true)
}
// 方法2: 添加时间戳重新导航
setTimeout(() => {
window.location.href =
window.location.origin + window.location.pathname + '?v=' + Date.now()
}, 100)
} catch (error) {
// 方法3: 最后的备用方案
window.location.href = window.location.href
}
}
// 显示更新提示
showUpdatePrompt() {
const shouldUpdate = confirm('发现新版本,是否立即更新?更新将获得更好的体验。')
if (shouldUpdate) {
this.forceReload()
}
}