mirror of
https://github.com/Wei-Shaw/claude-relay-service.git
synced 2026-01-22 16:43:35 +00:00
feat: 实现 API Keys 批量删除后端功能
- 新增 DELETE /admin/api-keys/batch 端点
- 支持批量删除最多100个API Keys
- 完整的请求参数验证(数组格式、数量限制、ID有效性)
- 逐个删除并记录成功/失败状态
- 详细的错误信息和日志记录
- 返回成功/失败统计结果
请求格式: { "keyIds": ["key1", "key2", ...] }
响应格式: { "success": true, "data": { "successCount": 2, "failedCount": 0, "errors": [] } }
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -814,6 +814,95 @@ router.delete('/api-keys/:keyId', authenticateAdmin, async (req, res) => {
|
||||
}
|
||||
})
|
||||
|
||||
// 批量删除API Keys
|
||||
router.delete('/api-keys/batch', authenticateAdmin, async (req, res) => {
|
||||
try {
|
||||
const { keyIds } = req.body
|
||||
|
||||
// 参数验证
|
||||
if (!keyIds || !Array.isArray(keyIds) || keyIds.length === 0) {
|
||||
return res.status(400).json({
|
||||
error: 'Invalid request',
|
||||
message: 'keyIds 必须是一个非空数组'
|
||||
})
|
||||
}
|
||||
|
||||
if (keyIds.length > 100) {
|
||||
return res.status(400).json({
|
||||
error: 'Too many keys',
|
||||
message: '每次最多只能删除100个API Keys'
|
||||
})
|
||||
}
|
||||
|
||||
// 验证keyIds格式
|
||||
const invalidKeys = keyIds.filter((id) => !id || typeof id !== 'string')
|
||||
if (invalidKeys.length > 0) {
|
||||
return res.status(400).json({
|
||||
error: 'Invalid key IDs',
|
||||
message: '包含无效的API Key ID'
|
||||
})
|
||||
}
|
||||
|
||||
logger.info(`🗑️ Admin attempting batch delete of ${keyIds.length} API keys`)
|
||||
|
||||
const results = {
|
||||
successCount: 0,
|
||||
failedCount: 0,
|
||||
errors: []
|
||||
}
|
||||
|
||||
// 逐个删除,记录成功和失败情况
|
||||
for (const keyId of keyIds) {
|
||||
try {
|
||||
// 检查API Key是否存在
|
||||
const apiKey = await apiKeyService.getApiKey(keyId)
|
||||
if (!apiKey) {
|
||||
results.failedCount++
|
||||
results.errors.push({ keyId, error: 'API Key 不存在' })
|
||||
continue
|
||||
}
|
||||
|
||||
// 执行删除
|
||||
await apiKeyService.deleteApiKey(keyId)
|
||||
results.successCount++
|
||||
|
||||
logger.success(`✅ Batch delete: API key ${keyId} deleted successfully`)
|
||||
} catch (error) {
|
||||
results.failedCount++
|
||||
results.errors.push({
|
||||
keyId,
|
||||
error: error.message || '删除失败'
|
||||
})
|
||||
|
||||
logger.error(`❌ Batch delete failed for key ${keyId}:`, error)
|
||||
}
|
||||
}
|
||||
|
||||
// 记录批量删除结果
|
||||
if (results.successCount > 0) {
|
||||
logger.success(
|
||||
`🎉 Batch delete completed: ${results.successCount} successful, ${results.failedCount} failed`
|
||||
)
|
||||
} else {
|
||||
logger.warn(
|
||||
`⚠️ Batch delete completed with no successful deletions: ${results.failedCount} failed`
|
||||
)
|
||||
}
|
||||
|
||||
return res.json({
|
||||
success: true,
|
||||
message: `批量删除完成`,
|
||||
data: results
|
||||
})
|
||||
} catch (error) {
|
||||
logger.error('❌ Failed to batch delete API keys:', error)
|
||||
return res.status(500).json({
|
||||
error: 'Batch delete failed',
|
||||
message: error.message
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
// 👥 账户分组管理
|
||||
|
||||
// 创建账户分组
|
||||
|
||||
Reference in New Issue
Block a user