199 lines
4.8 KiB
JavaScript
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;
|