/** * 会议数据缓存服务 * 用于缓存会议列表的查询结果,减少不必要的网络请求,提升用户体验 */ class MeetingCacheService { constructor() { // 缓存结构: filterKey -> { pages: { pageNum: {meetings, pagination} }, timestamp } this.cache = {}; // 默认缓存时间: 5分钟 this.defaultTTL = 5 * 60 * 1000; } /** * 生成过滤器键(不包含页码) * @param {number} userId - 用户ID * @param {string} filterType - 过滤类型: 'all', 'created', 'attended' * @param {string} searchQuery - 搜索关键词 * @param {Array} selectedTags - 选中的标签列表 * @returns {string} 过滤器键 */ generateFilterKey(userId, filterType, searchQuery = '', selectedTags = []) { const tagsStr = selectedTags.length > 0 ? selectedTags.sort().join(',') : ''; return `${userId}|${filterType}|${searchQuery}|${tagsStr}`; } /** * 检查缓存是否过期 * @param {number} timestamp - 缓存时间戳 * @returns {boolean} 是否过期 */ isExpired(timestamp) { return Date.now() - timestamp > this.defaultTTL; } /** * 获取指定页的缓存数据 * @param {string} filterKey - 过滤器键 * @param {number} page - 页码 * @returns {Object|null} 缓存的数据或null */ getPage(filterKey, page) { const filterCache = this.cache[filterKey]; if (!filterCache) { return null; } // 检查是否过期 if (this.isExpired(filterCache.timestamp)) { delete this.cache[filterKey]; return null; } return filterCache.pages[page] || null; } /** * 获取过滤器下所有已缓存的页面 * @param {string} filterKey - 过滤器键 * @returns {Object|null} 所有缓存的页面数据或null */ getAllPages(filterKey) { const filterCache = this.cache[filterKey]; if (!filterCache) { return null; } // 检查是否过期 if (this.isExpired(filterCache.timestamp)) { delete this.cache[filterKey]; return null; } return filterCache; } /** * 设置指定页的缓存 * @param {string} filterKey - 过滤器键 * @param {number} page - 页码 * @param {Array} meetings - 会议列表数据 * @param {Object} pagination - 分页信息 */ setPage(filterKey, page, meetings, pagination) { if (!this.cache[filterKey]) { this.cache[filterKey] = { pages: {}, timestamp: Date.now() }; } this.cache[filterKey].pages[page] = { meetings, pagination }; // 更新时间戳 this.cache[filterKey].timestamp = Date.now(); } /** * 清除指定过滤器的缓存 * @param {string} filterKey - 过滤器键 */ clearFilter(filterKey) { delete this.cache[filterKey]; } /** * 清除匹配模式的缓存 * @param {string} pattern - 匹配模式(可选) */ clearPattern(pattern) { if (!pattern) { // 清除所有缓存 this.cache = {}; return; } // 清除匹配的缓存 Object.keys(this.cache).forEach(key => { if (key.includes(pattern)) { delete this.cache[key]; } }); } /** * 清除所有缓存 */ clearAll() { this.cache = {}; } /** * 获取缓存统计信息(用于调试) * @returns {Object} 缓存统计信息 */ getStats() { const filterCount = Object.keys(this.cache).length; let totalPages = 0; let totalMeetings = 0; Object.values(this.cache).forEach(filterCache => { const pages = Object.keys(filterCache.pages).length; totalPages += pages; Object.values(filterCache.pages).forEach(page => { totalMeetings += page.meetings.length; }); }); return { filterCount, // 缓存的过滤器数量 totalPages, // 缓存的总页数 totalMeetings, // 缓存的总会议数 cacheSize: this._estimateSize() // 估算缓存大小(KB) }; } /** * 估算缓存占用的内存大小 * @private * @returns {number} 估算大小(KB) */ _estimateSize() { const jsonStr = JSON.stringify(this.cache); return Math.round(jsonStr.length / 1024); } /** * 检查缓存中是否存在指定的过滤器 * @param {string} filterKey - 过滤器键 * @returns {boolean} */ hasFilter(filterKey) { const filterCache = this.cache[filterKey]; if (!filterCache) return false; return !this.isExpired(filterCache.timestamp); } /** * 检查缓存中是否存在指定的页面 * @param {string} filterKey - 过滤器键 * @param {number} page - 页码 * @returns {boolean} */ hasPage(filterKey, page) { return this.getPage(filterKey, page) !== null; } } // 创建单例实例 const meetingCacheService = new MeetingCacheService(); export default meetingCacheService;