feat(attendance): add anomaly alert banner showing consecutive absences and frequent lates
This commit is contained in:
@@ -1,20 +1,7 @@
|
||||
import React, { useEffect, useState, useMemo, useCallback } from 'react';
|
||||
import {
|
||||
Table,
|
||||
Button,
|
||||
Modal,
|
||||
Form,
|
||||
DatePicker,
|
||||
Select,
|
||||
Space,
|
||||
message,
|
||||
Tag,
|
||||
Card,
|
||||
Input,
|
||||
Tooltip,
|
||||
Row,
|
||||
Col,
|
||||
Tabs,
|
||||
Table, Button, Modal, Form, DatePicker, Select, Space, message,
|
||||
Tag, Card, Input, Tooltip, Row, Col, Tabs, Alert,
|
||||
} from 'antd';
|
||||
import {
|
||||
PlusOutlined,
|
||||
@@ -115,6 +102,7 @@ interface DingRecord {
|
||||
matchStatus: string;
|
||||
studentId?: number;
|
||||
}
|
||||
interface AlertItem { studentId: number; studentName: string; className: string; type: string; count: number; lastDate: string }
|
||||
|
||||
// ── Component ──
|
||||
|
||||
@@ -126,6 +114,7 @@ const AttendancePage: React.FC = () => {
|
||||
const [page, setPage] = useState(1);
|
||||
const [pageSize, setPageSize] = useState(20);
|
||||
const [classOptions, setClassOptions] = useState<ClassOption[]>([]);
|
||||
const [alerts, setAlerts] = useState<AlertItem[]>([]);
|
||||
|
||||
// Filters
|
||||
const [filterClassId, setFilterClassId] = useState<number | undefined>(undefined);
|
||||
@@ -192,8 +181,9 @@ const AttendancePage: React.FC = () => {
|
||||
message.success('更新成功');
|
||||
setEditModalOpen(false);
|
||||
fetchRecords();
|
||||
} catch (e: any) {
|
||||
message.error(e?.message || '更新失败');
|
||||
} catch (e: unknown) {
|
||||
const err = e as { message?: string };
|
||||
message.error(err?.message || '更新失败');
|
||||
}
|
||||
};
|
||||
|
||||
@@ -275,6 +265,7 @@ const AttendancePage: React.FC = () => {
|
||||
useEffect(() => {
|
||||
fetchClasses();
|
||||
}, [fetchClasses]);
|
||||
useEffect(() => { api.get<AlertItem[]>('/attendance-records/alerts').then(setAlerts).catch(() => {}) }, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (calendarView) {
|
||||
@@ -577,6 +568,11 @@ const AttendancePage: React.FC = () => {
|
||||
// ── Render ──
|
||||
return (
|
||||
<div>
|
||||
{alerts.length > 0 && (
|
||||
<Alert type="warning" showIcon closable
|
||||
message={`考勤预警:${alerts.length} 名学生异常`}
|
||||
description={alerts.map(a => `${a.studentName}(${a.className || '-'}):${a.type} ${a.count}次,最近${a.lastDate}`).join(';')}
|
||||
style={{ marginBottom: 16 }} />)}
|
||||
<Tabs
|
||||
activeKey={activeTab}
|
||||
onChange={setActiveTab}
|
||||
|
||||
Reference in New Issue
Block a user