Files
lizhilunandClaude Opus 4.6 ac2d21a5a0 fix: 修复添加记录后首页数据不刷新的问题
将缓存清除逻辑从 stats.js 路由移至 app.js 全局中间件,
确保 records.js 路由的写操作也能触发缓存清除。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-31 16:59:32 +08:00

69 lines
1.6 KiB
JavaScript

/**
* 统计数据缓存模块
* 基于 LRU 算法的内存缓存
*/
const config = require('../config');
const logger = require('./logger');
const statsCache = new Map();
const CACHE_TTL = config.cache.ttl;
const MAX_CACHE_SIZE = config.cache.maxSize;
/**
* 获取缓存数据,如果不存在则通过 fetchFn 获取并缓存
* @param {string} key 缓存键
* @param {Function} fetchFn 获取数据的函数
* @returns {Promise} 缓存数据
*/
function getCached(key, fetchFn) {
const cached = statsCache.get(key);
if (cached && Date.now() - cached.ts < CACHE_TTL) {
// LRU: move to end
statsCache.delete(key);
statsCache.set(key, cached);
return Promise.resolve(cached.data);
}
// 超出最大缓存数量时,删除最旧的条目
if (statsCache.size >= MAX_CACHE_SIZE) {
const firstKey = statsCache.keys().next().value;
statsCache.delete(firstKey);
}
return Promise.resolve(fetchFn()).then(data => {
statsCache.set(key, { data, ts: Date.now() });
logger.debug(`缓存更新: ${key}`);
return data;
}).catch(err => {
logger.error('缓存获取失败:', err.message);
throw err;
});
}
/**
* 清除指定用户的所有缓存
* @param {number} userId 用户ID
*/
function clearUserCache(userId) {
const prefix = `:${userId}:`;
for (const key of statsCache.keys()) {
if (key.includes(prefix)) {
statsCache.delete(key);
logger.debug(`缓存清除: ${key}`);
}
}
}
/**
* 清除所有缓存
*/
function clearAllCache() {
statsCache.clear();
logger.debug('所有缓存已清除');
}
module.exports = {
getCached,
clearUserCache,
clearAllCache
};