mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-02 17:30:23 +08:00
Fix/usage transfer filter (#307)
* fix(usage): 恢复 usage 列表中的 fallback 路由信号 * fix(admin): 支持 usage 记录展示和筛选 fallback 转移 * fix(usage): 在用户 usage 记录中暴露 fallback 标记 * fix(usage): 共享 usage 页面支持 fallback 筛选 * fix(usage): 对齐 fallback 筛选相关前端类型 * fix(usage): propagate has_fallback through active polling --------- Co-authored-by: fawney19 <elky0401@gmail.com>
This commit is contained in:
@@ -401,6 +401,7 @@ export function useUsageData(options: UseUsageDataOptions) {
|
||||
api_format: existing.api_format || record.api_format,
|
||||
endpoint_api_format: existing.endpoint_api_format || record.endpoint_api_format,
|
||||
has_format_conversion: existing.has_format_conversion ?? record.has_format_conversion,
|
||||
has_fallback: existing.has_fallback === true || record.has_fallback === true,
|
||||
api_key_name: existing.api_key_name || record.api_key_name,
|
||||
provider_key_name: existing.provider_key_name || record.provider_key_name,
|
||||
rate_multiplier: existing.rate_multiplier ?? record.rate_multiplier,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { ref, computed, type Ref } from 'vue'
|
||||
import type { UsageRecord, FilterStatusValue } from '../types'
|
||||
import { isUsageRecordFailed } from '../utils/status'
|
||||
import { hasUsageFallback, isUsageRecordFailed } from '../utils/status'
|
||||
|
||||
export interface UseUsageFiltersOptions {
|
||||
/** 所有记录的响应式引用 */
|
||||
@@ -79,6 +79,8 @@ export function useUsageFilters(options: UseUsageFiltersOptions) {
|
||||
records = records.filter(record => isUsageRecordFailed(record))
|
||||
} else if (filterStatus.value === 'cancelled') {
|
||||
records = records.filter(record => record.status === 'cancelled')
|
||||
} else if (filterStatus.value === 'has_fallback') {
|
||||
records = records.filter(record => hasUsageFallback(record))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -127,7 +127,14 @@ export interface DateRangeParams {
|
||||
export type PeriodValue = 'today' | 'yesterday' | 'last7days' | 'last30days' | 'last90days'
|
||||
|
||||
// 筛选状态(简化为常用维度)
|
||||
export type FilterStatusValue = '__all__' | 'stream' | 'standard' | 'active' | 'failed' | 'cancelled'
|
||||
export type FilterStatusValue =
|
||||
'__all__' |
|
||||
'stream' |
|
||||
'standard' |
|
||||
'active' |
|
||||
'failed' |
|
||||
'cancelled' |
|
||||
'has_fallback'
|
||||
|
||||
// 默认统计状态
|
||||
export function createDefaultStats(): UsageStatsState {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
|
||||
import {
|
||||
hasUsageFallback,
|
||||
isUsageRecordFailed,
|
||||
isUsageRecordSuccessful,
|
||||
mapRequestStatusToTimelineStatus,
|
||||
@@ -91,6 +92,12 @@ describe('usage status helpers', () => {
|
||||
})).toBe('failed')
|
||||
})
|
||||
|
||||
it('uses explicit has_fallback flag for transfer filtering', () => {
|
||||
expect(hasUsageFallback(buildUsageRecord({ has_fallback: true }))).toBe(true)
|
||||
expect(hasUsageFallback(buildUsageRecord({ has_fallback: false }))).toBe(false)
|
||||
expect(hasUsageFallback(buildUsageRecord({ has_fallback: undefined }))).toBe(false)
|
||||
})
|
||||
|
||||
it('uses status code only as a last fallback for timeline status', () => {
|
||||
expect(resolveTimelineFinalStatus({
|
||||
statusCode: 200,
|
||||
|
||||
@@ -11,6 +11,12 @@ function hasLegacyFailureSignal(
|
||||
(typeof record.error_message === 'string' && record.error_message.trim().length > 0)
|
||||
}
|
||||
|
||||
export function hasUsageFallback(
|
||||
record: Pick<UsageRecord, 'has_fallback'>
|
||||
): boolean {
|
||||
return record.has_fallback === true
|
||||
}
|
||||
|
||||
function hasTerminalSuccessStatusCode(
|
||||
record: Pick<UsageRecord, 'status_code'>
|
||||
): boolean {
|
||||
|
||||
Reference in New Issue
Block a user