Files
YG-Datasets/easy-dataset-main/app/projects/[projectId]/eval-tasks/[taskId]/components/EvalHeader.js

141 lines
5.4 KiB
JavaScript

'use client';
import { Box, Paper, Typography, Chip, Grid, Divider } from '@mui/material';
import SmartToyIcon from '@mui/icons-material/SmartToy';
import AccessTimeIcon from '@mui/icons-material/AccessTime';
import { detailStyles } from '../detailStyles';
import { useTranslation } from 'react-i18next';
import { getModelIcon } from '@/lib/util/modelIcon';
export default function EvalHeader({ task, stats, filterCorrect, onFilterCorrectSelect }) {
const { t } = useTranslation();
if (!task) return null;
const { modelInfo, createAt, status, detail } = task;
const score = detail?.finalScore || 0;
const isPass = score >= 60;
const totalTime = task.endTime ? Math.floor((new Date(task.endTime) - new Date(task.createAt)) / 1000) : 0;
const incorrectCount = (stats?.totalQuestions || 0) - (stats?.correctCount || 0);
// 获取教师模型信息
const judgeModelId = detail?.judgeModelId;
const judgeProviderId = detail?.judgeProviderId;
const hasJudgeModel = judgeModelId && judgeProviderId;
return (
<Paper sx={detailStyles.headerCard}>
<Box sx={detailStyles.headerContent}>
{/* 左侧:模型信息 */}
<Box sx={{ flex: 1, display: 'flex', gap: 2 }}>
<Box
sx={{
width: 60,
height: 60,
borderRadius: 2,
bgcolor: 'transparent',
border: '2px solid',
borderColor: 'divider',
display: 'flex',
alignItems: 'center',
justifyContent: 'center'
}}
>
<img
src={getModelIcon(modelInfo?.modelName || modelInfo?.modelId)}
alt={modelInfo?.modelId || 'model'}
style={{ width: 44, height: 44, objectFit: 'contain' }}
/>
</Box>
<Box>
<Typography variant="h5" sx={{ fontWeight: 700, mb: 0.5 }}>
{modelInfo?.providerName || modelInfo?.providerId} / {modelInfo?.modelName || modelInfo?.modelId}
</Typography>
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1, color: 'text.secondary', flexWrap: 'wrap' }}>
{hasJudgeModel && (
<Chip
label={`${t('evalTasks.judgeModel')}: ${judgeProviderId} / ${judgeModelId}`}
size="small"
variant="outlined"
color="secondary"
sx={{ borderRadius: 1 }}
/>
)}
<Box sx={{ display: 'flex', alignItems: 'center', fontSize: '0.875rem' }}>
<AccessTimeIcon sx={{ fontSize: 16, mr: 0.5 }} />
{new Date(createAt).toLocaleString()}
{totalTime > 0 && ` ${t('evalTasks.durationFormat', { time: totalTime })}`}
</Box>
</Box>
</Box>
</Box>
{/* 中间:统计概览 (增加点击筛选) */}
<Box sx={{ display: 'flex', gap: 2, mx: 4 }}>
<Box
onClick={() => onFilterCorrectSelect(null)}
sx={{
...detailStyles.statBox,
cursor: 'pointer',
bgcolor: filterCorrect === null ? 'rgba(25, 118, 210, 0.08)' : 'background.default',
border: filterCorrect === null ? '1px solid' : '1px solid transparent',
borderColor: 'primary.main',
transition: 'all 0.2s'
}}
>
<Typography variant="h4" color="primary.main" fontWeight="bold">
{stats?.totalQuestions || 0}
</Typography>
<Typography variant="caption" color="text.secondary">
{t('evalTasks.totalQuestionsLabel')}
</Typography>
</Box>
<Box
onClick={() => onFilterCorrectSelect(true)}
sx={{
...detailStyles.statBox,
cursor: 'pointer',
bgcolor: filterCorrect === true ? 'rgba(46, 125, 50, 0.08)' : 'background.default',
border: filterCorrect === true ? '1px solid' : '1px solid transparent',
borderColor: 'success.main',
transition: 'all 0.2s'
}}
>
<Typography variant="h4" color="success.main" fontWeight="bold">
{stats?.correctCount || 0}
</Typography>
<Typography variant="caption" color="text.secondary">
{t('evalTasks.correctLabel')}
</Typography>
</Box>
<Box
onClick={() => onFilterCorrectSelect(false)}
sx={{
...detailStyles.statBox,
cursor: 'pointer',
bgcolor: filterCorrect === false ? 'rgba(211, 47, 47, 0.08)' : 'background.default',
border: filterCorrect === false ? '1px solid' : '1px solid transparent',
borderColor: 'error.main',
transition: 'all 0.2s'
}}
>
<Typography variant="h4" color="error.main" fontWeight="bold">
{incorrectCount}
</Typography>
<Typography variant="caption" color="text.secondary">
{t('evalTasks.incorrectLabel')}
</Typography>
</Box>
</Box>
{/* 右侧:分数印章 */}
<Box sx={detailStyles.scoreStamp(score, isPass)}>
<Typography sx={detailStyles.scoreValue}>{score.toFixed(1)}</Typography>
<Typography sx={detailStyles.scoreLabel}>SCORE</Typography>
</Box>
</Box>
</Paper>
);
}