feat: student profile as Drawer from student list

This commit is contained in:
2026-07-06 16:45:21 +08:00
parent 8f3a20140d
commit aac01594da

View File

@@ -16,7 +16,7 @@ import {
Row,
Col,
Card,
Descriptions,
Drawer,
} from 'antd';
import {
PlusOutlined,
@@ -83,6 +83,21 @@ const StudentsPage: React.FC = () => {
const [selectedRowKeys, setSelectedRowKeys] = useState<number[]>([]);
const [enrollmentData, setEnrollmentData] = useState<Record<number, EnrollmentInfo[]>>({});
const [form] = Form.useForm();
const [drawerOpen, setDrawerOpen] = useState(false);
const [drawerStudentId, setDrawerStudentId] = useState<number | null>(null);
const [drawerData, setDrawerData] = useState<any>(null);
const [drawerLoading, setDrawerLoading] = useState(false);
const openDrawer = async (studentId: number) => {
setDrawerStudentId(studentId);
setDrawerOpen(true);
setDrawerLoading(true);
try {
const res = await api.get(`/archive/${studentId}`);
setDrawerData(res);
} catch { setDrawerData(null); }
setDrawerLoading(false);
};
const handleViewSensitive = (studentId: number, field: string, value: string) => {
modal.confirm({
@@ -227,10 +242,9 @@ const StudentsPage: React.FC = () => {
dataIndex: 'name',
width: 120,
render: (v: string, record: any) => (
<a onClick={() => navigate(`/students/${record.id}/profile`)}>{v}</a>
<a onClick={() => openDrawer(record.id)}>{v}</a>
),
},
{ title: '性别', dataIndex: 'gender', width: 70 },
{
title: '电话',
dataIndex: 'phone',
@@ -570,6 +584,75 @@ const StudentsPage: React.FC = () => {
)}
</Form>
</Modal>
<Drawer
title={drawerData?.student?.name ? `${drawerData.student.name} — 学生档案` : '学生档案'}
open={drawerOpen}
onClose={() => { setDrawerOpen(false); setDrawerData(null); }}
width={720}
loading={drawerLoading}
>
{drawerData && (
<Tabs items={[
{
key: 'info', label: '基础信息',
children: (
<Descriptions column={2} size="small" bordered>
<Descriptions.Item label="姓名">{drawerData.student?.name}</Descriptions.Item>
<Descriptions.Item label="学号">{drawerData.student?.studentNo || '-'}</Descriptions.Item>
<Descriptions.Item label="电话">{drawerData.student?.phone || '-'}</Descriptions.Item>
<Descriptions.Item label="身份证">{drawerData.student?.idNumber || '-'}</Descriptions.Item>
<Descriptions.Item label="状态"><Tag>{drawerData.student?.status}</Tag></Descriptions.Item>
<Descriptions.Item label="目标院校">{drawerData.profile?.targetCollege || '-'}</Descriptions.Item>
<Descriptions.Item label="目标专业">{drawerData.profile?.targetMajor || '-'}</Descriptions.Item>
<Descriptions.Item label="科类方向">{drawerData.profile?.subjectDirection || '-'}</Descriptions.Item>
<Descriptions.Item label="年级">{drawerData.profile?.grade || '-'}</Descriptions.Item>
<Descriptions.Item label="校区">{drawerData.profile?.campusLocation || '-'}</Descriptions.Item>
<Descriptions.Item label="建档日期">{drawerData.profile?.profileDate || '-'}</Descriptions.Item>
</Descriptions>
),
},
{
key: 'enrollments', label: `报读记录 (${drawerData.enrollments?.length || 0})`,
children: drawerData.enrollments?.length ? (
<Table rowKey="id" size="small" pagination={false} dataSource={drawerData.enrollments} columns={[
{ title: '课程类别', dataIndex: 'courseCategory' },
{ title: '班型', dataIndex: 'classType' },
{ title: '班级', dataIndex: 'className' },
{ title: '班主任', dataIndex: 'headTeacher' },
{ title: '开课', dataIndex: 'startDate' },
{ title: '结课', dataIndex: 'endDate' },
]} />
) : <div style={{ color: '#999' }}></div>,
},
{
key: 'exams', label: `考试成绩 (${drawerData.examScores?.length || 0})`,
children: drawerData.examScores?.length ? (
<Table rowKey="id" size="small" pagination={false} dataSource={drawerData.examScores} columns={[
{ title: '类型', dataIndex: 'examType' },
{ title: '科目', dataIndex: 'subject' },
{ title: '分数', dataIndex: 'score' },
{ title: '班均', dataIndex: 'classAvg', render: (v: number) => v ?? '-' },
{ title: '排名', dataIndex: 'rank', render: (v: number) => v ?? '-' },
{ title: '日期', dataIndex: 'examDate' },
]} />
) : <div style={{ color: '#999' }}></div>,
},
{
key: 'result', label: '录取结果',
children: drawerData.result ? (
<Descriptions column={2} size="small" bordered>
<Descriptions.Item label="文化课成绩">{drawerData.result.cultureFinalScore ?? '-'}</Descriptions.Item>
<Descriptions.Item label="专业课成绩">{drawerData.result.professionalFinalScore ?? '-'}</Descriptions.Item>
<Descriptions.Item label="录取状态">{drawerData.result.admissionStatus || '-'}</Descriptions.Item>
<Descriptions.Item label="录取院校">{drawerData.result.admittedCollege || '-'}</Descriptions.Item>
<Descriptions.Item label="录取专业" span={2}>{drawerData.result.admittedMajor || '-'}</Descriptions.Item>
</Descriptions>
) : <div style={{ color: '#999' }}></div>,
},
]} />
)}
</Drawer>
</div>
);
};