mirror of
https://github.com/fawney19/Aether.git
synced 2026-10-07 01:47:47 +08:00
feat(usage): expose request timing details
This commit is contained in:
@@ -3,6 +3,7 @@ import { ref } from 'vue'
|
||||
|
||||
const {
|
||||
getAllUsageRecordsMock,
|
||||
getAllUsageRecordTotalMock,
|
||||
getUsageStatsMock,
|
||||
getUsageByModelMock,
|
||||
getUsageByProviderMock,
|
||||
@@ -10,6 +11,7 @@ const {
|
||||
meGetUsageMock,
|
||||
} = vi.hoisted(() => ({
|
||||
getAllUsageRecordsMock: vi.fn(),
|
||||
getAllUsageRecordTotalMock: vi.fn(),
|
||||
getUsageStatsMock: vi.fn(),
|
||||
getUsageByModelMock: vi.fn(),
|
||||
getUsageByProviderMock: vi.fn(),
|
||||
@@ -20,6 +22,7 @@ const {
|
||||
vi.mock('@/api/usage', () => ({
|
||||
usageApi: {
|
||||
getAllUsageRecords: getAllUsageRecordsMock,
|
||||
getAllUsageRecordTotal: getAllUsageRecordTotalMock,
|
||||
getUsageStats: getUsageStatsMock,
|
||||
getUsageByModel: getUsageByModelMock,
|
||||
getUsageByProvider: getUsageByProviderMock,
|
||||
@@ -72,6 +75,7 @@ describe('useUsageData', () => {
|
||||
limit: 20,
|
||||
offset: 0,
|
||||
})
|
||||
getAllUsageRecordTotalMock.mockResolvedValue(1)
|
||||
getUsageStatsMock.mockRejectedValue({
|
||||
response: { status: 500 },
|
||||
message: 'stats failed',
|
||||
@@ -143,6 +147,35 @@ describe('useUsageData', () => {
|
||||
})
|
||||
})
|
||||
|
||||
it('refreshes exact admin record totals after an estimated first page', async () => {
|
||||
const isAdminPage = ref(true)
|
||||
const { loadRecords, totalRecords } = useUsageData({ isAdminPage })
|
||||
const dateRange = { preset: 'last7days', tz_offset_minutes: 0 }
|
||||
|
||||
getAllUsageRecordsMock.mockResolvedValueOnce({
|
||||
records: [buildUsageRecord()],
|
||||
total: 21,
|
||||
total_is_estimated: true,
|
||||
limit: 20,
|
||||
offset: 0,
|
||||
})
|
||||
getAllUsageRecordTotalMock.mockResolvedValueOnce(122101)
|
||||
|
||||
await loadRecords({ page: 1, pageSize: 20 }, undefined, dateRange)
|
||||
|
||||
expect(getAllUsageRecordsMock).toHaveBeenCalledWith(expect.objectContaining({
|
||||
include_total: false,
|
||||
}))
|
||||
await Promise.resolve()
|
||||
await Promise.resolve()
|
||||
|
||||
expect(getAllUsageRecordTotalMock).toHaveBeenCalledWith(expect.objectContaining({
|
||||
preset: 'last7days',
|
||||
tz_offset_minutes: 0,
|
||||
}))
|
||||
expect(totalRecords.value).toBe(122101)
|
||||
})
|
||||
|
||||
it('continues loading admin breakdowns when the summary request fails', async () => {
|
||||
const isAdminPage = ref(true)
|
||||
const {
|
||||
|
||||
@@ -366,13 +366,19 @@ export function useUsageData(options: UseUsageDataOptions) {
|
||||
params.hide_unknown = true
|
||||
}
|
||||
|
||||
const response = await usageApi.getAllUsageRecords(params)
|
||||
const response = await usageApi.getAllUsageRecords({
|
||||
...params,
|
||||
include_total: false,
|
||||
})
|
||||
if (requestId !== loadRecordsRequestId) {
|
||||
return
|
||||
}
|
||||
const nextRecords = (response.records || []) as UsageRecord[]
|
||||
currentRecords.value = mergeRecordStatus(currentRecords.value, nextRecords)
|
||||
totalRecords.value = response.total || 0
|
||||
if (response.total_is_estimated === true) {
|
||||
void refreshAdminRecordTotal(params, requestId)
|
||||
}
|
||||
} else {
|
||||
// 用户页面:使用用户 API
|
||||
const userData = await meApi.getUsage(params)
|
||||
@@ -397,6 +403,20 @@ export function useUsageData(options: UseUsageDataOptions) {
|
||||
}
|
||||
}
|
||||
|
||||
async function refreshAdminRecordTotal(
|
||||
params: Record<string, unknown>,
|
||||
requestId: number
|
||||
): Promise<void> {
|
||||
try {
|
||||
const total = await usageApi.getAllUsageRecordTotal(params)
|
||||
if (requestId === loadRecordsRequestId) {
|
||||
totalRecords.value = total
|
||||
}
|
||||
} catch (error) {
|
||||
log.warn('加载使用记录总数失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
function mergePositiveDurationMs(
|
||||
existingValue: number | null | undefined,
|
||||
nextValue: number | null | undefined
|
||||
@@ -513,6 +533,8 @@ export function useUsageData(options: UseUsageDataOptions) {
|
||||
actual_cost: existing.actual_cost ?? record.actual_cost,
|
||||
response_time_ms: mergePositiveDurationMs(existing.response_time_ms, record.response_time_ms),
|
||||
first_byte_time_ms: mergePositiveDurationMs(existing.first_byte_time_ms, record.first_byte_time_ms),
|
||||
updated_at: existing.updated_at ?? record.updated_at,
|
||||
response_time_updated_at: existing.response_time_updated_at ?? record.response_time_updated_at,
|
||||
status_code: existing.status_code ?? record.status_code,
|
||||
error_message: existing.error_message ?? record.error_message,
|
||||
image_progress: existing.image_progress ?? record.image_progress,
|
||||
|
||||
Reference in New Issue
Block a user