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')} + + + + )} + /> + + + )} + {/* 统计卡片 */}