feat(图片缓存功能): 代码优化,解决了有时图片没顺利清除的问题,同步了两个缓存机制的版本号

This commit is contained in:
hzj 2025-12-22 15:14:43 +08:00
parent 9805cdbdee
commit d6481c1b27
4 changed files with 76 additions and 111 deletions

6
.env
View File

@ -1,10 +1,10 @@
# 应用版本号 # 应用版本号
VITE_APP_VERSION=2.0.3 VITE_APP_VERSION=2.0.4
# 版本类型 # 版本类型
# major:重大更新(清空用户缓存) # major:重大更新(清空用户缓存)
# minor:一般更新(仅清空图片缓存) # minor:一般更新(只清除图片和assets缓存)
# patch:日常小更新(不清空用户缓存) # patch:日常小更新(只清除图片缓存)
VITE_VERSION_TYPE=minor VITE_VERSION_TYPE=minor
# 是否启用版本检查 # 是否启用版本检查

View File

@ -1,6 +1,7 @@
import './assets/main.css' import './assets/main.css'
import { logEnvInfo } from './utils/env.js' import { logEnvInfo } from './utils/env.js'
import { versionChecker } from './utils/versionChecker.js' import { versionChecker } from './utils/versionChecker.js'
import { imageCacheManager } from '@/utils/imageCacheManager'
import { smartImage } from './directives/smartImage.js' import { smartImage } from './directives/smartImage.js'
import { createPinia } from 'pinia' import { createPinia } from 'pinia'
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate' import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
@ -14,8 +15,11 @@ import { useLangStore } from '@/stores/lang' // 移动到顶部
// 初始化环境信息 // 初始化环境信息
logEnvInfo() logEnvInfo()
// 版本检查 - 不需要处理返回结果,因为会自动处理 // 版本检查后添加
versionChecker.checkVersion() versionChecker.checkVersion().then(() => {
// 主动清理过期的图片缓存
imageCacheManager.clearOldCaches()
})
// 初始化权限系统 // 初始化权限系统
console.debug('🔐 Permission system initialized') console.debug('🔐 Permission system initialized')
@ -100,7 +104,7 @@ if (versionChecker.enableCheck) {
const versionResult = await versionChecker.checkServerVersion() const versionResult = await versionChecker.checkServerVersion()
if (versionResult.shouldUpdate) { if (versionResult.shouldUpdate) {
// 自动处理更新,不需要用户交互 // 自动处理更新,不需要用户交互
versionChecker.handleVersionUpdate(versionResult.versionType) await versionChecker.handleVersionUpdate(versionResult.versionType)
} }
}, 5 * 60 * 1000) }, 5 * 60 * 1000)
} }

View File

