diff --git a/frontend/src/pages/UsageLogs.tsx b/frontend/src/pages/UsageLogs.tsx index 5148b1c..b2221a4 100644 --- a/frontend/src/pages/UsageLogs.tsx +++ b/frontend/src/pages/UsageLogs.tsx @@ -1,10 +1,17 @@ import { startTransition, useMemo, useState } from "react"; import { useQuery } from "@tanstack/react-query"; import { apiClient } from "@/api/client"; -import { AnalyticsEventItem, AnalyticsRange, UsageLogFilterDimension, UsageLogFilters, UsageLogSearchData } from "@/types"; +import { + AnalyticsEventItem, + AnalyticsRange, + UsageLogFilterDimension, + UsageLogFilters, + UsageLogSearchData, +} from "@/types"; import { PageContainer } from "@/components/ui/page-container"; import { Alert, AlertDescription } from "@/components/ui/alert"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; +import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from "@/components/ui/dialog"; import { Input } from "@/components/ui/input"; @@ -164,13 +171,63 @@ const ClientSummary = ({ item }: { item: AnalyticsEventItem }) => { ); }; -const DetailField = ({ label, value, mono = false }: { label: string; value: string | number; mono?: boolean }) => { - const text = String(value || "--"); +const formatDetailValue = (value: string | number | null | undefined): string => { + if (value === null || value === undefined) { + return "--"; + } + + if (typeof value === "string" && value.trim().length === 0) { + return "--"; + } + + return String(value); +}; + +const DetailMetric = ({ label, value }: { label: string; value: string | number }) => { + const text = formatDetailValue(value); return ( -
- 记录 request id、trace id、错误摘要、IP、UA 与地理位置,适合定位某一批异常设备或单个失败链路。 -
-| 时间 | -模型 / 令牌 | -端点 / 渠道 | -结果 / 状态 | -方式 / 用时 | -资源消耗 | -详情 | -|||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
- {formatDateTime(item.timestamp)}
- {item.requestId || "--"}
- |
+
| 时间 | +模型 / 令牌 | +端点 / 渠道 | +结果 / 状态 | +方式 / 用时 | +资源消耗 | +详情 | +||
|---|---|---|---|---|---|---|---|---|
|
+ {formatDateTime(item.timestamp)}
+ {item.requestId || "--"}
+ |
-
- {item.requestedModel || "--"}
- {item.tokenName || "未命名令牌"}
- |
-
- {item.providerType || "--"}
- {item.channelKey || "--"}
- |
+
+ {item.requestedModel || "--"}
+ {item.tokenName || "未命名令牌"}
+ |
+
+ {item.providerType || "--"}
+ {item.channelKey || "--"}
+ |
-
-
-
- {item.result === "success" ? "成功" : "失败"}
-
-
-
- {item.upstreamStatus || "--"} · 重试 {item.retryCount}
-
- |
-
-
-
- {item.streamMode === "stream" ? "流式" : "非流式"}
-
- {formatDuration(item.latencyMs)}
- |
-
-
- {/* {formatCompactNumber(item.totalTokens)} tokens */}
-
- 输入 {formatCompactNumber(item.promptTokens)} / 输出{" "}
- {formatCompactNumber(item.completionTokens)}
-
- {formatCurrency(item.totalCost, displayDecimals)}
- |
-
- - |
没有匹配的日志记录
-调整时间范围、维度或关键字后重试。
-没有匹配的日志记录
+调整时间范围、维度或关键字后重试。
+