feat: 完善Gemini-Api账户相关的数据统计

This commit is contained in:
shaw
2025-11-23 22:28:26 +08:00
parent bae39d5468
commit 8863075fde
3 changed files with 42 additions and 13 deletions

View File

@@ -5842,16 +5842,32 @@ router.get('/account-usage-trend', authenticateAdmin, async (req, res) => {
}) })
] ]
} else if (group === 'gemini') { } else if (group === 'gemini') {
const geminiAccounts = await geminiAccountService.getAllAccounts() const geminiApiAccountService = require('../services/geminiApiAccountService')
accounts = geminiAccounts.map((account) => { const [geminiAccounts, geminiApiAccounts] = await Promise.all([
const id = String(account.id || '') geminiAccountService.getAllAccounts(),
const shortId = id ? id.slice(0, 8) : '未知' geminiApiAccountService.getAllAccounts(true)
return { ])
id,
name: account.name || account.email || `Gemini账号 ${shortId}`, accounts = [
platform: 'gemini' ...geminiAccounts.map((account) => {
} const id = String(account.id || '')
}) const shortId = id ? id.slice(0, 8) : '未知'
return {
id,
name: account.name || account.email || `Gemini账号 ${shortId}`,
platform: 'gemini'
}
}),
...geminiApiAccounts.map((account) => {
const id = String(account.id || '')
const shortId = id ? id.slice(0, 8) : '未知'
return {
id,
name: account.name || `Gemini-API账号 ${shortId}`,
platform: 'gemini-api'
}
})
]
} else if (group === 'droid') { } else if (group === 'droid') {
const droidAccounts = await droidAccountService.getAllAccounts() const droidAccounts = await droidAccountService.getAllAccounts()
accounts = droidAccounts.map((account) => { accounts = droidAccounts.map((account) => {

View File

@@ -11,6 +11,7 @@ const ACCOUNT_TYPE_CONFIG = {
'openai-responses': { prefix: 'openai_responses_account:' }, 'openai-responses': { prefix: 'openai_responses_account:' },
'azure-openai': { prefix: 'azure_openai:account:' }, 'azure-openai': { prefix: 'azure_openai:account:' },
gemini: { prefix: 'gemini_account:' }, gemini: { prefix: 'gemini_account:' },
'gemini-api': { prefix: 'gemini_api_account:' },
droid: { prefix: 'droid:account:' } droid: { prefix: 'droid:account:' }
} }
@@ -21,6 +22,7 @@ const ACCOUNT_TYPE_PRIORITY = [
'claude', 'claude',
'claude-console', 'claude-console',
'gemini', 'gemini',
'gemini-api',
'droid' 'droid'
] ]
@@ -31,6 +33,7 @@ const ACCOUNT_CATEGORY_MAP = {
'openai-responses': 'openai', 'openai-responses': 'openai',
'azure-openai': 'openai', 'azure-openai': 'openai',
gemini: 'gemini', gemini: 'gemini',
'gemini-api': 'gemini',
droid: 'droid' droid: 'droid'
} }
@@ -48,6 +51,9 @@ function normalizeAccountTypeKey(type) {
if (lower === 'azure_openai' || lower === 'azureopenai' || lower === 'azure-openai') { if (lower === 'azure_openai' || lower === 'azureopenai' || lower === 'azure-openai') {
return 'azure-openai' return 'azure-openai'
} }
if (lower === 'gemini_api' || lower === 'gemini-api') {
return 'gemini-api'
}
return lower return lower
} }
@@ -58,6 +64,9 @@ function sanitizeAccountIdForType(accountId, accountType) {
if (accountType === 'openai-responses') { if (accountType === 'openai-responses') {
return accountId.replace(/^responses:/, '') return accountId.replace(/^responses:/, '')
} }
if (accountType === 'gemini-api') {
return accountId.replace(/^api:/, '')
}
return accountId return accountId
} }
@@ -1322,6 +1331,9 @@ class ApiKeyService {
if (typeof rawAccountId === 'string' && rawAccountId.startsWith('responses:')) { if (typeof rawAccountId === 'string' && rawAccountId.startsWith('responses:')) {
candidateIds.add(rawAccountId.replace(/^responses:/, '')) candidateIds.add(rawAccountId.replace(/^responses:/, ''))
} }
if (typeof rawAccountId === 'string' && rawAccountId.startsWith('api:')) {
candidateIds.add(rawAccountId.replace(/^api:/, ''))
}
} }
if (candidateIds.size === 0) { if (candidateIds.size === 0) {
@@ -1346,6 +1358,7 @@ class ApiKeyService {
pushType('azure-openai') pushType('azure-openai')
} else if (lowerModel.includes('gemini')) { } else if (lowerModel.includes('gemini')) {
pushType('gemini') pushType('gemini')
pushType('gemini-api')
} else if (lowerModel.includes('claude') || lowerModel.includes('anthropic')) { } else if (lowerModel.includes('claude') || lowerModel.includes('anthropic')) {
pushType('claude') pushType('claude')
pushType('claude-console') pushType('claude-console')

View File

@@ -3814,7 +3814,7 @@ const normalizeFrontendAccountCategory = (type) => {
) { ) {
return 'openai' return 'openai'
} }
if (lower === 'gemini') { if (lower === 'gemini' || lower === 'gemini-api' || lower === 'gemini_api') {
return 'gemini' return 'gemini'
} }
if (lower === 'droid') { if (lower === 'droid') {
@@ -3843,8 +3843,8 @@ const isLikelyDeletedUsage = (info) => {
const looksLikeUuid = UUID_PATTERN.test(rawId) const looksLikeUuid = UUID_PATTERN.test(rawId)
const nameMissingOrSame = !accountName || accountName === rawId const nameMissingOrSame = !accountName || accountName === rawId
const typeUnknown = const normalizedType = normalizeFrontendAccountCategory(accountType)
!accountType || accountType === 'unknown' || ACCOUNT_TYPE_LABELS[accountType] === undefined const typeUnknown = !accountType || accountType === 'unknown' || normalizedType === 'other'
return looksLikeUuid && nameMissingOrSame && typeUnknown return looksLikeUuid && nameMissingOrSame && typeUnknown
} }