From 493b479373026582f3ede5d90e640792d3944037 Mon Sep 17 00:00:00 2001 From: iven Date: Tue, 28 Apr 2026 20:01:11 +0800 Subject: [PATCH] =?UTF-8?q?feat(web):=20DoctorDashboard=20=E9=9B=86?= =?UTF-8?q?=E6=88=90=E5=91=8A=E8=AD=A6=E6=91=98=E8=A6=81=E5=8D=A1=E7=89=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 在医生工作台新增待处理告警摘要区域,展示最近 5 条 pending 状态告警,点击「查看全部」跳转告警仪表盘。 --- .../StatisticsDashboard/DoctorDashboard.tsx | 78 ++++++++++++++++++- 1 file changed, 76 insertions(+), 2 deletions(-) diff --git a/apps/web/src/pages/health/StatisticsDashboard/DoctorDashboard.tsx b/apps/web/src/pages/health/StatisticsDashboard/DoctorDashboard.tsx index 654a82c..20fb82c 100644 --- a/apps/web/src/pages/health/StatisticsDashboard/DoctorDashboard.tsx +++ b/apps/web/src/pages/health/StatisticsDashboard/DoctorDashboard.tsx @@ -1,18 +1,38 @@ -import { Row, Col, Card, Statistic, List, Tag, Spin, Typography, Flex } from 'antd'; +import { Row, Col, Card, Statistic, List, Tag, Spin, Typography, Flex, Space, Button } from 'antd'; import { TeamOutlined, MessageOutlined, SafetyCertificateOutlined, MedicineBoxOutlined, ArrowUpOutlined, + AlertOutlined, + RightOutlined, } from '@ant-design/icons'; import { useEffect, useState, useCallback } from 'react'; +import { useNavigate } from 'react-router-dom'; import { pointsApi, type PersonalStats } from '../../../api/health/points'; +import { alertApi, type Alert } from '../../../api/health/alerts'; import { useStatsData } from './useStatsData'; import { useCountUp } from '../../../hooks/useCountUp'; +const SEVERITY_COLOR: Record = { + info: 'default', + warning: 'orange', + critical: 'red', + urgent: 'magenta', +}; + +const SEVERITY_LABEL: Record = { + info: '提示', + warning: '警告', + critical: '严重', + urgent: '紧急', +}; + export function DoctorDashboard() { + const navigate = useNavigate(); const [personal, setPersonal] = useState(null); + const [recentAlerts, setRecentAlerts] = useState([]); const [loading, setLoading] = useState(true); const { consultationStats } = useStatsData(); const myPatientsCount = useCountUp(personal?.my_patients ?? 0); @@ -29,11 +49,21 @@ export function DoctorDashboard() { } }, []); - useEffect(() => { fetchPersonal(); }, [fetchPersonal]); + const fetchRecentAlerts = useCallback(async () => { + try { + const result = await alertApi.list({ status: 'pending', page: 1, page_size: 5 }); + setRecentAlerts(result.data); + } catch { + // 静默降级 + } + }, []); + + useEffect(() => { fetchPersonal(); fetchRecentAlerts(); }, [fetchPersonal, fetchRecentAlerts]); if (loading && !personal) return ; const p = personal; + const pendingAlertCount = recentAlerts.length; return (
@@ -63,6 +93,50 @@ export function DoctorDashboard() { )} + {/* 告警摘要卡片 */} + {pendingAlertCount > 0 && ( + + + + {pendingAlertCount} 条待处理告警 + + } + extra={ + + } + > + ( + + + + {SEVERITY_LABEL[alert.severity] ?? alert.severity} + + {alert.title} + + {new Date(alert.created_at).toLocaleString('zh-CN')} + + + + )} + /> + + + )} + {/* 统计卡片 */}