fix: run leaderboard stats in background

This commit is contained in:
吉鑫升 committed 2026-06-05 21:15:20 +08:00
1 parent f4ccef8c70
commit db1b32612b
4 files changed
+269 -1

No files matched your search

+3
View File
@@ -104,6 +104,9 @@ export interface AdminLeaderboardResponse {
range_days: number;
since: string;
until: string;
status?: "ready" | "running" | "refreshing";
generated_at?: string;
message?: string;
overview: AdminLeaderboardOverview;
users_by_activity: AdminLeaderboardUser[];
users_by_questions: AdminLeaderboardUser[];
+4
View File
@@ -33,6 +33,10 @@ export function useUserLeaderboard(
limit,
],
queryFn: () => getUserLeaderboard(range, limit),
refetchInterval: (query) => {
const status = query.state.data?.status;
return status === "running" || status === "refreshing" ? 3000 : false;
},
});
}
@@ -1087,6 +1087,9 @@ export default function AdminUserLeaderboardPage() {
}, [data, query, tab]);
const overview = data?.overview;
const leaderboardStatus = data?.status;
const leaderboardPending = leaderboardStatus === "running" || leaderboardStatus === "refreshing";
const leaderboardHasRows = rankedUsers.length > 0 || (overview?.total_runs ?? 0) > 0 || (overview?.total_users ?? 0) > 0;
const topUsers = rankedUsers.slice(0, 3);
const userPageCount = Math.max(1, Math.ceil(rankedUsers.length / LEADERBOARD_PAGE_SIZE));
const visibleUsers = useMemo(() => {
@@ -1446,8 +1449,29 @@ export default function AdminUserLeaderboardPage() {
</div>
)}
{!isLoading && data && overview && (
{!isLoading && !error && leaderboardPending && !leaderboardHasRows && (
<div className="flex flex-col items-center justify-center gap-3 rounded-lg border border-[#F1D6D6] bg-white px-6 py-16 text-center text-sm text-[#5F6368] shadow-sm dark:border-[#462123] dark:bg-[#230D0F]">
<div className="flex items-center gap-2 font-medium text-[#202124] dark:text-white">
<Loader2 className="size-4 animate-spin text-[#C1121F]" />
<span>排行榜正在后台统计</span>
</div>
<div className="max-w-lg text-xs leading-5 text-[#7A5A5A] dark:text-[#D8B8B8]">
{data?.message || "统计任务已放到后台执行,页面会自动刷新结果。这样排行榜慢慢算,不会长时间占住当前接口请求。"}
</div>
</div>
)}
{!isLoading && data && overview && (!leaderboardPending || leaderboardHasRows) && (
<>
{leaderboardPending && leaderboardHasRows && (
<div className="flex flex-wrap items-center justify-between gap-3 rounded-lg border border-[#FDE68A] bg-[#FFFBEB] px-4 py-3 text-sm text-[#92400E] dark:border-amber-200/25 dark:bg-amber-300/10 dark:text-amber-100">
<div className="flex items-center gap-2">
<Loader2 className="size-4 animate-spin" />
<span>{data.message || "正在后台刷新排行榜,当前展示缓存结果。"}</span>
</div>
{data.generated_at && <span className="text-xs">缓存生成于 {fmtTime(data.generated_at)}</span>}
</div>
)}
<div className="grid gap-3 md:grid-cols-2 xl:grid-cols-4">
<StatCard icon={Users} accent="crimson" label="总用户" value={fmtNumber(overview.total_users)} note={`${fmtNumber(overview.active_users)} 位在当前时间段活跃`} />
<StatCard icon={MousePointerClick} accent="teal" label="使用次数" value={fmtNumber(overview.total_runs)} note={`${fmtNumber(overview.total_threads)} 个会话被创建`} />