import { useCallback, useState } from 'react'; import { Table, Button, Modal, Form, InputNumber, DatePicker, Input, message, Typography, Tooltip } from 'antd'; import { PlusOutlined, InfoCircleOutlined } from '@ant-design/icons'; import type { Dayjs } from 'dayjs'; import { healthDataApi } from '../../../api/health/healthData'; import type { VitalSigns } from '../../../api/health/healthData'; import { VitalSignsChart } from './VitalSignsChart'; import { usePaginatedData } from '../../../hooks/usePaginatedData'; const { Text } = Typography; interface Props { patientId: string; } const columns = [ { title: '记录日期', dataIndex: 'record_date', key: 'record_date', width: 110, fixed: 'left' as const, }, { title: () => ( 收缩压(晨) ), dataIndex: 'systolic_bp_morning', key: 'systolic_bp_morning', width: 110, render: (v?: number) => (v != null ? `${v} mmHg` : '-'), }, { title: () => ( 舒张压(晨) ), dataIndex: 'diastolic_bp_morning', key: 'diastolic_bp_morning', width: 110, render: (v?: number) => (v != null ? `${v} mmHg` : '-'), }, { title: '心率', dataIndex: 'heart_rate', key: 'heart_rate', width: 80, render: (v?: number) => (v != null ? `${v} bpm` : '-'), }, { title: '体重', dataIndex: 'weight', key: 'weight', width: 80, render: (v?: number) => (v != null ? `${v} kg` : '-'), }, { title: '血糖', dataIndex: 'blood_sugar', key: 'blood_sugar', width: 90, render: (v?: number) => (v != null ? `${v} mmol/L` : '-'), }, ]; export function VitalSignsTab({ patientId }: Props) { const [modalOpen, setModalOpen] = useState(false); const [form] = Form.useForm(); const [submitting, setSubmitting] = useState(false); const fetcher = useCallback( async (page: number, pageSize: number) => { return healthDataApi.listVitalSigns(patientId, { page, page_size: pageSize }); }, [patientId], ); const { data, total, page, loading, refresh } = usePaginatedData(fetcher, 10); const handleCreate = async (values: { record_date: Dayjs; systolic_bp_morning?: number; diastolic_bp_morning?: number; heart_rate?: number; weight?: number; blood_sugar?: number; water_intake_ml?: number; urine_output_ml?: number; notes?: string; }) => { setSubmitting(true); try { await healthDataApi.createVitalSigns(patientId, { record_date: values.record_date.format('YYYY-MM-DD'), systolic_bp_morning: values.systolic_bp_morning, diastolic_bp_morning: values.diastolic_bp_morning, heart_rate: values.heart_rate, weight: values.weight, blood_sugar: values.blood_sugar, water_intake_ml: values.water_intake_ml, urine_output_ml: values.urine_output_ml, notes: values.notes, }); message.success('体征数据录入成功'); setModalOpen(false); form.resetFields(); refresh(); } catch { message.error('录入失败'); } finally { setSubmitting(false); } }; // 最近一次数据摘要 const latest = data.length > 0 ? data[0] : null; return (
{/* 趋势图 */}
{/* 最新记录摘要条 */} {latest && (
最新记录({latest.record_date}) {latest.systolic_bp_morning != null && ( 收缩压 {latest.systolic_bp_morning} mmHg )} {latest.diastolic_bp_morning != null && ( 舒张压 {latest.diastolic_bp_morning} mmHg )} {latest.heart_rate != null && ( 心率 {latest.heart_rate} bpm )} {latest.weight != null && ( 体重 {latest.weight} kg )} {latest.blood_sugar != null && ( 血糖 {latest.blood_sugar} mmol/L )}
)} {/* 操作栏 + 表格 */}
历史记录(共 {total} 条)
refresh(p), showTotal: (t) => `共 ${t} 条`, size: 'small', style: { margin: 0 }, }} scroll={{ x: 600 }} /> setModalOpen(false)} onOk={() => form.submit()} confirmLoading={submitting} destroyOnClose width={600} >
); }