diff --git a/apps/web/src/api/ai/analysisSse.ts b/apps/web/src/api/ai/analysisSse.ts index cecf879..4dee7af 100644 --- a/apps/web/src/api/ai/analysisSse.ts +++ b/apps/web/src/api/ai/analysisSse.ts @@ -1,9 +1,10 @@ -export type AnalysisType = 'lab-report' | 'trends' | 'checkup-plan' | 'report-summary'; +export type AnalysisType = 'lab-report' | 'trends' | 'checkup-plan' | 'report-summary' | 'follow-up-summary'; interface AnalyzeBody { report_id?: string; patient_id?: string; metrics?: string[]; + source_id?: string; } const ENDPOINT_MAP: Record = { @@ -11,6 +12,7 @@ const ENDPOINT_MAP: Record = { 'trends': '/ai/analyze/trends', 'checkup-plan': '/ai/analyze/checkup-plan', 'report-summary': '/ai/analyze/report-summary', + 'follow-up-summary': '/ai/analyze/follow-up-summary', }; export interface SseCallbacks { diff --git a/apps/web/src/components/ai/AiAnalysisCard.tsx b/apps/web/src/components/ai/AiAnalysisCard.tsx index ccfb8d6..03a9b6d 100644 --- a/apps/web/src/components/ai/AiAnalysisCard.tsx +++ b/apps/web/src/components/ai/AiAnalysisCard.tsx @@ -11,6 +11,7 @@ export interface AiAnalysisCardProps { triggerLabel?: string; permission?: string; metrics?: string[]; + taskId?: string; } type AnalysisState = 'idle' | 'loading' | 'success' | 'error'; @@ -21,6 +22,7 @@ export function AiAnalysisCard({ triggerLabel = 'AI 分析', permission = 'ai.analysis.manage', metrics, + taskId, }: AiAnalysisCardProps) { const [state, setState] = useState('idle'); const [content, setContent] = useState(''); @@ -38,6 +40,9 @@ export function AiAnalysisCard({ 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; } @@ -55,7 +60,7 @@ export function AiAnalysisCard({ setErrorMsg('分析请求失败'); setState('error'); } - }, [analysisType, sourceRef, metrics]); + }, [analysisType, sourceRef, metrics, taskId]); const handleReset = useCallback(() => { setState('idle'); diff --git a/apps/web/src/pages/health/FollowUpTaskList.tsx b/apps/web/src/pages/health/FollowUpTaskList.tsx index acae252..85ec68b 100644 --- a/apps/web/src/pages/health/FollowUpTaskList.tsx +++ b/apps/web/src/pages/health/FollowUpTaskList.tsx @@ -11,7 +11,7 @@ import { Space, Popconfirm, } from 'antd'; -import { PlusOutlined, EditOutlined, SwapOutlined, DeleteOutlined } from '@ant-design/icons'; +import { PlusOutlined, EditOutlined, SwapOutlined, DeleteOutlined, ThunderboltOutlined } from '@ant-design/icons'; import type { ColumnsType, TablePaginationConfig } from 'antd/es/table'; import { dayjs } from '../../utils/dayjs'; import { followUpApi, type FollowUpTask, type CreateFollowUpTaskReq, type UpdateFollowUpTaskReq } from '../../api/health/followUp'; @@ -26,6 +26,7 @@ import { formatDate, formatDateTime } from '../../utils/format'; import { usePaginatedData } from '../../hooks/usePaginatedData'; import { useApiRequest } from '../../hooks/useApiRequest'; import { useDictionary } from '../../hooks/useDictionary'; +import { AiAnalysisCard } from '../../components/ai/AiAnalysisCard'; const STATUS_OPTIONS = [ { value: 'pending', label: '待处理' }, @@ -117,6 +118,9 @@ export default function FollowUpTaskList() { const [assignForm] = Form.useForm(); const [assignTask, setAssignTask] = useState(null); + // AI summary state + const [aiSummaryTaskId, setAiSummaryTaskId] = useState(null); + // --- Handlers --- const handleTableChange = (pagination: TablePaginationConfig) => { refresh(pagination.current ?? 1); @@ -280,7 +284,7 @@ export default function FollowUpTaskList() { { title: '操作', key: 'actions', - width: 220, + width: 280, render: (_: unknown, record: FollowUpTask) => ( @@ -292,6 +296,14 @@ export default function FollowUpTaskList() { > 填写记录 +