+ setDraft((state) => ({ ...state, keyword: event.target.value }))} onPressEnter={applyFilters} />
+ {!!selectedRows.length && 已选择 {selectedRows.length} 个教学任务草稿 {selectedDrafts.length} · 已发布 {selectedPublished.length} · 已归档 {selectedClosed.length}
}
+ {tasks.isError ? : rowKey="id" loading={tasks.isLoading} rowSelection={rowSelection} columns={columns} dataSource={tasks.data?.items} pagination={false} scroll={{ x: 1480 }} locale={{ emptyText: }} />}
+
+
+
+ setEditing(undefined)} onOk={() => form.submit()} destroyOnHidden>
+
+ {selectedCourse && }
+
+ ({ value: item.teacherId, label: `${item.teacherNumber} · ${item.name}${item.title ? ` · ${item.title}` : ''}` }))} onChange={(values) => { const primary = form.getFieldValue('primaryTeacherId'); if (primary && !values.includes(primary)) form.setFieldValue('primaryTeacherId', undefined) }} />
+ watchedTeacherIds.includes(item.teacherId)).map((item) => ({ value: item.teacherId, label: item.name }))} />
+ ({ value: item.id, label: `${item.code} · ${item.name} · ${item.majorName}` }))} />
+
+
+
+
+ setGenerationOpen(false)} onOk={() => generationForm.submit()} destroyOnHidden>
+
+
+
+
+}
diff --git a/web-react/src/pages/teaching-tasks.css b/web-react/src/pages/teaching-tasks.css
new file mode 100644
index 0000000..fb2d34e
--- /dev/null
+++ b/web-react/src/pages/teaching-tasks.css
@@ -0,0 +1 @@
+.teaching-tasks-page{gap:16px}.task-header-actions,.task-actions,.task-batch>div:last-child{display:flex;align-items:center;flex-wrap:wrap;gap:7px}.task-summary{display:grid;grid-template-columns:180px 1fr;border:1px solid var(--line);background:#fff}.task-summary>div{padding:13px 18px;border-right:1px solid var(--line)}.task-summary span,.task-summary strong,.task-summary small{display:block}.task-summary span{color:var(--ink-muted);font-size:8px;text-transform:uppercase}.task-summary strong{margin:4px 0;color:var(--teal);font:700 23px var(--font-data)}.task-summary small{color:var(--ink-muted);font-size:8px}.task-summary p{display:flex;align-items:center;gap:10px;margin:0;padding:15px 20px;color:var(--ink-muted);line-height:1.65}.task-summary p>.anticon{color:var(--teal);font-size:22px}.task-card{min-width:0;padding:16px;border:1px solid var(--line);background:#fff}.task-filters{display:grid;grid-template-columns:1.35fr repeat(3,minmax(135px,1fr));gap:8px;margin-bottom:12px}.task-filters>.ant-input:nth-of-type(2),.task-filters>.ant-input:nth-of-type(3){min-width:150px}.task-batch{display:flex;align-items:center;justify-content:space-between;gap:16px;margin-bottom:12px;padding:11px 13px;border:1px solid #b9d9d4;background:#f2fbf9}.task-batch>div:first-child{display:grid;gap:3px}.task-batch span{color:var(--ink-muted);font-size:9px}.task-number{font:700 9px var(--font-data);color:var(--brand-deep)}.task-course{display:grid;gap:3px}.task-course strong{color:var(--brand-deep)}.task-course span,.task-course small,.muted{color:var(--ink-muted)}.task-course small{font-size:8px}.task-pager{display:flex;align-items:center;justify-content:space-between;margin-top:15px;color:var(--ink-muted);font-size:9px}.task-pager>span>.ant-select{width:68px}.task-pager>div{display:flex;align-items:center;gap:10px}.task-form-grid{display:grid;grid-template-columns:1fr 1fr;align-items:start;gap:12px}.task-form-grid.three{grid-template-columns:repeat(3,1fr)}.task-form-grid .ant-input-number,.ant-form-item>.ant-row>.ant-form-item-control .ant-input-number{width:100%}.hours-check,.generation-teachers{margin-bottom:18px}.generation-preview{display:grid;grid-template-columns:auto auto 1fr;align-items:baseline;gap:8px;padding:13px 16px;border:1px solid #b9d9d4;background:#f2fbf9}.generation-preview strong{color:var(--teal);font:700 26px var(--font-data)}.generation-preview small{color:var(--ink-muted)}@media(max-width:900px){.task-filters{grid-template-columns:1fr 1fr}.task-batch{align-items:flex-start;flex-direction:column}}@media(max-width:650px){.task-header-actions,.task-batch>div:last-child{align-items:stretch;flex-direction:column}.task-header-actions>*,.task-batch button{width:100%}.task-summary{grid-template-columns:1fr}.task-summary>div{border-right:0;border-bottom:1px solid var(--line)}.task-filters,.task-form-grid,.task-form-grid.three{grid-template-columns:1fr}.task-pager{align-items:stretch;flex-direction:column}.task-pager>div{justify-content:space-between}}