diff --git a/apps/admin/src/components/CampusSwitcher.tsx b/apps/admin/src/components/CampusSwitcher.tsx
new file mode 100644
index 0000000..9104a70
--- /dev/null
+++ b/apps/admin/src/components/CampusSwitcher.tsx
@@ -0,0 +1,36 @@
+import React from 'react';
+import { Select, Typography } from 'antd';
+import { EnvironmentOutlined } from '@ant-design/icons';
+import { useCampus } from '../hooks/useCampus';
+
+const CampusSwitcher: React.FC = () => {
+ const { campuses, currentId, switchCampus, loading } = useCampus();
+
+ if (campuses.length <= 1) {
+ return (
+
+
+ {campuses[0]?.name || '主校区'}
+
+ );
+ }
+
+ const options = [
+ ...campuses.map((c) => ({ value: String(c.id), label: c.name })),
+ { value: '', label: '全部校区' },
+ ];
+
+ return (
+
+ );
+};
+
+export default CampusSwitcher;
diff --git a/apps/admin/src/hooks/useCampus.ts b/apps/admin/src/hooks/useCampus.ts
new file mode 100644
index 0000000..e07afa5
--- /dev/null
+++ b/apps/admin/src/hooks/useCampus.ts
@@ -0,0 +1,40 @@
+import { useState, useEffect, useCallback } from 'react';
+import api from '../api';
+
+interface Department {
+ id: number;
+ name: string;
+ type: string;
+ parentId: number | null;
+}
+
+export function useCampus() {
+ const [campuses, setCampuses] = useState([]);
+ const [currentId, setCurrentId] = useState(
+ () => localStorage.getItem('currentCampusId') || ''
+ );
+ const [loading, setLoading] = useState(true);
+
+ const fetchCampuses = useCallback(async () => {
+ try {
+ const data = await api.get('/departments') as unknown as Department[];
+ const campusList = data.filter((d) => d.type === 'campus');
+ setCampuses(campusList);
+ if (!currentId && campusList.length > 0) {
+ setCurrentId(String(campusList[0].id));
+ localStorage.setItem('currentCampusId', String(campusList[0].id));
+ }
+ } catch { /* ignore */ }
+ finally { setLoading(false); }
+ }, [currentId]);
+
+ useEffect(() => { fetchCampuses(); }, []);
+
+ const switchCampus = useCallback((id: string) => {
+ setCurrentId(id);
+ localStorage.setItem('currentCampusId', id);
+ window.dispatchEvent(new CustomEvent('campus-changed', { detail: id }));
+ }, []);
+
+ return { campuses, currentId, switchCampus, loading };
+}