feat: 添加API Key并发控制和编辑功能

- 新增API Key并发控制功能
  - 创建API Key时可设置并发限制(0为不限制)
  - 在认证中间件中实现并发检查
  - 使用Redis原子操作确保计数准确
  - 添加自动清理机制处理异常情况

- 新增API Key编辑功能
  - 支持修改Token限制和并发限制
  - 前端添加编辑按钮和模态框
  - 后端限制只能修改指定字段

- 其他改进
  - 添加test-concurrency.js测试脚本
  - 添加详细的功能说明文档
  - 所有代码通过ESLint检查

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
shaw
2025-07-16 09:45:47 +08:00
parent efa7048018
commit 12b41ceb25
9 changed files with 654 additions and 15 deletions

View File

@@ -714,6 +714,53 @@ class RedisClient {
logger.error('❌ Redis cleanup failed:', error);
}
}
// 增加并发计数
async incrConcurrency(apiKeyId) {
try {
const key = `concurrency:${apiKeyId}`;
const count = await this.client.incr(key);
// 设置过期时间为5分钟防止计数器永远不清零
await this.client.expire(key, 300);
return count;
} catch (error) {
logger.error('❌ Failed to increment concurrency:', error);
throw error;
}
}
// 减少并发计数
async decrConcurrency(apiKeyId) {
try {
const key = `concurrency:${apiKeyId}`;
const count = await this.client.decr(key);
// 如果计数降到0或以下删除键
if (count <= 0) {
await this.client.del(key);
return 0;
}
return count;
} catch (error) {
logger.error('❌ Failed to decrement concurrency:', error);
throw error;
}
}
// 获取当前并发数
async getConcurrency(apiKeyId) {
try {
const key = `concurrency:${apiKeyId}`;
const count = await this.client.get(key);
return parseInt(count || 0);
} catch (error) {
logger.error('❌ Failed to get concurrency:', error);
return 0;
}
}
}
module.exports = new RedisClient();