7 changed files with 4403 additions and 4629 deletions
@ -0,0 +1,127 @@ |
|||||
|
<template> |
||||
|
<div class="schedule-container"> |
||||
|
<!-- 周视图日历 --> |
||||
|
<FullCalendar |
||||
|
:options="calendarOptions" |
||||
|
ref="fullCalendar" |
||||
|
class="calendar" |
||||
|
/> |
||||
|
|
||||
|
<!-- 课程详情弹窗 --> |
||||
|
<el-dialog |
||||
|
v-model="dialogVisible" |
||||
|
title="课程人员安排" |
||||
|
width="30%" |
||||
|
:before-close="handleClose" |
||||
|
> |
||||
|
<div v-if="selectedEvent"> |
||||
|
<h3>{{ selectedEvent.title }}</h3> |
||||
|
<p>时间:{{ selectedEvent.time }}</p> |
||||
|
<h4>参与人员:</h4> |
||||
|
<ul> |
||||
|
<li v-for="person in selectedEvent.people" :key="person.id"> |
||||
|
{{ person.name }} - {{ person.role }} |
||||
|
</li> |
||||
|
</ul> |
||||
|
</div> |
||||
|
</el-dialog> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script setup> |
||||
|
import {ref} from 'vue'; |
||||
|
import FullCalendar from '@fullcalendar/vue3'; |
||||
|
import dayGridPlugin from '@fullcalendar/daygrid'; |
||||
|
import timeGridPlugin from '@fullcalendar/timegrid'; |
||||
|
import interactionPlugin from '@fullcalendar/interaction'; // 新增此行 |
||||
|
import zhLocale from '@fullcalendar/core/locales/zh-cn'; |
||||
|
|
||||
|
// 模拟课程数据(替换为真实接口数据) |
||||
|
const courses = ref([ |
||||
|
{ |
||||
|
id: 1, |
||||
|
title: '数学课', |
||||
|
start: '2025-05-18 08:00:00', |
||||
|
end: '2025-05-18 09:00:00', |
||||
|
people: [ |
||||
|
{id: 1, name: '张老师', role: '主讲'}, |
||||
|
{id: 2, name: '李同学', role: '学生'} |
||||
|
] |
||||
|
}, |
||||
|
{ |
||||
|
id: 2, |
||||
|
title: '英语课', |
||||
|
start: '2025-05-18 10:00:00', |
||||
|
end: '2025-05-18 11:00:00', |
||||
|
people: [ |
||||
|
{id: 3, name: '王老师', role: '主讲'} |
||||
|
] |
||||
|
} |
||||
|
]); |
||||
|
|
||||
|
// 弹窗相关 |
||||
|
const dialogVisible = ref(false); |
||||
|
const selectedEvent = ref(null); |
||||
|
|
||||
|
// FullCalendar 配置 |
||||
|
const calendarOptions = ref({ |
||||
|
locale: zhLocale, |
||||
|
plugins: [ |
||||
|
dayGridPlugin, |
||||
|
timeGridPlugin, |
||||
|
interactionPlugin // 新增此行 |
||||
|
], |
||||
|
initialView: 'timeGridWeek', // 周视图 |
||||
|
headerToolbar: { |
||||
|
left: 'prev,next today', |
||||
|
center: 'title', |
||||
|
right: 'timeGridWeek,timeGridDay' // 切换视图 |
||||
|
}, |
||||
|
events: courses.value, |
||||
|
eventClick: (info) => { |
||||
|
selectedEvent.value = { |
||||
|
title: info.event.title, |
||||
|
time: `${info.event.start.toLocaleTimeString()} - ${info.event.end.toLocaleTimeString()}`, |
||||
|
people: info.event.extendedProps.people |
||||
|
}; |
||||
|
dialogVisible.value = true; |
||||
|
}, |
||||
|
eventContent: (arg) => { |
||||
|
// 自定义事件内容(可选) |
||||
|
return {html: `<div class="fc-event-title">${arg.event.title}</div>`}; |
||||
|
}, |
||||
|
allDaySlot: false, // 隐藏全天时段 |
||||
|
slotDuration: '01:00', // 时间段间隔(1小时) |
||||
|
slotLabelFormat: { |
||||
|
hour: 'numeric', |
||||
|
minute: '2-digit', |
||||
|
omitZeroMinute: false, |
||||
|
meridiem: 'short' |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
// 关闭弹窗时重置数据 |
||||
|
const handleClose = () => { |
||||
|
dialogVisible.value = false; |
||||
|
selectedEvent.value = null; |
||||
|
}; |
||||
|
</script> |
||||
|
|
||||
|
<style> |
||||
|
.schedule-container { |
||||
|
padding: 20px; |
||||
|
} |
||||
|
|
||||
|
.calendar { |
||||
|
margin-bottom: 20px; |
||||
|
} |
||||
|
|
||||
|
.fc-event-title { |
||||
|
white-space: normal !important; |
||||
|
font-size: 14px; |
||||
|
} |
||||
|
|
||||
|
.fc-timegrid-event { |
||||
|
cursor: pointer; |
||||
|
} |
||||
|
</style> |
||||
File diff suppressed because it is too large
Loading…
Reference in new issue