教学任务按 授课周数 × 周学时 = 课程总学时 双端校验,不匹配会显示具体差额并阻止保存;公共课批量生成同样校验。
排课约束增加课程、教师、学院、授课方式、场地要求、约束状态筛选,并支持批量修改当前筛选结果。 新增“非排时课程”授课方式:不进入自动排课 不占星期、节次和教室 不阻塞课表发布 允许正常选课 在班级课表和学生个人课表中单独展示
This commit is contained in:
@@ -145,7 +145,28 @@ onMounted(async () => {
|
||||
<span v-if="timetable.plan">发布于 {{ new Date(timetable.plan.publishedAt).toLocaleString('zh-CN') }}</span>
|
||||
<span v-else>本学期课表尚未发布</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<section v-if="timetable?.flexibleCourses?.length" class="flexible-courses">
|
||||
<div class="flexible-heading">
|
||||
<div>
|
||||
<span>非排时课程</span>
|
||||
<strong>不占正常上课时间与场地</strong>
|
||||
</div>
|
||||
<small>共 {{ timetable.flexibleCourses.length }} 门</small>
|
||||
</div>
|
||||
<div class="flexible-course-list">
|
||||
<article v-for="course in timetable.flexibleCourses" :key="course.id">
|
||||
<span>{{ course.courseCode }} · {{ course.taskNumber }}</span>
|
||||
<strong>{{ course.courseName }}</strong>
|
||||
<p>{{ course.teacherNames.join('、') || '教师待定' }}</p>
|
||||
<small>
|
||||
第 {{ course.startWeek }}—{{ course.endWeek }} 周 ·
|
||||
每周 {{ course.weeklyHours }} 学时 · 共 {{ course.totalHours }} 学时
|
||||
</small>
|
||||
</article>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div v-if="timetable?.plan && timetable.entries.length" class="timetable-scroll">
|
||||
<div
|
||||
@@ -182,7 +203,7 @@ onMounted(async () => {
|
||||
</div>
|
||||
</div>
|
||||
<el-empty
|
||||
v-else-if="timetable && !loading"
|
||||
v-else-if="timetable && !loading && !timetable.flexibleCourses?.length"
|
||||
:description="timetable.plan ? '该课表暂时没有课程安排' : '所选学期尚未发布课表'"
|
||||
/>
|
||||
</section>
|
||||
@@ -190,21 +211,33 @@ onMounted(async () => {
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.timetable-page { display: grid; gap: 20px; }
|
||||
.public-timetable { min-height: 100vh; padding: 0 32px 40px; background: #f4f7fa; }
|
||||
.timetable-page { min-width: 0; width: 100%; display: grid; grid-template-columns: minmax(0, 1fr); gap: 20px; }
|
||||
.public-timetable { max-width: 100vw; min-height: 100vh; padding: 0 32px 40px; box-sizing: border-box; background: #f4f7fa; }
|
||||
.public-header { height: 68px; display: flex; align-items: center; justify-content: space-between; border-bottom: 1px solid #dce4eb; }
|
||||
.public-brand { color: #17324d; font-weight: 750; text-decoration: none; letter-spacing: .02em; }
|
||||
.login-link { color: #176b87; text-decoration: none; font-weight: 650; }
|
||||
.timetable-heading { display: flex; align-items: end; justify-content: space-between; gap: 24px; padding: 24px 28px; background: #fff; border: 1px solid #dce4eb; }
|
||||
.timetable-heading { display: flex; flex-wrap: wrap; align-items: end; justify-content: space-between; gap: 24px; padding: 24px 28px; background: #fff; border: 1px solid #dce4eb; }
|
||||
.timetable-heading h2 { margin: 5px 0 8px; color: #17324d; font-size: 27px; }
|
||||
.timetable-heading p { margin: 0; color: #647587; }
|
||||
.timetable-filters { display: flex; gap: 12px; }
|
||||
.timetable-filters { display: flex; flex-wrap: wrap; gap: 12px; }
|
||||
.timetable-filters .el-select { width: 270px; }
|
||||
.timetable-sheet { min-height: 360px; padding: 22px; background: #fff; border: 1px solid #dce4eb; }
|
||||
.timetable-sheet { min-width: 0; min-height: 360px; padding: 22px; background: #fff; border: 1px solid #dce4eb; }
|
||||
.sheet-meta { display: flex; justify-content: space-between; gap: 24px; margin-bottom: 18px; padding-bottom: 16px; border-bottom: 1px solid #e6ebf0; }
|
||||
.sheet-meta div { display: grid; gap: 3px; }
|
||||
.sheet-meta strong { color: #17324d; }
|
||||
.sheet-meta span { color: #718191; font-size: 13px; }
|
||||
.flexible-courses { margin-bottom: 20px; border: 1px solid #cfe1dc; background: #f5faf8; }
|
||||
.flexible-heading { padding: 12px 15px; display: flex; align-items: center; justify-content: space-between; border-bottom: 1px solid #dce9e5; }
|
||||
.flexible-heading > div { display: flex; align-items: baseline; gap: 10px; }
|
||||
.flexible-heading span { color: #176b5d; font-size: 12px; font-weight: 750; }
|
||||
.flexible-heading strong { color: #506c65; font-size: 12px; }
|
||||
.flexible-heading small { color: #718b84; }
|
||||
.flexible-course-list { padding: 12px; display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 10px; }
|
||||
.flexible-course-list article { padding: 12px 13px; display: grid; gap: 4px; border-left: 3px solid #2d8975; background: #fff; }
|
||||
.flexible-course-list article > span { color: #277766; font: 700 10px/1.3 Consolas, monospace; }
|
||||
.flexible-course-list article strong { color: #173f38; font-size: 14px; }
|
||||
.flexible-course-list article p { margin: 0; color: #5e746f; font-size: 12px; }
|
||||
.flexible-course-list article small { color: #778b86; font-size: 11px; }
|
||||
.timetable-scroll { overflow: auto; }
|
||||
.week-grid { min-width: 1120px; display: grid; grid-template-columns: 92px repeat(7, minmax(140px, 1fr)); position: relative; }
|
||||
.grid-corner, .day-head, .period-head { z-index: 2; background: #f3f6f8; border: 1px solid #dce4eb; color: #3f5366; }
|
||||
|
||||
Reference in New Issue
Block a user