feat: student profile as Drawer from student list
This commit is contained in:
@@ -16,7 +16,7 @@ import {
|
|||||||
Row,
|
Row,
|
||||||
Col,
|
Col,
|
||||||
Card,
|
Card,
|
||||||
Descriptions,
|
Drawer,
|
||||||
} from 'antd';
|
} from 'antd';
|
||||||
import {
|
import {
|
||||||
PlusOutlined,
|
PlusOutlined,
|
||||||
@@ -83,6 +83,21 @@ const StudentsPage: React.FC = () => {
|
|||||||
const [selectedRowKeys, setSelectedRowKeys] = useState<number[]>([]);
|
const [selectedRowKeys, setSelectedRowKeys] = useState<number[]>([]);
|
||||||
const [enrollmentData, setEnrollmentData] = useState<Record<number, EnrollmentInfo[]>>({});
|
const [enrollmentData, setEnrollmentData] = useState<Record<number, EnrollmentInfo[]>>({});
|
||||||
const [form] = Form.useForm();
|
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) => {
|
const handleViewSensitive = (studentId: number, field: string, value: string) => {
|
||||||
modal.confirm({
|
modal.confirm({
|
||||||
@@ -227,10 +242,9 @@ const StudentsPage: React.FC = () => {
|
|||||||
dataIndex: 'name',
|
dataIndex: 'name',
|
||||||
width: 120,
|
width: 120,
|
||||||
render: (v: string, record: any) => (
|
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: '电话',
|
title: '电话',
|
||||||
dataIndex: 'phone',
|
dataIndex: 'phone',
|
||||||
@@ -570,6 +584,75 @@ const StudentsPage: React.FC = () => {
|
|||||||
)}
|
)}
|
||||||
</Form>
|
</Form>
|
||||||
</Modal>
|
</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>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user