完善选课部分
This commit is contained in:
parent
57624139d0
commit
7d125a491a
File diff suppressed because it is too large
Load Diff
|
|
@ -67,3 +67,8 @@ export function courseAvailableSlots() {
|
||||||
export function courseAvailableRooms(params: Record<string, any>) {
|
export function courseAvailableRooms(params: Record<string, any>) {
|
||||||
return request.get({ url: '/course.schedule/classroom', params })
|
return request.get({ url: '/course.schedule/classroom', params })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 添加一项排课
|
||||||
|
export function courseSchedule(params: Record<string, any>) {
|
||||||
|
return request.post({ url: '/course.schedule', params })
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,65 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="delete-popup">
|
|
||||||
<popup
|
|
||||||
ref="popupRef"
|
|
||||||
title="删除确认"
|
|
||||||
:async="true"
|
|
||||||
width="400px"
|
|
||||||
:clickModalClose="true"
|
|
||||||
@confirm="handleSubmit"
|
|
||||||
@close="handleClose"
|
|
||||||
>
|
|
||||||
<el-form ref="formRef" :model="formData" label-width="120px" :rules="formRules">
|
|
||||||
<el-form-item label="删除数量" prop="count">
|
|
||||||
<el-input-number
|
|
||||||
v-model="formData.count"
|
|
||||||
placeholder="请输入删除数量"
|
|
||||||
:min="1"
|
|
||||||
:max="9999"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
</popup>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import type { FormInstance } from 'element-plus'
|
|
||||||
|
|
||||||
import { slotDelete } from '@/api/slot'
|
|
||||||
import Popup from '@/components/popup/index.vue'
|
|
||||||
import feedback from '@/utils/feedback'
|
|
||||||
|
|
||||||
const emit = defineEmits(['success', 'close'])
|
|
||||||
const formRef = shallowRef<FormInstance>()
|
|
||||||
const popupRef = shallowRef<InstanceType<typeof Popup>>()
|
|
||||||
|
|
||||||
const formData = reactive({
|
|
||||||
count: 1
|
|
||||||
})
|
|
||||||
|
|
||||||
const formRules = {
|
|
||||||
count: [
|
|
||||||
{ required: true, message: '请输入删除数量', trigger: ['blur'] },
|
|
||||||
{ type: 'number', min: 1, message: '数量必须大于0', trigger: ['blur'] }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleSubmit = async () => {
|
|
||||||
await formRef.value?.validate()
|
|
||||||
await slotDelete({ count: formData.count })
|
|
||||||
popupRef.value?.close()
|
|
||||||
feedback.msgSuccess('删除成功')
|
|
||||||
emit('success')
|
|
||||||
}
|
|
||||||
|
|
||||||
const open = () => {
|
|
||||||
formRef.value?.resetFields()
|
|
||||||
popupRef.value?.open()
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleClose = () => {
|
|
||||||
emit('close')
|
|
||||||
}
|
|
||||||
|
|
||||||
defineExpose({ open })
|
|
||||||
</script>
|
|
||||||
|
|
@ -1,139 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="edit-popup">
|
|
||||||
<popup
|
|
||||||
ref="popupRef"
|
|
||||||
:title="popupTitle"
|
|
||||||
:async="true"
|
|
||||||
width="550px"
|
|
||||||
:clickModalClose="true"
|
|
||||||
@confirm="handleSubmit"
|
|
||||||
@close="handleClose"
|
|
||||||
>
|
|
||||||
<el-form ref="formRef" :model="formData" label-width="164px" :rules="formRules">
|
|
||||||
<el-form-item label="开始时间" prop="startTime">
|
|
||||||
<el-time-picker
|
|
||||||
class="flex-1 !flex"
|
|
||||||
v-model="formData.startTime"
|
|
||||||
is-arrow-control
|
|
||||||
clearable
|
|
||||||
format="HH:mm"
|
|
||||||
value-format="HH:mm"
|
|
||||||
placeholder="请选择开始时间"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item v-if="mode == 'edit'" label="结束时间" prop="endTime">
|
|
||||||
<el-time-picker
|
|
||||||
class="flex-1 !flex"
|
|
||||||
v-model="formData.endTime"
|
|
||||||
is-arrow-control
|
|
||||||
clearable
|
|
||||||
format="HH:mm"
|
|
||||||
value-format="HH:mm"
|
|
||||||
placeholder="请选择结束时间"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item v-if="mode == 'add'" label="节次时长(分钟)" prop="duration">
|
|
||||||
<el-input-number v-model="formData.duration" :max="9999" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item
|
|
||||||
v-if="mode == 'add'"
|
|
||||||
label="节次间隔时长(分钟)"
|
|
||||||
prop="intervalDuration"
|
|
||||||
>
|
|
||||||
<el-input-number v-model="formData.intervalDuration" :max="9999" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item v-if="mode == 'add'" label="连续添加节次数量" prop="num">
|
|
||||||
<el-input-number
|
|
||||||
v-model="formData.num"
|
|
||||||
placeholder="请输入连续添加节次数量"
|
|
||||||
:max="9999"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="是否排课" prop="isScheduled">
|
|
||||||
<el-switch
|
|
||||||
v-model="formData.isScheduled"
|
|
||||||
:active-value="1"
|
|
||||||
:inactive-value="0"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
</popup>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import type { FormInstance } from 'element-plus'
|
|
||||||
import type { PropType } from 'vue'
|
|
||||||
|
|
||||||
import { slotEdit, slotInsert } from '@/api/slot'
|
|
||||||
import Popup from '@/components/popup/index.vue'
|
|
||||||
import feedback from '@/utils/feedback'
|
|
||||||
defineProps({
|
|
||||||
dictData: {
|
|
||||||
type: Object as PropType<Record<string, any[]>>,
|
|
||||||
default: () => ({})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
const emit = defineEmits(['success', 'close'])
|
|
||||||
const formRef = shallowRef<FormInstance>()
|
|
||||||
const popupRef = shallowRef<InstanceType<typeof Popup>>()
|
|
||||||
const mode = ref('add')
|
|
||||||
const popupTitle = computed(() => {
|
|
||||||
return mode.value == 'edit' ? '编辑节次' : '新增节次'
|
|
||||||
})
|
|
||||||
|
|
||||||
const formData = reactive({
|
|
||||||
startTime: '',
|
|
||||||
endTime: '',
|
|
||||||
duration: '',
|
|
||||||
section: '',
|
|
||||||
intervalDuration: '',
|
|
||||||
isScheduled: 1,
|
|
||||||
num: 1
|
|
||||||
})
|
|
||||||
|
|
||||||
const formRules = {
|
|
||||||
startTime: [
|
|
||||||
{
|
|
||||||
required: true,
|
|
||||||
message: '请选择开始时间',
|
|
||||||
trigger: ['blur']
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleSubmit = async () => {
|
|
||||||
await formRef.value?.validate()
|
|
||||||
const data: any = { ...formData }
|
|
||||||
mode.value == 'edit' ? await slotEdit(data) : await slotInsert(data)
|
|
||||||
popupRef.value?.close()
|
|
||||||
feedback.msgSuccess('操作成功')
|
|
||||||
emit('success')
|
|
||||||
}
|
|
||||||
|
|
||||||
const open = (type = 'add', defaultStartTime = '') => {
|
|
||||||
mode.value = type
|
|
||||||
formRef.value?.resetFields()
|
|
||||||
if (type === 'add' && defaultStartTime) {
|
|
||||||
formData.startTime = defaultStartTime
|
|
||||||
}
|
|
||||||
popupRef.value?.open()
|
|
||||||
}
|
|
||||||
|
|
||||||
const setFormData = async (data: Record<string, any>) => {
|
|
||||||
for (const key in formData) {
|
|
||||||
if (data[key] != null && data[key] != undefined) {
|
|
||||||
//@ts-ignore
|
|
||||||
formData[key] = data[key]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleClose = () => {
|
|
||||||
emit('close')
|
|
||||||
}
|
|
||||||
|
|
||||||
defineExpose({
|
|
||||||
open,
|
|
||||||
setFormData
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
@ -48,6 +48,12 @@
|
||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<!-- 选中时间段信息显示和清除按钮 -->
|
||||||
|
<el-form-item v-if="selectedTimeSlot" label="已选中时间段">
|
||||||
|
<el-tag type="info" size="large" closable @close="clearSelectedTimeSlot">
|
||||||
|
{{ getSelectedTimeSlotText() }}
|
||||||
|
</el-tag>
|
||||||
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</el-card>
|
</el-card>
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
|
|
@ -78,39 +84,39 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="星期一" min-width="80" align="center">
|
<!-- 星期列改为循环渲染,方便处理点击事件 -->
|
||||||
<template #default="{ row }">
|
<el-table-column
|
||||||
<div v-if="row[1]" />
|
v-for="day in weekDays"
|
||||||
</template>
|
:key="day.value"
|
||||||
</el-table-column>
|
:label="day.label"
|
||||||
<el-table-column label="星期二" min-width="80" align="center">
|
min-width="80"
|
||||||
<template #default="{ row }">
|
align="center"
|
||||||
<div v-if="row[2]" />
|
>
|
||||||
</template>
|
<template #default="{ row, $index }">
|
||||||
</el-table-column>
|
<div
|
||||||
<el-table-column label="星期三" min-width="80" align="center">
|
:class="[
|
||||||
<template #default="{ row }">
|
'time-slot-cell',
|
||||||
<div v-if="row[3]" />
|
isTimeSlotSelected($index, day.value, row[day.value]) ? 'time-slot-selected' : '',
|
||||||
</template>
|
row[day.value] ? '' : 'empty-slot'
|
||||||
</el-table-column>
|
]"
|
||||||
<el-table-column label="星期四" min-width="80" align="center">
|
@click="handleTimeSlotClick($index, day.value, row[day.value])"
|
||||||
<template #default="{ row }">
|
>
|
||||||
<div v-if="row[4]" />
|
<!-- 如果有课程信息,显示课程 -->
|
||||||
</template>
|
<div v-if="row[day.value]" class="course-info">
|
||||||
</el-table-column>
|
<div class="course-name">{{ row[day.value].courseName || '课程' }}</div>
|
||||||
<el-table-column label="星期五" min-width="80" align="center">
|
<div class="course-details">
|
||||||
<template #default="{ row }">
|
<div>教师: {{ row[day.value].teacherName || '未知' }}</div>
|
||||||
<div v-if="row[5]" />
|
<div>教室: {{ row[day.value].classroomName || '未知' }}</div>
|
||||||
</template>
|
</div>
|
||||||
</el-table-column>
|
</div>
|
||||||
<el-table-column label="星期六" min-width="80" align="center">
|
<!-- 空时间段显示可选状态 -->
|
||||||
<template #default="{ row }">
|
<div v-else class="empty-slot-content">
|
||||||
<div v-if="row[6]" />
|
<el-icon v-if="isTimeSlotSelected($index, day.value, row[day.value])" class="check-icon">
|
||||||
</template>
|
<Check />
|
||||||
</el-table-column>
|
</el-icon>
|
||||||
<el-table-column label="星期日" min-width="80" align="center">
|
<span v-else class="empty-text">点击选择</span>
|
||||||
<template #default="{ row }">
|
</div>
|
||||||
<div v-if="row[7]" />
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|
@ -134,7 +140,7 @@
|
||||||
v-for="item in getCourseLists.lists"
|
v-for="item in getCourseLists.lists"
|
||||||
:key="item.id"
|
:key="item.id"
|
||||||
shadow="hover"
|
shadow="hover"
|
||||||
class="cursor-pointer hover:bg-blue-50 transition-colors duration-200"
|
:class="['cursor-pointer transition-all duration-200', selectedCourseId === item.id ? 'selected-card' : 'hover:bg-blue-50']"
|
||||||
@click="handleCourseClick(item)"
|
@click="handleCourseClick(item)"
|
||||||
>
|
>
|
||||||
<div class="p-0">
|
<div class="p-0">
|
||||||
|
|
@ -197,7 +203,7 @@
|
||||||
v-for="item in getRoomLists.lists"
|
v-for="item in getRoomLists.lists"
|
||||||
:key="item.id"
|
:key="item.id"
|
||||||
shadow="hover"
|
shadow="hover"
|
||||||
class="cursor-pointer hover:bg-blue-50 transition-colors duration-200"
|
:class="['cursor-pointer transition-all duration-200', selectedRoomId === item.id ? 'selected-card' : 'hover:bg-blue-50']"
|
||||||
@click="handleClassroomClick(item)"
|
@click="handleClassroomClick(item)"
|
||||||
>
|
>
|
||||||
<div class="p-0">
|
<div class="p-0">
|
||||||
|
|
@ -232,21 +238,71 @@
|
||||||
</div>
|
</div>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
</el-tabs>
|
</el-tabs>
|
||||||
|
<!-- 排课操作按钮 -->
|
||||||
|
<div v-if="selectedTimeSlot" class="mt-6 p-4 border-t">
|
||||||
|
<h4 class="text-lg font-semibold mb-4">排课操作</h4>
|
||||||
|
<div class="space-y-4">
|
||||||
|
<div class="text-sm">
|
||||||
|
<div class="flex items-center mb-2">
|
||||||
|
<span class="font-medium mr-2">选中的时间段:</span>
|
||||||
|
<span>{{ getSelectedTimeSlotText() }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center mb-2">
|
||||||
|
<span class="font-medium mr-2">选中的课程:</span>
|
||||||
|
<span>{{ selectedCourseName || '未选择' }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center">
|
||||||
|
<span class="font-medium mr-2">选中的教室:</span>
|
||||||
|
<span>{{ selectedRoomName || '未选择' }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
size="large"
|
||||||
|
:disabled="!selectedCourseId"
|
||||||
|
@click="handleScheduleCourse"
|
||||||
|
plain
|
||||||
|
>
|
||||||
|
安排课程
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
type="danger"
|
||||||
|
size="large"
|
||||||
|
:disabled="!selectedTimeSlot.hasCourse"
|
||||||
|
@click="handleRemoveCourse"
|
||||||
|
plain
|
||||||
|
>
|
||||||
|
移除课程
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed, reactive, ref } from 'vue'
|
import { computed, reactive, ref } from 'vue'
|
||||||
|
import { Check } from '@element-plus/icons-vue'
|
||||||
|
|
||||||
import { classLists } from '@/api/class'
|
import { classLists } from '@/api/class'
|
||||||
import { configLists } from '@/api/config'
|
import { configLists } from '@/api/config'
|
||||||
import { courseAvailableRooms, courseAvailableSlots } from '@/api/course'
|
import { courseAvailableRooms, courseAvailableSlots, courseSchedule } from '@/api/course'
|
||||||
import { taskLists } from '@/api/task'
|
import { taskLists } from '@/api/task'
|
||||||
import { timeCurrentSemester } from '@/api/time'
|
import { timeCurrentSemester } from '@/api/time'
|
||||||
import { usePaging } from '@/hooks/usePaging'
|
import { usePaging } from '@/hooks/usePaging'
|
||||||
import feedback from '@/utils/feedback'
|
import feedback from '@/utils/feedback'
|
||||||
|
|
||||||
|
// 星期数组
|
||||||
|
const weekDays = [
|
||||||
|
{ label: '星期一', value: 1 },
|
||||||
|
{ label: '星期二', value: 2 },
|
||||||
|
{ label: '星期三', value: 3 },
|
||||||
|
{ label: '星期四', value: 4 },
|
||||||
|
{ label: '星期五', value: 5 },
|
||||||
|
{ label: '星期六', value: 6 },
|
||||||
|
{ label: '星期日', value: 7 }
|
||||||
|
]
|
||||||
|
|
||||||
const getConfigLists = ref<{
|
const getConfigLists = ref<{
|
||||||
lists: Array<{
|
lists: Array<{
|
||||||
id: number
|
id: number
|
||||||
|
|
@ -293,6 +349,12 @@ const getCourseLists = ref<{
|
||||||
const courseLoading = ref(false)
|
const courseLoading = ref(false)
|
||||||
// 选中的课程ID
|
// 选中的课程ID
|
||||||
const selectedCourseId = ref<number | null>(null)
|
const selectedCourseId = ref<number | null>(null)
|
||||||
|
// 选中的课程名称
|
||||||
|
const selectedCourseName = computed(() => {
|
||||||
|
if (!selectedCourseId.value) return ''
|
||||||
|
const course = getCourseLists.value.lists.find(item => item.id === selectedCourseId.value)
|
||||||
|
return course ? course.courseName : ''
|
||||||
|
})
|
||||||
|
|
||||||
// 教室列表数据
|
// 教室列表数据
|
||||||
const getRoomLists = ref<{
|
const getRoomLists = ref<{
|
||||||
|
|
@ -309,6 +371,24 @@ const getRoomLists = ref<{
|
||||||
const roomLoading = ref(false)
|
const roomLoading = ref(false)
|
||||||
// 选中的教室ID
|
// 选中的教室ID
|
||||||
const selectedRoomId = ref<number | null>(null)
|
const selectedRoomId = ref<number | null>(null)
|
||||||
|
// 选中的教室名称
|
||||||
|
const selectedRoomName = computed(() => {
|
||||||
|
if (!selectedRoomId.value) return ''
|
||||||
|
const room = getRoomLists.value.lists.find(item => item.id === selectedRoomId.value)
|
||||||
|
return room ? room.classroomName : ''
|
||||||
|
})
|
||||||
|
|
||||||
|
// 选中的时间段
|
||||||
|
interface SelectedTimeSlot {
|
||||||
|
id: number
|
||||||
|
rowIndex: number
|
||||||
|
dayOfWeek: number
|
||||||
|
startTime: string
|
||||||
|
endTime: string
|
||||||
|
hasCourse: boolean
|
||||||
|
courseData?: any
|
||||||
|
}
|
||||||
|
const selectedTimeSlot = ref<SelectedTimeSlot | null>(null)
|
||||||
|
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const queryParams = reactive({
|
const queryParams = reactive({
|
||||||
|
|
@ -323,11 +403,12 @@ const handleClassChange = async () => {
|
||||||
await fetchCourseLists()
|
await fetchCourseLists()
|
||||||
await fetchRoomLists()
|
await fetchRoomLists()
|
||||||
}
|
}
|
||||||
|
// 切换班级时清空选中
|
||||||
|
clearSelectedTimeSlot()
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleStudentClick = (item: any) => {
|
const handleStudentClick = (item: any) => {
|
||||||
queryParams.maxStudentCount = item.maxStudentCount || 0
|
queryParams.maxStudentCount = item.maxStudentCount || 0
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 学期变化处理
|
// 学期变化处理
|
||||||
|
|
@ -335,6 +416,8 @@ const handleSemesterChange = async () => {
|
||||||
if (queryParams.classId && queryParams.semesterId) {
|
if (queryParams.classId && queryParams.semesterId) {
|
||||||
await fetchCourseLists()
|
await fetchCourseLists()
|
||||||
}
|
}
|
||||||
|
// 切换学期时清空选中
|
||||||
|
clearSelectedTimeSlot()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取班级列表
|
// 获取班级列表
|
||||||
|
|
@ -472,6 +555,115 @@ const handleClassroomClick = (classroom: any) => {
|
||||||
selectedRoomId.value = selectedRoomId.value === classroom.id ? null : classroom.id
|
selectedRoomId.value = selectedRoomId.value === classroom.id ? null : classroom.id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 处理时间段点击
|
||||||
|
const handleTimeSlotClick = (rowIndex: number, dayOfWeek: number, cellData: any) => {
|
||||||
|
const row = tableData.value[rowIndex]
|
||||||
|
const id = cellData.id
|
||||||
|
const startTime = getRowStartTime(row)
|
||||||
|
const endTime = getRowEndTime(row)
|
||||||
|
|
||||||
|
// 如果点击的是已经选中的时间段,则取消选中
|
||||||
|
if (selectedTimeSlot.value &&
|
||||||
|
selectedTimeSlot.value.rowIndex === rowIndex &&
|
||||||
|
selectedTimeSlot.value.dayOfWeek === dayOfWeek) {
|
||||||
|
selectedTimeSlot.value = null
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置选中的时间段
|
||||||
|
selectedTimeSlot.value = {
|
||||||
|
id,
|
||||||
|
rowIndex,
|
||||||
|
dayOfWeek,
|
||||||
|
startTime,
|
||||||
|
endTime,
|
||||||
|
hasCourse: !!cellData,
|
||||||
|
courseData: cellData
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果有课程数据,自动选中对应的课程
|
||||||
|
if (cellData && cellData.courseId) {
|
||||||
|
const course = getCourseLists.value.lists.find(item => item.courseId === cellData.courseId)
|
||||||
|
if (course) {
|
||||||
|
selectedCourseId.value = course.id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 判断时间段是否被选中
|
||||||
|
const isTimeSlotSelected = (rowIndex: number, dayOfWeek: number, cellData: any) => {
|
||||||
|
return selectedTimeSlot.value &&
|
||||||
|
selectedTimeSlot.value.rowIndex === rowIndex &&
|
||||||
|
selectedTimeSlot.value.dayOfWeek === dayOfWeek
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清除选中的时间段
|
||||||
|
const clearSelectedTimeSlot = () => {
|
||||||
|
selectedTimeSlot.value = null
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取选中时间段的显示文本
|
||||||
|
const getSelectedTimeSlotText = () => {
|
||||||
|
if (!selectedTimeSlot.value) return ''
|
||||||
|
|
||||||
|
const dayText = weekDays.find(day => day.value === selectedTimeSlot.value!.dayOfWeek)?.label || ''
|
||||||
|
return `第${selectedTimeSlot.value.rowIndex + 1}节 ${dayText} ${selectedTimeSlot.value.startTime}-${selectedTimeSlot.value.endTime}`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 安排课程
|
||||||
|
const handleScheduleCourse = async () => {
|
||||||
|
if (!selectedTimeSlot.value || !selectedCourseId.value) {
|
||||||
|
feedback.msgError('请先选择时间段和课程')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 调用排课API
|
||||||
|
await courseSchedule({
|
||||||
|
timeSlotId: selectedTimeSlot.value.id,
|
||||||
|
courseId: selectedCourseId.value,
|
||||||
|
// date:
|
||||||
|
classroomId: selectedRoomId.value,
|
||||||
|
semesterId: queryParams.semesterId,
|
||||||
|
classId: queryParams.classId,
|
||||||
|
// teacherId:
|
||||||
|
})
|
||||||
|
|
||||||
|
feedback.msgSuccess('排课成功')
|
||||||
|
// 刷新课表数据
|
||||||
|
await getTimeLists()
|
||||||
|
// 清空选中状态
|
||||||
|
clearSelectedTimeSlot()
|
||||||
|
selectedCourseId.value = null
|
||||||
|
selectedRoomId.value = null
|
||||||
|
} catch (error) {
|
||||||
|
feedback.msgError('排课失败')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 移除课程
|
||||||
|
const handleRemoveCourse = async () => {
|
||||||
|
if (!selectedTimeSlot.value || !selectedTimeSlot.value.hasCourse) {
|
||||||
|
feedback.msgError('请先选择一个有课程的时间段')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// TODO: 这里调用移除课程API
|
||||||
|
// 示例:await removeCourse({
|
||||||
|
// timeSlotId: selectedTimeSlot.value.timeSlotId
|
||||||
|
// })
|
||||||
|
|
||||||
|
feedback.msgSuccess('课程移除成功')
|
||||||
|
// 刷新课表数据
|
||||||
|
await getTimeLists()
|
||||||
|
// 清空选中状态
|
||||||
|
clearSelectedTimeSlot()
|
||||||
|
} catch (error) {
|
||||||
|
feedback.msgError('移除课程失败')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 清理定时器
|
// 清理定时器
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
if (classSearchTimer.value) clearTimeout(classSearchTimer.value)
|
if (classSearchTimer.value) clearTimeout(classSearchTimer.value)
|
||||||
|
|
@ -563,8 +755,84 @@ fetchConfigLists()
|
||||||
border-color: #409eff;
|
border-color: #409eff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.selected-card {
|
||||||
|
border-color: #409eff !important;
|
||||||
|
background-color: #f0f7ff;
|
||||||
|
box-shadow: 0 2px 12px rgba(64, 158, 255, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
:deep(.el-tag) {
|
:deep(.el-tag) {
|
||||||
height: 24px;
|
height: 24px;
|
||||||
line-height: 22px;
|
line-height: 22px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 时间段单元格样式 */
|
||||||
|
.time-slot-cell {
|
||||||
|
height: 100%;
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 4px;
|
||||||
|
border: 2px solid transparent;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.time-slot-cell:hover {
|
||||||
|
border-color: #96caff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.time-slot-selected {
|
||||||
|
border-color: #409eff !important;
|
||||||
|
background-color: #f0f9ff;
|
||||||
|
border-color: #e0f2ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty-slot {
|
||||||
|
background-color: #fafafa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty-slot-content {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
height: 100%;
|
||||||
|
color: #909399;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty-slot-content .check-icon {
|
||||||
|
color: #67c23a;
|
||||||
|
font-size: 16px;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.course-info {
|
||||||
|
text-align: center;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.course-name {
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 12px;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
color: #303133;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.course-details {
|
||||||
|
font-size: 10px;
|
||||||
|
color: #606266;
|
||||||
|
line-height: 1.2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.course-details div {
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
>
|
>
|
||||||
<el-form-item label="字典类型">
|
<el-form-item label="字典类型">
|
||||||
<el-input
|
<el-input
|
||||||
:model-value="formData.type_value"
|
:model-value="formData.typeValue"
|
||||||
placeholder="请输入字典类型"
|
placeholder="请输入字典类型"
|
||||||
disabled
|
disabled
|
||||||
/>
|
/>
|
||||||
|
|
@ -69,12 +69,13 @@ const popupTitle = computed(() => {
|
||||||
})
|
})
|
||||||
const formData = reactive({
|
const formData = reactive({
|
||||||
id: '',
|
id: '',
|
||||||
type_value: '',
|
typeValue: '',
|
||||||
name: '',
|
name: '',
|
||||||
value: '',
|
value: '',
|
||||||
sort: 0,
|
sort: 0,
|
||||||
status: 1,
|
status: 1,
|
||||||
remark: '',
|
remark: '',
|
||||||
|
typeId: 0,
|
||||||
type_id: 0
|
type_id: 0
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
@ -116,6 +117,7 @@ const setFormData = (data: Record<any, any>) => {
|
||||||
if (data[key] != null && data[key] != undefined) {
|
if (data[key] != null && data[key] != undefined) {
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
formData[key] = data[key]
|
formData[key] = data[key]
|
||||||
|
formData.typeId = data.type_id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue