feat(schedules): replace teacher ID input with searchable user select, show teacher name, add schedule button

This commit is contained in:
2026-07-09 16:31:53 +08:00
parent c928ee0f65
commit d1d5b4681b

View File

@@ -10,6 +10,7 @@ import {
RightOutlined,
DeleteOutlined,
CloudSyncOutlined,
PlusOutlined,
} from '@ant-design/icons';
import dayjs, { Dayjs } from 'dayjs';
import api from '../../api';
@@ -49,6 +50,12 @@ interface ClassItem {
code: string;
}
interface UserItem {
id: number;
username: string;
name: string;
}
interface ScheduleFormValues {
classId: number;
subject: string;
@@ -83,6 +90,7 @@ const SchedulesPage: React.FC = () => {
// Data
const [classrooms, setClassrooms] = useState<ClassroomItem[]>([]);
const [classes, setClasses] = useState<ClassItem[]>([]);
const [users, setUsers] = useState<UserItem[]>([]);
const [matrix, setMatrix] = useState<Record<number, Record<number, ClassScheduleItem[]>>>({});
const [loading, setLoading] = useState(false);
@@ -236,6 +244,10 @@ const SchedulesPage: React.FC = () => {
fetchData();
}, [fetchData]);
useEffect(() => {
api.get<UserItem[]>('/rbac/users').then(setUsers).catch(() => {});
}, []);
// ---- Filtered classrooms ----
const filteredClassrooms = useMemo(() => {
@@ -394,6 +406,15 @@ const SchedulesPage: React.FC = () => {
[classes],
);
const userOptions = useMemo(
() =>
users.map((u) => ({
value: u.id,
label: `${u.name || u.username}${u.name ? ` (${u.username})` : ''}`,
})),
[users],
);
// ---- Render ----
const selectedClassroom = selectedCell
@@ -785,10 +806,15 @@ const SchedulesPage: React.FC = () => {
<Form.Item
name="teacherId"
label="教师ID(可选)"
normalize={(v) => (v ? Number(v) : undefined)}
label="教师(可选)"
>
<Input type="number" placeholder="输入教师用户ID" />
<Select
showSearch
allowClear
placeholder="搜索并选择教师"
optionFilterProp="label"
options={userOptions}
/>
</Form.Item>
<Form.Item label="教室">
@@ -828,6 +854,19 @@ const SchedulesPage: React.FC = () => {
</Form>
) : (
<div style={{ lineHeight: 2 }}>
<div style={{ marginBottom: 12, display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
<span style={{ fontWeight: 500 }}></span>
<Button
type="primary"
icon={<PlusOutlined />}
onClick={() => {
setModalMode('create');
form.resetFields();
}}
>
</Button>
</div>
{selectedSchedules.length === 0 ? (
<Empty description="该时段暂无排课" />
) : (
@@ -850,8 +889,10 @@ const SchedulesPage: React.FC = () => {
</div>
{s.teacherId != null && (
<div>
<strong>ID</strong>
{s.teacherId}
<strong></strong>
{users.find((u) => u.id === s.teacherId)?.name
|| users.find((u) => u.id === s.teacherId)?.username
|| `#${s.teacherId}`}
</div>
)}
<div>