feat: M4-01 — add cost, import, task, expiration metric cards to dashboard
Some checks failed
Deploy Admin Frontend / build-and-deploy (push) Failing after 7s

- Update DashboardStats type with new fields
- Add 4 new metric cards: today's AI cost, import tasks, failed tasks, upcoming expirations

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
WangDL 2026-05-24 17:36:26 +08:00
parent d3665e9a02
commit eb2764518d
2 changed files with 12 additions and 1 deletions

View File

@ -6,7 +6,7 @@ import * as echarts from 'echarts/core'
import { LineChart, BarChart } from 'echarts/charts'
import { GridComponent, TooltipComponent, TitleComponent, LegendComponent } from 'echarts/components'
import { CanvasRenderer } from 'echarts/renderers'
import { UserOutlined, BookOutlined, CloudOutlined, FileOutlined, ClusterOutlined } from '@ant-design/icons'
import { UserOutlined, BookOutlined, CloudOutlined, FileOutlined, ClusterOutlined, DollarOutlined, ImportOutlined, AlertOutlined, SafetyOutlined } from '@ant-design/icons'
import dayjs from 'dayjs'
import MetricCard from '@/components/MetricCard'
import { Progress, Space } from 'antd'
@ -61,6 +61,12 @@ export default function Dashboard() {
<Col xs={12} sm={12} lg={6}><MetricCard title="今日 AI 调用" value={stats?.totalAiCallsToday} loading={statsLoading} prefix={<CloudOutlined />} /></Col>
<Col xs={12} sm={12} lg={6}><MetricCard title="文件存储" value={stats ? formatStorage(stats.totalStorageBytes) : undefined} loading={statsLoading} prefix={<FileOutlined />} suffix={`${stats?.totalFiles ?? 0} 个文件`} /></Col>
</Row>
<Row gutter={[16, 16]} style={{ marginTop: 16 }}>
<Col xs={12} sm={12} lg={6}><MetricCard title="今日 AI 成本" value={stats?.todayAiCost != null ? `¥${stats.todayAiCost.toFixed(2)}` : undefined} loading={statsLoading} prefix={<DollarOutlined />} trend="up" trendValue={`${stats?.totalAiCallsToday ?? 0}`} trendLabel="今日调用" /></Col>
<Col xs={12} sm={12} lg={6}><MetricCard title="今日导入任务" value={stats?.todayImportCount ?? 0} loading={statsLoading} prefix={<ImportOutlined />} trend={stats?.failedImportCount ? 'down' : 'up'} trendValue={stats?.failedImportCount ? `${stats.failedImportCount} 失败` : '全部成功'} trendLabel="状态" /></Col>
<Col xs={12} sm={12} lg={6}><MetricCard title="近期失败任务" value={stats?.failedTasks ?? 0} loading={statsLoading} prefix={<AlertOutlined />} trend={stats?.failedTasks ? 'down' : 'up'} trendValue={stats?.failedTasks ? '需要关注' : '无异常'} trendLabel="7 天内" /></Col>
<Col xs={12} sm={12} lg={6}><MetricCard title="即将到期密钥" value={stats?.upcomingExpirations ?? 0} loading={statsLoading} prefix={<SafetyOutlined />} trend={stats?.upcomingExpirations ? 'down' : 'up'} trendValue="30 天内" trendLabel="到期" /></Col>
</Row>
<Row gutter={[16, 16]} style={{ marginTop: 16 }}>
<Col xs={24} lg={12}><EChartsChartContainer title="日活用户趋势(近 30 天)" loading={statsLoading} isEmpty={!stats?.userTrend?.length}><ReactEChartsCore echarts={echarts} option={userTrendOption} style={{ height: 300 }} notMerge lazyUpdate /></EChartsChartContainer></Col>
<Col xs={24} lg={12}><EChartsChartContainer title="AI 调用趋势(近 30 天)" loading={statsLoading} isEmpty={!stats?.aiCallTrend?.length}><ReactEChartsCore echarts={echarts} option={aiCallTrendOption} style={{ height: 300 }} notMerge /></EChartsChartContainer></Col>

View File

@ -26,6 +26,11 @@ export interface DashboardStats {
totalAiCallsToday: number
totalFiles: number
totalStorageBytes: number
todayImportCount: number
failedImportCount: number
todayAiCost: number
failedTasks: number
upcomingExpirations: number
userTrend: TrendPoint[]
aiCallTrend: TrendPoint[]
}