From 72592d3d77e70a20bc1470a2274d57a3b624d973 Mon Sep 17 00:00:00 2001 From: iven Date: Sat, 25 Apr 2026 22:38:46 +0800 Subject: [PATCH] =?UTF-8?q?fix(web):=20=E9=93=BE=E8=B7=AF=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E4=BF=AE=E5=A4=8D=20=E2=80=94=20=E5=81=A5=E5=BA=B7?= =?UTF-8?q?=E8=AE=B0=E5=BD=95=E6=9E=9A=E4=B8=BE=20+=20=E9=A2=84=E7=BA=A6?= =?UTF-8?q?=E5=90=8D=E7=A7=B0=E8=A7=A3=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - HealthRecordsTab: record_type 从自由文本 Input 改为 Select 枚举 (checkup/outpatient/inpatient → 体检/门诊/住院),匹配后端校验规则 - AppointmentList: 添加批量患者/医生名称解析,列表不再显示截断 UUID Co-Authored-By: Claude Opus 4.7 --- apps/web/src/pages/health/AppointmentList.tsx | 33 +++++++++++++++++-- .../health/components/HealthRecordsTab.tsx | 22 ++++++++++--- 2 files changed, 47 insertions(+), 8 deletions(-) diff --git a/apps/web/src/pages/health/AppointmentList.tsx b/apps/web/src/pages/health/AppointmentList.tsx index ad8f087..b8bd509 100644 --- a/apps/web/src/pages/health/AppointmentList.tsx +++ b/apps/web/src/pages/health/AppointmentList.tsx @@ -21,6 +21,8 @@ import { } from '@ant-design/icons'; import type { Dayjs } from 'dayjs'; import { appointmentApi, type Appointment, type CreateAppointmentReq } from '../../api/health/appointments'; +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'; @@ -83,6 +85,7 @@ export default function AppointmentList() { // 患者选择状态(受控组件,不挂在 Form.Item 上) const [selectedPatientId, setSelectedPatientId] = useState(undefined); const [selectedDoctorId, setSelectedDoctorId] = useState(undefined); + const [nameCache, setNameCache] = useState>({}); // ---- 数据获取 ---- const fetchData = useCallback(async (p = page, ps = pageSize) => { @@ -94,7 +97,31 @@ export default function AppointmentList() { status: statusFilter || undefined, date: dateFilter ? dateFilter.format('YYYY-MM-DD') : undefined, }); - setData(result.data); + const items = result.data; + // 批量解析患者和医生名称 + const missingIds = new Set(); + items.forEach((a) => { + if (a.patient_id && !nameCache[a.patient_id]) missingIds.add(a.patient_id); + if (a.doctor_id && !nameCache[a.doctor_id]) missingIds.add(a.doctor_id); + }); + const newCache: Record = {}; + await Promise.all( + Array.from(missingIds).map(async (id) => { + try { + const p = await patientApi.get(id); + newCache[id] = p.name; + } catch { + try { + const d = await doctorApi.get(id); + newCache[id] = d.name; + } catch { /* ignore */ } + } + }), + ); + if (Object.keys(newCache).length > 0) { + setNameCache((prev) => ({ ...prev, ...newCache })); + } + setData(items); setTotal(result.total); } catch { message.error('加载预约列表失败'); @@ -218,7 +245,7 @@ export default function AppointmentList() { key: 'patient_name', width: 100, render: (_: unknown, record: Appointment) => - record.patient_name ?? record.patient_id.slice(0, 8), + record.patient_name ?? nameCache[record.patient_id] ?? record.patient_id.slice(0, 8), }, { title: '医护', @@ -226,7 +253,7 @@ export default function AppointmentList() { key: 'doctor_name', width: 100, render: (_: unknown, record: Appointment) => { - return record.doctor_name || record.doctor_id?.slice(0, 8) || '-'; + return record.doctor_name || nameCache[record.doctor_id ?? ''] || record.doctor_id?.slice(0, 8) || '-'; }, }, { diff --git a/apps/web/src/pages/health/components/HealthRecordsTab.tsx b/apps/web/src/pages/health/components/HealthRecordsTab.tsx index 0fbe033..f89e092 100644 --- a/apps/web/src/pages/health/components/HealthRecordsTab.tsx +++ b/apps/web/src/pages/health/components/HealthRecordsTab.tsx @@ -1,5 +1,5 @@ import { useCallback, useState } from 'react'; -import { Table, Tag, Button, Modal, Form, Input, DatePicker, message } from 'antd'; +import { Table, Tag, Button, Modal, Form, Select, DatePicker, Input, message } from 'antd'; import { PlusOutlined } from '@ant-design/icons'; import type { Dayjs } from 'dayjs'; import { healthDataApi } from '../../../api/health/healthData'; @@ -10,8 +10,20 @@ interface Props { patientId: string; } +const RECORD_TYPE_OPTIONS = [ + { value: 'checkup', label: '体检' }, + { value: 'outpatient', label: '门诊' }, + { value: 'inpatient', label: '住院' }, +]; + +const RECORD_TYPE_MAP: Record = { + checkup: '体检', + outpatient: '门诊', + inpatient: '住院', +}; + const columns = [ - { title: '记录类型', dataIndex: 'record_type', key: 'record_type', width: 120, render: (v: string) => {v} }, + { title: '记录类型', dataIndex: 'record_type', key: 'record_type', width: 120, render: (v: string) => {RECORD_TYPE_MAP[v] || v} }, { title: '记录日期', dataIndex: 'record_date', key: 'record_date', width: 120 }, { title: '内容', dataIndex: 'content', key: 'content', ellipsis: true }, { title: '创建时间', dataIndex: 'created_at', key: 'created_at', width: 170, render: (v: string) => new Date(v).toLocaleString('zh-CN') }, @@ -32,7 +44,7 @@ export function HealthRecordsTab({ patientId }: Props) { const { data, total, page, loading, refresh } = usePaginatedData(fetcher, 10); const handleCreate = async (values: { - record_type: string; + record_type: 'checkup' | 'outpatient' | 'inpatient'; record_date: Dayjs; content?: string; }) => { @@ -84,8 +96,8 @@ export function HealthRecordsTab({ patientId }: Props) { width={520} >
- - + +