mirror of
https://gitee.com/wanwujie/sub2api
synced 2026-04-18 13:54:46 +08:00
feat: set last 24 hours as default date range in DashboardView
This commit is contained in:
@@ -348,12 +348,20 @@ const formatLocalDate = (date: Date): string => {
|
|||||||
return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`
|
return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`
|
||||||
}
|
}
|
||||||
|
|
||||||
const getTodayLocalDate = () => formatLocalDate(new Date())
|
const getLast24HoursRangeDates = (): { start: string; end: string } => {
|
||||||
|
const end = new Date()
|
||||||
|
const start = new Date(end.getTime() - 24 * 60 * 60 * 1000)
|
||||||
|
return {
|
||||||
|
start: formatLocalDate(start),
|
||||||
|
end: formatLocalDate(end)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Date range
|
// Date range
|
||||||
const granularity = ref<'day' | 'hour'>('hour')
|
const granularity = ref<'day' | 'hour'>('hour')
|
||||||
const startDate = ref(getTodayLocalDate())
|
const defaultRange = getLast24HoursRangeDates()
|
||||||
const endDate = ref(getTodayLocalDate())
|
const startDate = ref(defaultRange.start)
|
||||||
|
const endDate = ref(defaultRange.end)
|
||||||
|
|
||||||
// Granularity options for Select component
|
// Granularity options for Select component
|
||||||
const granularityOptions = computed(() => [
|
const granularityOptions = computed(() => [
|
||||||
|
|||||||
143
frontend/src/views/admin/__tests__/DashboardView.spec.ts
Normal file
143
frontend/src/views/admin/__tests__/DashboardView.spec.ts
Normal file
@@ -0,0 +1,143 @@
|
|||||||
|
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||||
|
import { flushPromises, mount } from '@vue/test-utils'
|
||||||
|
|
||||||
|
import type { DashboardStats } from '@/types'
|
||||||
|
import DashboardView from '../DashboardView.vue'
|
||||||
|
|
||||||
|
const { getSnapshotV2, getUserUsageTrend, getUserSpendingRanking } = vi.hoisted(() => ({
|
||||||
|
getSnapshotV2: vi.fn(),
|
||||||
|
getUserUsageTrend: vi.fn(),
|
||||||
|
getUserSpendingRanking: vi.fn()
|
||||||
|
}))
|
||||||
|
|
||||||
|
vi.mock('@/api/admin', () => ({
|
||||||
|
adminAPI: {
|
||||||
|
dashboard: {
|
||||||
|
getSnapshotV2,
|
||||||
|
getUserUsageTrend,
|
||||||
|
getUserSpendingRanking
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
|
||||||
|
vi.mock('@/stores/app', () => ({
|
||||||
|
useAppStore: () => ({
|
||||||
|
showError: vi.fn()
|
||||||
|
})
|
||||||
|
}))
|
||||||
|
|
||||||
|
vi.mock('vue-router', () => ({
|
||||||
|
useRouter: () => ({
|
||||||
|
push: vi.fn()
|
||||||
|
})
|
||||||
|
}))
|
||||||
|
|
||||||
|
vi.mock('vue-i18n', async () => {
|
||||||
|
const actual = await vi.importActual<typeof import('vue-i18n')>('vue-i18n')
|
||||||
|
return {
|
||||||
|
...actual,
|
||||||
|
useI18n: () => ({
|
||||||
|
t: (key: string) => key
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const formatLocalDate = (date: Date): string => {
|
||||||
|
const year = date.getFullYear()
|
||||||
|
const month = String(date.getMonth() + 1).padStart(2, '0')
|
||||||
|
const day = String(date.getDate()).padStart(2, '0')
|
||||||
|
return `${year}-${month}-${day}`
|
||||||
|
}
|
||||||
|
|
||||||
|
const createDashboardStats = (): DashboardStats => ({
|
||||||
|
total_users: 0,
|
||||||
|
today_new_users: 0,
|
||||||
|
active_users: 0,
|
||||||
|
hourly_active_users: 0,
|
||||||
|
stats_updated_at: '',
|
||||||
|
stats_stale: false,
|
||||||
|
total_api_keys: 0,
|
||||||
|
active_api_keys: 0,
|
||||||
|
total_accounts: 0,
|
||||||
|
normal_accounts: 0,
|
||||||
|
error_accounts: 0,
|
||||||
|
ratelimit_accounts: 0,
|
||||||
|
overload_accounts: 0,
|
||||||
|
total_requests: 0,
|
||||||
|
total_input_tokens: 0,
|
||||||
|
total_output_tokens: 0,
|
||||||
|
total_cache_creation_tokens: 0,
|
||||||
|
total_cache_read_tokens: 0,
|
||||||
|
total_tokens: 0,
|
||||||
|
total_cost: 0,
|
||||||
|
total_actual_cost: 0,
|
||||||
|
today_requests: 0,
|
||||||
|
today_input_tokens: 0,
|
||||||
|
today_output_tokens: 0,
|
||||||
|
today_cache_creation_tokens: 0,
|
||||||
|
today_cache_read_tokens: 0,
|
||||||
|
today_tokens: 0,
|
||||||
|
today_cost: 0,
|
||||||
|
today_actual_cost: 0,
|
||||||
|
average_duration_ms: 0,
|
||||||
|
uptime: 0,
|
||||||
|
rpm: 0,
|
||||||
|
tpm: 0
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('admin DashboardView', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
getSnapshotV2.mockReset()
|
||||||
|
getUserUsageTrend.mockReset()
|
||||||
|
getUserSpendingRanking.mockReset()
|
||||||
|
|
||||||
|
getSnapshotV2.mockResolvedValue({
|
||||||
|
stats: createDashboardStats(),
|
||||||
|
trend: [],
|
||||||
|
models: []
|
||||||
|
})
|
||||||
|
getUserUsageTrend.mockResolvedValue({
|
||||||
|
trend: [],
|
||||||
|
start_date: '',
|
||||||
|
end_date: '',
|
||||||
|
granularity: 'hour'
|
||||||
|
})
|
||||||
|
getUserSpendingRanking.mockResolvedValue({
|
||||||
|
ranking: [],
|
||||||
|
total_actual_cost: 0,
|
||||||
|
total_requests: 0,
|
||||||
|
total_tokens: 0,
|
||||||
|
start_date: '',
|
||||||
|
end_date: ''
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('uses last 24 hours as default dashboard range', async () => {
|
||||||
|
mount(DashboardView, {
|
||||||
|
global: {
|
||||||
|
stubs: {
|
||||||
|
AppLayout: { template: '<div><slot /></div>' },
|
||||||
|
LoadingSpinner: true,
|
||||||
|
Icon: true,
|
||||||
|
DateRangePicker: true,
|
||||||
|
Select: true,
|
||||||
|
ModelDistributionChart: true,
|
||||||
|
TokenUsageTrend: true,
|
||||||
|
Line: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
await flushPromises()
|
||||||
|
|
||||||
|
const now = new Date()
|
||||||
|
const yesterday = new Date(now.getTime() - 24 * 60 * 60 * 1000)
|
||||||
|
|
||||||
|
expect(getSnapshotV2).toHaveBeenCalledTimes(1)
|
||||||
|
expect(getSnapshotV2).toHaveBeenCalledWith(expect.objectContaining({
|
||||||
|
start_date: formatLocalDate(yesterday),
|
||||||
|
end_date: formatLocalDate(now),
|
||||||
|
granularity: 'hour'
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
})
|
||||||
Reference in New Issue
Block a user