Preserve usage provider identity

This commit is contained in:
fawney19
2026-05-20 20:56:36 +08:00
parent c972bbd397
commit 57910f906d
21 changed files with 340 additions and 104 deletions

View File

@@ -71,7 +71,9 @@ export interface UsageByUser {
}
export interface UsageByProvider {
provider_id: string
provider_id?: string | null
provider_key?: string
provider_identity_source?: 'provider_id' | 'legacy_name'
provider: string
request_count: number
total_tokens: number

View File

@@ -46,7 +46,7 @@
</TableRow>
<TableRow
v-for="provider in data"
:key="provider.provider"
:key="provider.providerKey ?? provider.providerId ?? provider.provider"
>
<TableCell class="font-medium py-2 px-2">
{{ provider.provider }}

View File

@@ -129,6 +129,9 @@ describe('useUsageData', () => {
])
getUsageByProviderMock.mockResolvedValueOnce([
{
provider_id: 'provider-openai',
provider_key: 'provider-openai',
provider_identity_source: 'provider_id',
provider: 'OpenAI',
request_count: 3,
total_tokens: 300,
@@ -159,6 +162,11 @@ describe('useUsageData', () => {
})
expect(modelStats.value).toHaveLength(1)
expect(providerStats.value).toHaveLength(1)
expect(providerStats.value[0]).toMatchObject({
providerId: 'provider-openai',
providerKey: 'provider-openai',
providerIdentitySource: 'provider_id',
})
expect(apiFormatStats.value).toHaveLength(1)
expect(availableModels.value).toEqual(['gpt-5'])
expect(availableProviders.value).toEqual(['OpenAI'])

View File

@@ -173,6 +173,9 @@ export function useUsageData(options: UseUsageDataOptions) {
const visibleProviderData = providerData.filter(item => isUsageProviderVisible(item.provider))
providerStats.value = visibleProviderData.map(item => ({
providerId: item.provider_id,
providerKey: item.provider_key,
providerIdentitySource: item.provider_identity_source,
provider: item.provider,
requests: item.request_count,
totalTokens: item.total_tokens || 0,

View File

@@ -41,6 +41,9 @@ export interface EnhancedModelStatsItem extends ModelStatsItem {
// 提供商统计
export interface ProviderStatsItem {
providerId?: string | null
providerKey?: string
providerIdentitySource?: 'provider_id' | 'legacy_name'
provider: string
requests: number
totalTokens: number

View File

@@ -727,7 +727,7 @@ const navigation = computed(() => {
items: [
{ name: '钱包中心', href: '/dashboard/wallet', icon: Wallet },
{ name: '套餐中心', href: '/dashboard/billing', icon: Package },
{ name: '我的邀请', href: '/dashboard/referral', icon: Gift },
...(moduleStore.isActive('referral') ? [{ name: '我的邀请', href: '/dashboard/referral', icon: Gift }] : []),
{ name: '使用统计', href: '/dashboard/usage', icon: BarChart3 },
]
}
@@ -749,19 +749,21 @@ const navigation = computed(() => {
Puzzle,
Server,
SlidersHorizontal,
CreditCard,
Gift,
}
// 添加模块菜单项(按 admin_menu_order 排序,只显示已激活的)
const moduleMenuItems = Object.values(moduleStore.modules)
.filter(m => m.active && m.admin_route && m.admin_menu_group === 'system')
.sort((a, b) => a.admin_menu_order - b.admin_menu_order)
.map(m => ({
name: m.display_name,
href: m.admin_route ?? '',
icon: iconMap[m.admin_menu_icon || ''] || Puzzle
}))
const activeModuleItems = (group: string) =>
Object.values(moduleStore.modules)
.filter(m => m.active && m.admin_route && m.admin_menu_group === group)
.sort((a, b) => a.admin_menu_order - b.admin_menu_order)
.map(m => ({
name: m.display_name,
href: m.admin_route ?? '',
icon: iconMap[m.admin_menu_icon || ''] || Puzzle
}))
systemItems.push(...moduleMenuItems)
systemItems.push(...activeModuleItems('system'))
// 模块管理和系统设置放在最后
systemItems.push({ name: '模块管理', href: '/admin/modules', icon: Puzzle })
@@ -788,9 +790,8 @@ const navigation = computed(() => {
{ name: '号池管理', href: '/admin/pool', icon: Database },
{ name: '独立密钥', href: '/admin/keys', icon: Key },
{ name: '钱包管理', href: '/admin/wallets', icon: Wallet },
{ name: '支付配置', href: '/admin/payment-gateways', icon: CreditCard },
{ name: '套餐管理', href: '/admin/billing-plans', icon: Package },
{ name: '邀请返利', href: '/admin/referrals', icon: Gift },
...activeModuleItems('management'),
{ name: '异步任务', href: '/admin/async-tasks', icon: Zap },
{ name: '使用记录', href: '/admin/usage', icon: BarChart3 },
]