Merge pull request #243 from tanaer/fixed

Fixed: 新增 Claude Console 账户限流机制开关
This commit is contained in:
Wesley Liddick
2025-08-13 17:49:47 +08:00
committed by GitHub
5 changed files with 27 additions and 16 deletions

View File

@@ -269,8 +269,8 @@ class Application {
} }
if (!version) { if (!version) {
try { try {
const packageJson = require('../package.json') const { version: pkgVersion } = require('../package.json')
version = packageJson.version version = pkgVersion
} catch (error) { } catch (error) {
version = '1.0.0' version = '1.0.0'
} }

View File

@@ -18,7 +18,6 @@ const crypto = require('crypto')
const fs = require('fs') const fs = require('fs')
const path = require('path') const path = require('path')
const config = require('../../config/config') const config = require('../../config/config')
const { v4: uuidv4 } = require('uuid')
const router = express.Router() const router = express.Router()
@@ -1548,7 +1547,8 @@ router.post('/claude-console-accounts', authenticateAdmin, async (req, res) => {
priority: priority || 50, priority: priority || 50,
supportedModels: supportedModels || [], supportedModels: supportedModels || [],
userAgent, userAgent,
rateLimitDuration: rateLimitDuration || 60, rateLimitDuration:
rateLimitDuration !== undefined && rateLimitDuration !== null ? rateLimitDuration : 60,
proxy, proxy,
accountType: accountType || 'shared' accountType: accountType || 'shared'
}) })
@@ -4658,7 +4658,6 @@ router.post('/openai-accounts', authenticateAdmin, async (req, res) => {
proxy, proxy,
accountType, accountType,
groupId, groupId,
dedicatedApiKeys,
rateLimitDuration, rateLimitDuration,
priority priority
} = req.body } = req.body
@@ -4675,7 +4674,8 @@ router.post('/openai-accounts', authenticateAdmin, async (req, res) => {
description: description || '', description: description || '',
accountType: accountType || 'shared', accountType: accountType || 'shared',
priority: priority || 50, priority: priority || 50,
rateLimitDuration: rateLimitDuration || 60, rateLimitDuration:
rateLimitDuration !== undefined && rateLimitDuration !== null ? rateLimitDuration : 60,
openaiOauth: openaiOauth || {}, openaiOauth: openaiOauth || {},
accountInfo: accountInfo || {}, accountInfo: accountInfo || {},
proxy: proxy?.enabled proxy: proxy?.enabled

View File

@@ -123,7 +123,9 @@ class ClaudeConsoleAccountService {
priority: parseInt(accountData.priority) || 50, priority: parseInt(accountData.priority) || 50,
supportedModels: JSON.parse(accountData.supportedModels || '[]'), supportedModels: JSON.parse(accountData.supportedModels || '[]'),
userAgent: accountData.userAgent, userAgent: accountData.userAgent,
rateLimitDuration: parseInt(accountData.rateLimitDuration) || 60, rateLimitDuration: Number.isNaN(parseInt(accountData.rateLimitDuration))
? 60
: parseInt(accountData.rateLimitDuration),
isActive: accountData.isActive === 'true', isActive: accountData.isActive === 'true',
proxy: accountData.proxy ? JSON.parse(accountData.proxy) : null, proxy: accountData.proxy ? JSON.parse(accountData.proxy) : null,
accountType: accountData.accountType || 'shared', accountType: accountData.accountType || 'shared',
@@ -172,7 +174,10 @@ class ClaudeConsoleAccountService {
accountData.supportedModels = parsedModels accountData.supportedModels = parsedModels
accountData.priority = parseInt(accountData.priority) || 50 accountData.priority = parseInt(accountData.priority) || 50
accountData.rateLimitDuration = parseInt(accountData.rateLimitDuration) || 60 {
const _parsedDuration = parseInt(accountData.rateLimitDuration)
accountData.rateLimitDuration = Number.isNaN(_parsedDuration) ? 60 : _parsedDuration
}
accountData.isActive = accountData.isActive === 'true' accountData.isActive = accountData.isActive === 'true'
accountData.schedulable = accountData.schedulable !== 'false' // 默认为true accountData.schedulable = accountData.schedulable !== 'false' // 默认为true
@@ -370,7 +375,10 @@ class ClaudeConsoleAccountService {
const minutesSinceRateLimit = (now - rateLimitedAt) / (1000 * 60) const minutesSinceRateLimit = (now - rateLimitedAt) / (1000 * 60)
// 使用账户配置的限流时间 // 使用账户配置的限流时间
const rateLimitDuration = account.rateLimitDuration || 60 const rateLimitDuration =
typeof account.rateLimitDuration === 'number' && !Number.isNaN(account.rateLimitDuration)
? account.rateLimitDuration
: 60
if (minutesSinceRateLimit >= rateLimitDuration) { if (minutesSinceRateLimit >= rateLimitDuration) {
await this.removeAccountRateLimit(accountId) await this.removeAccountRateLimit(accountId)
@@ -510,7 +518,8 @@ class ClaudeConsoleAccountService {
const rateLimitedAt = new Date(accountData.rateLimitedAt) const rateLimitedAt = new Date(accountData.rateLimitedAt)
const now = new Date() const now = new Date()
const minutesSinceRateLimit = Math.floor((now - rateLimitedAt) / (1000 * 60)) const minutesSinceRateLimit = Math.floor((now - rateLimitedAt) / (1000 * 60))
const rateLimitDuration = parseInt(accountData.rateLimitDuration) || 60 const __parsedDuration = parseInt(accountData.rateLimitDuration)
const rateLimitDuration = Number.isNaN(__parsedDuration) ? 60 : __parsedDuration
const minutesRemaining = Math.max(0, rateLimitDuration - minutesSinceRateLimit) const minutesRemaining = Math.max(0, rateLimitDuration - minutesSinceRateLimit)
return { return {

View File

@@ -3,7 +3,7 @@ const { v4: uuidv4 } = require('uuid')
const crypto = require('crypto') const crypto = require('crypto')
const config = require('../../config/config') const config = require('../../config/config')
const logger = require('../utils/logger') const logger = require('../utils/logger')
const { maskToken } = require('../utils/tokenMask') // const { maskToken } = require('../utils/tokenMask')
const { const {
logRefreshStart, logRefreshStart,
logRefreshSuccess, logRefreshSuccess,
@@ -11,7 +11,7 @@ const {
logTokenUsage, logTokenUsage,
logRefreshSkipped logRefreshSkipped
} = require('../utils/tokenRefreshLogger') } = require('../utils/tokenRefreshLogger')
const tokenRefreshService = require('./tokenRefreshService') // const tokenRefreshService = require('./tokenRefreshService')
// 加密相关常量 // 加密相关常量
const ALGORITHM = 'aes-256-cbc' const ALGORITHM = 'aes-256-cbc'
@@ -65,7 +65,7 @@ function decrypt(text) {
} }
// 刷新访问令牌 // 刷新访问令牌
async function refreshAccessToken(refreshToken) { async function refreshAccessToken(_refreshToken) {
try { try {
// OpenAI OAuth token 刷新实现 // OpenAI OAuth token 刷新实现
// TODO: 实现具体的 OpenAI OAuth token 刷新逻辑 // TODO: 实现具体的 OpenAI OAuth token 刷新逻辑
@@ -146,7 +146,10 @@ async function createAccount(accountData) {
accountType: accountData.accountType || 'shared', accountType: accountData.accountType || 'shared',
groupId: accountData.groupId || null, groupId: accountData.groupId || null,
priority: accountData.priority || 50, priority: accountData.priority || 50,
rateLimitDuration: accountData.rateLimitDuration || 60, rateLimitDuration:
accountData.rateLimitDuration !== undefined && accountData.rateLimitDuration !== null
? accountData.rateLimitDuration
: 60,
// OAuth相关字段加密存储 // OAuth相关字段加密存储
idToken: encrypt(oauthData.idToken || ''), idToken: encrypt(oauthData.idToken || ''),
accessToken: encrypt(oauthData.accessToken || ''), accessToken: encrypt(oauthData.accessToken || ''),

View File

@@ -1443,8 +1443,7 @@ const form = ref({
return '' return ''
})(), })(),
userAgent: props.account?.userAgent || '', userAgent: props.account?.userAgent || '',
enableRateLimit: enableRateLimit: props.account ? props.account.rateLimitDuration > 0 : true,
props.account?.rateLimitDuration && props.account?.rateLimitDuration > 0 ? true : false,
rateLimitDuration: props.account?.rateLimitDuration || 60, rateLimitDuration: props.account?.rateLimitDuration || 60,
// Bedrock 特定字段 // Bedrock 特定字段
accessKeyId: props.account?.accessKeyId || '', accessKeyId: props.account?.accessKeyId || '',