feat(图片、版本): 更新图片的预加载、缓存、加载指令、版本对象的生成和检查
This commit is contained in:
parent
cd1c802269
commit
0e24e75b62
9
.env
9
.env
@ -1,8 +1,11 @@
|
|||||||
# 应用版本号
|
# 应用版本号
|
||||||
VITE_APP_VERSION=1.6.8
|
VITE_APP_VERSION=1.6.9
|
||||||
|
|
||||||
# 构建时间戳(会在构建时自动更新)
|
# 版本类型
|
||||||
VITE_BUILD_TIME=""
|
# major:重大更新(清空用户缓存)
|
||||||
|
# minor:一般更新(可选择不清空缓存)
|
||||||
|
# patch:日常小更新(不清空用户缓存)
|
||||||
|
VITE_VERSION_TYPE=major
|
||||||
|
|
||||||
# 是否启用版本检查
|
# 是否启用版本检查
|
||||||
VITE_ENABLE_VERSION_CHECK=true
|
VITE_ENABLE_VERSION_CHECK=true
|
||||||
|
|||||||
@ -10,14 +10,20 @@ const __dirname = dirname(__filename)
|
|||||||
// 读取 .env 文件获取版本号
|
// 读取 .env 文件获取版本号
|
||||||
const envPath = resolve(__dirname, '../.env')
|
const envPath = resolve(__dirname, '../.env')
|
||||||
let version = '1.0.0'
|
let version = '1.0.0'
|
||||||
|
let versionType = 'patch'
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (existsSync(envPath)) {
|
if (existsSync(envPath)) {
|
||||||
const envContent = readFileSync(envPath, 'utf-8')
|
const envContent = readFileSync(envPath, 'utf-8')
|
||||||
const versionMatch = envContent.match(/VITE_APP_VERSION=([^\r\n]+)/)
|
const versionMatch = envContent.match(/VITE_APP_VERSION=([^\r\n]+)/)
|
||||||
|
const typeMatch = envContent.match(/VITE_VERSION_TYPE=([^\r\n]+)/)
|
||||||
|
|
||||||
if (versionMatch && versionMatch[1]) {
|
if (versionMatch && versionMatch[1]) {
|
||||||
version = versionMatch[1].replace(/['"]/g, '')
|
version = versionMatch[1].replace(/['"]/g, '')
|
||||||
}
|
}
|
||||||
|
if (typeMatch && typeMatch[1]) {
|
||||||
|
versionType = typeMatch[1].replace(/['"]/g, '')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.warn('无法读取 .env 文件,使用默认版本号:', error.message)
|
console.warn('无法读取 .env 文件,使用默认版本号:', error.message)
|
||||||
@ -26,6 +32,7 @@ try {
|
|||||||
// 生成版本信息
|
// 生成版本信息
|
||||||
const versionInfo = {
|
const versionInfo = {
|
||||||
version: version,
|
version: version,
|
||||||
|
type: versionType, // 新增版本类型
|
||||||
buildTime: new Date().toISOString(),
|
buildTime: new Date().toISOString(),
|
||||||
timestamp: Date.now(),
|
timestamp: Date.now(),
|
||||||
}
|
}
|
||||||
@ -40,4 +47,6 @@ if (!existsSync(distDir)) {
|
|||||||
const outputPath = resolve(distDir, 'version.json')
|
const outputPath = resolve(distDir, 'version.json')
|
||||||
writeFileSync(outputPath, JSON.stringify(versionInfo, null, 2))
|
writeFileSync(outputPath, JSON.stringify(versionInfo, null, 2))
|
||||||
|
|
||||||
console.log(`✅ 版本文件已生成: ${versionInfo.version} (${versionInfo.buildTime})`)
|
console.log(
|
||||||
|
`✅ 版本文件已生成: ${versionInfo.version}-${versionInfo.type} (${versionInfo.buildTime})`
|
||||||
|
)
|
||||||
|
|||||||
@ -3,37 +3,25 @@ import { imageCacheManager } from '@/utils/imageCacheManager'
|
|||||||
|
|
||||||
export const smartImage = {
|
export const smartImage = {
|
||||||
async mounted(el, binding) {
|
async mounted(el, binding) {
|
||||||
|
// 只有当绑定的值存在时才处理
|
||||||
if (binding.value) {
|
if (binding.value) {
|
||||||
// 设置加载状态样式
|
// 设置加载状态样式
|
||||||
el.style.opacity = '0'
|
el.style.opacity = '0'
|
||||||
el.style.transition = 'opacity 0.3s ease-in-out'
|
el.style.transition = 'opacity 0.3s ease-in-out'
|
||||||
|
|
||||||
try {
|
// 等待DOM更新确保样式生效
|
||||||
// 对于OSS图片使用特殊处理
|
await nextTick()
|
||||||
if (binding.value.startsWith('https://tkm-likei.oss-ap-southeast-1.aliyuncs.com/h5')) {
|
|
||||||
const img = new Image()
|
|
||||||
img.crossOrigin = 'anonymous'
|
|
||||||
img.onload = () => {
|
|
||||||
el.src = binding.value
|
|
||||||
el.style.opacity = '1'
|
|
||||||
}
|
|
||||||
img.onerror = (error) => {
|
|
||||||
console.warn(`图片加载失败: ${binding.value}`, error)
|
|
||||||
el.src = binding.value
|
|
||||||
el.style.opacity = '1'
|
|
||||||
}
|
|
||||||
img.src = binding.value
|
|
||||||
} else {
|
|
||||||
// 对于外部链接,直接使用普通加载方式
|
|
||||||
if (!imageCacheManager.isBuildAsset(binding.value)) {
|
|
||||||
el.src = binding.value
|
|
||||||
el.style.opacity = '1'
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 统一使用缓存管理器处理所有可缓存资源
|
||||||
|
if (imageCacheManager.isBuildAsset(binding.value)) {
|
||||||
await imageCacheManager.loadImage(binding.value)
|
await imageCacheManager.loadImage(binding.value)
|
||||||
el.src = binding.value
|
el.src = binding.value
|
||||||
el.style.opacity = '1'
|
el.style.opacity = '1'
|
||||||
|
} else {
|
||||||
|
// 外部链接直接加载
|
||||||
|
el.src = binding.value
|
||||||
|
el.style.opacity = '1'
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.warn(`图片加载失败: ${binding.value}`, error)
|
console.warn(`图片加载失败: ${binding.value}`, error)
|
||||||
@ -47,31 +35,17 @@ export const smartImage = {
|
|||||||
if (binding.value !== binding.oldValue && binding.value) {
|
if (binding.value !== binding.oldValue && binding.value) {
|
||||||
el.style.opacity = '0'
|
el.style.opacity = '0'
|
||||||
|
|
||||||
try {
|
// 等待DOM更新确保样式生效
|
||||||
// 对于OSS图片使用特殊处理
|
await nextTick()
|
||||||
if (binding.value.startsWith('https://tkm-likei.oss-ap-southeast-1.aliyuncs.com/h5')) {
|
|
||||||
const img = new Image()
|
|
||||||
img.crossOrigin = 'anonymous'
|
|
||||||
img.onload = () => {
|
|
||||||
el.src = binding.value
|
|
||||||
el.style.opacity = '1'
|
|
||||||
}
|
|
||||||
img.onerror = (error) => {
|
|
||||||
console.warn(`图片更新失败: ${binding.value}`, error)
|
|
||||||
el.src = binding.value
|
|
||||||
el.style.opacity = '1'
|
|
||||||
}
|
|
||||||
img.src = binding.value
|
|
||||||
} else {
|
|
||||||
// 对于外部链接,直接使用普通加载方式
|
|
||||||
if (!imageCacheManager.isBuildAsset(binding.value)) {
|
|
||||||
el.src = binding.value
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (imageCacheManager.isBuildAsset(binding.value)) {
|
||||||
await imageCacheManager.loadImage(binding.value)
|
await imageCacheManager.loadImage(binding.value)
|
||||||
el.src = binding.value
|
el.src = binding.value
|
||||||
el.style.opacity = '1'
|
el.style.opacity = '1'
|
||||||
|
} else {
|
||||||
|
el.src = binding.value
|
||||||
|
el.style.opacity = '1'
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.warn(`图片更新失败: ${binding.value}`, error)
|
console.warn(`图片更新失败: ${binding.value}`, error)
|
||||||
|
|||||||
@ -97,13 +97,13 @@ app.use(i18n)
|
|||||||
|
|
||||||
app.mount('#app')
|
app.mount('#app')
|
||||||
|
|
||||||
// 定期检查版本更新(每5分钟)
|
// 定时检查逻辑
|
||||||
if (versionChecker.enableCheck) {
|
if (versionChecker.enableCheck) {
|
||||||
setInterval(async () => {
|
setInterval(async () => {
|
||||||
const hasUpdate = await versionChecker.checkServerVersion()
|
const versionResult = await versionChecker.checkServerVersion()
|
||||||
if (hasUpdate) {
|
if (versionResult.shouldUpdate) {
|
||||||
// 自动处理更新,不需要用户交互
|
// 自动处理更新,不需要用户交互
|
||||||
versionChecker.handleVersionUpdate()
|
versionChecker.handleVersionUpdate(versionResult.versionType)
|
||||||
}
|
}
|
||||||
}, 5 * 60 * 1000)
|
}, 5 * 60 * 1000)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,12 +3,60 @@ class ImageCacheManager {
|
|||||||
constructor() {
|
constructor() {
|
||||||
this.cacheVersionKey = 'likei-image-cache-version'
|
this.cacheVersionKey = 'likei-image-cache-version'
|
||||||
this.currentAppVersion = import.meta.env.VITE_APP_VERSION || '1.0.0'
|
this.currentAppVersion = import.meta.env.VITE_APP_VERSION || '1.0.0'
|
||||||
this.cacheName = `likei-images-v${this.currentAppVersion}`
|
|
||||||
|
this.imageCacheName = `likei-images-v${this.currentAppVersion}` // OSS图片
|
||||||
|
this.assetCacheName = `likei-assets-v${this.currentAppVersion}` // 本地assets
|
||||||
|
|
||||||
this.maxCacheItems = 100 // 最大缓存数量(100张)
|
this.maxCacheItems = 100 // 最大缓存数量(100张)
|
||||||
this.maxCacheSize = 100 * 1024 * 1024 // 最大缓存大小(100MB)
|
this.maxCacheSize = 100 * 1024 * 1024 // 最大缓存大小(100MB)
|
||||||
|
|
||||||
|
this.pendingRequests = new Map() // 请求去重的关键
|
||||||
|
|
||||||
this.init()
|
this.init()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 根据资源类型选择缓存
|
||||||
|
async getCacheForUrl(url) {
|
||||||
|
if (url.startsWith('https://tkm-likei.oss-ap-southeast-1.aliyuncs.com/h5')) {
|
||||||
|
return await caches.open(this.imageCacheName)
|
||||||
|
} else {
|
||||||
|
return await caches.open(this.assetCacheName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 选择性清除缓存
|
||||||
|
async clearCacheSelective(clearType = 'images') {
|
||||||
|
if (!('caches' in window)) return
|
||||||
|
|
||||||
|
try {
|
||||||
|
const cacheNames = await caches.keys()
|
||||||
|
let cachesToClear = []
|
||||||
|
|
||||||
|
switch (clearType) {
|
||||||
|
case 'images':
|
||||||
|
cachesToClear = cacheNames.filter((name) => name.startsWith('likei-images-v'))
|
||||||
|
break
|
||||||
|
case 'assets':
|
||||||
|
cachesToClear = cacheNames.filter((name) => name.startsWith('likei-assets-v'))
|
||||||
|
break
|
||||||
|
case 'all':
|
||||||
|
// 清除所有相关缓存(除了动态内容)
|
||||||
|
cachesToClear = cacheNames.filter(
|
||||||
|
(name) => name.startsWith('likei-images-v') || name.startsWith('likei-assets-v')
|
||||||
|
)
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
// 默认只清除图片缓存
|
||||||
|
cachesToClear = cacheNames.filter((name) => name.startsWith('likei-images-v'))
|
||||||
|
}
|
||||||
|
|
||||||
|
await Promise.all(cachesToClear.map((name) => caches.delete(name)))
|
||||||
|
console.log(`已清理${clearType}类型缓存:`, cachesToClear)
|
||||||
|
} catch (error) {
|
||||||
|
console.warn('清理缓存失败:', error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async init() {
|
async init() {
|
||||||
await this.checkVersionAndUpdate()
|
await this.checkVersionAndUpdate()
|
||||||
}
|
}
|
||||||
@ -126,7 +174,7 @@ class ImageCacheManager {
|
|||||||
try {
|
try {
|
||||||
const cacheNames = await caches.keys()
|
const cacheNames = await caches.keys()
|
||||||
const oldCaches = cacheNames.filter(
|
const oldCaches = cacheNames.filter(
|
||||||
(name) => name.startsWith('likei-images-v') && name !== this.cacheName
|
(name) => name.startsWith('likei-images-v') && name !== this.imageCacheName
|
||||||
)
|
)
|
||||||
|
|
||||||
await Promise.all(oldCaches.map((name) => caches.delete(name)))
|
await Promise.all(oldCaches.map((name) => caches.delete(name)))
|
||||||
@ -173,14 +221,13 @@ class ImageCacheManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 缓存图片
|
// 分离缓存图片
|
||||||
async cacheImage(url) {
|
async cacheImage(url) {
|
||||||
if (!('caches' in window) || !url) return
|
if (!('caches' in window) || !url) return
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 只缓存本地构建后的资源,避免缓存外部网络图片
|
|
||||||
if (this.isBuildAsset(url)) {
|
if (this.isBuildAsset(url)) {
|
||||||
const cache = await caches.open(this.cacheName)
|
const cache = await this.getCacheForUrl(url) // 使用分离的缓存
|
||||||
const cachedResponse = await cache.match(url)
|
const cachedResponse = await cache.match(url)
|
||||||
|
|
||||||
if (!cachedResponse) {
|
if (!cachedResponse) {
|
||||||
@ -209,7 +256,7 @@ class ImageCacheManager {
|
|||||||
try {
|
try {
|
||||||
// 只从缓存获取本地资源
|
// 只从缓存获取本地资源
|
||||||
if (this.isBuildAsset(url)) {
|
if (this.isBuildAsset(url)) {
|
||||||
const cache = await caches.open(this.cacheName)
|
const cache = await caches.open(this.imageCacheName)
|
||||||
return await cache.match(url)
|
return await cache.match(url)
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
@ -221,32 +268,59 @@ class ImageCacheManager {
|
|||||||
|
|
||||||
// 智能加载图片
|
// 智能加载图片
|
||||||
async loadImage(src) {
|
async loadImage(src) {
|
||||||
return new Promise(async (resolve, reject) => {
|
// 1. 请求去重:检查是否有相同请求正在进行
|
||||||
|
if (this.pendingRequests.has(src)) {
|
||||||
|
// 返回现有的Promise,避免重复请求
|
||||||
|
return this.pendingRequests.get(src)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 创建新的加载Promise
|
||||||
|
const loadPromise = new Promise(async (resolve, reject) => {
|
||||||
try {
|
try {
|
||||||
// 首先尝试从缓存获取(仅限本地资源)
|
// 3. 尝试从缓存获取
|
||||||
const cachedResponse = await this.getCachedImage(src)
|
const cachedResponse = await this.getCachedImage(src)
|
||||||
if (cachedResponse) {
|
if (cachedResponse) {
|
||||||
|
// 4. 缓存命中,处理图片
|
||||||
const blob = await cachedResponse.blob()
|
const blob = await cachedResponse.blob()
|
||||||
const imageUrl = URL.createObjectURL(blob)
|
const imageUrl = URL.createObjectURL(blob)
|
||||||
|
|
||||||
|
// 5. 创建Image对象并设置src
|
||||||
const img = new Image()
|
const img = new Image()
|
||||||
img.onload = () => {
|
img.onload = () => {
|
||||||
|
// 6. 加载成功,清理临时URL并resolve
|
||||||
URL.revokeObjectURL(imageUrl)
|
URL.revokeObjectURL(imageUrl)
|
||||||
resolve(img)
|
resolve(img)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 7. 关键:加载失败时的处理
|
||||||
img.onerror = () => {
|
img.onerror = () => {
|
||||||
|
// 8. 清理临时URL
|
||||||
URL.revokeObjectURL(imageUrl)
|
URL.revokeObjectURL(imageUrl)
|
||||||
|
// 9. 回退到网络加载
|
||||||
this.loadImageFromNetwork(src, resolve, reject)
|
this.loadImageFromNetwork(src, resolve, reject)
|
||||||
}
|
}
|
||||||
img.src = imageUrl
|
|
||||||
|
img.src = imageUrl // 10. 开始加载
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 缓存中没有或不是本地资源,从网络加载
|
// 11. 缓存中没有或不是本地资源,从网络加载
|
||||||
this.loadImageFromNetwork(src, resolve, reject)
|
this.loadImageFromNetwork(src, resolve, reject)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.loadImageFromNetwork(src, resolve, reject)
|
this.loadImageFromNetwork(src, resolve, reject)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 12. 记录正在进行的请求
|
||||||
|
this.pendingRequests.set(src, loadPromise)
|
||||||
|
|
||||||
|
try {
|
||||||
|
const result = await loadPromise
|
||||||
|
return result
|
||||||
|
} finally {
|
||||||
|
// 13. 清理记录
|
||||||
|
this.pendingRequests.delete(src)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 从网络加载图片
|
// 从网络加载图片
|
||||||
@ -307,7 +381,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.cacheName)
|
const cache = await caches.open(this.imageCacheName)
|
||||||
const cachedResponse = await cache.match(src)
|
const cachedResponse = await cache.match(src)
|
||||||
|
|
||||||
// 只有当图片尚未缓存时才进行缓存操作
|
// 只有当图片尚未缓存时才进行缓存操作
|
||||||
|
|||||||
@ -1,8 +1,7 @@
|
|||||||
// src/utils/imagePreloader.js
|
// src/utils/imagePreloader.js
|
||||||
import { imageCacheManager } from '@/utils/imageCacheManager'
|
import { imageCacheManager } from '@/utils/imageCacheManager'
|
||||||
|
|
||||||
export const preloadImages = (sources, options = {}) => {
|
export const preloadImages = (sources, options) => {
|
||||||
const { useSmartCache = false } = options
|
|
||||||
let urls = []
|
let urls = []
|
||||||
|
|
||||||
// 支持数组和对象形式的图片源
|
// 支持数组和对象形式的图片源
|
||||||
@ -12,23 +11,15 @@ export const preloadImages = (sources, options = {}) => {
|
|||||||
urls = Object.values(sources)
|
urls = Object.values(sources)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (useSmartCache) {
|
// 使用 SmartImage 缓存系统
|
||||||
// 使用 SmartImage 缓存系统
|
urls.forEach((url) => {
|
||||||
urls.forEach((url) => {
|
if (imageCacheManager.isBuildAsset(url)) {
|
||||||
if (imageCacheManager.isBuildAsset(url)) {
|
imageCacheManager.loadImage(url) // 触发缓存加载
|
||||||
imageCacheManager.loadImage(url) // 触发缓存
|
} else {
|
||||||
} else {
|
|
||||||
const img = new Image()
|
|
||||||
img.src = url
|
|
||||||
}
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
// 使用浏览器默认缓存
|
|
||||||
urls.forEach((url) => {
|
|
||||||
const img = new Image()
|
const img = new Image()
|
||||||
img.src = url
|
img.src = url
|
||||||
})
|
}
|
||||||
}
|
})
|
||||||
|
|
||||||
console.log(`开始预加载 ${urls.length} 张图片`)
|
console.log(`开始预加载 ${urls.length} 张图片`)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,13 @@
|
|||||||
// 版本检查工具
|
// 版本检查工具
|
||||||
|
|
||||||
|
const PERSISTENT_KEYS = [
|
||||||
|
'preferred-language', // 语言设置
|
||||||
|
'userProfile', // 用户资料
|
||||||
|
'teamInfo', // 团队信息
|
||||||
|
'lastImgUrl', // 最后图片URL
|
||||||
|
'applyInfo', // 申请资料
|
||||||
|
]
|
||||||
|
|
||||||
export class VersionChecker {
|
export class VersionChecker {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.currentVersion = import.meta.env.VITE_APP_VERSION || Date.now().toString()
|
this.currentVersion = import.meta.env.VITE_APP_VERSION || Date.now().toString()
|
||||||
@ -30,6 +39,7 @@ export class VersionChecker {
|
|||||||
|
|
||||||
const versionInfo = await response.json()
|
const versionInfo = await response.json()
|
||||||
const serverVersion = versionInfo.version
|
const serverVersion = versionInfo.version
|
||||||
|
const versionType = versionInfo.type || 'patch' // 获取版本类型
|
||||||
const storedServerVersion = localStorage.getItem(this.serverVersionKey)
|
const storedServerVersion = localStorage.getItem(this.serverVersionKey)
|
||||||
|
|
||||||
// 更新服务器版本信息
|
// 更新服务器版本信息
|
||||||
@ -37,23 +47,28 @@ export class VersionChecker {
|
|||||||
|
|
||||||
// 比较版本
|
// 比较版本
|
||||||
if (storedServerVersion && storedServerVersion !== serverVersion) {
|
if (storedServerVersion && storedServerVersion !== serverVersion) {
|
||||||
console.log(`检测到服务器版本更新: ${storedServerVersion} -> ${serverVersion}`)
|
console.log(`检测到${versionType}版本更新: ${storedServerVersion} -> ${serverVersion}`)
|
||||||
return true
|
|
||||||
|
// 返回版本类型信息
|
||||||
|
return {
|
||||||
|
shouldUpdate: true,
|
||||||
|
versionType: versionType,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return { shouldUpdate: false }
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.warn('版本检查失败:', error)
|
console.warn('版本检查失败:', error)
|
||||||
return false
|
return { shouldUpdate: false }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查版本更新(综合方法)
|
// 检查版本更新(综合方法)
|
||||||
async checkVersion() {
|
async checkVersion() {
|
||||||
// 首先检查服务器版本
|
// 首先检查服务器版本
|
||||||
const hasServerUpdate = await this.checkServerVersion()
|
const versionResult = await this.checkServerVersion()
|
||||||
|
|
||||||
if (hasServerUpdate) {
|
if (versionResult.shouldUpdate) {
|
||||||
this.handleVersionUpdate()
|
this.handleVersionUpdate()
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -71,9 +86,28 @@ export class VersionChecker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 处理版本更新
|
// 处理版本更新
|
||||||
handleVersionUpdate() {
|
handleVersionUpdate(updateType = 'major') {
|
||||||
console.log('检测到新版本,正在清理缓存...')
|
console.log(`检测到${updateType}版本更新,正在清理缓存...`)
|
||||||
this.clearCache()
|
|
||||||
|
// 根据更新类型决定清除策略
|
||||||
|
switch (updateType) {
|
||||||
|
case 'major':
|
||||||
|
// 重大更新:清除所有缓存
|
||||||
|
this.clearCache()
|
||||||
|
break
|
||||||
|
case 'minor':
|
||||||
|
// 一般更新:只清除图片和assets缓存
|
||||||
|
this.clearCacheSelective('all')
|
||||||
|
break
|
||||||
|
case 'patch':
|
||||||
|
// 小更新:只清除图片缓存
|
||||||
|
this.clearCacheSelective('images')
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
// 默认:清除所有缓存
|
||||||
|
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)
|
||||||
|
|
||||||
@ -81,13 +115,66 @@ export class VersionChecker {
|
|||||||
this.forceReload()
|
this.forceReload()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 添加选择性清除缓存方法
|
||||||
|
clearCacheSelective(clearType = 'images') {
|
||||||
|
// 保存需要保留的数据
|
||||||
|
const preservedData = {}
|
||||||
|
|
||||||
|
PERSISTENT_KEYS.forEach((key) => {
|
||||||
|
const value = localStorage.getItem(key)
|
||||||
|
if (value !== null) {
|
||||||
|
preservedData[key] = value
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 清除sessionStorage
|
||||||
|
sessionStorage.clear()
|
||||||
|
|
||||||
|
// 清除指定类型的缓存
|
||||||
|
if ('caches' in window) {
|
||||||
|
caches
|
||||||
|
.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])
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// 清除应用缓存
|
// 清除应用缓存
|
||||||
clearCache() {
|
clearCache() {
|
||||||
// 保存需要保留的数据
|
// 保存需要保留的数据
|
||||||
const preservedData = {}
|
const preservedData = {}
|
||||||
const keysToPreserve = ['user_token', 'user_info', 'lang']
|
|
||||||
|
|
||||||
keysToPreserve.forEach((key) => {
|
PERSISTENT_KEYS.forEach((key) => {
|
||||||
const value = localStorage.getItem(key)
|
const value = localStorage.getItem(key)
|
||||||
if (value !== null) {
|
if (value !== null) {
|
||||||
preservedData[key] = value
|
preservedData[key] = value
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user