feat(access-logs): 优化概览饼图布局并在查询出错时增加日志记录

- 将设备类型与状态码饼图的断点由 xl 降为 lg,在大屏/笔记本视口下保持双列展示
- 修复 valueCountDistribution 在 ClickHouse 查询出错时静默吞掉错误的缺陷,引入 logger.ErrorF 捕获
- 补充 unreleased 变更日志
This commit is contained in:
ryan
2026-07-18 21:41:52 +08:00
parent e49078ac3b
commit bf71bc540b
6 changed files with 109 additions and 71 deletions
@@ -5,7 +5,7 @@ import type { EChartsOption } from 'echarts';
import ReactECharts from 'echarts-for-react';
import { Cell, Pie, PieChart } from 'recharts';
import { RankChart } from '@/components/data/rank-chart';
import { RankCard } from '@/components/data/rank-card';
import { TrendChart } from '@/components/data/trend-chart';
import { EmptyStateWithBorder } from '@/components/layout/empty';
import { ErrorInline } from '@/components/layout/error';
@@ -160,38 +160,6 @@ function toRankItems(items: DistributionItem[] | undefined) {
}));
}
function RankCard({
title,
description,
items,
color,
}: {
title: string;
description: string;
items: { label: string; value: number }[];
color: string;
}) {
return (
<Card className='border-dashed shadow-none'>
<CardHeader className='pb-3'>
<CardTitle className='text-sm font-semibold text-foreground'>
{title}
</CardTitle>
<CardDescription className='text-xs text-muted-foreground'>
{description}
</CardDescription>
</CardHeader>
<CardContent className='pt-0'>
<RankChart
items={items}
color={color}
emptyMessage={`暂无 ${title} 数据`}
/>
</CardContent>
</Card>
);
}
function PieDistributionCard({
title,
description,
@@ -236,13 +204,13 @@ function PieDistributionCard({
</CardHeader>
<CardContent className='pt-0'>
{chartData.length === 0 ? (
<div className='flex h-[450px] items-center justify-center rounded-md border border-dashed bg-muted/20 text-sm text-muted-foreground'>
<div className='flex h-[300px] items-center justify-center rounded-md border border-dashed bg-muted/20 text-sm text-muted-foreground'>
{emptyMessage}
</div>
) : (
<ChartContainer
config={chartConfig}
className='mx-auto h-[450px] w-full'
className='mx-auto h-[300px] w-full'
>
<PieChart>
<Pie
@@ -251,8 +219,8 @@ function PieDistributionCard({
nameKey='name'
cx='50%'
cy='46%'
innerRadius={72}
outerRadius={110}
innerRadius={50}
outerRadius={80}
paddingAngle={2}
>
{chartData.map((entry) => (
@@ -456,19 +424,16 @@ function OverviewContent({
<RankCard
title='Top Paths'
description='访问量最高的请求路径。'
color='#a78bfa'
items={toRankItems(data.top_paths)}
/>
<RankCard
title='Top Hosts'
description='流量集中的访问域名。'
color='#34d399'
items={toRankItems(data.top_hosts)}
/>
<RankCard
title='Top IPs'
description='请求次数最多的来源 IP。'
color='#38bdf8'
items={toRankItems(data.top_ips)}
/>
</div>
@@ -477,19 +442,16 @@ function OverviewContent({
<RankCard
title='Top browsers'
description='按浏览器聚合的请求排行。'
color='#f59e0b'
items={toRankItems(data.top_browsers)}
/>
<RankCard
title='Top Operating System'
description='按操作系统聚合的请求排行。'
color='#22c55e'
items={toRankItems(data.top_operating_systems)}
/>
<RankCard
title='Top User-Agent'
description='原始 User-Agent 请求排行。'
color='#818cf8'
items={toRankItems(data.top_user_agents)}
/>
</div>