fix(admin): polish spending ranking and usage defaults

This commit is contained in:
Peter
2026-03-16 00:17:47 +08:00
parent 6da5fa01b9
commit 8147866c09
10 changed files with 148 additions and 23 deletions

View File

@@ -5,6 +5,14 @@ import ModelDistributionChart from '../ModelDistributionChart.vue'
const messages: Record<string, string> = {
'admin.dashboard.modelDistribution': 'Model Distribution',
'admin.dashboard.spendingRankingTitle': 'User Spending Ranking',
'admin.dashboard.viewModelDistribution': 'Model Distribution',
'admin.dashboard.viewSpendingRanking': 'User Spending Ranking',
'admin.dashboard.spendingRankingUser': 'User',
'admin.dashboard.spendingRankingRequests': 'Requests',
'admin.dashboard.spendingRankingTokens': 'Tokens',
'admin.dashboard.spendingRankingSpend': 'Spend',
'admin.dashboard.spendingRankingOther': 'Others',
'admin.dashboard.model': 'Model',
'admin.dashboard.requests': 'Requests',
'admin.dashboard.tokens': 'Tokens',
@@ -13,6 +21,7 @@ const messages: Record<string, string> = {
'admin.dashboard.metricTokens': 'By Tokens',
'admin.dashboard.metricActualCost': 'By Actual Cost',
'admin.dashboard.noDataAvailable': 'No data available',
'admin.redeem.userPrefix': 'User #{id}',
}
vi.mock('vue-i18n', async () => {
@@ -116,4 +125,47 @@ describe('ModelDistributionChart', () => {
})
expect(label).toBe('model-b: $1.40 (87.5%)')
})
it('renders Others in the spending ranking table and uses a dedicated chart color', async () => {
const wrapper = mount(ModelDistributionChart, {
props: {
modelStats: [],
enableRankingView: true,
rankingItems: [
{ user_id: 1, email: 'alpha@example.com', actual_cost: 12, requests: 10, tokens: 1000 },
{ user_id: 2, email: 'beta@example.com', actual_cost: 8, requests: 6, tokens: 600 },
],
rankingTotalActualCost: 30,
rankingTotalRequests: 20,
rankingTotalTokens: 2000,
},
global: {
stubs: {
LoadingSpinner: true,
},
},
})
const rankingButton = wrapper.findAll('button').find((button) => button.text() === 'User Spending Ranking')
expect(rankingButton).toBeTruthy()
await rankingButton!.trigger('click')
const chartData = JSON.parse(wrapper.find('.chart-data').text())
expect(chartData.labels).toEqual([
'#1 alpha@example.com',
'#2 beta@example.com',
'Others',
])
expect(chartData.datasets[0].data).toEqual([12, 8, 10])
expect(chartData.datasets[0].backgroundColor[0]).toBe('#3b82f6')
expect(chartData.datasets[0].backgroundColor[2]).toBe('#94a3b8')
expect(chartData.datasets[0].backgroundColor[2]).not.toBe(chartData.datasets[0].backgroundColor[0])
const rows = wrapper.findAll('tbody tr')
expect(rows).toHaveLength(3)
expect(rows[2].text()).toContain('Others')
expect(rows[2].text()).toContain('4')
expect(rows[2].text()).toContain('400')
expect(rows[2].text()).toContain('$10.00')
})
})