diff --git a/src/routes/openaiRoutes.js b/src/routes/openaiRoutes.js index cf5a08c6..af1a482a 100644 --- a/src/routes/openaiRoutes.js +++ b/src/routes/openaiRoutes.js @@ -68,14 +68,14 @@ router.post('/responses', authenticateApiKey, async (req, res) => { // 从请求体中提取模型和流式标志 let requestedModel = req.body?.model || null - + // 如果模型是 gpt-5 开头且后面还有内容(如 gpt-5-2025-08-07),则覆盖为 gpt-5 if (requestedModel && requestedModel.startsWith('gpt-5-') && requestedModel !== 'gpt-5') { logger.info(`📝 Model ${requestedModel} detected, normalizing to gpt-5 for Codex API`) requestedModel = 'gpt-5' req.body.model = 'gpt-5' // 同时更新请求体中的模型 } - + const isStream = req.body?.stream !== false // 默认为流式(兼容现有行为) // 判断是否为 Codex CLI 的请求 diff --git a/src/services/unifiedGeminiScheduler.js b/src/services/unifiedGeminiScheduler.js index 8ff6d5e5..face2c81 100644 --- a/src/services/unifiedGeminiScheduler.js +++ b/src/services/unifiedGeminiScheduler.js @@ -38,6 +38,8 @@ class UnifiedGeminiScheduler { logger.info( `🎯 Using bound dedicated Gemini account: ${boundAccount.name} (${apiKeyData.geminiAccountId}) for API key ${apiKeyData.name}` ) + // 更新账户的最后使用时间 + await geminiAccountService.markAccountUsed(apiKeyData.geminiAccountId) return { accountId: apiKeyData.geminiAccountId, accountType: 'gemini' @@ -62,6 +64,8 @@ class UnifiedGeminiScheduler { logger.info( `🎯 Using sticky session account: ${mappedAccount.accountId} (${mappedAccount.accountType}) for session ${sessionHash}` ) + // 更新账户的最后使用时间 + await geminiAccountService.markAccountUsed(mappedAccount.accountId) return mappedAccount } else { logger.warn( @@ -108,6 +112,9 @@ class UnifiedGeminiScheduler { `🎯 Selected account: ${selectedAccount.name} (${selectedAccount.accountId}, ${selectedAccount.accountType}) with priority ${selectedAccount.priority} for API key ${apiKeyData.name}` ) + // 更新账户的最后使用时间 + await geminiAccountService.markAccountUsed(selectedAccount.accountId) + return { accountId: selectedAccount.accountId, accountType: selectedAccount.accountType @@ -378,6 +385,8 @@ class UnifiedGeminiScheduler { logger.info( `🎯 Using sticky session account from group: ${mappedAccount.accountId} (${mappedAccount.accountType}) for session ${sessionHash}` ) + // 更新账户的最后使用时间 + await geminiAccountService.markAccountUsed(mappedAccount.accountId) return mappedAccount } } @@ -473,6 +482,9 @@ class UnifiedGeminiScheduler { `🎯 Selected account from Gemini group ${group.name}: ${selectedAccount.name} (${selectedAccount.accountId}, ${selectedAccount.accountType}) with priority ${selectedAccount.priority}` ) + // 更新账户的最后使用时间 + await geminiAccountService.markAccountUsed(selectedAccount.accountId) + return { accountId: selectedAccount.accountId, accountType: selectedAccount.accountType diff --git a/src/services/unifiedOpenAIScheduler.js b/src/services/unifiedOpenAIScheduler.js index cd93cb59..0c8b89a5 100644 --- a/src/services/unifiedOpenAIScheduler.js +++ b/src/services/unifiedOpenAIScheduler.js @@ -38,6 +38,8 @@ class UnifiedOpenAIScheduler { logger.info( `🎯 Using bound dedicated OpenAI account: ${boundAccount.name} (${apiKeyData.openaiAccountId}) for API key ${apiKeyData.name}` ) + // 更新账户的最后使用时间 + await openaiAccountService.recordUsage(apiKeyData.openaiAccountId, 0) return { accountId: apiKeyData.openaiAccountId, accountType: 'openai' @@ -62,6 +64,8 @@ class UnifiedOpenAIScheduler { logger.info( `🎯 Using sticky session account: ${mappedAccount.accountId} (${mappedAccount.accountType}) for session ${sessionHash}` ) + // 更新账户的最后使用时间 + await openaiAccountService.recordUsage(mappedAccount.accountId, 0) return mappedAccount } else { logger.warn( @@ -108,6 +112,9 @@ class UnifiedOpenAIScheduler { `🎯 Selected account: ${selectedAccount.name} (${selectedAccount.accountId}, ${selectedAccount.accountType}) with priority ${selectedAccount.priority} for API key ${apiKeyData.name}` ) + // 更新账户的最后使用时间 + await openaiAccountService.recordUsage(selectedAccount.accountId, 0) + return { accountId: selectedAccount.accountId, accountType: selectedAccount.accountType @@ -372,6 +379,8 @@ class UnifiedOpenAIScheduler { logger.info( `🎯 Using sticky session account from group: ${mappedAccount.accountId} (${mappedAccount.accountType})` ) + // 更新账户的最后使用时间 + await openaiAccountService.recordUsage(mappedAccount.accountId, 0) return mappedAccount } } @@ -459,6 +468,9 @@ class UnifiedOpenAIScheduler { `🎯 Selected account from group: ${selectedAccount.name} (${selectedAccount.accountId}) with priority ${selectedAccount.priority}` ) + // 更新账户的最后使用时间 + await openaiAccountService.recordUsage(selectedAccount.accountId, 0) + return { accountId: selectedAccount.accountId, accountType: selectedAccount.accountType diff --git a/web/admin-spa/src/components/accounts/AccountForm.vue b/web/admin-spa/src/components/accounts/AccountForm.vue index 86faf2de..f7ab22d0 100644 --- a/web/admin-spa/src/components/accounts/AccountForm.vue +++ b/web/admin-spa/src/components/accounts/AccountForm.vue @@ -355,8 +355,8 @@ @@ -529,8 +529,8 @@ @@ -1115,8 +1115,8 @@ @@ -1234,8 +1234,8 @@ diff --git a/web/admin-spa/src/components/accounts/OAuthFlow.vue b/web/admin-spa/src/components/accounts/OAuthFlow.vue index fa798518..f688f988 100644 --- a/web/admin-spa/src/components/accounts/OAuthFlow.vue +++ b/web/admin-spa/src/components/accounts/OAuthFlow.vue @@ -325,6 +325,17 @@
请在新标签页中打开授权链接,登录您的 OpenAI 账户并授权。
++ + 重要提示:授权后页面可能会加载较长时间,请耐心等待。 +
++ 当浏览器地址栏变为 + http://localhost:1455/... + 开头时,表示授权已完成。 +
+@@ -345,27 +356,40 @@ 3
输入 Authorization Code
+输入授权链接或 Code
- 授权完成后,页面会显示一个 - Authorization Code,请将其复制并粘贴到下方输入框: + 授权完成后,当页面地址变为 + http://localhost:1455/... 时:
- - 请粘贴从OpenAI页面复制的Authorization Code -
++ + 提示:您可以直接复制整个链接或仅复制 code + 参数值,系统会自动识别。 +
++ • 完整链接示例:http://localhost:1455/auth/callback?code=ac_4hm8... +
++ • 仅 Code 示例:ac_4hm8iqmx9A2fzMy_cwye7U3W7... +
+