feat: 态势感知模块 - 实时监控面板+后端API

This commit is contained in:
freedakgmail
2026-07-30 09:01:01 +08:00
parent 6bab0ad84a
commit 268e085ffa
9 changed files with 1294 additions and 7 deletions
+36
View File
@@ -53,6 +53,11 @@ export function DashboardPage() {
queryFn: () => api.get('/platform/economics'),
})
const { data: alertsData } = useQuery({
queryKey: ['sa-alerts'],
queryFn: () => api.get('/situational-awareness/alerts'),
})
const pageLoading = odLoading || dailyLoading || riskLoading || priorityLoading || loopLoading
const od = (overview as any)?.data
@@ -62,6 +67,8 @@ export function DashboardPage() {
const lh = (loopHealth as any)?.data
const quadrantRows = (quadrantData as any)?.data || []
const platformRows = (platformData as any)?.data || []
const alerts = ((alertsData as any)?.data?.alerts || []) as any[]
const alertSummary = (alertsData as any)?.data
const QUADRANT_COLORS: Record<string, string> = {
'明星门店': '#22c55e', '稳健经营': '#3b82f6', '规模承压': '#eab308', '重点改善': '#ef4444', '高效潜力': '#a855f7',
@@ -220,6 +227,35 @@ export function DashboardPage() {
</CollapsibleSection>
)}
{/* 态势感知预警 */}
{alerts.length > 0 && (
<CollapsibleSection
title="态势感知预警"
subtitle="营收异动 · 成本异动 · 人力异动 · 平台依赖 · 任务逾期"
headerRight={
<div className="flex gap-2">
{alertSummary?.red > 0 && <span className="rounded-md bg-red-50 px-2 py-0.5 text-xs font-medium text-red-700"> {alertSummary.red}</span>}
{alertSummary?.orange > 0 && <span className="rounded-md bg-orange-50 px-2 py-0.5 text-xs font-medium text-orange-700"> {alertSummary.orange}</span>}
<span className="text-xs text-muted-foreground"> {alertSummary?.total || 0} </span>
</div>
}
>
<div className="grid gap-2 md:grid-cols-2">
{alerts.slice(0, 6).map((a, i) => (
<div key={i} className={`flex items-start gap-2 rounded-md border p-2.5 ${a.level === 'red' ? 'border-red-200 bg-red-50/50' : a.level === 'orange' ? 'border-orange-200 bg-orange-50/50' : 'border-yellow-200 bg-yellow-50/50'}`}>
<span className={`mt-0.5 flex h-5 w-5 shrink-0 items-center justify-center rounded-full text-[10px] font-bold ${a.level === 'red' ? 'text-red-700' : a.level === 'orange' ? 'text-orange-700' : 'text-yellow-700'}`}>
{a.level === 'red' ? '红' : a.level === 'orange' ? '橙' : '黄'}
</span>
<div className="min-w-0 flex-1">
<p className="truncate text-xs font-medium">{a.title}</p>
<p className="mt-0.5 truncate text-xs text-muted-foreground">{a.detail}</p>
</div>
</div>
))}
</div>
</CollapsibleSection>
)}
{/* 图表区 */}
<div className="grid gap-4 lg:grid-cols-2">
<CollapsibleSection title="日度实收趋势" subtitle="近30天实收变化">