feat: 优化API Key批量创建和账户限流状态显示

- 添加 bedrockAccountId 和 rateLimitCost 字段到批量创建 API Key 功能
- 格式化 claudeAccountService 中的日志输出
- 改进账户视图中会话进度条样式,限流状态显示红色

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
shaw
2025-09-14 11:59:09 +08:00
parent aabf909c61
commit 158a9b9a31
3 changed files with 29 additions and 5 deletions

View File

@@ -688,10 +688,12 @@ router.post('/api-keys/batch', authenticateAdmin, async (req, res) => {
claudeConsoleAccountId,
geminiAccountId,
openaiAccountId,
bedrockAccountId,
permissions,
concurrencyLimit,
rateLimitWindow,
rateLimitRequests,
rateLimitCost,
enableModelRestriction,
restrictedModels,
enableClientRestriction,
@@ -735,10 +737,12 @@ router.post('/api-keys/batch', authenticateAdmin, async (req, res) => {
claudeConsoleAccountId,
geminiAccountId,
openaiAccountId,
bedrockAccountId,
permissions,
concurrencyLimit,
rateLimitWindow,
rateLimitRequests,
rateLimitCost,
enableModelRestriction,
restrictedModels,
enableClientRestriction,

View File

@@ -1200,9 +1200,13 @@ class ClaudeAccountService {
accountData.schedulable = 'true'
delete accountData.rateLimitAutoStopped
logger.info(`✅ Auto-resuming scheduling for account ${accountId} after rate limit cleared`)
logger.info(`📊 Account ${accountId} state after recovery: schedulable=${accountData.schedulable}`)
logger.info(
`📊 Account ${accountId} state after recovery: schedulable=${accountData.schedulable}`
)
} else {
logger.info(` Account ${accountId} did not need auto-resume: autoStopped=${accountData.rateLimitAutoStopped}, schedulable=${accountData.schedulable}`)
logger.info(
` Account ${accountId} did not need auto-resume: autoStopped=${accountData.rateLimitAutoStopped}, schedulable=${accountData.schedulable}`
)
}
await redis.setClaudeAccount(accountId, accountData)

View File

@@ -585,7 +585,10 @@
<div
:class="[
'h-2 rounded-full transition-all duration-300',
getSessionProgressBarClass(account.sessionWindow.sessionWindowStatus)
getSessionProgressBarClass(
account.sessionWindow.sessionWindowStatus,
account
)
]"
:style="{ width: account.sessionWindow.progress + '%' }"
/>
@@ -872,7 +875,7 @@
<div
:class="[
'h-full transition-all duration-300',
getSessionProgressBarClass(account.sessionWindow.sessionWindowStatus)
getSessionProgressBarClass(account.sessionWindow.sessionWindowStatus, account)
]"
:style="{ width: account.sessionWindow.progress + '%' }"
/>
@@ -2009,13 +2012,26 @@ const formatRelativeTime = (dateString) => {
}
// 获取会话窗口进度条的样式类
const getSessionProgressBarClass = (status) => {
const getSessionProgressBarClass = (status, account = null) => {
// 根据状态返回不同的颜色类,包含防御性检查
if (!status) {
// 无状态信息时默认为蓝色
return 'bg-gradient-to-r from-blue-500 to-indigo-600'
}
// 检查账号是否处于限流状态
const isRateLimited =
account &&
(account.isRateLimited ||
account.status === 'rate_limited' ||
(account.rateLimitStatus && account.rateLimitStatus.isRateLimited) ||
account.rateLimitStatus === 'limited')
// 如果账号处于限流状态,显示红色
if (isRateLimited) {
return 'bg-gradient-to-r from-red-500 to-red-600'
}
// 转换为小写进行比较,避免大小写问题
const normalizedStatus = String(status).toLowerCase()