feat: classroom status filter + export button + menu (departments/notifications)
This commit is contained in:
@@ -24,6 +24,7 @@ import {
|
||||
KeyOutlined,
|
||||
CheckCircleOutlined,
|
||||
LaptopOutlined,
|
||||
BellOutlined,
|
||||
} from '@ant-design/icons';
|
||||
import { usePermission } from '../hooks/usePermission';
|
||||
import NotificationBell from '../components/NotificationBell';
|
||||
@@ -107,6 +108,8 @@ const allMenuItems: MenuItemType[] = [
|
||||
label: '系统管理',
|
||||
permission: 'log:view',
|
||||
children: [
|
||||
{ key: '/departments', icon: <HomeOutlined />, label: '校区/部门', permission: 'department:view' },
|
||||
{ key: '/notifications', icon: <BellOutlined />, label: '通知中心', permission: 'notification:view' },
|
||||
{ key: '/operation-logs', icon: <AuditOutlined />, label: '操作日志', permission: 'log:view' },
|
||||
{ key: '/roles', icon: <SafetyOutlined />, label: '角色管理', permission: 'role:view' },
|
||||
{ key: '/permissions', icon: <KeyOutlined />, label: '权限一览', permission: 'role:view' },
|
||||
|
||||
@@ -52,14 +52,14 @@ const ClassroomsPage: React.FC = () => {
|
||||
const [showArchived, setShowArchived] = useState(false);
|
||||
const [form] = Form.useForm();
|
||||
const [searchText, setSearchText] = useState('');
|
||||
const [filterStatus, setFilterStatus] = useState<string | undefined>(undefined);
|
||||
|
||||
const filteredData = useMemo(() => {
|
||||
if (!searchText) return data;
|
||||
const s = searchText.toLowerCase();
|
||||
return data.filter(
|
||||
(d: any) => d.name?.toLowerCase().includes(s) || d.building?.toLowerCase().includes(s),
|
||||
);
|
||||
}, [data, searchText]);
|
||||
let result = data;
|
||||
if (searchText) { const s = searchText.toLowerCase(); result = result.filter((d: Record<string, unknown>) => (typeof d.name === 'string' && d.name.toLowerCase().includes(s)) || (typeof d.building === 'string' && d.building.toLowerCase().includes(s))); }
|
||||
if (filterStatus) result = result.filter((d: Record<string, unknown>) => d.status === filterStatus);
|
||||
return result;
|
||||
}, [data, searchText, filterStatus]);
|
||||
|
||||
const fetchData = async () => {
|
||||
setLoading(true);
|
||||
@@ -223,6 +223,7 @@ const ClassroomsPage: React.FC = () => {
|
||||
if (!e.target.value) setSearchText('');
|
||||
}}
|
||||
/>
|
||||
<Select placeholder="状态" allowClear style={{ width: 110 }} value={filterStatus} onChange={setFilterStatus} options={[{value:'available',label:'可用'},{value:'in_use',label:'使用中'},{value:'maintenance',label:'维护中'}]} />
|
||||
<Button
|
||||
type={showArchived ? 'primary' : 'default'}
|
||||
onClick={() => setShowArchived(!showArchived)}
|
||||
@@ -243,6 +244,7 @@ const ClassroomsPage: React.FC = () => {
|
||||
>
|
||||
添加教室
|
||||
</PermissionButton>
|
||||
<PermissionButton permission="classroom:view" icon={<DownloadOutlined />} onClick={() => { const baseURL = '/api'; const token = localStorage.getItem('token'); fetch(`${baseURL}/classrooms/export`, { headers: { Authorization: `Bearer ${token}` } }).then(r => r.blob()).then(b => { const a = document.createElement('a'); a.href = URL.createObjectURL(b); a.download = '教室使用报表.xlsx'; a.click(); }); }}>导出报表</PermissionButton>
|
||||
<Upload
|
||||
accept=".xlsx,.xls"
|
||||
showUploadList={false}
|
||||
|
||||
Reference in New Issue
Block a user