diff --git a/src/components/monitor/RequestLogs.tsx b/src/components/monitor/RequestLogs.tsx index 6aa22f6..93f433c 100644 --- a/src/components/monitor/RequestLogs.tsx +++ b/src/components/monitor/RequestLogs.tsx @@ -2,7 +2,7 @@ import { useMemo, useState, useEffect, useRef, useCallback } from 'react'; import { useTranslation } from 'react-i18next'; import { useVirtualizer } from '@tanstack/react-virtual'; import { Card } from '@/components/ui/Card'; -import { usageApi } from '@/services/api'; +import { usageApi, authFilesApi } from '@/services/api'; import { useDisableModel } from '@/hooks'; import { TimeRangeSelector, formatTimeRangeCaption, type TimeRange } from './TimeRangeSelector'; import { DisableModelModal } from './DisableModelModal'; @@ -41,6 +41,7 @@ interface LogEntry { inputTokens: number; outputTokens: number; totalTokens: number; + authIndex: string; } interface ChannelModelRequest { @@ -92,6 +93,9 @@ export function RequestLogs({ data, loading: parentLoading, providerMap, provide const [logLoading, setLogLoading] = useState(false); const [isFirstLoad, setIsFirstLoad] = useState(true); + // 认证文件索引到名称的映射 + const [authIndexMap, setAuthIndexMap] = useState>({}); + // 使用禁用模型 Hook const { disableState, @@ -124,6 +128,33 @@ export function RequestLogs({ data, loading: parentLoading, providerMap, provide } }, [parentLoading, data]); + // 加载认证文件映射(authIndex -> 文件名) + const loadAuthIndexMap = useCallback(async () => { + try { + const response = await authFilesApi.list(); + const files = response?.files || []; + const map: Record = {}; + files.forEach((file) => { + // 兼容 auth_index 和 authIndex 两种字段名(API 返回的是 auth_index) + const rawAuthIndex = (file as Record)['auth_index'] ?? file.authIndex; + if (rawAuthIndex !== undefined && rawAuthIndex !== null) { + const authIndexKey = String(rawAuthIndex).trim(); + if (authIndexKey) { + map[authIndexKey] = file.name; + } + } + }); + setAuthIndexMap(map); + } catch (err) { + console.warn('Failed to load auth files for index mapping:', err); + } + }, []); + + // 初始加载认证文件映射 + useEffect(() => { + loadAuthIndexMap(); + }, [loadAuthIndexMap]); + // 独立获取日志数据 const fetchLogData = useCallback(async () => { setLogLoading(true); @@ -283,6 +314,7 @@ export function RequestLogs({ data, loading: parentLoading, providerMap, provide inputTokens: detail.tokens.input_tokens || 0, outputTokens: detail.tokens.output_tokens || 0, totalTokens: detail.tokens.total_tokens || 0, + authIndex: detail.auth_index || '', }); }); }); @@ -409,9 +441,14 @@ export function RequestLogs({ data, loading: parentLoading, providerMap, provide const stats = getStats(entry); const rateValue = parseFloat(stats.successRate); const disabled = isModelDisabled(entry.source, entry.model); + // 将 authIndex 映射为文件名 + const authDisplayName = entry.authIndex ? (authIndexMap[entry.authIndex] || entry.authIndex) : '-'; return ( <> + + {authDisplayName} + {maskSecret(entry.apiKey)} @@ -580,6 +617,7 @@ export function RequestLogs({ data, loading: parentLoading, providerMap, provide +
{t('monitor.logs.header_auth')} {t('monitor.logs.header_api')} {t('monitor.logs.header_request_type')} {t('monitor.logs.header_model')}