import { useCallback, useState, useMemo } from 'react'; import { Table, Tag, Button, Modal, Form, Input, DatePicker, message, Popconfirm, Space, Card } from 'antd'; import { PlusOutlined, EditOutlined, DeleteOutlined, AuditOutlined, ThunderboltOutlined } from '@ant-design/icons'; import { dayjs } from '../../../utils/dayjs'; import type { Dayjs } from 'dayjs'; import { healthDataApi } from '../../../api/health/healthData'; import type { LabReport } from '../../../api/health/healthData'; import { usePaginatedData } from '../../../hooks/usePaginatedData'; import { AuthButton } from '../../../components/AuthButton'; import { handleApiError } from '../../../api/client'; import { startAnalysis } from '../../../api/ai/analysisSse'; interface Props { patientId: string; } const STATUS_MAP: Record = { pending: { color: 'orange', label: '待审核' }, reviewed: { color: 'green', label: '已审核' }, }; export function LabReportsTab({ patientId }: Props) { const [modalOpen, setModalOpen] = useState(false); const [editingRecord, setEditingRecord] = useState(null); const [form] = Form.useForm(); const [submitting, setSubmitting] = useState(false); const [reviewOpen, setReviewOpen] = useState(false); const [reviewRecord, setReviewRecord] = useState(null); const [reviewNotes, setReviewNotes] = useState(''); const [reviewSubmitting, setReviewSubmitting] = useState(false); const [analyzingReportId, setAnalyzingReportId] = useState(null); const [analysisContent, setAnalysisContent] = useState(''); const handleAiAnalysis = async (reportId: string) => { setAnalyzingReportId(reportId); setAnalysisContent(''); await startAnalysis('lab-report', { report_id: reportId }, { onChunk: (content) => setAnalysisContent(prev => prev + content), onError: (msg) => { message.error(msg); setAnalyzingReportId(null); }, onDone: () => { message.success('AI 分析完成'); setAnalyzingReportId(null); }, }); }; const fetcher = useCallback( async (page: number, pageSize: number) => { return healthDataApi.listLabReports(patientId, { page, page_size: pageSize }); }, [patientId], ); const { data, total, page, loading, refresh } = usePaginatedData(fetcher, 10); const openCreateModal = () => { setEditingRecord(null); form.resetFields(); setModalOpen(true); }; const openEditModal = (record: LabReport) => { setEditingRecord(record); form.setFieldsValue({ report_date: dayjs(record.report_date), report_type: record.report_type, doctor_interpretation: record.doctor_interpretation, }); setModalOpen(true); }; const handleSubmit = async (values: { report_date: Dayjs; report_type: string; doctor_interpretation?: string; }) => { setSubmitting(true); try { if (editingRecord) { await healthDataApi.updateLabReport(patientId, editingRecord.id, { report_date: values.report_date.format('YYYY-MM-DD'), report_type: values.report_type, doctor_interpretation: values.doctor_interpretation, version: editingRecord.version, }); message.success('化验报告更新成功'); } else { await healthDataApi.createLabReport(patientId, { report_date: values.report_date.format('YYYY-MM-DD'), report_type: values.report_type, doctor_interpretation: values.doctor_interpretation, }); message.success('化验报告添加成功'); } setModalOpen(false); setEditingRecord(null); form.resetFields(); refresh(); } catch (err) { handleApiError(err, editingRecord ? '更新失败' : '添加失败'); } finally { setSubmitting(false); } }; const handleDelete = async (record: LabReport) => { try { await healthDataApi.deleteLabReport(patientId, record.id); message.success('化验报告删除成功'); refresh(); } catch (err) { handleApiError(err, '删除失败'); } }; const openReviewModal = (record: LabReport) => { setReviewRecord(record); setReviewNotes(record.doctor_notes || ''); setReviewOpen(true); }; const handleReview = async () => { if (!reviewRecord) return; setReviewSubmitting(true); try { await healthDataApi.reviewLabReport(patientId, reviewRecord.id, { version: reviewRecord.version, doctor_notes: reviewNotes || undefined, }); message.success('审核完成'); setReviewOpen(false); setReviewRecord(null); setReviewNotes(''); refresh(); } catch (err) { handleApiError(err, '审核失败'); } finally { setReviewSubmitting(false); } }; const columns = useMemo(() => [ { title: '报告日期', dataIndex: 'report_date', key: 'report_date', width: 120 }, { title: '报告类型', dataIndex: 'report_type', key: 'report_type', width: 120, render: (v: string) => {v} }, { title: '状态', dataIndex: 'status', key: 'status', width: 90, render: (v: string) => { const m = STATUS_MAP[v]; return m ? {m.label} : {v}; }, }, { title: '医生解读', dataIndex: 'doctor_interpretation', key: 'doctor_interpretation', ellipsis: true }, { title: '创建时间', dataIndex: 'created_at', key: 'created_at', width: 170, render: (v: string) => new Date(v).toLocaleString('zh-CN') }, { title: '操作', key: 'actions', width: 180, render: (_: unknown, record: LabReport) => ( {record.status === 'pending' && ( )} handleDelete(record)} okText="确认" cancelText="取消"> ), }, ], [openEditModal, handleDelete]); return (
refresh(p), showTotal: (t) => `共 ${t} 条`, style: { margin: 0 }, }} /> {analysisContent && (
{analysisContent}
)} { setModalOpen(false); setEditingRecord(null); }} onOk={() => form.submit()} confirmLoading={submitting} destroyOnClose width={520} >
{ setReviewOpen(false); setReviewRecord(null); }} onOk={handleReview} confirmLoading={reviewSubmitting} destroyOnClose width={480} > {reviewRecord && (

报告类型:{reviewRecord.report_type}

报告日期:{reviewRecord.report_date}

{reviewRecord.doctor_interpretation && (

医生解读:{reviewRecord.doctor_interpretation}

)}
setReviewNotes(e.target.value)} placeholder="填写审核意见(可选)" />
)}
); }