From 0197f890189f6d68657a541a822c4647e8d2737d Mon Sep 17 00:00:00 2001 From: selfrelease Date: Sun, 19 Jul 2026 21:52:40 +0800 Subject: [PATCH] =?UTF-8?q?feat(dashboard):=20add=20company=20filter=20?= =?UTF-8?q?=E2=80=94=20switch=20between=20portfolio=20overview=20and=20sin?= =?UTF-8?q?gle=20company=20view?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/app/(investor)/dashboard/page.tsx | 49 +++++++++++++++---- .../components/dashboard/HealthHeatmap.tsx | 9 ++-- 2 files changed, 46 insertions(+), 12 deletions(-) diff --git a/frontend/src/app/(investor)/dashboard/page.tsx b/frontend/src/app/(investor)/dashboard/page.tsx index 86b73df..afcf255 100644 --- a/frontend/src/app/(investor)/dashboard/page.tsx +++ b/frontend/src/app/(investor)/dashboard/page.tsx @@ -4,6 +4,7 @@ import { useEffect, useState } from "react"; import { Building2, Heart, AlertTriangle, FileText, TrendingUp, TrendingDown, Minus } from "lucide-react"; import Link from "next/link"; import { getDashboardSummary, type DashboardSummary } from "@/lib/dashboard"; +import { listCompanies, type Company } from "@/lib/companies"; import { LoadingSpinner } from "@/components/shared/LoadingSpinner"; import { EmptyState } from "@/components/shared/EmptyState"; import { HealthScoreBadge } from "@/components/shared/HealthScoreBadge"; @@ -14,13 +15,19 @@ import { HealthHeatmap, HealthTrends } from "@/components/dashboard/HealthHeatma */ export default function InvestorDashboardPage() { const [summary, setSummary] = useState(null); + const [companies, setCompanies] = useState([]); + const [selectedCompanyId, setSelectedCompanyId] = useState(""); const [isLoading, setIsLoading] = useState(true); useEffect(() => { async function load() { try { - const resp = await getDashboardSummary(); - if (resp.data) setSummary(resp.data); + const [summaryResp, companiesResp] = await Promise.all([ + getDashboardSummary(), + listCompanies({ page_size: 100 }), + ]); + if (summaryResp.data) setSummary(summaryResp.data); + if (companiesResp.data?.items) setCompanies(companiesResp.data.items); } catch { // ignore } finally { @@ -76,11 +83,35 @@ export default function InvestorDashboardPage() { }, ]; + // 筛选后的评分列表 + const filteredScores = selectedCompanyId + ? summary?.recent_scores.filter((s) => s.company_id === selectedCompanyId) ?? [] + : summary?.recent_scores ?? []; + + // 选中的企业名称 + const selectedCompany = companies.find((c) => c.id === selectedCompanyId); + return (
-
-

投资机构驾驶舱

-

Portfolio 全局健康度与风险概览

+
+
+

投资机构驾驶舱

+

+ {selectedCompany ? `${selectedCompany.name} — 企业健康度概览` : "Portfolio 全局健康度与风险概览"} +

+
+ + {/* 企业筛选器 */} +
{/* KPI 卡片 */} @@ -113,9 +144,9 @@ export default function InvestorDashboardPage() {
- {summary && summary.recent_scores.length > 0 ? ( + {filteredScores.length > 0 ? (
- {summary.recent_scores.map((score) => ( + {filteredScores.map((score) => (
@@ -156,10 +187,10 @@ export default function InvestorDashboardPage() {

健康度热力图

- +
- +
diff --git a/frontend/src/components/dashboard/HealthHeatmap.tsx b/frontend/src/components/dashboard/HealthHeatmap.tsx index 4cf38e2..6736a75 100644 --- a/frontend/src/components/dashboard/HealthHeatmap.tsx +++ b/frontend/src/components/dashboard/HealthHeatmap.tsx @@ -155,16 +155,19 @@ export function HealthTrends({ companyId }: { companyId?: string }) {
); } -export function HealthHeatmap() { +export function HealthHeatmap({ companyId }: { companyId?: string }) { const [data, setData] = useState([]); const [loading, setLoading] = useState(true); useEffect(() => { apiFetch("/dashboard/heatmap") - .then((res) => setData((res.data as HeatmapRow[]) || [])) + .then((res) => { + const rows = (res.data as HeatmapRow[]) || []; + setData(companyId ? rows.filter((r) => r.company_id === companyId) : rows); + }) .catch(() => {}) .finally(() => setLoading(false)); - }, []); + }, [companyId]); if (loading) return ; if (!data.length) return ;