import { Injectable, HttpException, HttpStatus } from '@nestjs/common'; import { RedisService } from '../../infrastructure/redis/redis.service'; @Injectable() export class RateLimitService { constructor(private readonly redis: RedisService) {} async checkLimit( key: string, maxRequests: number, windowSeconds: number, ): Promise { const count = await this.redis.incr(key); if (count === 1) { await this.redis.expire(key, windowSeconds); } if (count > maxRequests) { throw new HttpException( { statusCode: HttpStatus.TOO_MANY_REQUESTS, message: `请求过于频繁,请${windowSeconds}秒后再试`, retryAfter: windowSeconds, }, HttpStatus.TOO_MANY_REQUESTS, ); } } async loginLimit(ip: string): Promise { const today = new Date().toISOString().split('T')[0]; await this.checkLimit(`rate:ip:${ip}:login:${today}`, 20, 1800); } async feedbackLimit(ip: string): Promise { await this.checkLimit(`rate:ip:${ip}:feedback:hourly`, 5, 3600); } async aiAnalysisLimit(userId: string): Promise { const today = new Date().toISOString().split('T')[0]; await this.checkLimit(`rate:user:${userId}:ai:daily:${today}`, 50, 86400); } async fileUploadLimit(userId: string): Promise { await this.checkLimit(`rate:user:${userId}:upload:hourly`, 10, 3600); } }