'use client'; import { Card, CardContent, Box, Typography, Chip, Checkbox, IconButton, Tooltip, Divider } from '@mui/material'; import DeleteIcon from '@mui/icons-material/Delete'; import EditIcon from '@mui/icons-material/Edit'; import CheckCircleIcon from '@mui/icons-material/CheckCircle'; import RadioButtonCheckedIcon from '@mui/icons-material/RadioButtonChecked'; import CheckBoxIcon from '@mui/icons-material/CheckBox'; import ShortTextIcon from '@mui/icons-material/ShortText'; import NotesIcon from '@mui/icons-material/Notes'; import CheckIcon from '@mui/icons-material/Check'; import CloseIcon from '@mui/icons-material/Close'; import { useTheme, alpha } from '@mui/material/styles'; import { useTranslation } from 'react-i18next'; import { useRouter } from 'next/navigation'; // 题型图标和颜色映射 const QUESTION_TYPE_CONFIG = { true_false: { icon: CheckCircleIcon, color: 'success', bgColor: 'success.light' }, single_choice: { icon: RadioButtonCheckedIcon, color: 'primary', bgColor: 'primary.light' }, multiple_choice: { icon: CheckBoxIcon, color: 'secondary', bgColor: 'secondary.light' }, short_answer: { icon: ShortTextIcon, color: 'warning', bgColor: 'warning.light' }, open_ended: { icon: NotesIcon, color: 'info', bgColor: 'info.light' } }; export default function EvalDatasetCard({ item, selected, onSelect, onEdit, onDelete, projectId }) { const theme = useTheme(); const { t } = useTranslation(); const router = useRouter(); const typeConfig = QUESTION_TYPE_CONFIG[item.questionType] || QUESTION_TYPE_CONFIG.short_answer; const TypeIcon = typeConfig.icon; // 解析选项 const options = item.options ? typeof item.options === 'string' ? JSON.parse(item.options || '[]') : item.options : []; // 解析答案 const correctAnswer = item.correctAnswer; const handleCardClick = e => { // 如果点击的是复选框或按钮,不跳转 if (e.target.closest('.MuiCheckbox-root') || e.target.closest('.MuiIconButton-root')) { return; } router.push(`/projects/${projectId}/eval-datasets/${item.id}`); }; return ( {/* 头部:题型标签和操作 */} { e.stopPropagation(); onSelect(item.id); }} sx={{ p: 0.5, ml: -0.5 }} /> } label={t(`eval.questionTypes.${item.questionType}`)} size="small" color={typeConfig.color} variant="outlined" sx={{ fontWeight: 600, borderWidth: '1.5px', bgcolor: alpha(theme.palette[typeConfig.color].main, 0.05) }} /> { e.stopPropagation(); onEdit(item); }} sx={{ color: 'text.secondary', '&:hover': { color: 'primary.main', bgcolor: alpha(theme.palette.primary.main, 0.1) } }} > { e.stopPropagation(); onDelete(item.id); }} sx={{ color: 'text.secondary', '&:hover': { color: 'error.main', bgcolor: alpha(theme.palette.error.main, 0.1) } }} > {/* 问题内容 */} {item.questionType === 'true_false' && correctAnswer} {item.question} {/* 选项列表(仅单选/多选显示) */} {(item.questionType === 'single_choice' || item.questionType === 'multiple_choice') && options.length > 0 && ( {(item.questionType === 'multiple_choice' ? options : options.slice(0, 4)).map((option, index) => { const optionLabel = String.fromCharCode(65 + index); // A, B, C, D // 解析多选题答案,支持多种格式:数组、JSON字符串、逗号分隔字符串 const parseMultipleAnswers = answer => { if (Array.isArray(answer)) return answer; if (!answer) return []; // 尝试解析 JSON 数组 if (answer.startsWith('[')) { try { return JSON.parse(answer); } catch (e) { return []; } } // 逗号分隔字符串格式,如 "A,B,D" return answer.split(',').map(s => s.trim()); }; const isCorrect = item.questionType === 'multiple_choice' ? parseMultipleAnswers(correctAnswer).includes(optionLabel) : correctAnswer === optionLabel; return ( {optionLabel}. {option} ); })} {item.questionType === 'single_choice' && options.length > 4 && ( ... +{options.length - 4} {t('eval.moreOptions')} )} )} {/* 非选择题且非判断题答案 */} {item.questionType !== 'single_choice' && item.questionType !== 'multiple_choice' && item.questionType !== 'true_false' && correctAnswer && ( {t('eval.answer')}: {correctAnswer} )} {/* 底部元信息 */} {item.chunks ? ( ) : ( )} {item.tags && ( {item.tags .split(/[,,]/) .slice(0, 2) .map((tag, index) => ( ))} {item.tags.split(/[,,]/).length > 2 && ( +{item.tags.split(/[,,]/).length - 2} )} )} ); }