P8 平台轻量化改造 + SSG修复 + 编程导师 + 文档完善
- Prisma: Tool 模型加 affiliateLink;免费用户沙盒 10→5 次/日 - 后端: Tools API + /admin/tools CRUD 5 端点;Practices 完整模块 - 导航: 主菜单隐藏企业版/社区(URL 可访问) - 首页: 重定位为 AI 工具指南;新增精选工具区块;Feature 重写 - 工具页: affiliateLink 绿色推荐 Badge - SSG 修复: config.ts 构建时直连 localhost:4000,页面 108→127 - 沙盒: 新增编程导师场景(苏格拉底教学法) - 练习系统: Practices 多场景练习(含结构化评分) - 技能广场: 6 个付费 Skill(标题大师/回款助手等) - 管理后台: Models/Posts/Practices CRUD 页面 - 文档: README + progress.md 全面更新;AGENTS.md 同步定位 - 清理: .env.example 移除;tsbuildinfo gitignore
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
import { ThrottlerStorage } from '@nestjs/throttler';
|
||||
import Redis from 'ioredis';
|
||||
|
||||
export class RedisThrottlerStorage implements ThrottlerStorage {
|
||||
private redis: Redis;
|
||||
|
||||
constructor() {
|
||||
this.redis = new Redis({
|
||||
host: process.env.REDIS_HOST || 'localhost',
|
||||
port: parseInt(process.env.REDIS_PORT || '6379', 10),
|
||||
password: process.env.REDIS_PASSWORD || undefined,
|
||||
keyPrefix: 'throttle:',
|
||||
});
|
||||
}
|
||||
|
||||
async increment(key: string, ttl: number, limit: number, blockDuration: number, throttlerName: string): Promise<{
|
||||
totalHits: number;
|
||||
timeToExpire: number;
|
||||
isBlocked: boolean;
|
||||
timeToBlockExpire: number;
|
||||
}> {
|
||||
const redisKey = `throttle:${throttlerName}:${key}`;
|
||||
const total = await this.redis.incr(redisKey);
|
||||
if (total === 1) {
|
||||
await this.redis.pexpire(redisKey, ttl);
|
||||
}
|
||||
const ttlRemaining = await this.redis.pttl(redisKey);
|
||||
return {
|
||||
totalHits: total,
|
||||
timeToExpire: Math.max(0, Math.ceil(ttlRemaining / 1000)),
|
||||
isBlocked: total > limit,
|
||||
timeToBlockExpire: total > limit ? Math.max(0, Math.ceil(ttlRemaining / 1000)) : 0,
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user