fix: 修复 Gemini 统计功能的多个问题

主要修复:
1. geminiRoutes.js 主端点现在使用统一调度器(unifiedGeminiScheduler)
   - 支持模型过滤
   - 支持账户调度控制
   - 与 Claude 保持一致的调度逻辑

2. 修复 Gemini 账户统计数据获取
   - admin 路由现在正确获取 Gemini 账户的使用统计
   - 使用 redis.getAccountUsageStats 获取真实数据
   - 与 Claude 账户统计逻辑保持一致

这些修复确保了 Gemini 服务的数据统计功能正常工作,包括:
- 请求次数统计
- Token 使用量统计
- 模型级别的统计数据
- API Keys 页面和账户管理页面的数据显示

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
shaw
2025-08-04 17:35:15 +08:00
parent 63f92bec84
commit 2ad5d02468
2 changed files with 44 additions and 13 deletions

View File

@@ -1423,13 +1423,29 @@ router.get('/gemini-accounts', authenticateAdmin, async (req, res) => {
try { try {
const accounts = await geminiAccountService.getAllAccounts(); const accounts = await geminiAccountService.getAllAccounts();
// 为Gemini账户添加空的使用统计(暂时 // 为每个账户添加使用统计信息与Claude账户相同的逻辑
const accountsWithStats = accounts.map(account => ({ const accountsWithStats = await Promise.all(accounts.map(async (account) => {
...account, try {
usage: { const usageStats = await redis.getAccountUsageStats(account.id);
daily: { tokens: 0, requests: 0, allTokens: 0 }, return {
total: { tokens: 0, requests: 0, allTokens: 0 }, ...account,
averages: { rpm: 0, tpm: 0 } usage: {
daily: usageStats.daily,
total: usageStats.total,
averages: usageStats.averages
}
};
} catch (statsError) {
logger.warn(`⚠️ Failed to get usage stats for Gemini account ${account.id}:`, statsError.message);
// 如果获取统计失败,返回空统计
return {
...account,
usage: {
daily: { tokens: 0, requests: 0, allTokens: 0 },
total: { tokens: 0, requests: 0, allTokens: 0 },
averages: { rpm: 0, tpm: 0 }
}
};
} }
})); }));

View File

@@ -66,16 +66,31 @@ router.post('/messages', authenticateApiKey, async (req, res) => {
// 生成会话哈希用于粘性会话 // 生成会话哈希用于粘性会话
const sessionHash = generateSessionHash(req); const sessionHash = generateSessionHash(req);
// 选择可用的 Gemini 账户 // 使用统一调度选择可用的 Gemini 账户(传递请求的模型)
const account = await geminiAccountService.selectAvailableAccount( let accountId;
apiKeyData.id, try {
sessionHash const schedulerResult = await unifiedGeminiScheduler.selectAccountForApiKey(
); apiKeyData,
sessionHash,
model // 传递请求的模型进行过滤
);
accountId = schedulerResult.accountId;
} catch (error) {
logger.error('Failed to select Gemini account:', error);
return res.status(503).json({
error: {
message: error.message || 'No available Gemini accounts',
type: 'service_unavailable'
}
});
}
// 获取账户详情
const account = await geminiAccountService.getAccount(accountId);
if (!account) { if (!account) {
return res.status(503).json({ return res.status(503).json({
error: { error: {
message: 'No available Gemini accounts', message: 'Selected account not found',
type: 'service_unavailable' type: 'service_unavailable'
} }
}); });