diff --git a/apps/web/src/pages/health/AiAnalysisList.tsx b/apps/web/src/pages/health/AiAnalysisList.tsx index b30e316..12be95e 100644 --- a/apps/web/src/pages/health/AiAnalysisList.tsx +++ b/apps/web/src/pages/health/AiAnalysisList.tsx @@ -1,4 +1,5 @@ import { useEffect, useState, useCallback, useMemo } from 'react'; +import { useSearchParams, Link } from 'react-router-dom'; import { Table, Select, Tag, Space, Button, message, Typography } from 'antd'; import { RobotOutlined, @@ -247,12 +248,15 @@ function SuggestionPanel({ analysisId, isDark }: { analysisId: string; isDark: b // --------------------------------------------------------------------------- export default function AiAnalysisList() { + const [searchParams] = useSearchParams(); + const urlPatientId = searchParams.get('patient_id'); const [data, setData] = useState([]); const [total, setTotal] = useState(0); const [loading, setLoading] = useState(false); - const [query, setQuery] = useState<{ page: number; page_size: number; analysis_type?: string }>({ + const [query, setQuery] = useState<{ page: number; page_size: number; analysis_type?: string; patient_id?: string }>({ page: 1, page_size: 20, + patient_id: urlPatientId || undefined, }); const [expandedId, setExpandedId] = useState(null); const [detail, setDetail] = useState(null); @@ -313,12 +317,14 @@ export default function AiAnalysisList() { ), }, { - title: '患者 ID', + title: '患者', dataIndex: 'patient_id', key: 'patient_id', - width: 120, + width: 140, render: (v: string) => ( - {v.slice(0, 8)} + + {v.slice(0, 8)} + ), }, { diff --git a/apps/web/src/pages/health/AppointmentList.tsx b/apps/web/src/pages/health/AppointmentList.tsx index 36fcb14..fcee3c8 100644 --- a/apps/web/src/pages/health/AppointmentList.tsx +++ b/apps/web/src/pages/health/AppointmentList.tsx @@ -1,4 +1,5 @@ import { useState, useCallback, useEffect, useMemo } from 'react'; +import { useSearchParams } from 'react-router-dom'; import { Table, Button, @@ -83,6 +84,8 @@ interface AppointmentFilters { } export default function AppointmentList() { + const [searchParams] = useSearchParams(); + const urlPatientId = searchParams.get('patient_id'); const [drawerOpen, setDrawerOpen] = useState(false); const [submitting, setSubmitting] = useState(false); @@ -104,7 +107,7 @@ export default function AppointmentList() { page_size: pageSize, status: filters.status || undefined, date: dateStart === dateEnd ? dateStart : undefined, - patient_id: undefined, // 后端暂不支持 patientSearch 文本搜索 + patient_id: urlPatientId || undefined, }); }, [], diff --git a/apps/web/src/pages/health/ConsultationList.tsx b/apps/web/src/pages/health/ConsultationList.tsx index 31fd5b7..542f5c6 100644 --- a/apps/web/src/pages/health/ConsultationList.tsx +++ b/apps/web/src/pages/health/ConsultationList.tsx @@ -12,7 +12,7 @@ import { } from 'antd'; import { PlusOutlined, CloseCircleOutlined } from '@ant-design/icons'; import type { ColumnsType, TablePaginationConfig } from 'antd/es/table'; -import { useNavigate } from 'react-router-dom'; +import { useNavigate, useSearchParams } from 'react-router-dom'; import { consultationApi, type Session, type CreateSessionReq } from '../../api/health/consultations'; import { StatusTag } from './components/StatusTag'; import { PatientSelect } from './components/PatientSelect'; @@ -49,6 +49,8 @@ interface ConsultationFilters { export default function ConsultationList() { const navigate = useNavigate(); + const [searchParams] = useSearchParams(); + const urlPatientId = searchParams.get('patient_id'); // Close session const [closingId, setClosingId] = useState(null); @@ -63,13 +65,14 @@ export default function ConsultationList() { async (page: number, pageSize: number, filters: ConsultationFilters) => { const params: Record = { page, page_size: pageSize }; if (filters.status) params.status = filters.status; + if (urlPatientId) params.patient_id = urlPatientId; if (filters.dateRange) { params.created_start = filters.dateRange[0]; params.created_end = filters.dateRange[1]; } return consultationApi.listSessions(params as Parameters[0]); }, - [], + [urlPatientId], ); const { diff --git a/apps/web/src/pages/health/DialysisManageList.tsx b/apps/web/src/pages/health/DialysisManageList.tsx index 589c5bd..070c37a 100644 --- a/apps/web/src/pages/health/DialysisManageList.tsx +++ b/apps/web/src/pages/health/DialysisManageList.tsx @@ -1,5 +1,6 @@ -import { useState, useCallback, useMemo } from 'react'; +import { useState, useCallback, useMemo, useEffect } from 'react'; import { Table, Tag, Button, Modal, Form, InputNumber, DatePicker, Select, message, Popconfirm, Space, Input } from 'antd'; +import { useSearchParams } from 'react-router-dom'; import { PlusOutlined, EditOutlined, DeleteOutlined, AuditOutlined } from '@ant-design/icons'; import { dayjs } from '../../utils/dayjs'; import type { Dayjs } from 'dayjs'; @@ -27,7 +28,9 @@ interface PatientOption { } export default function DialysisManageList() { - const [selectedPatientId, setSelectedPatientId] = useState(null); + const [searchParams] = useSearchParams(); + const urlPatientId = searchParams.get('patient_id'); + const [selectedPatientId, setSelectedPatientId] = useState(urlPatientId); const [patientOptions, setPatientOptions] = useState([]); const [patientSearch, setPatientSearch] = useState(''); const [modalOpen, setModalOpen] = useState(false); @@ -38,6 +41,15 @@ export default function DialysisManageList() { const [reviewRecord, setReviewRecord] = useState(null); const [reviewSubmitting, setReviewSubmitting] = useState(false); + // URL 带了 patient_id 时预加载患者选项 + useEffect(() => { + if (urlPatientId) { + patientApi.get(urlPatientId).then((p) => { + if (p) setPatientOptions([{ id: p.id, name: p.name }]); + }).catch(() => {}); + } + }, [urlPatientId]); + const searchPatients = async (keyword: string) => { if (!keyword.trim()) { setPatientOptions([]); diff --git a/apps/web/src/pages/health/FollowUpTaskList.tsx b/apps/web/src/pages/health/FollowUpTaskList.tsx index bc568a0..f4da370 100644 --- a/apps/web/src/pages/health/FollowUpTaskList.tsx +++ b/apps/web/src/pages/health/FollowUpTaskList.tsx @@ -1,4 +1,5 @@ import { useState, useCallback } from 'react'; +import { useSearchParams } from 'react-router-dom'; import { Table, Select, @@ -61,6 +62,9 @@ interface AssignFormValues { } export default function FollowUpTaskList() { + const [searchParams] = useSearchParams(); + const urlPatientId = searchParams.get('patient_id'); + // --- Paginated data with usePaginatedData --- const fetchFn = useCallback( async (page: number, pageSize: number, filters: FollowUpFilters) => { @@ -68,13 +72,14 @@ export default function FollowUpTaskList() { if (filters.status) params.status = filters.status; if (filters.followUpType) params.follow_up_type = filters.followUpType; if (filters.assigneeId) params.assigned_to = filters.assigneeId; + if (urlPatientId) params.patient_id = urlPatientId; if (filters.dateRange) { params.planned_date_start = filters.dateRange[0]; params.planned_date_end = filters.dateRange[1]; } return followUpApi.listTasks(params as Parameters[0]); }, - [], + [urlPatientId], ); const {