forked from wangziqi/gongxue-base
feat(students): add multi-enrollment comparison view in student list expand row
This commit is contained in:
@@ -12,6 +12,10 @@ import {
|
||||
Popconfirm,
|
||||
Upload,
|
||||
App,
|
||||
Row,
|
||||
Col,
|
||||
Card,
|
||||
Descriptions,
|
||||
} from 'antd';
|
||||
import {
|
||||
PlusOutlined,
|
||||
@@ -43,6 +47,25 @@ const statusMap: Record<string, { text: string; color: string }> = {
|
||||
archived: { text: '已归档', color: '#999' },
|
||||
};
|
||||
|
||||
interface EnrollmentInfo {
|
||||
classId: number;
|
||||
className: string;
|
||||
classType: string;
|
||||
startDate: string;
|
||||
endDate: string;
|
||||
joinDate: string;
|
||||
leaveDate: string;
|
||||
status: string;
|
||||
attendanceStats: {
|
||||
total: number;
|
||||
present: number;
|
||||
absent: number;
|
||||
late: number;
|
||||
leave: number;
|
||||
rate: number;
|
||||
};
|
||||
}
|
||||
|
||||
const StudentsPage: React.FC = () => {
|
||||
const { modal } = App.useApp();
|
||||
const [data, setData] = useState<any[]>([]);
|
||||
@@ -54,6 +77,7 @@ const StudentsPage: React.FC = () => {
|
||||
const [showArchived, setShowArchived] = useState(false);
|
||||
const [archivedCount, setArchivedCount] = useState(0);
|
||||
const [selectedRowKeys, setSelectedRowKeys] = useState<number[]>([]);
|
||||
const [enrollmentData, setEnrollmentData] = useState<Record<number, EnrollmentInfo[]>>({});
|
||||
const [form] = Form.useForm();
|
||||
|
||||
const handleViewSensitive = (studentId: number, field: string, value: string) => {
|
||||
@@ -395,7 +419,59 @@ const StudentsPage: React.FC = () => {
|
||||
onChange: (keys) => setSelectedRowKeys(keys as number[]),
|
||||
getCheckboxProps: (record: any) => ({ disabled: record.status === 'archived' }),
|
||||
}}
|
||||
/>
|
||||
expandable={{
|
||||
rowExpandable: () => true,
|
||||
expandedRowRender: (record) => {
|
||||
const enrollments = enrollmentData[record.id];
|
||||
if (!enrollments) return null;
|
||||
if (enrollments.length < 2) {
|
||||
return (
|
||||
<div style={{ padding: 8, color: '#999', fontSize: 13 }}>
|
||||
当前仅 {enrollments.length} 个班型,无可对比数据
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<Card title="多班型对比" size="small" style={{ margin: '8px 0' }}>
|
||||
<Row gutter={16}>
|
||||
{enrollments.map((enr, idx) => (
|
||||
<Col span={12} key={enr.classId}>
|
||||
<Card
|
||||
size="small"
|
||||
title={enr.classType || `班型 ${idx + 1}`}
|
||||
style={{ background: idx === 0 ? '#f0f5ff' : '#f6ffed' }}
|
||||
>
|
||||
<Descriptions column={1} size="small">
|
||||
<Descriptions.Item label="班级">{enr.className || '-'}</Descriptions.Item>
|
||||
<Descriptions.Item label="开班日期">{enr.startDate || enr.joinDate || '-'}</Descriptions.Item>
|
||||
<Descriptions.Item label="结课日期">{enr.endDate || enr.leaveDate || '-'}</Descriptions.Item>
|
||||
<Descriptions.Item label="状态">
|
||||
<Tag color={enr.status === 'active' ? 'green' : 'default'}>
|
||||
{enr.status || '-'}
|
||||
</Tag>
|
||||
</Descriptions.Item>
|
||||
</Descriptions>
|
||||
</Card>
|
||||
</Col>
|
||||
))}
|
||||
</Row>
|
||||
</Card>
|
||||
);
|
||||
},
|
||||
onExpand: async (expanded, record) => {
|
||||
if (expanded && !enrollmentData[record.id]) {
|
||||
try {
|
||||
const res = await api.get<{ enrollments: EnrollmentInfo[] }>(
|
||||
`/students/${record.id}/compare-classes`,
|
||||
);
|
||||
setEnrollmentData((prev) => ({ ...prev, [record.id]: res.enrollments }));
|
||||
} catch {
|
||||
setEnrollmentData((prev) => ({ ...prev, [record.id]: [] }));
|
||||
}
|
||||
}
|
||||
},
|
||||
}}
|
||||
/>
|
||||
<style>{`.archived-row { opacity: 0.6; background: #fafafa !important; }`}</style>
|
||||
<Modal
|
||||
title={editing ? '编辑学生' : '添加学生'}
|
||||
|
||||
@@ -193,6 +193,8 @@ export class StudentsService {
|
||||
classId: e.classId,
|
||||
className: e.class?.name || '',
|
||||
classType: e.class?.classType || '',
|
||||
startDate: e.class?.startDate || '',
|
||||
endDate: e.class?.endDate || '',
|
||||
joinDate: e.joinDate,
|
||||
leaveDate: e.leaveDate,
|
||||
status: e.status,
|
||||
|
||||
Reference in New Issue
Block a user