> }, { key: 'constraints', label: '课程排课约束', children: <> rowKey="id" size="small" rowSelection={constraintSelection} columns={constraintColumns} dataSource={filteredConstraints} pagination={{ pageSize: 10 }} locale={{ emptyText: }} />> }]} />
+
+ setConstraintEditor(undefined)} onOk={() => constraintForm.submit()}> ({ value: index + 1, label }))} /> ({ value: index + 1, label }))} />{!!constraintEditor?.coursePracticeHours && <>>}
+ setBatchOpen(false)} onOk={() => batchForm.submit()}>修改授课方式修改场地要求修改允许上课日 ({ value: index + 1, label }))} />修改允许节次范围修改普通课教室范围修改实验场地范围
+
+}
diff --git a/web-react/src/pages/schedules.css b/web-react/src/pages/schedules.css
new file mode 100644
index 0000000..298dee5
--- /dev/null
+++ b/web-react/src/pages/schedules.css
@@ -0,0 +1 @@
+.schedules-page{gap:16px}.schedule-header-actions,.schedule-actions,.settings-lead>div:last-child{display:flex;align-items:center;flex-wrap:wrap;gap:8px}.schedule-toolbar{display:grid;grid-template-columns:210px 1fr;gap:12px;align-items:stretch}.schedule-versions{display:flex;gap:7px;overflow-x:auto}.schedule-versions>button{display:grid;min-width:118px;padding:9px 12px;text-align:left;border:1px solid var(--line);background:#fff;color:var(--ink);cursor:pointer}.schedule-versions>button.active{border-color:var(--teal);box-shadow:inset 0 0 0 1px var(--teal);background:#f2fbf9}.schedule-versions strong,.schedule-versions span,.schedule-versions small{display:block}.schedule-versions span,.schedule-versions small{color:var(--ink-muted);font-size:8px}.schedule-sheet,.schedule-empty{min-width:0;padding:17px;border:1px solid var(--line);background:#fff}.schedule-sheet>header{display:flex;align-items:flex-start;justify-content:space-between;gap:18px}.schedule-sheet>header span,.schedule-sheet>header p{color:var(--ink-muted);font-size:9px}.schedule-sheet>header h2{margin:5px 0;color:var(--brand-deep);font-size:21px}.schedule-job{display:grid;gap:7px;margin-top:14px;padding:12px 14px;border-left:3px solid #56709a;background:#f5f7fa}.schedule-job.is-succeeded{border-color:var(--teal);background:#f2fbf9}.schedule-job.is-failed{border-color:#b42318;background:#fff5f4}.schedule-job ol{margin:6px 0;padding-left:18px}.schedule-search{display:flex;align-items:center;gap:8px;margin:15px 0}.schedule-search>.ant-input-affix-wrapper{max-width:340px}.schedule-search>span{color:var(--ink-muted);font-size:9px}.timetable-scroll{overflow:auto}.timetable-grid{min-width:1180px;border-top:1px solid var(--line);border-left:1px solid var(--line)}.timetable-grid>.timetable-day,.timetable-corner{display:inline-flex;align-items:center;justify-content:center;width:calc((100% - 90px)/7);min-height:38px;border-right:1px solid var(--line);border-bottom:1px solid var(--line);background:#f6f7f9;font-weight:700}.timetable-corner{width:90px}.timetable-row{display:grid;grid-template-columns:90px repeat(7,1fr)}.timetable-period,.timetable-cell{min-height:105px;border-right:1px solid var(--line);border-bottom:1px solid var(--line)}.timetable-period{display:grid;place-content:center;text-align:center;background:#fafafa}.timetable-period strong{font:700 16px var(--font-data)}.timetable-period span{color:var(--ink-muted);font-size:7px}.timetable-cell{position:relative;padding:4px}.timetable-cell>article{position:relative;display:grid;gap:3px;margin-bottom:4px;padding:7px;border-left:3px solid var(--brand);background:#eef3ff;cursor:pointer}.timetable-cell>article.experiment{border-color:#af6b17;background:#fff7e8}.timetable-cell article span,.timetable-cell article small,.timetable-cell article i{color:var(--ink-muted);font-size:7px;font-style:normal}.timetable-cell article button{position:absolute;right:3px;top:2px;border:0;background:transparent;color:#b42318;cursor:pointer}.timetable-cell em{display:block;margin-top:32px;text-align:center;color:#a5adba;font-size:8px;font-style:normal}.schedule-form-grid{display:grid;grid-template-columns:1fr 1fr;gap:12px}.schedule-form-grid.three{grid-template-columns:repeat(3,1fr)}.schedule-form-grid .ant-input-number,.optimization-form .ant-input-number{width:100%}.entry-alert{margin-bottom:16px}.settings-lead{display:flex;align-items:center;justify-content:space-between;gap:14px;margin-bottom:14px}.settings-lead>div:first-child{display:grid;gap:3px}.settings-lead span{color:var(--ink-muted);font-size:9px}.optimization-form{margin-top:16px}.constraint-filters{display:grid;grid-template-columns:1fr 220px;gap:8px;margin-bottom:12px}.constraint-task{display:grid;gap:3px}.constraint-task span{color:var(--ink-muted);font-size:8px}@media(max-width:900px){.schedule-toolbar{grid-template-columns:1fr}.schedule-sheet>header,.settings-lead{align-items:stretch;flex-direction:column}.schedule-search{align-items:stretch;flex-direction:column}.schedule-search>.ant-input-affix-wrapper{max-width:none}}@media(max-width:620px){.schedule-header-actions,.schedule-actions{align-items:stretch;flex-direction:column}.schedule-header-actions>*,.schedule-actions>*{width:100%}.schedule-form-grid,.schedule-form-grid.three,.constraint-filters{grid-template-columns:1fr}}