@ -50,6 +50,7 @@ class ImageCacheManager {
cachesToClear = cacheNames.filter((name) => name.startsWith('likei-images-v')) cachesToClear = cacheNames.filter((name) => name.startsWith('likei-images-v'))
} }
// 等待所有清除操作完成
await Promise.all(cachesToClear.map((name) => caches.delete(name))) await Promise.all(cachesToClear.map((name) => caches.delete(name)))
console.log(`已清理${clearType}类型缓存:`, cachesToClear) console.log(`已清理${clearType}类型缓存:`, cachesToClear)
} catch (error) { } catch (error) {
@ -256,7 +257,7 @@ class ImageCacheManager {
try { try {
// 只从缓存获取本地资源 // 只从缓存获取本地资源
if (this.isBuildAsset(url)) { if (this.isBuildAsset(url)) {
const cache = await caches.open(this.imageCacheName) const cache = await this.getCacheForUrl(url) // 使用相同的逻辑选择缓存
return await cache.match(url) return await cache.match(url)
} }
return null return null
@ -381,7 +382,7 @@ class ImageCacheManager {
// 检查浏览器是否支持缓存API以及资源是否适合缓存 // 检查浏览器是否支持缓存API以及资源是否适合缓存
if (!('caches' in window) || !this.isBuildAsset(src)) return if (!('caches' in window) || !this.isBuildAsset(src)) return
const cache = await caches.open(this.imageCacheName) const cache = await this.getCacheForUrl(src)
const cachedResponse = await cache.match(src) const cachedResponse = await cache.match(src)
// 只有当图片尚未缓存时才进行缓存操作 // 只有当图片尚未缓存时才进行缓存操作

View File

@ -1,5 +1,7 @@
// 版本检查工具 // 版本检查工具
import { imageCacheManager } from '@/utils/imageCacheManager'
const PERSISTENT_KEYS = [ const PERSISTENT_KEYS = [
'preferred-language', // 语言设置 'preferred-language', // 语言设置
'userProfile', // 用户资料 'userProfile', // 用户资料
@ -70,6 +72,7 @@ export class VersionChecker {
if (versionResult.shouldUpdate) { if (versionResult.shouldUpdate) {
this.handleVersionUpdate() this.handleVersionUpdate()
localStorage.setItem('likei-image-cache-version', this.currentVersion) // 同步 imageCacheManager 的版本信息
return true return true
} }
@ -79,6 +82,7 @@ export class VersionChecker {
if (storedLocalVersion !== this.currentVersion) { if (storedLocalVersion !== this.currentVersion) {
// 本地版本变化,可能是首次加载或本地版本升级 // 本地版本变化,可能是首次加载或本地版本升级
localStorage.setItem(this.storageKey, this.currentVersion) localStorage.setItem(this.storageKey, this.currentVersion)
localStorage.setItem('likei-image-cache-version', this.currentVersion)
console.log(`本地版本更新到: ${this.currentVersion}`) console.log(`本地版本更新到: ${this.currentVersion}`)
} }
@ -86,138 +90,94 @@ export class VersionChecker {
} }
// 处理版本更新 // 处理版本更新
handleVersionUpdate(updateType = 'major') { async handleVersionUpdate(updateType = 'major') {
console.log(`检测到${updateType}版本更新,正在清理缓存...`) console.log(`检测到${updateType}版本更新,正在清理缓存...`)
// 根据更新类型决定清除策略 // 根据更新类型决定清除策略
switch (updateType) { switch (updateType) {
case 'major': case 'major':
// 重大更新:清除所有缓存 await this.clearCache() // 重大更新:清除所有缓存
this.clearCache()
break break
case 'minor': case 'minor':
// 一般更新:清除图片和assets缓存 await imageCacheManager.clearCacheSelective('all') // 一般更新:清除图片和assets缓存
this.clearCacheSelective('all') this.clearSessionData() // 清除 session 数据
break break
case 'patch': case 'patch':
// 小更新:只清除图片缓存 await imageCacheManager.clearCacheSelective('images') // 小更新:只清除图片缓存
this.clearCacheSelective('images')
break break
default: default:
// 默认:清除所有缓存 // 默认:清除所有缓存
this.clearCache() await this.clearCache()
} }
localStorage.setItem(this.storageKey, this.currentVersion) localStorage.setItem(this.storageKey, this.currentVersion)
localStorage.setItem(this.serverVersionKey, this.currentVersion) localStorage.setItem(this.serverVersionKey, this.currentVersion)
localStorage.setItem('likei-image-cache-version', this.currentVersion)
// 直接刷新页面 // 直接刷新页面
this.forceReload() this.forceReload()
} }
// 添加选择性清除缓存方法 // 添加专门处理 session 数据的方法
clearCacheSelective(clearType = 'images') { clearSessionData() {
// 保存需要保留的数据 try {
const preservedData = {} // 保存需要保留的数据
const preservedData = {}
PERSISTENT_KEYS.forEach((key) => {
const value = localStorage.getItem(key)
if (value !== null) {
preservedData[key] = value
}
})
PERSISTENT_KEYS.forEach((key) => { // 清除 sessionStorage
const value = localStorage.getItem(key) sessionStorage.clear()
if (value !== null) {
preservedData[key] = value
}
})
// 清除sessionStorage // 恢复保留的数据
sessionStorage.clear() Object.keys(preservedData).forEach((key) => {
localStorage.setItem(key, preservedData[key])
// 清除指定类型的缓存 })
if ('caches' in window) { } catch (error) {
caches console.warn('清理 session 数据失败:', error)
.keys()
.then((names) => {
let cachesToClear = []
switch (clearType) {
case 'images':
cachesToClear = names.filter((name) => name.startsWith('likei-images-v'))
break
case 'assets':
cachesToClear = names.filter((name) => name.startsWith('likei-assets-v'))
break
case 'all':
cachesToClear = names.filter(
(name) => name.startsWith('likei-images-v') || name.startsWith('likei-assets-v')
)
break
default:
cachesToClear = names.filter((name) => name.startsWith('likei-images-v'))
}
cachesToClear.forEach((name) => {
caches.delete(name)
})
console.log(`已选择性清除${clearType}缓存:`, cachesToClear)
})
.catch((err) => {
console.warn('清除缓存失败:', err)
})
} }
// 恢复保留的数据
Object.keys(preservedData).forEach((key) => {
localStorage.setItem(key, preservedData[key])
})
} }
// 清除应用缓存 // 建议改为 async/await 风格以保持一致性
clearCache() { async clearCache() {
// 保存需要保留的数据 try {
const preservedData = {} // 保存需要保留的数据
const preservedData = {}
PERSISTENT_KEYS.forEach((key) => {
const value = localStorage.getItem(key)
if (value !== null) {
preservedData[key] = value
}
})
PERSISTENT_KEYS.forEach((key) => { // 清除所有localStorage
const value = localStorage.getItem(key) localStorage.clear()
if (value !== null) {
preservedData[key] = value // 恢复保留的数据
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)))
} }
})
// 清除所有localStorage // 注销Service Worker如果存在
localStorage.clear() if ('serviceWorker' in navigator) {
const registrations = await navigator.serviceWorker.getRegistrations()
// 恢复保留的数据 await Promise.all(registrations.map((reg) => reg.unregister()))
Object.keys(preservedData).forEach((key) => { }
localStorage.setItem(key, preservedData[key]) } catch (error) {
}) console.warn('清除缓存失败:', error)
// 清除sessionStorage
sessionStorage.clear()
// 清除所有缓存
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)
})
} }
} }