import React from 'react'; import { App, Button, Input, Popconfirm, Select, Space, Upload, } from 'antd'; import type { UploadProps } from 'antd'; import { CloudUploadOutlined, DeleteOutlined, DownloadOutlined, ExportOutlined, InboxOutlined, PlusOutlined, SwapOutlined, SyncOutlined, UndoOutlined, UploadOutlined, } from '@ant-design/icons'; import PermissionButton from '../../components/PermissionButton'; import { RefreshButton } from '../../components/RefreshButton'; import { statusMap } from './StudentColumns'; export interface StudentsToolbarProps { onSearchName: (value: string) => void; filterStatus?: string; onFilterStatus: (value?: string) => void; effectiveFilterOrganizationId?: number; onFilterOrganization: (value?: number) => void; canViewOrganizations: boolean; organizations: Array<{ id: number; name: string }>; filterClassId?: number; onFilterClass: (value?: number) => void; classOptions: Array<{ id: number; name: string; code?: string }>; filterTeacherId?: number; onFilterTeacher: (value?: number) => void; teacherOptions: Array<{ id: number; name: string; username: string }>; showArchived: boolean; onToggleArchived: () => void; selectedRowKeys: number[]; batchLoading: boolean; canEditStudent: boolean; canPurgeStudent: boolean; canDeleteStudent: boolean; canSyncJinshuju: boolean; canSyncDingTalk: boolean; dingSyncLoading: boolean; onBatchRestore: () => void; onBatchPurge: () => void; onBatchDelete: () => void; onAddStudent: () => void; onOpenJinshuju: () => void; onDingTalkSync: () => void; onCreateImport: UploadProps['customRequest']; onUpdateImport: UploadProps['customRequest']; onDownloadTemplate: () => void; onExport: () => void; templateLoading?: boolean; exportLoading?: boolean; refreshLoading?: boolean; onRefresh?: () => void; } export const StudentsToolbar: React.FC = ({ onSearchName, filterStatus, onFilterStatus, effectiveFilterOrganizationId, onFilterOrganization, canViewOrganizations, organizations, filterClassId, onFilterClass, classOptions, filterTeacherId, onFilterTeacher, teacherOptions, showArchived, onToggleArchived, selectedRowKeys, batchLoading, canEditStudent, canPurgeStudent, canDeleteStudent, canSyncJinshuju, canSyncDingTalk, dingSyncLoading, onBatchRestore, onBatchPurge, onBatchDelete, onAddStudent, onOpenJinshuju, onDingTalkSync, onCreateImport, onUpdateImport, onDownloadTemplate, onExport, templateLoading, exportLoading, refreshLoading, onRefresh, }) => { const { modal } = App.useApp(); return ( <>
{canViewOrganizations ? ( ) : null} ({ value: item.id, label: item.name === item.username ? item.name : `${item.name}(${item.username})`, }))} /> {onRefresh ? : null} {showArchived && canEditStudent ? ( <> {canPurgeStudent ? ( ) : null} ) : !showArchived && canDeleteStudent ? ( ) : null} {!showArchived ? ( } onClick={onAddStudent} > 添加学生 ) : null} {!showArchived && ( <> { const file = options.file as File; modal.confirm({ title: '确认覆盖更新学生资料?', content: `将按手机号/身份证匹配并更新「${file.name}」中的学生资料,匹配到的学生记录会被直接覆盖且无法撤销。建议先导出名单核对后再操作。`, okText: '确认更新', okButtonProps: { danger: true }, cancelText: '取消', onOk: () => { // 实现方只使用 { file, onSuccess, onError };info 参数仅用于满足类型签名 onUpdateImport?.(options, { defaultRequest: () => undefined }); }, }); }} > )} {!showArchived && canSyncJinshuju ? ( ) : null} {!showArchived && canSyncDingTalk ? ( ) : null} } loading={templateLoading} onClick={onDownloadTemplate} > 下载模板 } loading={exportLoading} onClick={onExport} > 导出名单
); };