添加claude账号维度计算token费用

This commit is contained in:
leslie
2025-07-25 21:27:17 +08:00
parent 4325de90e1
commit 5522967792
5 changed files with 304 additions and 9 deletions

View File

@@ -791,6 +791,73 @@ router.post('/gemini-accounts/:accountId/refresh', authenticateAdmin, async (req
}
});
// 📊 账户使用统计
// 获取所有账户的使用统计
router.get('/accounts/usage-stats', authenticateAdmin, async (req, res) => {
try {
const accountsStats = await redis.getAllAccountsUsageStats();
res.json({
success: true,
data: accountsStats,
summary: {
totalAccounts: accountsStats.length,
activeToday: accountsStats.filter(account => account.daily.requests > 0).length,
totalDailyTokens: accountsStats.reduce((sum, account) => sum + (account.daily.allTokens || 0), 0),
totalDailyRequests: accountsStats.reduce((sum, account) => sum + (account.daily.requests || 0), 0)
},
timestamp: new Date().toISOString()
});
} catch (error) {
logger.error('❌ Failed to get accounts usage stats:', error);
res.status(500).json({
success: false,
error: 'Failed to get accounts usage stats',
message: error.message
});
}
});
// 获取单个账户的使用统计
router.get('/accounts/:accountId/usage-stats', authenticateAdmin, async (req, res) => {
try {
const { accountId } = req.params;
const accountStats = await redis.getAccountUsageStats(accountId);
// 获取账户基本信息
const accountData = await claudeAccountService.getAccount(accountId);
if (!accountData) {
return res.status(404).json({
success: false,
error: 'Account not found'
});
}
res.json({
success: true,
data: {
...accountStats,
accountInfo: {
name: accountData.name,
email: accountData.email,
status: accountData.status,
isActive: accountData.isActive,
createdAt: accountData.createdAt
}
},
timestamp: new Date().toISOString()
});
} catch (error) {
logger.error('❌ Failed to get account usage stats:', error);
res.status(500).json({
success: false,
error: 'Failed to get account usage stats',
message: error.message
});
}
});
// 📊 系统统计
// 获取系统概览

View File

@@ -68,8 +68,9 @@ async function handleMessagesRequest(req, res) {
const cacheReadTokens = usageData.cache_read_input_tokens || 0;
const model = usageData.model || 'unknown';
// 记录真实的token使用量包含模型信息和所有4种token
apiKeyService.recordUsage(req.apiKey.id, inputTokens, outputTokens, cacheCreateTokens, cacheReadTokens, model).catch(error => {
// 记录真实的token使用量包含模型信息和所有4种token以及账户ID
const accountId = usageData.accountId;
apiKeyService.recordUsage(req.apiKey.id, inputTokens, outputTokens, cacheCreateTokens, cacheReadTokens, model, accountId).catch(error => {
logger.error('❌ Failed to record stream usage:', error);
});
@@ -135,8 +136,9 @@ async function handleMessagesRequest(req, res) {
const cacheReadTokens = jsonData.usage.cache_read_input_tokens || 0;
const model = jsonData.model || req.body.model || 'unknown';
// 记录真实的token使用量包含模型信息和所有4种token
await apiKeyService.recordUsage(req.apiKey.id, inputTokens, outputTokens, cacheCreateTokens, cacheReadTokens, model);
// 记录真实的token使用量包含模型信息和所有4种token以及账户ID
const accountId = response.accountId;
await apiKeyService.recordUsage(req.apiKey.id, inputTokens, outputTokens, cacheCreateTokens, cacheReadTokens, model, accountId);
// 更新时间窗口内的token计数
if (req.rateLimitInfo) {