/** * OmniCard AI (CRMmp) - 移动端名片离线多媒体缓存与本地持久化策略 * 严格遵循 AGENTS.md 规范与 uts 跨端强类型语法 */ export interface MediaCacheEntry { url: string; localPath: string; cachedAt: number; expireAt: number; sizeBytes?: number; } export interface CachedMediaResult { localPath: string; isExpired: boolean; } export interface MediaCacheStats { totalEntries: number; oldestEntryAt?: number; } const STORAGE_CACHE_KEY = 'omni_media_cache_index'; /** * 获取底层全部缓存索引映射 */ function getIndexMap(): Record { try { const raw = uni.getStorageSync(STORAGE_CACHE_KEY); if (!raw) return {}; return JSON.parse(String(raw)) || {}; } catch (e) { return {}; } } /** * 保存索引映射 */ function saveIndexMap(map: Record): void { try { uni.setStorageSync(STORAGE_CACHE_KEY, JSON.stringify(map)); } catch (e) {} } /** * 获取指定多媒体 URL 的本地缓存 */ export function getCachedMedia(url?: string): CachedMediaResult | null { if (!url || typeof url !== 'string') return null; const map = getIndexMap(); const entry = map[url]; if (!entry) return null; const now = Date.now(); const isExpired = now > entry.expireAt; return { localPath: entry.localPath, isExpired, }; } /** * 存入多媒体缓存索引 */ export function saveMediaToCache( url: string, localPath: string, expireHours: number = 72 ): void { if (!url || !localPath) return; const map = getIndexMap(); const now = Date.now(); const expireAt = now + expireHours * 3600 * 1000; map[url] = { url, localPath, cachedAt: now, expireAt, }; saveIndexMap(map); } /** * 定期/按需淘汰清理过期缓存条目 */ export function pruneExpiredMediaCache(): number { const map = getIndexMap(); const now = Date.now(); let prunedCount = 0; const newMap: Record = {}; for (const [key, entry] of Object.entries(map)) { if (now > entry.expireAt) { prunedCount++; } else { newMap[key] = entry; } } saveIndexMap(newMap); return prunedCount; } /** * 获取多媒体缓存状态统计 */ export function getMediaCacheStats(): MediaCacheStats { const map = getIndexMap(); const entries = Object.values(map); let oldest: number | undefined = undefined; for (const e of entries) { if (oldest === undefined || e.cachedAt < oldest) { oldest = e.cachedAt; } } return { totalEntries: entries.length, oldestEntryAt: oldest, }; } /** * 清空全部多媒体缓存 */ export function clearAllMediaCache(): void { try { uni.removeStorageSync(STORAGE_CACHE_KEY); } catch (e) {} }