Skip to content

Commit e76c5d7

Browse files
committed
fix(sns-media): 恢复朋友圈图片本地缓存优先
- /api/sns/media 先解析微信本地 cache/*/Sns/Img 与封面缓存,本地未命中后才走 WeFlow 远程下载解密 - 前端朋友圈图片请求重新携带 post_id、media_id、create_time、尺寸、md5 等本地匹配参数 - 朋友圈离线导出同步改为本地缓存优先,避免导出时优先触发网络请求
1 parent 9089e7c commit e76c5d7

3 files changed

Lines changed: 466 additions & 26 deletions

File tree

frontend/pages/sns.vue

Lines changed: 59 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1964,6 +1964,33 @@ const upgradeTencentHttps = (u) => {
19641964
return raw
19651965
}
19661966

1967+
const normalizeHex32 = (value) => {
1968+
const raw = String(value ?? '').trim()
1969+
if (!raw) return ''
1970+
const hex = raw.replace(/[^0-9a-fA-F]/g, '').toLowerCase()
1971+
return hex.length >= 32 ? hex.slice(0, 32) : ''
1972+
}
1973+
1974+
const mediaSizeKey = (m) => {
1975+
const t = String(m?.type ?? '')
1976+
const w = String(m?.size?.width || m?.size?.w || '').trim()
1977+
const h = String(m?.size?.height || m?.size?.h || '').trim()
1978+
const total = String(m?.size?.totalSize || m?.size?.total_size || m?.size?.total || '').trim()
1979+
return `${t}:${w}:${h}:${total}`
1980+
}
1981+
1982+
const mediaSizeGroupIndex = (post, m, idx) => {
1983+
const list = Array.isArray(post?.media) ? post.media : []
1984+
const key = mediaSizeKey(m)
1985+
const i0 = Number(idx) || 0
1986+
if (!key || i0 <= 0) return i0
1987+
let count = 0
1988+
for (let i = 0; i < i0; i++) {
1989+
if (mediaSizeKey(list[i]) === key) count++
1990+
}
1991+
return count
1992+
}
1993+
19671994
const getSnsMediaUrl = (post, m, idx, rawUrl) => {
19681995
const raw = upgradeTencentHttps(String(rawUrl || '').trim())
19691996
if (!raw) return ''
@@ -1980,12 +2007,37 @@ const getSnsMediaUrl = (post, m, idx, rawUrl) => {
19802007
const host = new URL(raw).hostname.toLowerCase()
19812008
if (host.endsWith('.qpic.cn') || host.endsWith('.qlogo.cn') || host.endsWith('.tc.qq.com')) {
19822009
const acc = String(selectedAccount.value || '').trim()
1983-
// Match WeFlow's image pipeline: use a stable URL + key/token and let the
1984-
// backend handle cache-first remote fetch/decrypt. Avoid attaching legacy
1985-
// local-match metadata to the main image path so browser caching can reuse
1986-
// the same request URL for list + preview.
2010+
const ct = String(post?.createTime || '').trim()
2011+
const w = String(m?.size?.width || m?.size?.w || '').trim()
2012+
const h = String(m?.size?.height || m?.size?.h || '').trim()
2013+
const ts = String(m?.size?.totalSize || m?.size?.total_size || m?.size?.total || '').trim()
2014+
const sizeIdx = mediaSizeGroupIndex(post, m, idx)
2015+
let md5 = normalizeHex32(m?.urlAttrs?.md5 || m?.thumbAttrs?.md5 || m?.urlAttrs?.MD5 || m?.thumbAttrs?.MD5)
2016+
if (!md5) {
2017+
const match = /[?&]md5=([0-9a-fA-F]{16,32})/.exec(raw)
2018+
if (match?.[1]) md5 = normalizeHex32(match[1])
2019+
}
2020+
19872021
const parts = new URLSearchParams()
19882022
if (acc) parts.set('account', acc)
2023+
if (ct) parts.set('create_time', ct)
2024+
if (w) parts.set('width', w)
2025+
if (h) parts.set('height', h)
2026+
if (/^\d+$/.test(ts)) parts.set('total_size', ts)
2027+
parts.set('idx', String(Number(sizeIdx) || 0))
2028+
2029+
const pid = String(post?.id || post?.tid || '').trim()
2030+
if (pid) parts.set('post_id', pid)
2031+
2032+
const mid = String(m?.id || '').trim()
2033+
if (mid) parts.set('media_id', mid)
2034+
2035+
const postType = String(post?.type || '1').trim()
2036+
if (postType) parts.set('post_type', postType)
2037+
2038+
const mediaType = String(m?.type || '2').trim()
2039+
if (mediaType) parts.set('media_type', mediaType)
2040+
19892041
const token = String(m?.token || m?.urlAttrs?.token || m?.thumbAttrs?.token || '').trim()
19902042
if (token) parts.set('token', token)
19912043

@@ -1995,8 +2047,9 @@ const getSnsMediaUrl = (post, m, idx, rawUrl) => {
19952047
parts.set('use_cache', snsUseCache.value ? '1' : '0')
19962048
// When cache is disabled, bust browser caching so backend really downloads+decrypts each time.
19972049
if (!snsUseCache.value) parts.set('_t', String(Date.now()))
1998-
// Bump this when changing the WeFlow-aligned image pipeline to avoid stale browser caches.
1999-
parts.set('v', '10')
2050+
if (md5) parts.set('md5', md5)
2051+
// 修改后端媒体匹配逻辑时递增版本号,避免浏览器复用旧的错误缓存。
2052+
parts.set('v', '11')
20002053
parts.set('url', raw)
20012054
return `${apiBase}/sns/media?${parts.toString()}`
20022055
}

0 commit comments

Comments
 (0)