From f934ca0eaf8c8454277250f43f82e91ab1968fe0 Mon Sep 17 00:00:00 2001 From: iven Date: Mon, 27 Apr 2026 09:47:37 +0800 Subject: [PATCH] =?UTF-8?q?perf(web):=20ConsultationList/FollowUpTaskList?= =?UTF-8?q?=20=E7=A7=BB=E9=99=A4=20N+1=20nameCache?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 后端已内联 patient_name/doctor_name,前端移除逐条查询。 Session/FollowUpTask 接口添加 name 可选字段。 FollowUpTaskList 保留 assignee 的 getUser 查询(users 表未内联)。 --- apps/web/src/api/health/consultations.ts | 2 + apps/web/src/api/health/followUp.ts | 1 + .../web/src/pages/health/ConsultationList.tsx | 75 +++---------------- .../web/src/pages/health/FollowUpTaskList.tsx | 63 ++++++---------- 4 files changed, 36 insertions(+), 105 deletions(-) diff --git a/apps/web/src/api/health/consultations.ts b/apps/web/src/api/health/consultations.ts index 6b12308..a23eff6 100644 --- a/apps/web/src/api/health/consultations.ts +++ b/apps/web/src/api/health/consultations.ts @@ -6,6 +6,8 @@ export interface Session { id: string; patient_id: string; doctor_id?: string; + patient_name?: string; + doctor_name?: string; consultation_type: string; status: string; last_message_at?: string; diff --git a/apps/web/src/api/health/followUp.ts b/apps/web/src/api/health/followUp.ts index eee6215..1f4aec9 100644 --- a/apps/web/src/api/health/followUp.ts +++ b/apps/web/src/api/health/followUp.ts @@ -6,6 +6,7 @@ export interface FollowUpTask { id: string; patient_id: string; assigned_to?: string; + patient_name?: string; follow_up_type: string; planned_date: string; status: string; diff --git a/apps/web/src/pages/health/ConsultationList.tsx b/apps/web/src/pages/health/ConsultationList.tsx index 29e3833..d62f66b 100644 --- a/apps/web/src/pages/health/ConsultationList.tsx +++ b/apps/web/src/pages/health/ConsultationList.tsx @@ -13,8 +13,6 @@ import { PlusOutlined, CloseCircleOutlined } from '@ant-design/icons'; import type { ColumnsType, TablePaginationConfig } from 'antd/es/table'; import { useNavigate } from 'react-router-dom'; import { consultationApi, type Session, type CreateSessionReq } from '../../api/health/consultations'; -import { patientApi } from '../../api/health/patients'; -import { doctorApi } from '../../api/health/doctors'; import { StatusTag } from './components/StatusTag'; import { PatientSelect } from './components/PatientSelect'; import { DoctorSelect } from './components/DoctorSelect'; @@ -69,10 +67,6 @@ export default function ConsultationList() { // Close session const [closingId, setClosingId] = useState(null); - // Label caches - const [patientLabels, setPatientLabels] = useState>({}); - const [doctorLabels, setDoctorLabels] = useState>({}); - const isDark = useThemeMode(); // --- Data fetching --- @@ -82,48 +76,12 @@ export default function ConsultationList() { const result = await consultationApi.listSessions(params); setSessions(result.data); setTotal(result.total); - - // 批量解析患者名称 - const patientIds = [...new Set(result.data.map((s) => s.patient_id))]; - const missingPatientIds = patientIds.filter((id) => !patientLabels[id]); - if (missingPatientIds.length > 0) { - const newLabels: Record = {}; - await Promise.all( - missingPatientIds.map(async (id) => { - try { - const detail = await patientApi.get(id); - newLabels[id] = detail.name; - } catch { - newLabels[id] = id.slice(0, 8); - } - }), - ); - setPatientLabels((prev) => ({ ...prev, ...newLabels })); - } - - // 批量解析医生名称 - const doctorIds = [...new Set(result.data.map((s) => s.doctor_id).filter(Boolean))] as string[]; - const missingDoctorIds = doctorIds.filter((id) => !doctorLabels[id]); - if (missingDoctorIds.length > 0) { - const newLabels: Record = {}; - await Promise.all( - missingDoctorIds.map(async (id) => { - try { - const detail = await doctorApi.get(id); - newLabels[id] = detail.name; - } catch { - newLabels[id] = id.slice(0, 8); - } - }), - ); - setDoctorLabels((prev) => ({ ...prev, ...newLabels })); - } } catch { message.error('加载咨询列表失败'); } finally { setLoading(false); } - }, [patientLabels, doctorLabels]); + }, []); useEffect(() => { fetchSessions(query); @@ -142,14 +100,6 @@ export default function ConsultationList() { })); }; - const handlePatientLabel = (id: string, label: string) => { - setPatientLabels((prev) => ({ ...prev, [id]: label })); - }; - - const handleDoctorLabel = (id: string, label: string) => { - setDoctorLabels((prev) => ({ ...prev, [id]: label })); - }; - // Create session const handleCreate = async () => { try { @@ -195,18 +145,19 @@ export default function ConsultationList() { const columns: ColumnsType = [ { title: '患者', - dataIndex: 'patient_id', - key: 'patient_id', + dataIndex: 'patient_name', + key: 'patient_name', width: 140, - render: (id: string) => patientLabels[id] || id.slice(0, 8), + render: (_: unknown, record: Session) => + record.patient_name ?? record.patient_id.slice(0, 8), }, { title: '医护', - dataIndex: 'doctor_id', - key: 'doctor_id', + dataIndex: 'doctor_name', + key: 'doctor_name', width: 140, - render: (id: string | undefined) => - id ? doctorLabels[id] || id.slice(0, 8) : '-', + render: (_: unknown, record: Session) => + record.doctor_name ?? record.doctor_id?.slice(0, 8) ?? '-', }, { title: '咨询类型', @@ -383,14 +334,10 @@ export default function ConsultationList() { label="患者" rules={[{ required: true, message: '请选择患者' }]} > - handlePatientLabel(_val, label)} - /> + - handleDoctorLabel(_val, label)} - /> +