feat(image-cache): 新增图片本地缓存并全站接入
引入 cached-image 组件与 image-cache 工具,实现签名 URL 稳定 key 剥离、downloadFile 落盘及 TTL/LRU 清理,替换 11 个页面与 clothes-card 共 22 处网络图片渲染点,减少 CDN 重复流量。
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
// cached-image —— 通用图片组件:网络图经 utils/image-cache 落盘后展示(命中时零网络请求),
|
||||
// 本地路径(wxfile:// / http://tmp / 包内路径等)原样直出;
|
||||
// 未命中缓存时先骨架占位、下载完成后显示本地文件,失败自动回退网络地址,功能不受影响。
|
||||
|
||||
import { getCachedLocalPath, resolveImage, dropImageCache } from '../../utils/image-cache'
|
||||
|
||||
Component({
|
||||
properties: {
|
||||
src: { type: String, value: '' },
|
||||
// 与 image 组件对齐:未显式传入时保持 scaleToFill 默认行为
|
||||
mode: { type: String, value: 'scaleToFill' },
|
||||
lazyLoad: { type: Boolean, value: false },
|
||||
},
|
||||
data: {
|
||||
// 实际渲染地址:本地文件路径或回退的网络地址;空串 = 骨架占位中
|
||||
shown: '',
|
||||
},
|
||||
observers: {
|
||||
src() {
|
||||
this.refresh()
|
||||
},
|
||||
},
|
||||
lifetimes: {
|
||||
attached() {
|
||||
;(this as any)._alive = true
|
||||
this.refresh()
|
||||
},
|
||||
detached() {
|
||||
;(this as any)._alive = false
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
refresh() {
|
||||
const src = this.data.src
|
||||
const seq = (((this as any)._seq as number) || 0) + 1
|
||||
;(this as any)._seq = seq
|
||||
|
||||
if (!src) {
|
||||
this.setData({ shown: '' })
|
||||
return
|
||||
}
|
||||
if (src.indexOf('https://') !== 0) {
|
||||
// 本地/包内路径直接渲染,不进入缓存流程
|
||||
this.setData({ shown: src })
|
||||
return
|
||||
}
|
||||
const hit = getCachedLocalPath(src)
|
||||
if (hit) {
|
||||
this.setData({ shown: hit })
|
||||
return
|
||||
}
|
||||
// 未命中:先占位,下载落盘后显示本地文件(期间不渲染网络地址,避免额外请求抵消缓存收益)
|
||||
if (this.data.shown) this.setData({ shown: '' })
|
||||
resolveImage(src).then(
|
||||
(localPath) => {
|
||||
if ((this as any)._alive === false || (this as any)._seq !== seq) return
|
||||
this.setData({ shown: localPath })
|
||||
},
|
||||
() => {
|
||||
if ((this as any)._alive === false || (this as any)._seq !== seq) return
|
||||
// 缓存不可用时回退网络地址,保证功能可用
|
||||
this.setData({ shown: src })
|
||||
}
|
||||
)
|
||||
},
|
||||
onImgError() {
|
||||
const shown = this.data.shown
|
||||
const src = this.data.src
|
||||
// 网络地址自身失败或非网络图:不再处理,避免循环回退
|
||||
if (!shown || !src || shown.indexOf('https://') === 0) return
|
||||
;(this as any)._seq = (((this as any)._seq as number) || 0) + 1
|
||||
// 本地文件失效(被系统清理/损坏):清理缓存并回退网络地址一次
|
||||
dropImageCache(src)
|
||||
this.setData({ shown: src })
|
||||
},
|
||||
},
|
||||
})
|
||||
Reference in New Issue
Block a user