add path cont

This commit is contained in:
2025-04-10 12:14:54 +08:00
parent a8576121e9
commit e101d19e00
3 changed files with 271 additions and 15 deletions

View File

@@ -34,18 +34,47 @@ const PathAnalytics: React.FC<PathAnalyticsProps> = ({ startTime, endTime, linkI
const response = await fetch(`/api/events/path-analytics?${params.toString()}`);
if (!response.ok) {
throw new Error('获取路径分析数据失败');
throw new Error('Failed to fetch path analytics data');
}
const result = await response.json();
if (result.success && result.data) {
setPathData(result.data);
// 自定义处理路径数据,根据是否有子路径来分组
const rawData = result.data;
const pathMap = new Map<string, number>();
let totalClicks = 0;
rawData.forEach((item: PathData) => {
const urlPath = item.path;
totalClicks += item.count;
// 解析路径,检查是否有子路径
const pathParts = urlPath.split('?')[0].split('/').filter(Boolean);
// 基础路径(例如/5seaii或者带有查询参数但没有子路径的路径视为同一个路径
// 子路径(例如/5seaii/bbbbb单独统计
const groupKey = pathParts.length > 1 ? urlPath : `/${pathParts[0]}`;
const currentCount = pathMap.get(groupKey) || 0;
pathMap.set(groupKey, currentCount + item.count);
});
// 转换回数组并排序
const groupedPathData = Array.from(pathMap.entries())
.map(([path, count]) => ({
path,
count,
percentage: totalClicks > 0 ? count / totalClicks : 0,
}))
.sort((a, b) => b.count - a.count);
setPathData(groupedPathData);
} else {
setError(result.error || '加载路径分析失败');
setError(result.error || 'Failed to load path analytics');
}
} catch (err) {
setError(err instanceof Error ? err.message : '发生错误');
setError(err instanceof Error ? err.message : 'An error occurred');
} finally {
setLoading(false);
}
@@ -65,25 +94,25 @@ const PathAnalytics: React.FC<PathAnalyticsProps> = ({ startTime, endTime, linkI
}
if (!linkId) {
return <div className="py-4 text-gray-500"></div>;
return <div className="py-4 text-gray-500">Select a specific link to view path analytics.</div>;
}
if (pathData.length === 0) {
return <div className="py-4 text-gray-500"></div>;
return <div className="py-4 text-gray-500">No path data available for this link.</div>;
}
return (
<div>
<div className="text-sm text-gray-500 mb-4">
URL参数组合会被视为不同的路径 /abc?p=1 /abc?p=2
Note: Paths are grouped by subpath. URLs with different query parameters but the same base path (without subpath) are grouped together.
</div>
<div className="overflow-x-auto">
<table className="min-w-full divide-y divide-gray-200">
<thead>
<tr>
<th className="px-6 py-3 bg-gray-50 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"></th>
<th className="px-6 py-3 bg-gray-50 text-right text-xs font-medium text-gray-500 uppercase tracking-wider"></th>
<th className="px-6 py-3 bg-gray-50 text-right text-xs font-medium text-gray-500 uppercase tracking-wider"></th>
<th className="px-6 py-3 bg-gray-50 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Path</th>
<th className="px-6 py-3 bg-gray-50 text-right text-xs font-medium text-gray-500 uppercase tracking-wider">Clicks</th>
<th className="px-6 py-3 bg-gray-50 text-right text-xs font-medium text-gray-500 uppercase tracking-wider">Percentage</th>
</tr>
</thead>
<tbody className="bg-white divide-y divide-gray-200">