feat: 初始化仓库
This commit is contained in:
514
src/pages/classroom/classroom.vue
Normal file
514
src/pages/classroom/classroom.vue
Normal file
@@ -0,0 +1,514 @@
|
||||
<script setup lang="ts">
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import { ref } from 'vue'
|
||||
import { usePageStore } from '~/stores'
|
||||
import { useAppStore } from '~/stores/modules/app'
|
||||
import cusSelects from '~/components/cus-selects-fan.vue'
|
||||
import UBasePage from '~/components/UnoUI/UBasePage/UBasePage.vue'
|
||||
import { type BuildInfo, getBuildListAPI } from '~/services/course'
|
||||
const { timeSetting, startDate, endDate, campusList, campusId } = storeToRefs(
|
||||
useAppStore(),
|
||||
)
|
||||
const { setPageConfig } = usePageStore()
|
||||
const { getEmptyClassroom } = useAppStore()
|
||||
const dateStr = ref<string>('')
|
||||
const selectDate = ref<string | Date>(new Date())
|
||||
const timeRange = ref<number[]>([1, 2])
|
||||
const campus = ref<string>('')
|
||||
const classroom = ref<string>('')
|
||||
const classroomList = ref<BuildInfo[]>([
|
||||
{
|
||||
name: '全部',
|
||||
id: '',
|
||||
campus: '',
|
||||
campus_id: '',
|
||||
},
|
||||
])
|
||||
|
||||
const getBuilds = async () => {
|
||||
uni.showLoading({ title: '加载中~' })
|
||||
const res = await getBuildListAPI(campus.value)
|
||||
if (res.code === 200) {
|
||||
classroomList.value = res.data
|
||||
classroomList.value.push(
|
||||
{
|
||||
name: '全部',
|
||||
id: '',
|
||||
campus: '',
|
||||
campus_id: '',
|
||||
},
|
||||
)
|
||||
classroom.value = ''
|
||||
uni.hideLoading()
|
||||
uni.showToast({ icon: 'success', title: '加载成功!' })
|
||||
}
|
||||
else {
|
||||
uni.hideLoading()
|
||||
}
|
||||
}
|
||||
const onCampusSelectChange = async (e) => {
|
||||
campus.value = e
|
||||
await getBuilds()
|
||||
}
|
||||
const onClassroomSelectChange = async (e) => {
|
||||
classroom.value = e
|
||||
}
|
||||
/** 起始节数类别 -2未知 -1全天 0上午 1下午 2晚上 */
|
||||
const timeRangeType = ref<number>(-1)
|
||||
|
||||
/** 日历组件 */
|
||||
const calendarRef = ref()
|
||||
const timeList = [
|
||||
[
|
||||
'开始节次',
|
||||
'第1节',
|
||||
'第2节',
|
||||
'第3节',
|
||||
'第4节',
|
||||
'第5节',
|
||||
'第6节',
|
||||
'第7节',
|
||||
'第8节',
|
||||
'第9节',
|
||||
'第10节',
|
||||
'第11节',
|
||||
'第12节',
|
||||
],
|
||||
[
|
||||
'持续节次',
|
||||
'持续1节',
|
||||
'持续2节',
|
||||
'持续3节',
|
||||
'持续4节',
|
||||
'持续5节',
|
||||
'持续6节',
|
||||
'持续7节',
|
||||
'持续8节',
|
||||
'持续9节',
|
||||
'持续10节',
|
||||
'持续11节',
|
||||
'持续12节',
|
||||
],
|
||||
]
|
||||
|
||||
const showTimeActionSheet = ref(false)
|
||||
const timeValue = ref([1, 1])
|
||||
/** 设置起始时间段 */
|
||||
const setTimeRange = (e: number) => {
|
||||
const all = timeSetting.value.map(item => item.index).sort((a, b) => a - b)
|
||||
const morinig = timeSetting.value
|
||||
.filter(item => item.time === 0)
|
||||
.map(item => item.index)
|
||||
.sort((a, b) => a - b)
|
||||
const afternoon = timeSetting.value
|
||||
.filter(item => item.time === 1)
|
||||
.map(item => item.index)
|
||||
.sort((a, b) => a - b)
|
||||
const night = timeSetting.value
|
||||
.filter(item => item.time === 2)
|
||||
.map(item => item.index)
|
||||
.sort((a, b) => a - b)
|
||||
switch (e) {
|
||||
case 0:
|
||||
timeRange.value = [morinig[0], morinig.slice(-1)[0]]
|
||||
timeRangeType.value = 0
|
||||
return
|
||||
case 1:
|
||||
timeRange.value = [afternoon[0], afternoon.slice(-1)[0]]
|
||||
timeRangeType.value = 1
|
||||
return
|
||||
case 2:
|
||||
timeRange.value = [night[0], night.slice(-1)[0]]
|
||||
timeRangeType.value = 2
|
||||
return
|
||||
case 3:
|
||||
timeRange.value = [all[0], all.slice(-1)[0]]
|
||||
timeRangeType.value = 3
|
||||
return
|
||||
default:
|
||||
timeRangeType.value = -1
|
||||
}
|
||||
}
|
||||
|
||||
/** 获取使用时间 */
|
||||
const getUseTime = (nowDate = new Date()) => {
|
||||
let year: string | number = nowDate.getFullYear()
|
||||
year = year.toString().slice(-2)
|
||||
let month: string | number = nowDate.getMonth() + 1
|
||||
if (month < 10)
|
||||
month = `0${month}`
|
||||
|
||||
let date: string | number = nowDate.getDate()
|
||||
if (date < 10)
|
||||
date = `0${date}`
|
||||
selectDate.value = `${nowDate.getFullYear()}-${month}-${date}`
|
||||
const day = nowDate.getDay()
|
||||
const dayList = ['周日', '周一', '周二', '周三', '周四', '周五', '周六']
|
||||
const time = nowDate.getTime() - new Date(startDate.value).getTime()
|
||||
let nowWeek = time / 1000 / 60 / 60 / 24 / 7
|
||||
if (nowWeek < 0) {
|
||||
dateStr.value = `未开学-${dayList[day]}(${year}/${month}/${date})`
|
||||
return
|
||||
}
|
||||
if (nowDate > new Date(endDate.value)) {
|
||||
dateStr.value = `学期已结束-${dayList[day]}(${year}/${month}/${date})`
|
||||
return
|
||||
}
|
||||
nowWeek = Math.floor(nowWeek) + 1
|
||||
dateStr.value = `第${nowWeek}周-${dayList[day]}(${year}/${month}/${date})`
|
||||
}
|
||||
|
||||
/** 启动日历 */
|
||||
const onOpenCalender = () => {
|
||||
calendarRef.value.open()
|
||||
}
|
||||
|
||||
/** 日期变动 */
|
||||
const onCalenderConfirm = (e: any) => {
|
||||
selectDate.value = e.fulldate
|
||||
getUseTime(new Date(e.fulldate))
|
||||
}
|
||||
function handleConfirmTimeActionSheet() {
|
||||
showTimeActionSheet.value = false
|
||||
}
|
||||
|
||||
function handleTimeChange(e: any) {
|
||||
const value = e.detail.value
|
||||
const start = value[0] ? value[0] : 1
|
||||
const duration = value[1] ? value[1] : 1
|
||||
timeValue.value = [start, duration]
|
||||
const all = timeSetting.value.map(item => item.index).sort((a, b) => a - b)
|
||||
const morinig = timeSetting.value
|
||||
.filter(item => item.time === 0)
|
||||
.map(item => item.index)
|
||||
.sort((a, b) => a - b)
|
||||
const afternoon = timeSetting.value
|
||||
.filter(item => item.time === 1)
|
||||
.map(item => item.index)
|
||||
.sort((a, b) => a - b)
|
||||
const night = timeSetting.value
|
||||
.filter(item => item.time === 2)
|
||||
.map(item => item.index)
|
||||
.sort((a, b) => a - b)
|
||||
if (start + duration <= timeSetting.value.length)
|
||||
timeRange.value = [start, start + duration]
|
||||
else timeRange.value = [start, start]
|
||||
if (
|
||||
timeRange.value[0] === morinig[0]
|
||||
&& timeRange.value[1] === morinig.slice(-1)[0]
|
||||
)
|
||||
timeRangeType.value = 0
|
||||
else if (
|
||||
timeRange.value[0] === afternoon[0]
|
||||
&& timeRange.value[1] === afternoon.slice(-1)[0]
|
||||
)
|
||||
timeRangeType.value = 1
|
||||
else if (
|
||||
timeRange.value[0] === night[0]
|
||||
&& timeRange.value[1] === night.slice(-1)[0]
|
||||
)
|
||||
timeRangeType.value = 2
|
||||
else if (
|
||||
timeRange.value[0] === all[0]
|
||||
&& timeRange.value[1] === all.slice(-1)[0]
|
||||
)
|
||||
timeRangeType.value = 3
|
||||
else timeRangeType.value = -1
|
||||
}
|
||||
/** 查询空教室 */
|
||||
const queryClassroom = async () => {
|
||||
const startTime
|
||||
= new Date(
|
||||
`${selectDate.value}T${
|
||||
timeSetting.value[timeRange.value[0] - 1].start
|
||||
}:00+08:00`,
|
||||
).getTime() / 1000
|
||||
const endTime
|
||||
= new Date(
|
||||
`${selectDate.value}T${
|
||||
timeSetting.value[timeRange.value[1] - 1].end
|
||||
}:00+08:00`,
|
||||
).getTime() / 1000
|
||||
const flag = await getEmptyClassroom(
|
||||
{ campus_id: campus.value, build_id: classroom.value, startStamp: startTime, endStamp: endTime },
|
||||
dateStr.value,
|
||||
timeRange.value,
|
||||
)
|
||||
if (flag) {
|
||||
uni.navigateTo({
|
||||
url: '/pages/classroom/detail',
|
||||
})
|
||||
}
|
||||
}
|
||||
/** 页面挂载 */
|
||||
onLoad(async () => {
|
||||
getUseTime()
|
||||
campus.value = campusId.value
|
||||
if (campus.value)
|
||||
await getBuilds()
|
||||
})
|
||||
onShow(() => {
|
||||
setPageConfig({ showNavBar: false, pageTitle: '空教室查询' })
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UBasePage>
|
||||
<view class="title">
|
||||
<text>空闲教室查询</text>
|
||||
</view>
|
||||
<view class="container">
|
||||
<view class="query-form">
|
||||
<view class="query-form-item" @click="onOpenCalender">
|
||||
<view class="query-form-item-left">
|
||||
<uni-icons type="calendar" color="#A0E2AA" size="24" />
|
||||
<text>使用时间</text>
|
||||
</view>
|
||||
<view class="query-form-item-right">
|
||||
{{ dateStr }}
|
||||
</view>
|
||||
</view>
|
||||
<view class="query-form-item" @click="showTimeActionSheet = true">
|
||||
<view class="query-form-item-left">
|
||||
<uni-icons type="settings" color="#C8CD9A" size="24" />
|
||||
<text>起始节数</text>
|
||||
</view>
|
||||
<view class="query-form-item-right">
|
||||
第{{ timeRange[0] }}-{{ timeRange[1] }}节
|
||||
</view>
|
||||
</view>
|
||||
<view class="query-form-item">
|
||||
<view class="query-form-item-left">
|
||||
<uni-icons type="map" color="#F9BD56" 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-form-item">
|
||||
<view class="query-form-item-left">
|
||||
<uni-icons type="location" color="#FEC2BF" size="24" />
|
||||
<text>教室位置</text>
|
||||
</view>
|
||||
<view>
|
||||
<cus-selects
|
||||
:value="classroom"
|
||||
filterable
|
||||
:data="classroomList"
|
||||
:value-type="{ label: 'name', value: 'id' }"
|
||||
placeholder="请选择教室~"
|
||||
style="width: 100%"
|
||||
@change="onClassroomSelectChange"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 查询范围 -->
|
||||
<view class="query-time-range">
|
||||
<text
|
||||
:class="timeRangeType === 0 ? 'active' : ''"
|
||||
@click="setTimeRange(0)"
|
||||
>
|
||||
上午
|
||||
</text>
|
||||
<text
|
||||
:class="timeRangeType === 1 ? 'active' : ''"
|
||||
@click="setTimeRange(1)"
|
||||
>
|
||||
下午
|
||||
</text>
|
||||
<text
|
||||
:class="timeRangeType === 2 ? 'active' : ''"
|
||||
@click="setTimeRange(2)"
|
||||
>
|
||||
晚上
|
||||
</text>
|
||||
<text
|
||||
:class="timeRangeType === 3 ? 'active' : ''"
|
||||
@click="setTimeRange(3)"
|
||||
>
|
||||
全天
|
||||
</text>
|
||||
</view>
|
||||
</view>
|
||||
<view
|
||||
class="qurry-button"
|
||||
bind:tap="queryClassroom"
|
||||
@click="queryClassroom"
|
||||
>
|
||||
查询
|
||||
</view>
|
||||
</UBasePage>
|
||||
|
||||
<uni-calendar
|
||||
ref="calendarRef"
|
||||
:date="selectDate"
|
||||
:insert="false"
|
||||
:start-date="startDate"
|
||||
:end-date="endDate"
|
||||
@confirm="onCalenderConfirm"
|
||||
/>
|
||||
|
||||
<!-- time action sheet -->
|
||||
<view @touchmove.prevent>
|
||||
<view
|
||||
class="bg-white w-full min-h-10 transition-all ease-in-out z-100 duration-300 fixed dark:bg-#121212"
|
||||
:class="showTimeActionSheet ? 'bottom-0' : '-bottom-full'"
|
||||
>
|
||||
<view class="flex flex-col py-6 gap-6">
|
||||
<view
|
||||
class="flex font-medium text-xl px-4 justify-between items-center"
|
||||
>
|
||||
选择上课时间
|
||||
<view
|
||||
class="font-normal text-base text-green-500"
|
||||
@click="handleConfirmTimeActionSheet"
|
||||
>
|
||||
确定
|
||||
</view>
|
||||
</view>
|
||||
<picker-view class="h-40" :value="timeValue" @change="handleTimeChange">
|
||||
<picker-view-column>
|
||||
<view
|
||||
v-for="(item, index) in timeList[0]"
|
||||
:key="index"
|
||||
class="flex justify-center items-center"
|
||||
>
|
||||
{{ item }}
|
||||
</view>
|
||||
</picker-view-column>
|
||||
<picker-view-column>
|
||||
<view
|
||||
v-for="(item, index) in timeList[1]"
|
||||
:key="index"
|
||||
class="flex justify-center items-center"
|
||||
>
|
||||
{{ item }}
|
||||
</view>
|
||||
</picker-view-column>
|
||||
</picker-view>
|
||||
</view>
|
||||
<view
|
||||
class="flex pb-safe border-t-4 border-gray-200 h-12 text-lg justify-center items-center dark:border-opacity-20"
|
||||
hover-class="bg-gray-200 bg-opacity-50"
|
||||
:hover-stay-time="150"
|
||||
@click="showTimeActionSheet = false"
|
||||
>
|
||||
关闭
|
||||
</view>
|
||||
</view>
|
||||
<view
|
||||
class="bg-dark-100 bg-opacity-50 transition-all top-0 right-0 bottom-0 left-0 z-90 fixed"
|
||||
:class="
|
||||
showTimeActionSheet ? 'opacity-100 visible' : 'opacity-0 invisible'
|
||||
"
|
||||
@click="showTimeActionSheet = false"
|
||||
/>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
page {
|
||||
background: #f1f2f4;
|
||||
}
|
||||
.title {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
position: fixed;
|
||||
width: 45%;
|
||||
height: 10%;
|
||||
background: #fff;
|
||||
top: 8%;
|
||||
left: 32%;
|
||||
z-index: 1;
|
||||
border-radius: 50rpx;
|
||||
transform: translate(-8%, -0%);
|
||||
box-shadow: 0rpx 4rpx 8rpx rgba(0, 0, 0, 0.1);
|
||||
|
||||
text {
|
||||
font-size: 36rpx;
|
||||
font-weight: bold;
|
||||
color: #297fe4;
|
||||
}
|
||||
}
|
||||
.container {
|
||||
position: fixed;
|
||||
top: 25%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -20%);
|
||||
/* border: solid red 2rpx; */
|
||||
background: #fff;
|
||||
width: 80%;
|
||||
height: 60%;
|
||||
border-radius: 20rpx;
|
||||
box-shadow: 0rpx 4rpx 8rpx rgba(0, 0, 0, 0.1);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
|
||||
.query-form {
|
||||
padding: 30rpx;
|
||||
|
||||
.query-form-item {
|
||||
border-bottom: 2rpx solid #e9e9e9;
|
||||
padding: 20rpx 0;
|
||||
margin-bottom: 30rpx;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
.query-form-item-left {
|
||||
width: 40%;
|
||||
text {
|
||||
margin-left: 5rpx;
|
||||
color: #29a1f7;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.query-time-range {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
padding: 30rpx;
|
||||
text {
|
||||
background: #69b8f0;
|
||||
width: 130rpx;
|
||||
height: 90rpx;
|
||||
text-align: center;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: 40rpx;
|
||||
}
|
||||
.active {
|
||||
background-color: orange;
|
||||
}
|
||||
}
|
||||
}
|
||||
.qurry-button {
|
||||
position: fixed;
|
||||
width: 30%;
|
||||
height: 5%;
|
||||
top: 75%;
|
||||
left: 45%;
|
||||
transform: translate(-35%, -15%);
|
||||
background: #29a1f7;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
font-size: 36rpx;
|
||||
border-radius: 30rpx;
|
||||
}
|
||||
</style>
|
||||
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>
|
||||
139
src/pages/classroom/detail.vue
Normal file
139
src/pages/classroom/detail.vue
Normal file
@@ -0,0 +1,139 @@
|
||||
<script setup lang="ts">
|
||||
import { onShow } from '@dcloudio/uni-app'
|
||||
import { useAppStore } from '~/stores/modules/app'
|
||||
import { usePageStore } from '~/stores/modules/page'
|
||||
const { emptyClassroom } = storeToRefs(useAppStore())
|
||||
const { setPageConfig } = usePageStore()
|
||||
onShow(() => {
|
||||
setPageConfig({
|
||||
showNavBar: true,
|
||||
pageTitle: '空闲教室',
|
||||
showBackAction: true,
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UBasePage>
|
||||
<view class="tilte-content">
|
||||
<view class="title-content-left">
|
||||
<text>查询结果:</text><text style="margin-left: 20rpx">
|
||||
{{ emptyClassroom.data.length }}
|
||||
</text>
|
||||
</view>
|
||||
<view class="title-content-right">
|
||||
<text>{{ emptyClassroom.date }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view
|
||||
v-for="(item, index) in emptyClassroom.data"
|
||||
:key="index"
|
||||
class="empty-content-item"
|
||||
>
|
||||
<view class="empty-content-item-left">
|
||||
{{ item.campus }}
|
||||
</view>
|
||||
<view class="empty-content-item-right">
|
||||
<view class="empty-content-item-right-item">
|
||||
<uni-icons type="map" color="#F9BD56" size="24" />
|
||||
<text>{{ item.build }}</text>
|
||||
</view>
|
||||
<view class="empty-content-item-right-item">
|
||||
<uni-icons type="location" color="#FEC2BF" size="24" />
|
||||
<text>{{ item.name }}</text>
|
||||
</view>
|
||||
<view class="empty-content-item-right-item">
|
||||
<uni-icons type="settings" color="#C8CD9A" size="24" />
|
||||
<text>
|
||||
第{{ emptyClassroom.timeRange[0] }}-{{
|
||||
emptyClassroom.timeRange[1]
|
||||
}}节
|
||||
</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</UBasePage>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
page {
|
||||
background: #f5f7f8;
|
||||
}
|
||||
.tilte-content {
|
||||
padding: 30rpx;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
.title-content-left {
|
||||
width: 220rpx;
|
||||
height: 80rpx;
|
||||
background: white;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
font-size: 30rpx;
|
||||
color: #2095f2;
|
||||
font-weight: bold;
|
||||
border-radius: 30rpx;
|
||||
}
|
||||
.title-content-right {
|
||||
width: 400rpx;
|
||||
height: 80rpx;
|
||||
background: white;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
font-size: 30rpx;
|
||||
color: #2095f2;
|
||||
font-weight: bold;
|
||||
border-radius: 30rpx;
|
||||
}
|
||||
|
||||
.empty-content-item {
|
||||
background: white;
|
||||
margin: 30rpx;
|
||||
border-radius: 30rpx;
|
||||
height: 200rpx;
|
||||
box-shadow: 0px 0px 24rpx -4rpx rgba(0, 0, 0, 0.1);
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
}
|
||||
.empty-content-item-left {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100rpx;
|
||||
height: 100%;
|
||||
font-size: 40rpx;
|
||||
background-color: #2095f2;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
border-top-left-radius: 30rpx;
|
||||
border-bottom-left-radius: 30rpx;
|
||||
writing-mode: vertical-rl;
|
||||
}
|
||||
|
||||
.empty-content-item-right {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-around;
|
||||
margin-left: 20rpx;
|
||||
width: 80%;
|
||||
height: 100%;
|
||||
}
|
||||
.empty-content-item-right-item {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
}
|
||||
.empty-content-item-right-item text {
|
||||
margin-left: 5rpx;
|
||||
color: #2095f2;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user