feat: 初始化仓库
This commit is contained in:
310
src/pages/classroom/course.vue
Normal file
310
src/pages/classroom/course.vue
Normal file
@@ -0,0 +1,310 @@
|
||||
<script setup lang="ts">
|
||||
import { onShow } from '@dcloudio/uni-app'
|
||||
import FullCalendar from '@fullcalendar/vue3'
|
||||
import timeGridPlugin from '@fullcalendar/timegrid'
|
||||
import interactionPlugin from '@fullcalendar/interaction'
|
||||
import listPlugin from '@fullcalendar/list'
|
||||
import dayjs from 'dayjs'
|
||||
|
||||
import { onMounted, ref } from 'vue'
|
||||
import type {
|
||||
CalendarOptions,
|
||||
} from '@fullcalendar/core'
|
||||
import cusSelects from '~/components/cus-selects-fan.vue'
|
||||
import { usePageStore } from '~/stores/modules/page'
|
||||
import { useAppStore } from '~/stores/modules/app'
|
||||
import { type BuildInfo, type ClassroomCourseInfo, type ClassroomInfo, getBuildListAPI, getClassroomCourseListAPI, getClassroomListAPI } from '~/services/course'
|
||||
|
||||
const { startDate, campusList, campusId, buildId, classroomId } = storeToRefs(useAppStore())
|
||||
const { setPageConfig } = usePageStore()
|
||||
onShow(() => {
|
||||
setPageConfig({
|
||||
showNavBar: true,
|
||||
pageTitle: '教室课表',
|
||||
showBackAction: true,
|
||||
})
|
||||
})
|
||||
// #ifdef H5
|
||||
const campus = ref('')
|
||||
const buildList = ref<BuildInfo[]>([])
|
||||
const classroomList = ref<ClassroomInfo[]>([])
|
||||
|
||||
const getClassroomList = async () => {
|
||||
if (buildId.value) {
|
||||
uni.showLoading({ title: '加载中~' })
|
||||
const res = await getClassroomListAPI(buildId.value)
|
||||
if (res.code === 200)
|
||||
classroomList.value = res.data
|
||||
uni.hideLoading()
|
||||
uni.showToast({ icon: res.code === 200 ? 'success' : 'error', title: res.msg })
|
||||
}
|
||||
}
|
||||
|
||||
const getBuildList = async () => {
|
||||
if (campusId.value) {
|
||||
uni.showLoading({ title: '加载中~' })
|
||||
const res = await getBuildListAPI(campus.value)
|
||||
if (res.code === 200)
|
||||
buildList.value = res.data
|
||||
uni.hideLoading()
|
||||
uni.showToast({ icon: res.code === 200 ? 'success' : 'error', title: res.msg })
|
||||
}
|
||||
}
|
||||
|
||||
const onCampusSelectChange = async (e: string) => {
|
||||
campus.value = e
|
||||
await getBuildList()
|
||||
}
|
||||
const onBuildSelectChange = async (e: string) => {
|
||||
buildId.value = e
|
||||
await getClassroomList()
|
||||
}
|
||||
|
||||
/** 当前事件列表 */
|
||||
const currentEvents = ref([])
|
||||
/** 日历对象 */
|
||||
const fullCalendar = ref()
|
||||
const courseList = ref<ClassroomCourseInfo[]>([])
|
||||
|
||||
const getClassroomCourses = async () => {
|
||||
const startTime = dayjs(startDate.value).unix()
|
||||
// const start = dayjs(fullCalendar.value.getApi().view.activeStart).unix()
|
||||
const endTime = dayjs(fullCalendar.value.getApi().view.activeEnd).unix()
|
||||
const week = Math.floor((endTime - startTime) / (60 * 60 * 24 * 7))
|
||||
if (classroomId.value) {
|
||||
const res = await getClassroomCourseListAPI(classroomId.value, week)
|
||||
|
||||
if (res.code === 200) {
|
||||
courseList.value = res.data
|
||||
if (res.data) {
|
||||
fullCalendar.value.getApi().removeAllEvents() // 清除所有事件
|
||||
currentEvents.value = courseList.value.map(data => ({
|
||||
id: data.id,
|
||||
title: `${data.course} - ${data.teacher}`,
|
||||
start: data.startTime.replace('T', ' ').replace('Z', ''),
|
||||
end: data.endTime.replace('T', ' ').replace('Z', ''),
|
||||
extendedProps: {
|
||||
classnames: data.classnames,
|
||||
campus: data.campus,
|
||||
build: data.build,
|
||||
},
|
||||
}))
|
||||
fullCalendar.value.getApi().addEventSource(currentEvents.value) // 添加新的事件源
|
||||
}
|
||||
}
|
||||
fullCalendar.value.getApi().render() // 手动刷新日历
|
||||
}
|
||||
}
|
||||
const onClassroomSelectChange = async (e: string) => {
|
||||
classroomId.value = e
|
||||
await getClassroomCourses()
|
||||
}
|
||||
/** 自定义上周按钮点击事件 */
|
||||
const preWeekCustomClick = async () => {
|
||||
fullCalendar.value.getApi().prev() // 切换到上一周
|
||||
await getClassroomCourses()
|
||||
}
|
||||
/** 自定义下周按钮点击事件 */
|
||||
const nextWeekCustomClick = async () => {
|
||||
fullCalendar.value.getApi().next()
|
||||
await getClassroomCourses()
|
||||
}
|
||||
|
||||
/** 日历组件属性 */
|
||||
const calendarOptions = ref<CalendarOptions>({
|
||||
// 插件
|
||||
plugins: [
|
||||
listPlugin, // 列表视图插件
|
||||
timeGridPlugin, // 周视图和日视图插件
|
||||
interactionPlugin, // 交互插件,支持点击事件
|
||||
],
|
||||
// 自定义按钮
|
||||
customButtons: {
|
||||
preWeekCustom: {
|
||||
text: '上周',
|
||||
click() {
|
||||
preWeekCustomClick() // 点击调用 preWeekCustomClick 函数
|
||||
},
|
||||
},
|
||||
nextWeekCustom: {
|
||||
text: '下周',
|
||||
click() {
|
||||
nextWeekCustomClick() // 点击调用 nextWeekCustomClick 函数
|
||||
},
|
||||
},
|
||||
},
|
||||
/** 修改headerToolbar */
|
||||
headerToolbar: {
|
||||
left: 'preWeekCustom',
|
||||
center: 'title', // 显示日历标题
|
||||
right: 'nextWeekCustom',
|
||||
},
|
||||
dayHeaderFormat: {
|
||||
weekday: 'short', // 显示周几,如"周日"
|
||||
month: '2-digit', // 显示两位数的月份
|
||||
day: '2-digit', // 显示两位数的日期
|
||||
omitCommas: true, // 去除逗号
|
||||
},
|
||||
/** 设置日历高度 */
|
||||
contentHeight: uni.getWindowInfo().windowHeight - 260, // 动态计算高度
|
||||
timeZone: 'Asia/Shanghai',
|
||||
/** 默认视图 (月:dayGridMonth,周:timeGridWeek,日:timeGridDay) */
|
||||
initialView: 'timeGridWeek', // 默认显示周视图
|
||||
firstDay: 1, // 一周的第一天,0表示星期天,1表示星期一
|
||||
slotMinTime: '08:00', // 最小时间段,08:00
|
||||
slotMaxTime: '22:10', // 最大时间段,22:10
|
||||
slotDuration: '00:05', // 时间间隔,5分钟
|
||||
slotLabelFormat: {
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
omitZeroMinute: false, // 忽略零分钟
|
||||
hour12: false, // 24小时制
|
||||
meridiem: 'short',
|
||||
},
|
||||
eventTimeFormat: {
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
hour12: false, // 24小时制
|
||||
},
|
||||
eventColor: '#3BB2E3', // 全部日历日程背景色
|
||||
themeSystem: 'bootstrap', // 主题色(本地测试未能生效)
|
||||
events: currentEvents.value, // 事件列表
|
||||
editable: false, // 是否可以拖动修改事件
|
||||
allDaySlot: false, // 是否显示全天事件区域
|
||||
nowIndicator: true, // 是否显示当前时间线
|
||||
selectable: true, // 是否可以选择时间段
|
||||
selectMirror: true, // 是否在选择时间段时显示虚影
|
||||
handleWindowResize: true, // 是否在窗口大小变化时调整日历
|
||||
navLinks: false, // 是否可以通过点击日期导航
|
||||
fixedWeekCount: true, // 每月显示固定周数
|
||||
showNonCurrentDates: true, // 是否显示非当前月的日期
|
||||
dayMaxEvents: true, // 每天最大事件数,超过则显示更多按钮
|
||||
weekends: true, // 是否显示周末
|
||||
/** 切换语言 */
|
||||
locale: 'zh-cn', // 语言设置为简体中文
|
||||
buttonText: {
|
||||
today: '今天',
|
||||
week: '周视图',
|
||||
day: '日',
|
||||
list: '周列表',
|
||||
},
|
||||
})
|
||||
|
||||
onMounted(async () => {
|
||||
campus.value = campusId.value
|
||||
await getBuildList()
|
||||
await getClassroomList()
|
||||
await getClassroomCourses()
|
||||
fullCalendar.value.getApi().render()
|
||||
})
|
||||
// #endif
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<!-- #ifdef H5 -->
|
||||
<UBasePage>
|
||||
<view class="query-select">
|
||||
<view class="query-select-item">
|
||||
<view class="query-select-item-left">
|
||||
<uni-icons type="map" color="#A0E2AA" size="24" />
|
||||
<text>校区</text>
|
||||
</view>
|
||||
<view>
|
||||
<cus-selects
|
||||
:value="campus"
|
||||
filterable
|
||||
:data="campusList"
|
||||
:value-type="{ label: 'name', value: 'id' }"
|
||||
placeholder="请选择校区~"
|
||||
style="width: 100%"
|
||||
@change="onCampusSelectChange"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="query-select-item">
|
||||
<view class="query-select-item-left">
|
||||
<uni-icons type="home" color="#F9BD56" size="24" />
|
||||
<text>教学楼</text>
|
||||
</view>
|
||||
<view>
|
||||
<cus-selects
|
||||
:value="buildId"
|
||||
filterable
|
||||
:data="buildList"
|
||||
:value-type="{ label: 'name', value: 'id' }"
|
||||
placeholder="请选择教学楼~"
|
||||
style="width: 100%"
|
||||
@change="onBuildSelectChange"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="query-select-item">
|
||||
<view class="query-select-item-left">
|
||||
<uni-icons type="location" color="#FEC2BF" size="24" />
|
||||
<text>教室</text>
|
||||
</view>
|
||||
<view>
|
||||
<cus-selects
|
||||
:value="classroomId"
|
||||
filterable
|
||||
:data="classroomList"
|
||||
:value-type="{ label: 'name', value: 'id' }"
|
||||
placeholder="请选择教室~"
|
||||
style="width: 100%"
|
||||
@change="onClassroomSelectChange"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<FullCalendar ref="fullCalendar" :options="calendarOptions">
|
||||
<template #eventContent="arg">
|
||||
<view class="calender-content">
|
||||
{{ arg.timeText }}
|
||||
</view>
|
||||
<view class="calender-content">
|
||||
{{ arg.event.title }}
|
||||
</view>
|
||||
<view class="calender-content">
|
||||
上课班级数量: {{ arg.event.extendedProps.classnames.length }}
|
||||
</view>
|
||||
</template>
|
||||
</FullCalendar>
|
||||
</UBasePage>
|
||||
<!-- #endif -->
|
||||
<!-- #ifndef H5 -->
|
||||
<web-view src="/hybrid/html/calender.html" :fullscreen="false" style="width: 100%; height: 500px;" />
|
||||
<!-- #endif -->
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.query-select{
|
||||
padding: 10rpx 20rpx;
|
||||
background-image: linear-gradient(-225deg, #FFFEFF 0%, #D7FFFE 100%);
|
||||
.query-select-item{
|
||||
border-bottom: 2rpx solid #e9e9e9;
|
||||
padding: 10rpx 0;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
.query-select-item-left {
|
||||
width: 30%;
|
||||
text {
|
||||
margin-left: 5rpx;
|
||||
color: #29a1f7;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.calender-content{
|
||||
text-align: center;
|
||||
}
|
||||
:deep(.fc .fc-toolbar-title){
|
||||
font-size: 30rpx;
|
||||
}
|
||||
:deep(.fc){
|
||||
font-size: 26rpx;
|
||||
}
|
||||
:deep(.fc .fc-toolbar.fc-header-toolbar){
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user