1.首先 FullCalendar 版本如下
"@fullcalendar/core": "^4.3.1",
"@fullcalendar/daygrid": "^4.3.0",
"@fullcalendar/interaction": "^4.3.0",
"@fullcalendar/moment": "^4.3.0",
"@fullcalendar/timegrid": "^4.3.0",
"@fullcalendar/vue": "^4.3.1",
2.代码
<template>
<div>
<div>
<el-form>
<el-form-item label="实验室名称">
<el-select v-model="labNumber" @change="getlab" placeholder="请选择" size="mini">
<el-option
v-for="item in labList"
:key="item.lNumber"
:label="item.lName"
:value="item.lNumber"
>
</el-option>
</el-select>
</el-form-item>
<el-form-item label="实验大楼">
<el-input v-model="labNumform.unitNum" size="mini"></el-input>
</el-form-item>
<el-form-item label="实验楼层">
<el-input v-model="labNumform.lLevel" size="mini"></el-input>
</el-form-item>
<el-form-item label="实验名称">
<el-select v-model="labNum" @change="getable" placeholder="请选择" size="mini">
<el-option
v-for="item in sylist"
:key="item.labNumber"
:label="item.labName"
:value="item.labNumber"
>
</el-option>
</el-select>
</el-form-item>
<el-form-item label="实验台号">
<el-select
v-model="stationNumber"
@change="changThnum"
placeholder="请选择"
size="mini"
>
<el-option
v-for="item in Numlist"
:key="item.labNumber"
:label="item"
:value="item"
>
</el-option>
</el-select>
</el-form-item>
</el-form>
</div>
<!-- 日历 -->
<div class="calendar">
<FullCalendar :plugins="calendarPlugins"
:all-day-slot="false"
:header="{
left:'prev',
center:'title',
right: 'today ,next'
}"
:slot-event-overlap="false"
:events="events"
:button-text="{
today: '今天'
}"
:unselect-auto="true"
:select-overlap="false"
firstDay="1"
weekNumberCalculation="ISO"
:select-allow="handlerSeelctAllow"
select-mirror="true"
:min-time="mintime"
:max-time="maxtime"
selectable="true"
slot-duration="00:30"
slot-label-format="HH:mm"
title-format="YYYY年MM月D日"
default-view="timeGridWeek"
locale="zh-cn"
@dateClick="handleDateClick"
@select="handleSelect"
:valid-range="visibleRange"
/>
</div>
<!-- 预约选择框 -->
<div class="diogbox" v-if="dialogVisible">
<div class="diog">
<div class="top">实验室预约</div>
<ul class="center">
<li>
<span class="leixing">预约类型</span>
<el-select
v-model="typeApply"
@change="selectType"
placeholder="请选择"
>
<el-option
v-for="item in typeList"
:key="item.rRemarks"
:label="item.type"
:value="item.rRemarks"
>
</el-option>
</el-select>
</li>
<!-- itemName: "老师002项目1" itemNo: "项目编号111" -->
<li class="project" v-if="flagNum == 4">
<el-select
v-model="pNumber"
placeholder="请选择项目组名称"
@change="getItemName"
>
<el-option
v-for="(item, index) in project"
:key="index"
:label="item.itemName"
:value="item.itemNo"
>
</el-option>
</el-select>
</li>
<li class="task" v-if="flagNum == 5">
<el-select
v-model="pNumber"
placeholder="请选择课题组名称"
@change="getrName"
>
<el-option
v-for="(item, index) in reslist"
:key="index"
:label="item.rName"
:value="item.rNumber"
>
</el-option>
</el-select>
</li>
<li class="two">
<span>预约开始时间</span><i style="list">{{ xzDate }}</i>
<el-input v-model="showStartTime"></el-input>
</li>
<li class="two">
<span>预约结束时间</span><i>{{ xzDate }}</i>
<el-input v-model="showstopTime"></el-input>
</li>
</ul>
<div class="bottom">
<el-button size="min" class="submit" @click="addReview"
>提交</el-button
>
<el-button size="min" @click="handleClose">取消</el-button>
</div>
</div>
</div>
</div>
</template>
<script>
import {
findLab,
findlabNum,
findCourse,
findCourseBy,
cycleInfo,
findPeriod,
prolist,
reslist,
addReview,
} from "../request/api";
import FullCalendar from '@fullcalendar/vue'
import dayGridPlugin from '@fullcalendar/daygrid'
import interactionPlugin from '@fullcalendar/interaction'
import momentPlugin from '@fullcalendar/moment'
import '@fullcalendar/core/locales/zh-cn'
import timeGridPlulgin from '@fullcalendar/timegrid'
export default {
components: {
FullCalendar
},
data() {
return {
calendarApi:"",
dialogVisible:false,
mintime:"1:00",
maxtime:"22:00",
events:[],
calendarPlugins: [dayGridPlugin, timeGridPlulgin, momentPlugin, interactionPlugin],
// 随时判断时间是否合法,通过返回true/false来判断是否能够选择
handlerSeelctAllow: info => {
const currentDate = new Date()
const header=this.GetDateStr(this.minNum).getDay()
const tail=this.GetDateStr(this.maxNum).getDay()
const start = info.start.getDay()
const end = info.end.getDay()
console.log(info.start); console.log(info.end);
console.log(start <= end && start >= currentDate);
// return (start <= end && start >= currentDate)
return (start==end&&start>=header&&start<=tail)
},
selected: "", //选中值
labList: null, // 获取实验室列表
labId: "0",
nowDate:
new Date().getFullYear() +
"-" +
((new Date().getMonth() + 1 + "").length == 1
? "0" + (new Date().getMonth() + 1)
: new Date().getMonth() + 1) +
"-" +
((new Date().getDate() + "").length == 1
? "0" + new Date().getDate()
: new Date().getDate()),
backWeeks: "",
nextWeeks: "",
weeksList: [],
checkDate: [], // 用户在日历中选中的日期列表
timeScope: [],
labList: [], //实验室列表
sylist: [], //实验信息列表
Numlist: [], //台号列表
labNumber: "",
labNum: "",
labNumform: {},
stationNumber: "", //实验台号
contentList: [],
messageList: [], //处理后的预约内容
dialogVisible: false, //
typeList: [
{ rRemarks: 3, type: "个人预约" },
{ rRemarks: 4, type: "项目组预约" },
{ rRemarks: 5, type: "课题组预约" },
], //预约类型列表
typeApply: "", //预约类型
project: [], //项目下拉列表
reslist: [], //课题组下拉
xzDate: "",
stTime: "", //选择的开始时间
edTime: "", //选择结束时间
pNumber: "", //课题组/项目组编号
pName: "", //课题组/项目编号
flagNum: "",
expName: "", //实验名称
startTime: "", //提交的开始时间
stopTime: "", //提交结束时间
showStartTime:"",//展示的开始时间
showstopTime:"",//展示的结束时间
minNum: "", //最早预约时间
maxNum: "", //最迟预约时间
scopeDate: [], //可预约日期范围
endlist: [], //结束时间可选范围
Noscope: [], //不可选择的范围
visibleRange:{
},
}
},
computed:{
// visibleRange () { //限制日期时间,因为是预约功能,需要设置当前时间之后的多少天内可以预约,超过时间则不能预约
// // let nowDate = new Date()
// return {
// start: this.minNum,
// end: this.maxNum //后面写了一个方法转化
// }
// },
},
methods: {
handleClose() {
this.dialogVisible = false;
this.typeApply="";
this.pNumber="";
this.findPeriod();
},
//选择预约类型
selectType(e) {
this.flagNum = e;
},
//获取项目组下拉
getProlist(lNumber) {
prolist({ lNumber }).then((res) => {
this.project = res;
});
},
//获取项目名称
getItemName(e) {
this.project.some((Element) => {
if (Element.itemNo == e) {
this.pName = Element.itemName;
return true;
}
});
},
//获取课题组名称
getrName(e) {
this.reslist.some((Element) => {
if (Element.rNumber == e) {
this.pName = Element.rName;
return true;
}
});
},
//获取课题组下拉
getreslist(lNumber) {
reslist({ lNumber }).then((res) => {
this.reslist = res;
});
},
//获取实验室
findLab() {
findLab().then((res) => {
this.labList = res.data;
this.labNumber = res.data[0].lNumber;
this.getCycleInfo(this.labNumber);
this.getlab(this.labNumber);
});
},
getlab(e) {
this.findPeriod();
this.labNumber = "";
this.labNumber = e;
this.getfindlabNum(e);
this.findCourse(e);
this.getCycleInfo(e);
this.getProlist(e);
this.getreslist(e);
},
//获取实验室信息
getfindlabNum(labNumber) {
findlabNum({ labNumber }).then((res) => {
this.labNumform = res.data;
});
},
//获取实验信息列表
findCourse(lNumber) {
findCourse({ lNumber }).then((res) => {
if (res.length !== 0) {
this.sylist = res;
this.labNum = res[0].labNumber;
this.findCourseBy(this.labNum);
this.getable(this.labNum);
} else {
this.labNum = "";
}
});
},
//选择实验名称
getable(e) {
this.labNum = e; //实验编号
this.sylist.some((Element) => {
if (Element.labNumber == e) {
this.expName = Element.labName;
return true;
}
});
this.findCourseBy(e);
},
findCourseBy(labNumber) {
findCourseBy({ labNumber }).then((res) => {
var Numlist = res.stationNumber.split(",");
this.stationNumber = Numlist[0];
this.Numlist = Numlist;
this.findPeriod();
});
},
//查询预约设置信息
getCycleInfo(lNumber) {
cycleInfo({ lNumber }).then((res) => {
if (res.data !== "") {
console.log(res);
this.visibleRange.start = res.data.startTime;
this.visibleRange.end = res.data.stopTime;
this.mintime = res.data.beginTime;
this.maxtime= res.data.endTime;
console.log(this.mintime , this.maxtime);
this.minNum=res.data.minNum;
this.maxNum=res.data.maxNum;
// this.mintime=beginTime;
// this.maxtime=endTime;
// this.visibleRange.start=start
// this.visibleRange.start=start
console.log(this.minNum);
console.log(this.maxNum);
}
});
},
// //计算可预约日期
// getmayDate() {
// //最早预约日期
// var start = this.GetDateStr(this.minNum);
// //最迟预约日期
// var end = this.GetDateStr(this.maxNum);
// // this.scopeDate = this.getDateBetween(start, end);
// },
//计算几天后的日期
GetDateStr(AddDayCount) {
var dd = new Date();
dd.setDate(dd.getDate() + AddDayCount); //获取AddDayCount天后的日期
// var y = dd.getFullYear();
// var m =
// dd.getMonth() + 1 < 10 ? "0" + (dd.getMonth() + 1) : dd.getMonth() + 1; //获取当前月份的日期,不足10补0
// var d = dd.getDate() < 10 ? "0" + dd.getDate() : dd.getDate(); //获取当前几号,不足10补0
// console.log(d);
return dd;
},
//选择实验台号
changThnum() {
this.findPeriod();
},
//获取实验预约信息
findPeriod() {
findPeriod({
lNumber: this.labNumber,
stationNumber: this.stationNumber,
}).then((res) => {
console.log(res)
res.forEach(element => {
element['start']=element['startTime']
element['end']=element['endTime']
});
console.log(res);
this.events=res;
});
},
// 当点击时候
handleDateClick(arg) {
console.log(arg)
},
// 当选择结束的时候获取开始和结束时间
handleSelect(info) {
this.startTime=info.startStr
this.endTime=info.endStr
var showStartTime=info.startStr
var showstopTime=info.endStr
this.showStartTime=this.gsh(showStartTime)
this.showstopTime=this.gsh(showstopTime)
console.log('form' + info.startStr + ' to ' + info.endStr)
this.dialogVisible=true
},
//格式化开始时间与结束时间
gsh(str) {
var oDate = new Date(str),
oYear = oDate.getFullYear(),
oMonth = oDate.getMonth() + 1,
oDay = oDate.getDate(),
oHour = oDate.getHours(),
oMin = oDate.getMinutes(),
oSen = oDate.getSeconds(),
oTime = oYear + '-' + this.getzf(oMonth) + '-' + this.getzf(oDay) + ' ' + this.getzf(oHour) + ':' + this.getzf(oMin) + ':' + this.getzf(oSen); //最后拼接时间
return oTime;
},
//补0操作
getzf(num) {
if(parseInt(num) < 10) {
num = '0' + num;
}
return num;
},
//提交预约
addReview() {
if (this.typeApply == "") {
this.$message.error("预约类型不能为空");
return;
}
if (this.flagNum !== 3 && this.pNumber == "") {
this.$message.error("请选择预约项目");
return;
}
addReview({
lNumber: this.labNumber,
stationNumber: this.stationNumber,
labNumber: this.labNum,
expName: this.expName,
pNumber: this.pNumber,
pName: this.pName,
rRemarks: this.typeApply,
startTime: this.startTime,
stopTime: this.endTime,
}).then((res) => {
if (res.code == 200) {
this.$message.success("预约成功");
this.handleClose();
} else {
this.$message.error("预约失败:" + res.message);
}
});
},
},
created() {
this.findLab();
},
}
</script>
<style lang="less" scoped>
@import '~@fullcalendar/core/main.css';
@import '~@fullcalendar/daygrid/main.css';
@import '~@fullcalendar/timegrid/main.css';
.el-form {
display: flex;
width: 100%;
flex-wrap: wrap;
margin-bottom: 15px;
}
.el-form-item {
display: flex;
margin-bottom: 0;
}
/deep/ .el-form-item__label {
width: 80px;
padding-right: 10px !important;
}
.diogbox {
width: 100%;
height: 100%;
position: absolute;
background: rgba(0, 0, 0, 0.5);
top: 0;
left: 0;
z-index: 100;
}
.diog {
width: 64.285714rem;
border: 0.071429rem solid #ccc;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: #ffffff;
text-align: left;
.top {
height: 6.214286rem;
line-height: 6.214286rem;
// background-color: rgba(224, 224, 224, 0.9);
padding-left: 1.428571rem;
border-bottom: 1px solid #ececec;
color: #3c763d;
text-align: center;
}
ul {
margin-top: 1.071429rem;
padding: 0 1.428571rem;
box-sizing: border-box;
}
li {
display: flex;
flex-direction: row;
margin-top: 1.428571rem;
span {
margin-bottom: 1.071429rem;
width: 16rem;
}
.leixing{
width: 13rem;
}
}
li:nth-child(1) {
display: flex;
align-items: center;
// flex-direction: column;
}
.two {
align-items: baseline;
.el-select {
margin-left: 1.071429rem;
}
}
.bottom {
margin-top: 2.142857rem;
margin-bottom: 5rem;
text-align: center;
/deep/ .submit {
background: #3c763d;
color: #fff;
}
}
.project,.task{
box-sizing: border-box;
padding-left: 12.857143rem;
}
}
/deep/.fc-toolbar.fc-header-toolbar{
margin-bottom: 10px;
}
/deep/.fc-toolbar.fc-header-toolbar h2{
font-size: 20px;
}
/deep/.fc-button-primary{
background-color: #3c763d;
border-color: #3c763d;
}
.fc th, .fc td{
line-height: 2.5;
}
</style>