import React from 'react'; import { Avatar, Button, DatePicker, Select, Spin, Tooltip, } from 'antd'; import { ExportOutlined, FileSearchOutlined, ReloadOutlined, ScheduleOutlined, UndoOutlined, WarningFilled, } from '@ant-design/icons'; import dayjs, { type Dayjs } from 'dayjs'; import PermissionButton from '../../components/PermissionButton'; import { ADMIN_METRIC_META, STATUS_META, type AlertItem, type AttendanceSummary, type ClassOption, type DingTalkSyncStatus, type HistoryScheduleOption, } from './AttendanceAdmin.helpers'; export const AttendanceAdminHeader: React.FC<{ syncStatus: DingTalkSyncStatus | null; canEdit: boolean; refreshingDingTalk: boolean; onOpenPeriodConfig: () => void; onRefreshDingTalk: () => void; onExport: () => void; attendanceDate: Dayjs | null; onDateChange: (date: Dayjs | null) => void; classId?: number; onClassChange: (value?: number) => void; classOptions: ClassOption[]; effectiveScheduleId?: number; onScheduleChange: (value?: number) => void; scheduleOptions: HistoryScheduleOption[]; scheduleOptionsLoading: boolean; session?: string; onSessionChange: (value?: string) => void; sessionOptions: Array<{ value: string; label: string }>; onReset: () => void; onQuery: () => void; selectedClass: string; dateLabel: string; visibleStudentCount: number; total: number; headTeacherNames: string; lifeTeacherNames: string; subjectTeacherNames: string; attendanceRate: number; summary: AttendanceSummary; metricFilter: string; onMetricFilterChange: (key: string) => void; alerts: AlertItem[]; }> = ({ syncStatus, canEdit, refreshingDingTalk, onOpenPeriodConfig, onRefreshDingTalk, onExport, attendanceDate, onDateChange, classId, onClassChange, classOptions, effectiveScheduleId, onScheduleChange, scheduleOptions, scheduleOptionsLoading, session, onSessionChange, sessionOptions, onReset, onQuery, selectedClass, dateLabel, visibleStudentCount, total, headTeacherNames, lifeTeacherNames, subjectTeacherNames, attendanceRate, summary, metricFilter, onMetricFilterChange, alerts, }) => { return ( <>

学生考勤中心

班级考勤总览
{syncStatus?.lastPulledAt ? `最近拉取钉钉 ${dayjs(syncStatus.lastPulledAt).format('YYYY-MM-DD HH:mm')}` : '暂无钉钉拉取记录'} {canEdit && ( )} } loading={refreshingDingTalk} onClick={onRefreshDingTalk} > 刷新钉钉考勤 } onClick={onExport}> 导出当前报表
current.isAfter(dayjs(), 'day')} onChange={onDateChange} />
: '当前日期没有排课'} onChange={onScheduleChange} options={scheduleOptions.map((schedule) => ({ value: schedule.id, label: `${schedule.subject}(${schedule.startTime}-${schedule.endTime})`, }))} />

{selectedClass}

{dateLabel} · 当前展示 {visibleStudentCount} 名学生 / {total} 条记录

班主任 {headTeacherNames}
生活老师 {lifeTeacherNames}
任课老师 {subjectTeacherNames}
{ADMIN_METRIC_META.map((metric) => { const value = metric.key === 'all' ? `${attendanceRate}%` : metric.key === 'absent' ? summary.absent + summary.pending : (summary[metric.key as keyof AttendanceSummary] ?? 0); const meta = STATUS_META[metric.key] ?? { className: 'is-present' }; return ( ); })}
{alerts.length > 0 && (
{alerts.length} 名学生存在连续异常 建议优先核查最近 14 天的缺勤记录
`${item.studentName}:${item.type}${item.count}次`) .join(';')} >
)} ); };