import { useState, useCallback } from 'react'; import { Button, Card, Spin, Empty, Alert } from 'antd'; import { ThunderboltOutlined, ReloadOutlined } from '@ant-design/icons'; import { startAnalysis, type AnalysisType } from '../../api/ai/analysisSse'; import { AuthButton } from '../AuthButton'; export interface AiAnalysisCardProps { analysisType: AnalysisType; sourceRef: string; patientId?: string; triggerLabel?: string; permission?: string; metrics?: string[]; taskId?: string; } type AnalysisState = 'idle' | 'loading' | 'success' | 'error'; export function AiAnalysisCard({ analysisType, sourceRef, triggerLabel = 'AI 分析', permission = 'ai.analysis.manage', metrics, taskId, }: AiAnalysisCardProps) { const [state, setState] = useState('idle'); const [content, setContent] = useState(''); const [errorMsg, setErrorMsg] = useState(''); const handleStart = useCallback(async () => { setState('loading'); setContent(''); setErrorMsg(''); const body: Record = {}; if (analysisType === 'lab-report' || analysisType === 'report-summary') { body.report_id = sourceRef; } if (analysisType === 'trends' || analysisType === 'checkup-plan') { body.patient_id = sourceRef; } if (analysisType === 'follow-up-summary') { body.source_id = taskId || sourceRef; } if (metrics) { body.metrics = metrics; } try { await startAnalysis(analysisType, body, { onChunk: (chunk) => setContent(prev => prev + chunk), onError: (msg) => { setErrorMsg(msg); setState('error'); }, onDone: () => setState('success'), }); } catch { setErrorMsg('分析请求失败'); setState('error'); } }, [analysisType, sourceRef, metrics, taskId]); const handleReset = useCallback(() => { setState('idle'); setContent(''); setErrorMsg(''); }, []); const TriggerButton = permission ? ( ) : ( ); if (state === 'idle') { return TriggerButton; } if (state === 'loading') { return (
} />
AI 正在分析...
); } if (state === 'error') { return ( } onClick={handleStart}> 重试 } /> ); } if (!content) { return ; } return ( {triggerLabel}结果} size="small" style={{ marginTop: 12 }} extra={ } >
{content}
); }