feat(dashboard, risk): add SWR query hook and lazy load charts

This commit is contained in:
2026-06-10 13:58:31 +08:00
parent 1c80a3ae75
commit 13ae574aad
6 changed files with 108 additions and 37 deletions

View File

@@ -1,5 +1,6 @@
"use client";
import dynamic from "next/dynamic";
import Link from "next/link";
import type { ReactNode } from "react";
import { useTranslation } from "react-i18next";
@@ -23,10 +24,6 @@ import { getAdminRequestLocale } from "@/lib/admin-locale";
import { cn } from "@/lib/utils";
import { DashboardKpiCard } from "@/modules/dashboard/dashboard-visuals";
import { DASHBOARD_CHART_COLORS } from "@/modules/dashboard/dashboard-chart-config";
import {
DailyTrendChart,
PlayBreakdownChart,
} from "@/modules/dashboard/dashboard-trend-charts";
import {
DASHBOARD_ANALYTICS_PERIODS,
DASHBOARD_RANKING_METRICS,
@@ -34,6 +31,16 @@ import {
type DashboardAnalyticsState,
} from "@/modules/dashboard/use-dashboard-analytics";
// recharts 图表组件懒加载
const DailyTrendChart = dynamic(
() => import("@/modules/dashboard/dashboard-trend-charts").then((m) => ({ default: m.DailyTrendChart })),
{ ssr: false },
);
const PlayBreakdownChart = dynamic(
() => import("@/modules/dashboard/dashboard-trend-charts").then((m) => ({ default: m.PlayBreakdownChart })),
{ ssr: false },
);
function computeDeltaPercent(series: number[]): string | null {
if (series.length < 2) {
return null;

View File

@@ -1,5 +1,6 @@
"use client";
import dynamic from "next/dynamic";
import Link from "next/link";
import { useCallback, useEffect, useMemo, useState, type ReactElement, type ReactNode } from "react";
import { useTranslation } from "react-i18next";
@@ -35,16 +36,6 @@ import { AdminNoResourceState, AdminTableNoResourceRow } from "@/components/admi
import { Button, buttonVariants } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Skeleton } from "@/components/ui/skeleton";
import {
AbnormalTransferPanelFooter,
CapUsageBar,
FinanceStructureChart,
HotUsageBars,
ResultBatchQueueSummary,
PlatformLifetimePayoutSnapshot,
DashboardPanelCard,
SettlementStatusChart,
} from "@/modules/dashboard/dashboard-visuals";
import { useAdminCurrencyCatalog } from "@/hooks/use-admin-currency-catalog";
import { adminWeekdayKeyForDate, formatAdminCalendarToday } from "@/lib/admin-datetime";
import { normalizeAdminLanguage } from "@/i18n";
@@ -66,6 +57,40 @@ import type { AdminDrawFinanceSummaryData } from "@/types/api/admin-draw-finance
import type { AdminRiskPoolRow } from "@/types/api/admin-risk";
import type { DrawCurrentSnapshot } from "@/types/api/public-draw";
// recharts 图表组件懒加载,避免 ~200KB 进入主 bundle
const DashboardPanelCard = dynamic(
() => import("@/modules/dashboard/dashboard-visuals").then((m) => ({ default: m.DashboardPanelCard })),
{ ssr: false },
);
const AbnormalTransferPanelFooter = dynamic(
() => import("@/modules/dashboard/dashboard-visuals").then((m) => ({ default: m.AbnormalTransferPanelFooter })),
{ ssr: false },
);
const CapUsageBar = dynamic(
() => import("@/modules/dashboard/dashboard-visuals").then((m) => ({ default: m.CapUsageBar })),
{ ssr: false },
);
const FinanceStructureChart = dynamic(
() => import("@/modules/dashboard/dashboard-visuals").then((m) => ({ default: m.FinanceStructureChart })),
{ ssr: false },
);
const HotUsageBars = dynamic(
() => import("@/modules/dashboard/dashboard-visuals").then((m) => ({ default: m.HotUsageBars })),
{ ssr: false },
);
const ResultBatchQueueSummary = dynamic(
() => import("@/modules/dashboard/dashboard-visuals").then((m) => ({ default: m.ResultBatchQueueSummary })),
{ ssr: false },
);
const PlatformLifetimePayoutSnapshot = dynamic(
() => import("@/modules/dashboard/dashboard-visuals").then((m) => ({ default: m.PlatformLifetimePayoutSnapshot })),
{ ssr: false },
);
const SettlementStatusChart = dynamic(
() => import("@/modules/dashboard/dashboard-visuals").then((m) => ({ default: m.SettlementStatusChart })),
{ ssr: false },
);
type HotPlayTab = "4D" | "3D" | "2D" | "special";
function formatMoneyMinor(minor: number, currencyCode: string | null): string {