feat: 完善管理界面功能和用户体验

- 添加 API Key 窗口倒计时组件 (WindowCountdown)
- 添加自定义下拉菜单组件 (CustomDropdown)
- 优化账户和 API Key 管理界面交互
- 改进教程页面布局和说明文字
- 完善账户状态显示和错误处理

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
shaw
2025-08-08 14:14:46 +08:00
parent 4adc8d9695
commit 7e1a9daa6b
9 changed files with 881 additions and 190 deletions

View File

@@ -620,6 +620,7 @@ router.put('/api-keys/:keyId', authenticateAdmin, async (req, res) => {
concurrencyLimit,
rateLimitWindow,
rateLimitRequests,
isActive,
claudeAccountId,
claudeConsoleAccountId,
geminiAccountId,
@@ -726,6 +727,7 @@ router.put('/api-keys/:keyId', authenticateAdmin, async (req, res) => {
if (expiresAt === null) {
// null 表示永不过期
updates.expiresAt = null
updates.isActive = true
} else {
// 验证日期格式
const expireDate = new Date(expiresAt)
@@ -733,6 +735,7 @@ router.put('/api-keys/:keyId', authenticateAdmin, async (req, res) => {
return res.status(400).json({ error: 'Invalid expiration date format' })
}
updates.expiresAt = expiresAt
updates.isActive = expireDate > new Date() // 如果过期时间在当前时间之后,则设置为激活状态
}
}
@@ -756,6 +759,14 @@ router.put('/api-keys/:keyId', authenticateAdmin, async (req, res) => {
updates.tags = tags
}
// 处理活跃/禁用状态状态, 放在过期处理后以确保后续增加禁用key功能
if (isActive !== undefined) {
if (typeof isActive !== 'boolean') {
return res.status(400).json({ error: 'isActive must be a boolean' })
}
updates.isActive = isActive
}
await apiKeyService.updateApiKey(keyId, updates)
logger.success(`📝 Admin updated API key: ${keyId}`)