All files / middleware cache.ts

0% Statements 0/57
0% Branches 0/1
0% Functions 0/1
0% Lines 0/57

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98                                                                                                                                                                                                   
import { redisService } from '../services/redis.service';
 
interface CacheOptions {
  ttl: number;           // 缓存时间(秒)
  keyPrefix?: string;    // 键前缀
  keyGenerator?: (ctx: any) => string; // 自定义键生成器
}
 
/**
 * 缓存中间件
 * @param options 缓存配置
 */
export function createCache(options: CacheOptions) {
  return async (ctx: any, next: any) => {
    // 如果 Redis 不可用,跳过缓存
    if (!redisService.isAvailable()) {
      return await next();
    }
 
    try {
      // 生成缓存键
      const cacheKey = options.keyGenerator
        ? `${options.keyPrefix || 'cache'}:${options.keyGenerator(ctx)}`
        : `${options.keyPrefix || 'cache'}:${ctx.method}:${ctx.url}`;
 
      // 尝试从缓存获取
      const cachedData = await redisService.get(cacheKey);
      if (cachedData) {
        ctx.set('X-Cache', 'HIT');
        ctx.body = JSON.parse(cachedData);
        return;
      }
 
      // 执行请求
      await next();
 
      // 缓存成功的响应
      if (ctx.status === 200 && ctx.body) {
        await redisService.set(cacheKey, JSON.stringify(ctx.body), options.ttl);
        ctx.set('X-Cache', 'MISS');
      }
    } catch (error) {
      console.error('[Cache] 缓存中间件错误:', (error as Error).message);
      // 缓存失败不影响请求
      return await next();
    }
  };
}
 
/**
 * 清除缓存中间件
 * @param keyPrefix 键前缀
 */
export function clearCache(keyPrefix: string) {
  return async (ctx: any, next: any) => {
    if (redisService.isAvailable()) {
      await redisService.delPattern(`${keyPrefix}:*`);
    }
    return await next();
  };
}
 
/**
 * 常用缓存配置
 */
 
// 用户信息缓存(5 分钟)
export const userCache = createCache({
  ttl: 300,
  keyPrefix: 'user',
  keyGenerator: (ctx) => ctx.state.user?.id || 'anonymous',
});
 
// 音色列表缓存(1 小时)
export const voiceListCache = createCache({
  ttl: 3600,
  keyPrefix: 'voice:list',
});
 
// 书籍详情缓存(10 分钟)
export const bookDetailCache = createCache({
  ttl: 600,
  keyPrefix: 'book:detail',
  keyGenerator: (ctx) => ctx.params.id || ctx.query.id,
});
 
// 热门书籍缓存(5 分钟)
export const hotBooksCache = createCache({
  ttl: 300,
  keyPrefix: 'book:hot',
});
 
// 会员权益缓存(1 小时)
export const memberBenefitsCache = createCache({
  ttl: 3600,
  keyPrefix: 'member:benefits',
});