From 76d242e024fd5a77d9dffdede266a9f24bece34c Mon Sep 17 00:00:00 2001 From: shaw Date: Fri, 6 Feb 2026 20:18:38 +0800 Subject: [PATCH] =?UTF-8?q?refactor(frontend):=20=E5=A4=8D=E7=94=A8=20Toke?= =?UTF-8?q?nUsageTrend=20=E7=BB=84=E4=BB=B6=E4=BC=98=E5=8C=96=E7=94=A8?= =?UTF-8?q?=E6=88=B7=20Dashboard=20=E5=9B=BE=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 用户 Dashboard 的 Token 使用趋势图表现在显示 Input/Output/Cache 三种类型, 并在 Tooltip 中显示 Actual 和 Standard 价格,与管理员页面保持一致。 --- .../user/dashboard/UserDashboardCharts.vue | 57 +------------------ 1 file changed, 3 insertions(+), 54 deletions(-) diff --git a/frontend/src/components/user/dashboard/UserDashboardCharts.vue b/frontend/src/components/user/dashboard/UserDashboardCharts.vue index 39e8bb30..22148592 100644 --- a/frontend/src/components/user/dashboard/UserDashboardCharts.vue +++ b/frontend/src/components/user/dashboard/UserDashboardCharts.vue @@ -55,16 +55,7 @@ -
-
- -
-

{{ t('dashboard.tokenUsageTrend') }}

-
- -
{{ t('dashboard.noDataAvailable') }}
-
-
+ @@ -75,7 +66,8 @@ import { useI18n } from 'vue-i18n' import LoadingSpinner from '@/components/common/LoadingSpinner.vue' import DateRangePicker from '@/components/common/DateRangePicker.vue' import Select from '@/components/common/Select.vue' -import { Line, Doughnut } from 'vue-chartjs' +import { Doughnut } from 'vue-chartjs' +import TokenUsageTrend from '@/components/charts/TokenUsageTrend.vue' import type { TrendDataPoint, ModelStat } from '@/types' import { formatCostFixed as formatCost, formatNumberLocaleString as formatNumber, formatTokensK as formatTokens } from '@/utils/format' import { Chart as ChartJS, CategoryScale, LinearScale, PointElement, LineElement, ArcElement, Title, Tooltip, Legend, Filler } from 'chart.js' @@ -93,28 +85,6 @@ const modelData = computed(() => !props.models?.length ? null : { }] }) -const trendData = computed(() => !props.trend?.length ? null : { - labels: props.trend.map((d: TrendDataPoint) => d.date), - datasets: [ - { - label: t('dashboard.input'), - data: props.trend.map((d: TrendDataPoint) => d.input_tokens), - borderColor: '#3b82f6', - backgroundColor: 'rgba(59, 130, 246, 0.1)', - tension: 0.3, - fill: true - }, - { - label: t('dashboard.output'), - data: props.trend.map((d: TrendDataPoint) => d.output_tokens), - borderColor: '#10b981', - backgroundColor: 'rgba(16, 185, 129, 0.1)', - tension: 0.3, - fill: true - } - ] -}) - const doughnutOptions = { responsive: true, maintainAspectRatio: false, @@ -127,25 +97,4 @@ const doughnutOptions = { } } } - -const lineOptions = { - responsive: true, - maintainAspectRatio: false, - plugins: { - legend: { display: true, position: 'top' as const }, - tooltip: { - callbacks: { - label: (context: any) => `${context.dataset.label}: ${formatTokens(context.parsed.y)} tokens` - } - } - }, - scales: { - y: { - beginAtZero: true, - ticks: { - callback: (value: any) => formatTokens(value) - } - } - } -}