/** * 全文复筛 - 详情与复核抽屉组件 * * 功能: * 1. Tab1: 双模型AI判断对比(12字段) * 2. Tab2: PDF全文预览(MVP占位符) * 3. Tab3: 12字段详细证据 * 4. 底部: 人工决策表单 */ import { useState } from 'react'; import { Drawer, Tabs, Card, Row, Col, Tag, Form, Radio, Input, Button, Space, Divider, Alert, Table, Collapse, } from 'antd'; import type { TableColumnsType } from 'antd'; import { CheckCircleOutlined, CloseCircleOutlined, ExclamationCircleOutlined, FilePdfOutlined, } from '@ant-design/icons'; import ConclusionTag from './ConclusionTag'; const { TextArea } = Input; // 12字段结果类型 interface FieldResult { completeness: 'complete' | 'partial' | 'missing'; extractability: 'extractable' | 'difficult' | 'impossible'; evidence: string; pageNumber?: number; } // 全文复筛结果类型 interface FulltextResult { resultId: string; literatureId: string; literature: { id: string; pmid?: string; title: string; authors?: string; journal?: string; year?: number; }; modelAResult: { modelName: string; fields: Record; overall: { conclusion: 'include' | 'exclude'; confidence: number; reason: string; }; }; modelBResult: { modelName: string; fields: Record; overall: { conclusion: 'include' | 'exclude'; confidence: number; reason: string; }; }; conflict: { isConflict: boolean; severity: 'high' | 'medium' | 'low'; conflictFields: string[]; }; review: { finalDecision: 'include' | 'exclude' | null; }; } interface Props { visible: boolean; result: FulltextResult | null; onClose: () => void; onSubmitReview: (resultId: string, decision: 'include' | 'exclude', note?: string) => void; isReviewing: boolean; } // 12字段名称映射 const FIELD_NAMES: Record = { field_1: '研究设计', field_2: '随机化方法', field_3: '分配隐藏', field_4: '盲法', field_5: '研究对象', field_6: '样本量', field_7: '干预措施', field_8: '对照措施', field_9: '结局指标', field_10: '结果数据', field_11: '统计方法', field_12: '结果完整性', }; const FulltextDetailDrawer: React.FC = ({ visible, result, onClose, onSubmitReview, isReviewing, }) => { const [form] = Form.useForm(); const [activeTab, setActiveTab] = useState('comparison'); if (!result) return null; // 处理提交 const handleSubmit = async () => { try { const values = await form.validateFields(); onSubmitReview(result.resultId, values.decision, values.note); form.resetFields(); } catch (error) { // 验证失败 } }; // Tab1: 双模型对比表格 const renderComparisonTab = () => { const fieldsData = Object.entries(FIELD_NAMES).map(([key, name]) => ({ key, fieldName: name, modelA: result.modelAResult.fields[key], modelB: result.modelBResult.fields[key], })); const columns: TableColumnsType = [ { title: '字段', dataIndex: 'fieldName', key: 'fieldName', width: 120, }, { title: `${result.modelAResult.modelName} - 完整性`, key: 'modelA_completeness', width: 120, align: 'center', render: (_, record) => { const completeness = record.modelA?.completeness; const colorMap = { complete: 'success', partial: 'warning', missing: 'error', }; return completeness ? ( {completeness} ) : ( '-' ); }, }, { title: `${result.modelBResult.modelName} - 完整性`, key: 'modelB_completeness', width: 120, align: 'center', render: (_, record) => { const completeness = record.modelB?.completeness; const colorMap = { complete: 'success', partial: 'warning', missing: 'error', }; return completeness ? ( {completeness} ) : ( '-' ); }, }, { title: '冲突', key: 'conflict', width: 80, align: 'center', render: (_, record) => { const isConflict = record.modelA?.completeness !== record.modelB?.completeness; return isConflict ? ( ) : ( ); }, }, ]; return (
{/* 整体结论对比 */} {result.modelAResult.modelName}
} >
置信度: {(result.modelAResult.overall.confidence * 100).toFixed(0)}%
{result.modelAResult.overall.reason}
{result.modelBResult.modelName} } >
置信度: {(result.modelBResult.overall.confidence * 100).toFixed(0)}%
{result.modelBResult.overall.reason}
{/* 12字段对比表格 */} ); }; // Tab2: PDF预览(MVP占位符) const renderPdfTab = () => { return (

PDF预览功能

该功能将在后续版本中实现

); }; // Tab3: 12字段详细证据 const renderFieldsDetailTab = () => { const fieldsData = Object.entries(FIELD_NAMES).map(([key, name]) => ({ key, label: name, children: ( {result.modelAResult.modelName}}> {result.modelAResult.fields[key] ? (
完整性: {result.modelAResult.fields[key].completeness}
可提取性: {result.modelAResult.fields[key].extractability}
证据:
{result.modelAResult.fields[key].evidence || '未提供证据'}
{result.modelAResult.fields[key].pageNumber && (
页码: {result.modelAResult.fields[key].pageNumber}
)}
) : (
无数据
)}
{result.modelBResult.modelName}}> {result.modelBResult.fields[key] ? (
完整性: {result.modelBResult.fields[key].completeness}
可提取性: {result.modelBResult.fields[key].extractability}
证据:
{result.modelBResult.fields[key].evidence || '未提供证据'}
{result.modelBResult.fields[key].pageNumber && (
页码: {result.modelBResult.fields[key].pageNumber}
)}
) : (
无数据
)}
), })); return ; }; return (
全文复筛 - 详情与复核
{result.literature.title}
} placement="right" width="80%" onClose={onClose} open={visible} footer={
} > {/* 文献元信息 */}
PMID: {result.literature.pmid || '-'}
作者: {result.literature.authors || '-'}
期刊: {result.literature.journal || '-'} ( {result.literature.year || '-'})
{/* 冲突提示 */} {result.conflict.isConflict && ( )} {/* Tab内容 */} {/* 人工决策表单 */}
纳入 排除 prevValues.decision !== currentValues.decision } > {({ getFieldValue }) => getFieldValue('decision') === 'exclude' ? ( ) : null }