feat: 重构各业务模块管理页面与服务
This commit is contained in:
179
apps/admin/src/pages/Students/StudentModals.tsx
Normal file
179
apps/admin/src/pages/Students/StudentModals.tsx
Normal file
@@ -0,0 +1,179 @@
|
||||
import React from 'react';
|
||||
import { App, Descriptions, Drawer, Form, Input, Modal, Select } from 'antd';
|
||||
import JinshujuMatchModal from '../../components/JinshujuMatchModal';
|
||||
import StudentProfileContent from '../../components/StudentProfileContent';
|
||||
import { SENSITIVE_LABELS } from './StudentColumns';
|
||||
|
||||
type AppModal = ReturnType<typeof App.useApp>['modal'];
|
||||
|
||||
export const showCreateImportResult = (
|
||||
modal: AppModal,
|
||||
result: { message?: string; imported?: number; skipped?: number },
|
||||
) => {
|
||||
const imported = result.imported ?? 0;
|
||||
const skipped = result.skipped ?? 0;
|
||||
modal.success({
|
||||
title: '导入完成',
|
||||
okText: '知道了',
|
||||
content: (
|
||||
<div>
|
||||
<Descriptions column={1} size="small">
|
||||
<Descriptions.Item label="成功新增">{imported} 人</Descriptions.Item>
|
||||
<Descriptions.Item label="跳过">{skipped} 人</Descriptions.Item>
|
||||
</Descriptions>
|
||||
<div style={{ marginTop: 12, fontWeight: 600 }}>跳过原因:</div>
|
||||
<ul style={{ marginBottom: 0, paddingLeft: 20 }}>
|
||||
<li>姓名为空</li>
|
||||
<li>已存在同名学生</li>
|
||||
</ul>
|
||||
<div style={{ marginTop: 8, color: '#8c8c8c', fontSize: 12 }}>
|
||||
当前后端只返回统计汇总,暂时无法列出具体哪几行被跳过。
|
||||
</div>
|
||||
</div>
|
||||
),
|
||||
});
|
||||
};
|
||||
|
||||
export const showUpdateImportResult = (
|
||||
modal: AppModal,
|
||||
result: { message?: string; matched?: number; skipped?: number },
|
||||
) => {
|
||||
const matched = result.matched ?? 0;
|
||||
const skipped = result.skipped ?? 0;
|
||||
modal.success({
|
||||
title: '更新完成',
|
||||
okText: '知道了',
|
||||
content: (
|
||||
<div>
|
||||
<Descriptions column={1} size="small">
|
||||
<Descriptions.Item label="成功更新">{matched} 人</Descriptions.Item>
|
||||
<Descriptions.Item label="未匹配">{skipped} 人</Descriptions.Item>
|
||||
</Descriptions>
|
||||
<div style={{ marginTop: 12, fontWeight: 600 }}>匹配规则:</div>
|
||||
<div>手机号优先,身份证号其次</div>
|
||||
<div style={{ marginTop: 8, color: '#8c8c8c', fontSize: 12 }}>
|
||||
当前后端只返回统计汇总,暂时无法列出具体哪几行未匹配。
|
||||
</div>
|
||||
</div>
|
||||
),
|
||||
});
|
||||
};
|
||||
|
||||
export const StudentEditModal: React.FC<{
|
||||
open: boolean;
|
||||
editing: boolean;
|
||||
saving: boolean;
|
||||
form: ReturnType<typeof Form.useForm>[0];
|
||||
canChooseOrganization: boolean;
|
||||
organizations: Array<{ id: number; name: string; isHost?: boolean }>;
|
||||
onOk?: () => void;
|
||||
onCancel: () => void;
|
||||
}> = ({
|
||||
open,
|
||||
editing,
|
||||
saving,
|
||||
form,
|
||||
canChooseOrganization,
|
||||
organizations,
|
||||
onOk,
|
||||
onCancel,
|
||||
}) => {
|
||||
return (
|
||||
<Modal
|
||||
title={editing ? '编辑学生' : '添加学生'}
|
||||
className="student-form-modal"
|
||||
width={720}
|
||||
open={open}
|
||||
onOk={onOk}
|
||||
onCancel={onCancel}
|
||||
okText="保存"
|
||||
confirmLoading={saving}
|
||||
>
|
||||
<Form form={form} layout="vertical" className="student-form-grid">
|
||||
<Form.Item name="name" label="姓名" rules={[{ required: true }]}>
|
||||
<Input />
|
||||
</Form.Item>
|
||||
<Form.Item name="studentNo" label="学号">
|
||||
<Input placeholder="学生的学号" />
|
||||
</Form.Item>
|
||||
<Form.Item name="gender" label="性别">
|
||||
<Select
|
||||
allowClear
|
||||
options={[
|
||||
{ value: '男', label: '男' },
|
||||
{ value: '女', label: '女' },
|
||||
]}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item name="phone" label={SENSITIVE_LABELS.phone}>
|
||||
<Input />
|
||||
</Form.Item>
|
||||
<Form.Item name="idNumber" label="身份证">
|
||||
<Input />
|
||||
</Form.Item>
|
||||
<Form.Item name="ethnicity" label="民族">
|
||||
<Input placeholder="如:汉族" />
|
||||
</Form.Item>
|
||||
<Form.Item name="emergencyContact" label="紧急联系人">
|
||||
<Input />
|
||||
</Form.Item>
|
||||
<Form.Item name="emergencyPhone" label={SENSITIVE_LABELS.emergencyPhone}>
|
||||
<Input />
|
||||
</Form.Item>
|
||||
{canChooseOrganization ? (
|
||||
<Form.Item
|
||||
name="organizationId"
|
||||
label="所属机构"
|
||||
rules={[{ required: true, message: '请选择所属机构' }]}
|
||||
>
|
||||
<Select
|
||||
showSearch
|
||||
optionFilterProp="label"
|
||||
placeholder="选择所属机构"
|
||||
options={organizations.map((organization) => ({
|
||||
value: organization.id,
|
||||
label: organization.isHost
|
||||
? `${organization.name}(本机构)`
|
||||
: organization.name,
|
||||
}))}
|
||||
/>
|
||||
</Form.Item>
|
||||
) : null}
|
||||
<Form.Item name="supervisor" label="负责人/班主任">
|
||||
<Input />
|
||||
</Form.Item>
|
||||
{editing && (
|
||||
<Form.Item name="status" label="状态">
|
||||
<Select
|
||||
options={[
|
||||
{ value: 'active', label: '在读' },
|
||||
{ value: 'graduated', label: '已毕业' },
|
||||
{ value: 'withdrawn', label: '已退训' },
|
||||
]}
|
||||
/>
|
||||
</Form.Item>
|
||||
)}
|
||||
</Form>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
export const JinshujuModal: React.FC<{
|
||||
open: boolean;
|
||||
onClose: () => void;
|
||||
onApplied: () => void;
|
||||
}> = ({ open, onClose, onApplied }) => {
|
||||
return <JinshujuMatchModal open={open} onClose={onClose} onApplied={onApplied} />;
|
||||
};
|
||||
|
||||
export const StudentDrawer: React.FC<{
|
||||
open: boolean;
|
||||
studentId: number | null;
|
||||
onClose: () => void;
|
||||
}> = ({ open, studentId, onClose }) => {
|
||||
return (
|
||||
<Drawer title={null} open={open} onClose={onClose} size={720}>
|
||||
{studentId && <StudentProfileContent studentId={studentId} inDrawer onClose={onClose} />}
|
||||
</Drawer>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user