import React, { useCallback, useMemo } from 'react'; import { Alert, Button, Card, Descriptions, Empty, Space, Spin, Table, Tag, Tooltip } from 'antd'; import type { ColumnsType } from 'antd/es/table'; import { ArrowLeftOutlined, EyeOutlined } from '@ant-design/icons'; import { useNavigate, useParams } from 'react-router'; import api from '../../api'; import EditableCell from '../../components/EditableCell'; import { useViewSensitive } from '../../hooks/useViewSensitive'; import { maskPhone } from '../../utils/sensitive'; import { message } from '../../ui/app-message'; import { useQuery } from '@tanstack/react-query'; import { useApiMutation } from '../../hooks/useApiMutation'; import { validateResponse } from '../../utils/validate'; import { examDetailSchema } from '../../api/schemas'; import { usePermission } from '../../hooks/usePermission'; import type { ExamItem } from './types'; import './style.css'; import { getErrorMessage } from '../../utils/error'; interface ScoreRow { id: number; studentId: number; phone: string; name: string; score: number | null; classAvg: number | null; rank: number | null; } interface ExamDetail extends ExamItem { scores: ScoreRow[]; } const PhoneCell: React.FC<{ row: ScoreRow }> = ({ row }) => { const { hasPermission } = usePermission(); const reveal = useViewSensitive(row.studentId, '考试管理', hasPermission('log:create')); if (!row.phone) return <>-; return ( {maskPhone(row.phone)} {hasPermission('log:create') ? (

{detail.examName}

{detail.status === 'archived' ? 已归档 : null}
{detail.status === 'archived' ? ( ) : null} {detail.examType} {detail.subject} {detail.className} {detail.examDate} {detail.enteredScores}/{detail.totalStudents},均分 {average ?? '-'} columns={columns} dataSource={detail.scores} rowKey="id" loading={loading} scroll={{ x: 1310 }} pagination={{ defaultPageSize: 30, showSizeChanger: true, pageSizeOptions: [30, 50, 100], }} locale={{ emptyText: }} /> ); }; export default ExamDetailPage;