教学任务按 授课周数 × 周学时 = 课程总学时 双端校验,不匹配会显示具体差额并阻止保存;公共课批量生成同样校验。
排课约束增加课程、教师、学院、授课方式、场地要求、约束状态筛选,并支持批量修改当前筛选结果。 新增“非排时课程”授课方式:不进入自动排课 不占星期、节次和教室 不阻塞课表发布 允许正常选课 在班级课表和学生个人课表中单独展示
This commit is contained in:
@@ -77,6 +77,14 @@ const availableClasses = computed(() => {
|
||||
const selectedCourse = computed(() =>
|
||||
courses.value.find((item) => item.id === form.courseId),
|
||||
)
|
||||
const plannedHours = computed(() =>
|
||||
form.startWeek && form.endWeek && form.weeklyHours && form.endWeek >= form.startWeek
|
||||
? (form.endWeek - form.startWeek + 1) * form.weeklyHours
|
||||
: 0,
|
||||
)
|
||||
const hoursMatch = computed(() =>
|
||||
!selectedCourse.value || plannedHours.value === selectedCourse.value.totalHours,
|
||||
)
|
||||
const assignableTeachers = computed(() => {
|
||||
if (!selectedCourse.value) return teachers.value
|
||||
const approvedIds = new Set(manualEligibleTeachers.value.map((item) => item.teacherId))
|
||||
@@ -92,6 +100,21 @@ const publicCourses = computed(() =>
|
||||
['GeneralRequired', 'GeneralElective'].includes(item.nature),
|
||||
),
|
||||
)
|
||||
const selectedGenerationCourse = computed(() =>
|
||||
publicCourses.value.find((item) => item.id === generationForm.courseId),
|
||||
)
|
||||
const generationPlannedHours = computed(() =>
|
||||
generationForm.startWeek &&
|
||||
generationForm.endWeek &&
|
||||
generationForm.weeklyHours &&
|
||||
generationForm.endWeek >= generationForm.startWeek
|
||||
? (generationForm.endWeek - generationForm.startWeek + 1) * generationForm.weeklyHours
|
||||
: 0,
|
||||
)
|
||||
const generationHoursMatch = computed(() =>
|
||||
!selectedGenerationCourse.value ||
|
||||
generationPlannedHours.value === selectedGenerationCourse.value.totalHours,
|
||||
)
|
||||
const manageableCourses = computed(() => {
|
||||
if (isSuperAdmin.value) return courses.value
|
||||
return courses.value.filter((item) => {
|
||||
@@ -265,7 +288,8 @@ function resetForm(detail?: any) {
|
||||
capacity: 60,
|
||||
startWeek: 1,
|
||||
endWeek: 16,
|
||||
weeklyHours: 2,
|
||||
weeklyHours: 2,
|
||||
schedulingMode: 'Standard',
|
||||
teacherIds: [],
|
||||
primaryTeacherId: undefined,
|
||||
classIds: [],
|
||||
@@ -325,6 +349,12 @@ async function save() {
|
||||
ElMessage.warning('开始周不能晚于结束周。')
|
||||
return
|
||||
}
|
||||
if (!hoursMatch.value) {
|
||||
ElMessage.warning(
|
||||
`课程总学时为 ${selectedCourse.value.totalHours},当前授课安排合计 ${plannedHours.value} 学时,请调整周次或周学时。`,
|
||||
)
|
||||
return
|
||||
}
|
||||
try {
|
||||
if (editingId.value) await http.put(`/teaching-tasks/${editingId.value}`, form)
|
||||
else await http.post('/teaching-tasks', form)
|
||||
@@ -466,6 +496,12 @@ async function generatePublicTasks() {
|
||||
ElMessage.warning('该课程还没有审核通过的可授课教师。')
|
||||
return
|
||||
}
|
||||
if (!generationHoursMatch.value) {
|
||||
ElMessage.warning(
|
||||
`课程总学时为 ${selectedGenerationCourse.value.totalHours},当前授课安排合计 ${generationPlannedHours.value} 学时,请调整周次或周学时。`,
|
||||
)
|
||||
return
|
||||
}
|
||||
try {
|
||||
await ElMessageBox.confirm(
|
||||
`将 ${generationForm.classIds.length} 个行政班分成 ${generationGroupCount.value} 个教学班,并在 ${eligibleTeachers.value.length} 名合格教师中随机均衡分配。生成结果为草稿,确定继续吗?`,
|
||||
@@ -618,7 +654,7 @@ onMounted(async () => {
|
||||
<el-form-item label="开课学期" required><el-select v-model="form.academicTermId" @change="loadManualEligibleTeachers"><el-option v-for="item in terms" :key="item.id" :label="item.name" :value="item.id" /></el-select></el-form-item>
|
||||
<el-form-item label="课程" required>
|
||||
<el-select v-model="form.courseId" filterable @change="form.teacherIds = []; form.primaryTeacherId = undefined; loadManualEligibleTeachers()">
|
||||
<el-option v-for="item in filteredManageableCourses" :key="item.id" :label="`${item.code} · ${item.name}`" :value="item.id" />
|
||||
<el-option v-for="item in filteredManageableCourses" :key="item.id" :label="`${item.code} · ${item.name}(${item.totalHours} 学时)`" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</div>
|
||||
@@ -640,7 +676,26 @@ onMounted(async () => {
|
||||
<el-form-item label="开始周"><el-input-number v-model="form.startWeek" :min="1" :max="30" /></el-form-item>
|
||||
<el-form-item label="结束周"><el-input-number v-model="form.endWeek" :min="1" :max="30" /></el-form-item>
|
||||
</div>
|
||||
<el-form-item label="周学时"><el-input-number v-model="form.weeklyHours" :min="1" :max="40" /></el-form-item>
|
||||
<el-form-item label="周学时"><el-input-number v-model="form.weeklyHours" :min="1" :max="40" /></el-form-item>
|
||||
<div
|
||||
v-if="selectedCourse"
|
||||
:class="['hours-validation', { invalid: !hoursMatch }]"
|
||||
>
|
||||
<b>{{ hoursMatch ? '学时匹配' : '学时不匹配' }}</b>
|
||||
<span>
|
||||
第 {{ form.startWeek }}—{{ form.endWeek }} 周 × 每周 {{ form.weeklyHours }} 学时
|
||||
= {{ plannedHours }} 学时;课程库总学时 {{ selectedCourse.totalHours }}。
|
||||
</span>
|
||||
</div>
|
||||
<el-form-item label="授课方式">
|
||||
<el-radio-group v-model="form.schedulingMode">
|
||||
<el-radio-button value="Standard">正常排课</el-radio-button>
|
||||
<el-radio-button value="Flexible">非排时课程</el-radio-button>
|
||||
</el-radio-group>
|
||||
<small class="field-hint">
|
||||
非排时课程不进入自动排课,不占用星期、节次和场地,并在课表中单独列出。
|
||||
</small>
|
||||
</el-form-item>
|
||||
<el-form-item label="授课教师">
|
||||
<el-select v-model="form.teacherIds" multiple filterable @change="onTeachersChanged">
|
||||
<el-option v-for="item in assignableTeachers" :key="item.id" :label="`${item.teacherNumber} · ${item.name}`" :value="item.id" />
|
||||
@@ -757,9 +812,19 @@ onMounted(async () => {
|
||||
<el-input-number v-model="generationForm.endWeek" :min="1" :max="30" />
|
||||
</el-form-item>
|
||||
</div>
|
||||
<el-form-item label="周学时">
|
||||
<el-input-number v-model="generationForm.weeklyHours" :min="1" :max="40" />
|
||||
</el-form-item>
|
||||
<el-form-item label="周学时">
|
||||
<el-input-number v-model="generationForm.weeklyHours" :min="1" :max="40" />
|
||||
</el-form-item>
|
||||
<div
|
||||
v-if="selectedGenerationCourse"
|
||||
:class="['hours-validation', { invalid: !generationHoursMatch }]"
|
||||
>
|
||||
<b>{{ generationHoursMatch ? '学时匹配' : '学时不匹配' }}</b>
|
||||
<span>
|
||||
当前合计 {{ generationPlannedHours }} 学时;课程库总学时
|
||||
{{ selectedGenerationCourse.totalHours }}。
|
||||
</span>
|
||||
</div>
|
||||
<div class="generation-preview">
|
||||
<span>预计生成</span>
|
||||
<b>{{ generationGroupCount }}</b>
|
||||
|
||||
Reference in New Issue
Block a user