imetting_frontend/src/services/meetingCacheService.js

199 lines
4.8 KiB
JavaScript

/**
* 会议数据缓存服务
* 用于缓存会议列表的查询结果,减少不必要的网络请求,提升用户体验
*/
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<string>} 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;