topfans/frontend/utils/avatarCache.js
2026-04-07 23:08:49 +08:00

198 lines
4.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 头像文件缓存管理工具
/**
* 生成缓存key
* @param {string} avatarUrl - OSS头像路径
* @returns {string} 缓存key
*/
function getCacheKey(avatarUrl) {
// 对avatarUrl进行简单hash作为缓存key的一部分
let hash = 0;
for (let i = 0; i < avatarUrl.length; i++) {
hash = ((hash << 5) - hash) + avatarUrl.charCodeAt(i);
hash = hash & hash; // Convert to 32bit integer
}
return `avatar_file_${Math.abs(hash)}`;
}
/**
* 从本地缓存获取头像文件路径
* @param {string} avatarUrl - OSS头像路径
* @returns {Promise<string|null>} 缓存的本地文件路径如果没有则返回null
*/
export async function getCachedAvatarPath(avatarUrl) {
if (!avatarUrl) return null;
try {
const cacheKey = getCacheKey(avatarUrl);
const cached = uni.getStorageSync(cacheKey);
if (cached) {
const cacheData = JSON.parse(cached);
// 检查缓存的avatar_url是否匹配防止hash碰撞
if (cacheData.avatarUrl === avatarUrl && cacheData.localPath) {
// 验证文件是否还存在
return new Promise((resolve) => {
uni.getFileInfo({
filePath: cacheData.localPath,
success: () => {
console.log('使用缓存的头像文件:', cacheData.localPath);
resolve(cacheData.localPath);
},
fail: () => {
// 文件不存在,清除缓存记录
console.log('缓存文件不存在,清除记录');
uni.removeStorageSync(cacheKey);
resolve(null);
}
});
});
}
}
} catch (error) {
console.error('获取缓存头像路径失败:', error);
}
return null;
}
/**
* 下载并缓存头像文件到本地
* @param {string} avatarUrl - OSS头像路径
* @param {string} realUrl - 真实的预签名URL
* @returns {Promise<string|null>} 本地文件路径失败返回null
*/
export async function downloadAndCacheAvatar(avatarUrl, realUrl) {
if (!avatarUrl || !realUrl) return null;
try {
console.log('开始下载头像文件...');
// 1. 下载文件到临时目录
const downloadResult = await new Promise((resolve, reject) => {
uni.downloadFile({
url: realUrl,
success: (res) => {
if (res.statusCode === 200) {
resolve(res.tempFilePath);
} else {
reject(new Error(`下载失败,状态码: ${res.statusCode}`));
}
},
fail: (err) => {
reject(err);
}
});
});
// 2. 将临时文件保存为永久文件
const savedPath = await new Promise((resolve, reject) => {
uni.saveFile({
tempFilePath: downloadResult,
success: (res) => {
resolve(res.savedFilePath);
},
fail: (err) => {
reject(err);
}
});
});
// 3. 保存文件路径到缓存
const cacheKey = getCacheKey(avatarUrl);
const cacheData = {
avatarUrl: avatarUrl,
localPath: savedPath,
cachedAt: Date.now()
};
uni.setStorageSync(cacheKey, JSON.stringify(cacheData));
console.log('头像文件已缓存到:', savedPath);
return savedPath;
} catch (error) {
console.error('下载并缓存头像失败:', error);
return null;
}
}
/**
* 清除指定头像的缓存文件
* @param {string} avatarUrl - OSS头像路径
*/
export function clearAvatarCache(avatarUrl) {
if (!avatarUrl) return;
try {
const cacheKey = getCacheKey(avatarUrl);
const cached = uni.getStorageSync(cacheKey);
if (cached) {
const cacheData = JSON.parse(cached);
// 删除本地文件
if (cacheData.localPath) {
uni.removeSavedFile({
filePath: cacheData.localPath,
success: () => {
console.log('已删除缓存的头像文件:', cacheData.localPath);
},
fail: (err) => {
console.error('删除缓存文件失败:', err);
}
});
}
// 删除缓存记录
uni.removeStorageSync(cacheKey);
console.log('已清除头像缓存记录');
}
} catch (error) {
console.error('清除头像缓存失败:', error);
}
}
/**
* 清除所有头像缓存文件
*/
export function clearAllAvatarCache() {
try {
const storageInfo = uni.getStorageInfoSync();
const keys = storageInfo.keys || [];
// 找到所有头像缓存的key并删除
keys.forEach(key => {
if (key.startsWith('avatar_file_')) {
try {
const cached = uni.getStorageSync(key);
if (cached) {
const cacheData = JSON.parse(cached);
// 删除本地文件
if (cacheData.localPath) {
uni.removeSavedFile({
filePath: cacheData.localPath,
success: () => {
console.log('已删除缓存文件:', cacheData.localPath);
},
fail: () => {
// 忽略错误,可能文件已经不存在
}
});
}
}
// 删除缓存记录
uni.removeStorageSync(key);
} catch (e) {
console.error('清除单个缓存失败:', e);
}
}
});
console.log('已清除所有头像缓存');
} catch (error) {
console.error('清除所有头像缓存失败:', error);
}
}