|
|
|
|
@ -1,56 +1,132 @@
|
|
|
|
|
<template>
|
|
|
|
|
<el-dialog v-model="visible" :title="`${classData?.className || ''} — 课程安排`" width="800px" align-center destroy-on-close @closed="emit('closed')">
|
|
|
|
|
<div class="filter-bar" style="padding: 0 0 16px 0">
|
|
|
|
|
<el-button type="primary" :icon="Plus" size="small" @click="addCourseRow">添加课程</el-button>
|
|
|
|
|
<el-dialog v-model="visible" :title="`${classData?.className || ''} — 课程安排`" width="850px" align-center destroy-on-close @closed="emit('closed')">
|
|
|
|
|
<div v-loading="loading" style="min-height: 200px">
|
|
|
|
|
<div class="toolbar">
|
|
|
|
|
<div class="toolbar-left">
|
|
|
|
|
<el-button type="primary" :icon="Plus" size="small" @click="showAddDialog">新增课程安排</el-button>
|
|
|
|
|
<el-button type="danger" :icon="Delete" size="small" :disabled="selectedIds.length === 0" @click="batchDelete">批量删除</el-button>
|
|
|
|
|
</div>
|
|
|
|
|
<span v-if="selectedIds.length > 0" class="toolbar-tip">已选 {{ selectedIds.length }} 项</span>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<el-table ref="tableRef" :data="scheduleList" stripe border size="small" empty-text="暂无课程安排数据" @selection-change="onSelectionChange">
|
|
|
|
|
<el-table-column type="selection" width="40" />
|
|
|
|
|
<el-table-column label="课程名称" min-width="180">
|
|
|
|
|
<template #default="{ row }">{{ getCourseName(row.courseId) }}</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column label="授课教师" width="110">
|
|
|
|
|
<template #default="{ row }">{{ getTeacherName(row.teacherId) }}</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column label="星期" width="80" align="center">
|
|
|
|
|
<template #default="{ row }">{{ weekLabel[row.weekDay] || row.weekDay }}</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column label="学期" width="120" align="center">
|
|
|
|
|
<template #default="{ row }">{{ row.semester }}</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column prop="status" label="状态" width="90" align="center">
|
|
|
|
|
<template #default="{ row }">
|
|
|
|
|
<el-tag :type="row.status === 1 ? 'success' : 'info'" size="small">{{ row.status === 1 ? '进行中' : '已结束' }}</el-tag>
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column label="操作" width="150" align="center" fixed="right">
|
|
|
|
|
<template #default="{ row }">
|
|
|
|
|
<el-button type="primary" link size="small" @click="showDetail(row)">详情</el-button>
|
|
|
|
|
<el-button type="primary" link size="small" @click="showEditDialog(row)">修改</el-button>
|
|
|
|
|
<el-button type="danger" link size="small" @click="handleDelete(row.id)">删除</el-button>
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
</el-table>
|
|
|
|
|
</div>
|
|
|
|
|
<el-table :data="currentCourses" stripe border size="small">
|
|
|
|
|
<el-table-column label="课程名称" min-width="160">
|
|
|
|
|
<template #default="{ row }">
|
|
|
|
|
<el-input v-model="row.courseName" placeholder="课程名称" size="small" />
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column label="授课教师" width="110">
|
|
|
|
|
<template #default="{ row }">
|
|
|
|
|
<el-input v-model="row.teacherName" placeholder="教师" size="small" />
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column label="星期" width="90" align="center">
|
|
|
|
|
<template #default="{ row }">
|
|
|
|
|
<el-select v-model="row.weekday" size="small" style="width: 100%">
|
|
|
|
|
<el-option v-for="(w, i) in weekdays" :key="i" :label="w" :value="i + 1" />
|
|
|
|
|
</el-select>
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column label="开始节次" width="90" align="center">
|
|
|
|
|
<template #default="{ row }">
|
|
|
|
|
<el-input-number v-model="row.startPeriod" :min="1" :max="12" size="small" controls-position="right" style="width: 100%" />
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column label="结束节次" width="90" align="center">
|
|
|
|
|
<template #default="{ row }">
|
|
|
|
|
<el-input-number v-model="row.endPeriod" :min="1" :max="12" size="small" controls-position="right" style="width: 100%" />
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column label="教室" width="140">
|
|
|
|
|
<template #default="{ row }">
|
|
|
|
|
<el-input v-model="row.classroom" placeholder="教室" size="small" />
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column label="操作" width="70" align="center">
|
|
|
|
|
<template #default="{ $index }">
|
|
|
|
|
<el-button link type="danger" size="small" :icon="Delete" @click="currentCourses.splice($index, 1)" />
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
</el-table>
|
|
|
|
|
|
|
|
|
|
<template #footer>
|
|
|
|
|
<el-button @click="visible = false">关闭</el-button>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<!-- 新增/编辑课程安排弹窗 -->
|
|
|
|
|
<el-dialog v-model="addVisible" :title="isEdit ? '编辑课程安排' : '新增课程安排'" width="500px" append-to-body destroy-on-close @closed="onFormDialogClosed">
|
|
|
|
|
<el-form ref="addFormRef" :model="addForm" :rules="addRules" label-width="90px" label-position="left">
|
|
|
|
|
<el-form-item label="课程名称" prop="courseId">
|
|
|
|
|
<el-select v-model="addForm.courseId" placeholder="请选择课程" filterable style="width: 100%">
|
|
|
|
|
<el-option v-for="c in courseOptions" :key="c.id" :label="c.courseName" :value="c.id" />
|
|
|
|
|
</el-select>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<el-form-item label="授课老师" prop="teacherId">
|
|
|
|
|
<el-select v-model="addForm.teacherId" placeholder="请选择老师" filterable style="width: 100%">
|
|
|
|
|
<el-option v-for="t in teacherOptions" :key="t.id" :label="t.name" :value="t.id" />
|
|
|
|
|
</el-select>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<el-form-item label="星期几" prop="weekDay">
|
|
|
|
|
<el-select v-model="addForm.weekDay" placeholder="请选择星期" style="width: 100%">
|
|
|
|
|
<el-option v-for="w in weekdayOptions" :key="w.value" :label="w.label" :value="w.value" />
|
|
|
|
|
</el-select>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<el-form-item label="教学楼" prop="buildingId">
|
|
|
|
|
<el-select v-model="addForm.buildingId" placeholder="请选择教学楼" @change="onBuildingChange" style="width: 100%">
|
|
|
|
|
<el-option v-for="b in buildingOptions" :key="b.id" :label="b.buildingName" :value="b.id" />
|
|
|
|
|
</el-select>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<el-form-item label="教室" prop="classroomId">
|
|
|
|
|
<el-select v-model="addForm.classroomId" placeholder="请选择教室" filterable style="width: 100%">
|
|
|
|
|
<el-option v-for="r in filteredRoomOptions" :key="r.id" :label="r.name" :value="r.id" />
|
|
|
|
|
</el-select>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<el-form-item label="开始节次" prop="startSection">
|
|
|
|
|
<el-input-number v-model="addForm.startSection" :min="1" :max="12" style="width: 100%" />
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<el-form-item label="结束节次" prop="endSection">
|
|
|
|
|
<el-input-number v-model="addForm.endSection" :min="1" :max="12" style="width: 100%" />
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<el-form-item label="开始周" prop="startWeek">
|
|
|
|
|
<el-input-number v-model="addForm.startWeek" :min="1" :max="20" style="width: 100%" />
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<el-form-item label="结束周" prop="endWeek">
|
|
|
|
|
<el-input-number v-model="addForm.endWeek" :min="1" :max="20" style="width: 100%" />
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<el-form-item label="学期" prop="semester">
|
|
|
|
|
<el-input v-model="addForm.semester" placeholder="请输入学期,如:2024-2025-1" style="width: 100%" />
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<el-form-item label="状态" prop="status">
|
|
|
|
|
<el-radio-group v-model="addForm.status">
|
|
|
|
|
<el-radio :value="1">启用</el-radio>
|
|
|
|
|
<el-radio :value="0">结束</el-radio>
|
|
|
|
|
</el-radio-group>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</el-form>
|
|
|
|
|
<template #footer>
|
|
|
|
|
<el-button @click="addVisible = false">取消</el-button>
|
|
|
|
|
<el-button type="primary" :loading="addLoading" @click="saveSchedule">保存</el-button>
|
|
|
|
|
</template>
|
|
|
|
|
</el-dialog>
|
|
|
|
|
|
|
|
|
|
<!-- 课程安排详情弹窗 -->
|
|
|
|
|
<el-dialog v-model="detailVisible" title="课程安排详情" width="600px" append-to-body destroy-on-close>
|
|
|
|
|
<el-descriptions :column="2" border v-if="detailData">
|
|
|
|
|
<el-descriptions-item label="课程名称">{{ getCourseName(detailData.courseId) }}</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="授课教师">{{ getTeacherName(detailData.teacherId) }}</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="星期">{{ weekLabel[detailData.weekDay] || detailData.weekDay }}</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="学期">{{ detailData.semester }}</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="开始节次">{{ detailData.startSection }}</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="结束节次">{{ detailData.endSection }}</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="开始周">{{ detailData.startWeek }}</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="结束周">{{ detailData.endWeek }}</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="教学楼">{{ getBuildingName(detailData.classroomId) }}</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="教室">{{ getRoomName(detailData.classroomId) }}</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="状态">
|
|
|
|
|
<el-tag :type="detailData.status === 1 ? 'success' : 'info'" size="small">{{ detailData.status === 1 ? '进行中' : '已结束' }}</el-tag>
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
</el-descriptions>
|
|
|
|
|
<template #footer>
|
|
|
|
|
<el-button @click="detailVisible = false">关闭</el-button>
|
|
|
|
|
</template>
|
|
|
|
|
</el-dialog>
|
|
|
|
|
</el-dialog>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script setup>
|
|
|
|
|
import { ref, watch, computed } from 'vue'
|
|
|
|
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
|
|
|
|
import { Plus, Delete } from '@element-plus/icons-vue'
|
|
|
|
|
import { getSchedulePage, addSchedule, updateSchedule, deleteSchedule, getTeacherList, getCourses, getRooms, getBuildingList } from '@/api/info'
|
|
|
|
|
|
|
|
|
|
const props = defineProps({
|
|
|
|
|
modelValue: { type: Boolean, default: false },
|
|
|
|
|
@ -64,45 +140,280 @@ const visible = computed({
|
|
|
|
|
set: (val) => emit('update:modelValue', val)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
const currentCourses = ref([])
|
|
|
|
|
|
|
|
|
|
const weekdays = ['一', '二', '三', '四', '五']
|
|
|
|
|
|
|
|
|
|
// 模拟各班级课程
|
|
|
|
|
const courseMap = {
|
|
|
|
|
1: [
|
|
|
|
|
{ courseName: '数据结构与算法', teacherName: '张明', weekday: 1, startPeriod: 1, endPeriod: 2, classroom: '阶梯教室101' },
|
|
|
|
|
{ courseName: '操作系统', teacherName: '李华', weekday: 2, startPeriod: 3, endPeriod: 4, classroom: '多媒体教室102' },
|
|
|
|
|
{ courseName: '计算机网络', teacherName: '王芳', weekday: 3, startPeriod: 1, endPeriod: 2, classroom: '多媒体教室201' },
|
|
|
|
|
{ courseName: '数据库原理', teacherName: '陈伟', weekday: 4, startPeriod: 5, endPeriod: 6, classroom: '多媒体教室201' }
|
|
|
|
|
],
|
|
|
|
|
2: [
|
|
|
|
|
{ courseName: '计算机网络', teacherName: '王芳', weekday: 1, startPeriod: 3, endPeriod: 4, classroom: '多媒体教室102' },
|
|
|
|
|
{ courseName: '数据库原理', teacherName: '陈伟', weekday: 2, startPeriod: 1, endPeriod: 2, classroom: '多媒体教室201' },
|
|
|
|
|
{ courseName: '数据结构与算法', teacherName: '张明', weekday: 3, startPeriod: 5, endPeriod: 6, classroom: '阶梯教室101' }
|
|
|
|
|
],
|
|
|
|
|
3: [
|
|
|
|
|
{ courseName: '软件工程', teacherName: '刘洋', weekday: 1, startPeriod: 1, endPeriod: 2, classroom: '多媒体教室101' },
|
|
|
|
|
{ courseName: 'Java程序设计', teacherName: '赵丽', weekday: 2, startPeriod: 3, endPeriod: 4, classroom: '多媒体教室102' },
|
|
|
|
|
{ courseName: '软件测试', teacherName: '孙磊', weekday: 3, startPeriod: 1, endPeriod: 2, classroom: '多媒体教室201' }
|
|
|
|
|
]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 弹窗打开时根据 classData 加载课程数据
|
|
|
|
|
watch(() => props.modelValue, (val) => {
|
|
|
|
|
const loading = ref(false)
|
|
|
|
|
const scheduleList = ref([])
|
|
|
|
|
|
|
|
|
|
// 下拉选项
|
|
|
|
|
const teacherOptions = ref([])
|
|
|
|
|
const courseOptions = ref([])
|
|
|
|
|
const buildingOptions = ref([])
|
|
|
|
|
const allRooms = ref([]) // 全部教室(含 buildingId,供筛选与映射)
|
|
|
|
|
|
|
|
|
|
const weekdayOptions = [
|
|
|
|
|
{ label: '星期一', value: 1 },
|
|
|
|
|
{ label: '星期二', value: 2 },
|
|
|
|
|
{ label: '星期三', value: 3 },
|
|
|
|
|
{ label: '星期四', value: 4 },
|
|
|
|
|
{ label: '星期五', value: 5 },
|
|
|
|
|
{ label: '星期六', value: 6 },
|
|
|
|
|
{ label: '星期日', value: 7 }
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
const weekLabel = ['', '一', '二', '三', '四', '五', '六', '日']
|
|
|
|
|
|
|
|
|
|
const getTeacherName = (teacherId) => {
|
|
|
|
|
const t = teacherOptions.value.find(item => item.id === teacherId)
|
|
|
|
|
return t ? t.name : ''
|
|
|
|
|
}
|
|
|
|
|
const getCourseName = (courseId) => {
|
|
|
|
|
const c = courseOptions.value.find(item => item.id === courseId)
|
|
|
|
|
return c ? c.courseName : ''
|
|
|
|
|
}
|
|
|
|
|
const getRoomName = (roomId) => {
|
|
|
|
|
const r = allRooms.value.find(item => item.id === roomId)
|
|
|
|
|
return r ? r.name : ''
|
|
|
|
|
}
|
|
|
|
|
const getBuildingName = (classroomId) => {
|
|
|
|
|
const r = allRooms.value.find(item => item.id === classroomId)
|
|
|
|
|
if (!r) return ''
|
|
|
|
|
const b = buildingOptions.value.find(item => item.id === r.buildingId)
|
|
|
|
|
return b ? b.buildingName : ''
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 加载基础数据
|
|
|
|
|
const fetchBaseData = async () => {
|
|
|
|
|
try {
|
|
|
|
|
const [teacherRes, courseRes, roomRes, buildingRes] = await Promise.all([
|
|
|
|
|
getTeacherList(),
|
|
|
|
|
getCourses({ current: 1, size: 9999 }),
|
|
|
|
|
getRooms({ current: 1, size: 9999 }),
|
|
|
|
|
getBuildingList()
|
|
|
|
|
])
|
|
|
|
|
|
|
|
|
|
if (teacherRes.code === 200 && teacherRes.data) {
|
|
|
|
|
teacherOptions.value = Array.isArray(teacherRes.data) ? teacherRes.data : []
|
|
|
|
|
}
|
|
|
|
|
if (courseRes.code === 200 && courseRes.data) {
|
|
|
|
|
courseOptions.value = courseRes.data.records || []
|
|
|
|
|
}
|
|
|
|
|
if (roomRes.code === 200 && roomRes.data) {
|
|
|
|
|
const list = roomRes.data.records || []
|
|
|
|
|
allRooms.value = list.map(r => ({
|
|
|
|
|
id: r.id,
|
|
|
|
|
name: r.roomName || r.classroomName || `教室${r.id}`,
|
|
|
|
|
buildingId: r.buildingId
|
|
|
|
|
}))
|
|
|
|
|
}
|
|
|
|
|
if (buildingRes.code === 200 && buildingRes.data) {
|
|
|
|
|
buildingOptions.value = Array.isArray(buildingRes.data) ? buildingRes.data : []
|
|
|
|
|
}
|
|
|
|
|
} catch {
|
|
|
|
|
// 忽略
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 根据选中教学楼筛选教室
|
|
|
|
|
const filteredRoomOptions = computed(() => {
|
|
|
|
|
if (!addForm.value.buildingId) return []
|
|
|
|
|
return allRooms.value.filter(r => r.buildingId === addForm.value.buildingId)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
// 切换教学楼时清空教室选择
|
|
|
|
|
const onBuildingChange = () => {
|
|
|
|
|
addForm.value.classroomId = null
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 加载课程安排列表
|
|
|
|
|
const fetchSchedules = async () => {
|
|
|
|
|
if (!props.classData) return
|
|
|
|
|
try {
|
|
|
|
|
const res = await getSchedulePage({
|
|
|
|
|
current: 1,
|
|
|
|
|
size: 9999,
|
|
|
|
|
classId: props.classData.id
|
|
|
|
|
})
|
|
|
|
|
if (res.code === 200 && res.data) {
|
|
|
|
|
scheduleList.value = res.data.records || []
|
|
|
|
|
}
|
|
|
|
|
} catch {
|
|
|
|
|
scheduleList.value = []
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 弹窗打开时加载数据
|
|
|
|
|
watch(() => props.modelValue, async (val) => {
|
|
|
|
|
if (val && props.classData) {
|
|
|
|
|
currentCourses.value = courseMap[props.classData.id] ? [...courseMap[props.classData.id]] : []
|
|
|
|
|
loading.value = true
|
|
|
|
|
scheduleList.value = []
|
|
|
|
|
try {
|
|
|
|
|
await Promise.all([fetchBaseData(), fetchSchedules()])
|
|
|
|
|
} catch {
|
|
|
|
|
// ignore
|
|
|
|
|
} finally {
|
|
|
|
|
loading.value = false
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
const addCourseRow = () => {
|
|
|
|
|
currentCourses.value.push({
|
|
|
|
|
courseName: '新课程',
|
|
|
|
|
teacherName: '',
|
|
|
|
|
weekday: 1,
|
|
|
|
|
startPeriod: 1,
|
|
|
|
|
endPeriod: 2,
|
|
|
|
|
classroom: ''
|
|
|
|
|
})
|
|
|
|
|
// ==================== 新增/编辑课程安排 ====================
|
|
|
|
|
const addVisible = ref(false)
|
|
|
|
|
const addLoading = ref(false)
|
|
|
|
|
const addFormRef = ref(null)
|
|
|
|
|
const isEdit = ref(false)
|
|
|
|
|
const editId = ref(null)
|
|
|
|
|
|
|
|
|
|
const addRules = {
|
|
|
|
|
courseId: [{ required: true, message: '请选择课程', trigger: 'change' }],
|
|
|
|
|
teacherId: [{ required: true, message: '请选择授课老师', trigger: 'change' }],
|
|
|
|
|
weekDay: [{ required: true, message: '请选择星期', trigger: 'change' }],
|
|
|
|
|
buildingId: [{ required: true, message: '请选择教学楼', trigger: 'change' }],
|
|
|
|
|
classroomId: [{ required: true, message: '请选择教室', trigger: 'change' }],
|
|
|
|
|
startSection: [{ required: true, message: '请输入开始节次', trigger: 'blur' }],
|
|
|
|
|
endSection: [{ required: true, message: '请输入结束节次', trigger: 'blur' }],
|
|
|
|
|
startWeek: [{ required: true, message: '请输入开始周', trigger: 'blur' }],
|
|
|
|
|
endWeek: [{ required: true, message: '请输入结束周', trigger: 'blur' }]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const defaultForm = () => ({
|
|
|
|
|
courseId: null,
|
|
|
|
|
teacherId: null,
|
|
|
|
|
weekDay: 1,
|
|
|
|
|
buildingId: null,
|
|
|
|
|
classroomId: null,
|
|
|
|
|
startSection: 1,
|
|
|
|
|
endSection: 2,
|
|
|
|
|
startWeek: 1,
|
|
|
|
|
endWeek: 16,
|
|
|
|
|
semester: '',
|
|
|
|
|
status: 1
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
const addForm = ref(defaultForm())
|
|
|
|
|
|
|
|
|
|
const onFormDialogClosed = () => {
|
|
|
|
|
isEdit.value = false
|
|
|
|
|
editId.value = null
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const showAddDialog = () => {
|
|
|
|
|
addForm.value = defaultForm()
|
|
|
|
|
isEdit.value = false
|
|
|
|
|
editId.value = null
|
|
|
|
|
addVisible.value = true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const showEditDialog = (row) => {
|
|
|
|
|
// 根据 classroomId 反查 buildingId
|
|
|
|
|
const room = allRooms.value.find(r => r.id === row.classroomId)
|
|
|
|
|
addForm.value = {
|
|
|
|
|
courseId: row.courseId,
|
|
|
|
|
teacherId: row.teacherId,
|
|
|
|
|
weekDay: row.weekDay,
|
|
|
|
|
buildingId: room ? room.buildingId : null,
|
|
|
|
|
classroomId: row.classroomId,
|
|
|
|
|
startSection: row.startSection,
|
|
|
|
|
endSection: row.endSection,
|
|
|
|
|
startWeek: row.startWeek,
|
|
|
|
|
endWeek: row.endWeek,
|
|
|
|
|
semester: row.semester || '',
|
|
|
|
|
status: row.status
|
|
|
|
|
}
|
|
|
|
|
isEdit.value = true
|
|
|
|
|
editId.value = row.id
|
|
|
|
|
addVisible.value = true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const saveSchedule = async () => {
|
|
|
|
|
if (!addFormRef.value) return
|
|
|
|
|
try {
|
|
|
|
|
await addFormRef.value.validate()
|
|
|
|
|
addLoading.value = true
|
|
|
|
|
const payload = {
|
|
|
|
|
courseId: addForm.value.courseId,
|
|
|
|
|
teacherId: addForm.value.teacherId,
|
|
|
|
|
weekDay: addForm.value.weekDay,
|
|
|
|
|
buildingId: addForm.value.buildingId,
|
|
|
|
|
classroomId: addForm.value.classroomId,
|
|
|
|
|
classId: props.classData.id,
|
|
|
|
|
startSection: addForm.value.startSection,
|
|
|
|
|
endSection: addForm.value.endSection,
|
|
|
|
|
startWeek: addForm.value.startWeek,
|
|
|
|
|
endWeek: addForm.value.endWeek,
|
|
|
|
|
semester: addForm.value.semester,
|
|
|
|
|
status: addForm.value.status
|
|
|
|
|
}
|
|
|
|
|
if (isEdit.value) {
|
|
|
|
|
payload.id = editId.value
|
|
|
|
|
await updateSchedule(payload)
|
|
|
|
|
ElMessage.success('修改成功')
|
|
|
|
|
} else {
|
|
|
|
|
await addSchedule(payload)
|
|
|
|
|
ElMessage.success('新增成功')
|
|
|
|
|
}
|
|
|
|
|
addVisible.value = false
|
|
|
|
|
await fetchSchedules()
|
|
|
|
|
} catch {
|
|
|
|
|
// 表单校验失败或请求错误
|
|
|
|
|
} finally {
|
|
|
|
|
addLoading.value = false
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ==================== 详情 ====================
|
|
|
|
|
const detailVisible = ref(false)
|
|
|
|
|
const detailData = ref(null)
|
|
|
|
|
|
|
|
|
|
const showDetail = (row) => {
|
|
|
|
|
detailData.value = row
|
|
|
|
|
detailVisible.value = true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ==================== 删除 ====================
|
|
|
|
|
const tableRef = ref(null)
|
|
|
|
|
const selectedIds = ref([])
|
|
|
|
|
|
|
|
|
|
const onSelectionChange = (selection) => {
|
|
|
|
|
selectedIds.value = selection.map(item => item.id)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const handleDelete = (id) => {
|
|
|
|
|
ElMessageBox.confirm('确定要删除该课程安排吗?', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' })
|
|
|
|
|
.then(async () => {
|
|
|
|
|
await deleteSchedule([id])
|
|
|
|
|
ElMessage.success('删除成功')
|
|
|
|
|
await fetchSchedules()
|
|
|
|
|
})
|
|
|
|
|
.catch(() => {})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const batchDelete = () => {
|
|
|
|
|
if (selectedIds.value.length === 0) return
|
|
|
|
|
ElMessageBox.confirm(`确定要删除选中的 ${selectedIds.value.length} 条课程安排吗?`, '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' })
|
|
|
|
|
.then(async () => {
|
|
|
|
|
await deleteSchedule(selectedIds.value)
|
|
|
|
|
ElMessage.success('删除成功')
|
|
|
|
|
selectedIds.value = []
|
|
|
|
|
await fetchSchedules()
|
|
|
|
|
})
|
|
|
|
|
.catch(() => {})
|
|
|
|
|
}
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<style scoped>
|
|
|
|
|
.toolbar {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
padding: 0 0 16px 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.toolbar-left {
|
|
|
|
|
display: flex;
|
|
|
|
|
gap: 10px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.toolbar-tip {
|
|
|
|
|
font-size: 13px;
|
|
|
|
|
color: #909399;
|
|
|
|
|
}
|
|
|
|
|
</style>
|
|
|
|
|
|