mirror of
https://github.com/Wei-Shaw/claude-relay-service.git
synced 2026-01-23 19:18:59 +00:00
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:
@@ -688,10 +688,12 @@ router.post('/api-keys/batch', authenticateAdmin, async (req, res) => {
|
|||||||
claudeConsoleAccountId,
|
claudeConsoleAccountId,
|
||||||
geminiAccountId,
|
geminiAccountId,
|
||||||
openaiAccountId,
|
openaiAccountId,
|
||||||
|
bedrockAccountId,
|
||||||
permissions,
|
permissions,
|
||||||
concurrencyLimit,
|
concurrencyLimit,
|
||||||
rateLimitWindow,
|
rateLimitWindow,
|
||||||
rateLimitRequests,
|
rateLimitRequests,
|
||||||
|
rateLimitCost,
|
||||||
enableModelRestriction,
|
enableModelRestriction,
|
||||||
restrictedModels,
|
restrictedModels,
|
||||||
enableClientRestriction,
|
enableClientRestriction,
|
||||||
@@ -735,10 +737,12 @@ router.post('/api-keys/batch', authenticateAdmin, async (req, res) => {
|
|||||||
claudeConsoleAccountId,
|
claudeConsoleAccountId,
|
||||||
geminiAccountId,
|
geminiAccountId,
|
||||||
openaiAccountId,
|
openaiAccountId,
|
||||||
|
bedrockAccountId,
|
||||||
permissions,
|
permissions,
|
||||||
concurrencyLimit,
|
concurrencyLimit,
|
||||||
rateLimitWindow,
|
rateLimitWindow,
|
||||||
rateLimitRequests,
|
rateLimitRequests,
|
||||||
|
rateLimitCost,
|
||||||
enableModelRestriction,
|
enableModelRestriction,
|
||||||
restrictedModels,
|
restrictedModels,
|
||||||
enableClientRestriction,
|
enableClientRestriction,
|
||||||
|
|||||||
@@ -1200,9 +1200,13 @@ class ClaudeAccountService {
|
|||||||
accountData.schedulable = 'true'
|
accountData.schedulable = 'true'
|
||||||
delete accountData.rateLimitAutoStopped
|
delete accountData.rateLimitAutoStopped
|
||||||
logger.info(`✅ Auto-resuming scheduling for account ${accountId} after rate limit cleared`)
|
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 {
|
} 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)
|
await redis.setClaudeAccount(accountId, accountData)
|
||||||
|
|
||||||
|
|||||||
@@ -585,7 +585,10 @@
|
|||||||
<div
|
<div
|
||||||
:class="[
|
:class="[
|
||||||
'h-2 rounded-full transition-all duration-300',
|
'h-2 rounded-full transition-all duration-300',
|
||||||
getSessionProgressBarClass(account.sessionWindow.sessionWindowStatus)
|
getSessionProgressBarClass(
|
||||||
|
account.sessionWindow.sessionWindowStatus,
|
||||||
|
account
|
||||||
|
)
|
||||||
]"
|
]"
|
||||||
:style="{ width: account.sessionWindow.progress + '%' }"
|
:style="{ width: account.sessionWindow.progress + '%' }"
|
||||||
/>
|
/>
|
||||||
@@ -872,7 +875,7 @@
|
|||||||
<div
|
<div
|
||||||
:class="[
|
:class="[
|
||||||
'h-full transition-all duration-300',
|
'h-full transition-all duration-300',
|
||||||
getSessionProgressBarClass(account.sessionWindow.sessionWindowStatus)
|
getSessionProgressBarClass(account.sessionWindow.sessionWindowStatus, account)
|
||||||
]"
|
]"
|
||||||
:style="{ width: account.sessionWindow.progress + '%' }"
|
:style="{ width: account.sessionWindow.progress + '%' }"
|
||||||
/>
|
/>
|
||||||
@@ -2009,13 +2012,26 @@ const formatRelativeTime = (dateString) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 获取会话窗口进度条的样式类
|
// 获取会话窗口进度条的样式类
|
||||||
const getSessionProgressBarClass = (status) => {
|
const getSessionProgressBarClass = (status, account = null) => {
|
||||||
// 根据状态返回不同的颜色类,包含防御性检查
|
// 根据状态返回不同的颜色类,包含防御性检查
|
||||||
if (!status) {
|
if (!status) {
|
||||||
// 无状态信息时默认为蓝色
|
// 无状态信息时默认为蓝色
|
||||||
return 'bg-gradient-to-r from-blue-500 to-indigo-600'
|
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()
|
const normalizedStatus = String(status).toLowerCase()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user