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