diff --git a/frontend/src/components/usage/UsageLatencyCell.vue b/frontend/src/components/usage/UsageLatencyCell.vue
index 7024ea86d..6fd1f9b9d 100644
--- a/frontend/src/components/usage/UsageLatencyCell.vue
+++ b/frontend/src/components/usage/UsageLatencyCell.vue
@@ -10,6 +10,14 @@ const props = defineProps<{
}>()
const latencyDetails = computed(() => usageLatencyDetails(props.record))
+
+const latencyTones = {
+ good: 'text-cp-success-text',
+ warn: 'text-cp-warning-text',
+ // 主题的 Orange 与 Warning 共用色种,混入 Error 让相邻两档可区分
+ slow: 'latency-slow',
+ critical: 'text-cp-error-text',
+}
@@ -18,9 +26,13 @@ const latencyDetails = computed(() => usageLatencyDetails(props.record))
class="grid grid-cols-[auto_auto] items-center justify-end gap-x-2 gap-y-1.5 whitespace-nowrap font-mono text-cp-sm leading-none font-heavy tabular-nums"
>
首字
- {{ latencyDetails.firstOutputDisplay }}
+
+ {{ latencyDetails.firstOutputDisplay }}
+
总耗时
- {{ latencyDetails.totalDisplay }}
+
+ {{ latencyDetails.totalDisplay }}
+
@@ -58,3 +70,9 @@ const latencyDetails = computed(() => usageLatencyDetails(props.record))
+
+
diff --git a/frontend/src/components/usage/shared/presenter.ts b/frontend/src/components/usage/shared/presenter.ts
index 245283588..d5e25b433 100644
--- a/frontend/src/components/usage/shared/presenter.ts
+++ b/frontend/src/components/usage/shared/presenter.ts
@@ -224,11 +224,26 @@ export function usageLatencyDetails(record: UsageLatencyRecord) {
return {
upstreamDisplay,
firstOutputDisplay: formatDuration(firstTokenMs),
+ firstOutputSeverity: latencySeverity(firstTokenMs, [10_000, 30_000, 60_000]),
totalDisplay: formatDuration(totalMs),
+ totalSeverity: latencySeverity(totalMs, [60_000, 180_000, 300_000]),
sections,
}
}
+function latencySeverity(ms: number | null, thresholds: readonly [number, number, number]): 'good' | 'warn' | 'slow' | 'critical' | null {
+ if (ms === null)
+ return null
+ // 沿用 sub2api 的固定分档,边界值进入下一档,不改变请求状态
+ if (ms >= thresholds[2])
+ return 'critical'
+ if (ms >= thresholds[1])
+ return 'slow'
+ if (ms >= thresholds[0])
+ return 'warn'
+ return 'good'
+}
+
export function usageBillingText(record: Pick) {
return record.billing?.totalAmountDisplay || '—'
}