| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521 |
- <template>
- <div class="container">
- <FullCalendar
- ref="fullCalendar"
- class="calendar-container-calendar"
- :options="calendarOptions"
- >
- <template v-slot:eventContent="arg">
- <!-- 弹窗信息 -->
- <el-popover
- trigger="click"
- popper-class="fullcalendar-popover"
- placement="right"
- :width="268"
- popper-style="padding: 0;border:none;background:none"
- >
- <!-- 预约信息 -->
- <template #reference>
- <div
- class="st1 cursor-pointer"
- :class="'status' + arg.event.extendedProps.status"
- >
- <span class="mr8">{{ arg.event.extendedProps.projectName }}</span>
- <span>
- {{ parseTime(arg.event.start, "HH:mm") }} -
- {{ parseTime(arg.event.end, "HH:mm") }}
- </span>
- </div>
- </template>
- <!-- 预约详细信息 -->
- <template #default>
- <div class="popover-def-header">
- <div class="name mt7">
- <span class="mr2">{{ arg.event.extendedProps.instName }}</span>
- 预约信息
- </div>
- <div class="date mt8 pb25">
- <span class="mr2">{{ changeTime(arg.event.start) }}</span>
- <span class="mr2">({{ getWeek(arg.event.start) }})</span>
- <span>
- {{ parseTime(arg.event.start, "HH:mm") }} ~
- {{ parseTime(arg.event.end, "HH:mm") }}
- </span>
- </div>
- </div>
- <div class="popover-def-content">
- <div class="content-felx mb12">
- <p class="mx-1" tag="b" size="small">
- 地点: {{ arg.event.extendedProps.placeAddress }}
- </p>
- </div>
- <div class="content-felx mb12">
- <p class="mx-1" size="small">
- 课题组:{{ arg.event.extendedProps.projectName }}
- </p>
- </div>
- <div class="content-felx mb12">
- <p class="mx-1" size="small">
- 预约人: {{ arg.event.extendedProps.userName }}
- </p>
- </div>
- </div>
- </template>
- </el-popover>
- </template>
- </FullCalendar>
- </div>
- </template>
- <script>
- import to from "await-to-js";
- import FullCalendar from "@fullcalendar/vue";
- import dayGridPlugin from "@fullcalendar/daygrid";
- import timeGridPlugin from "@fullcalendar/timegrid";
- import interactionPlugin from "@fullcalendar/interaction";
- import { getAppointListByInst } from "@/api/instr/index";
- import moment from "moment";
- export default {
- name: "equipment",
- components: {
- FullCalendar,
- },
- data() {
- return {
- recordData: [],
- searchForm: {
- instId: 0,
- startTimeEnd: "",
- startTimeStart: "",
- },
- calendarOptions: {
- plugins: [
- dayGridPlugin,
- timeGridPlugin,
- interactionPlugin, // needed for dateClick
- ],
- height: 600,
- headerToolbar: {
- left: null,
- center: "prev,title,next,today",
- right: null,
- },
- customButtons: {
- prev: {
- click: () => {
- this.prevWeekClick();
- },
- },
- next: {
- click: () => {
- this.nextWeekClick();
- },
- },
- today: {
- text: "本周",
- click: () => {
- this.todayWeekClick();
- },
- },
- },
- locale: "zh-cn", // 切换语言,当前为中文
- // headerToolbar: false,
- headerToolbar: {
- left: null,
- center: "prev,title,next,today",
- right: null,
- },
- events: [], //事件事件+文本
- initialView: "timeGridWeek", // 默认为那个视图(月:dayGridMonth,周:timeGridWeek,日:timeGridDay)
- selectMirror: true,
- dayMaxEvents: true,
- firstDay: 1, //new Date().getDay(), // 设置一周中显示的第一天是哪天,周日是0,周一是1,类推 new Date().getDay()当前天
- slotLabelFormat: {
- hour: "2-digit",
- minute: "2-digit",
- meridiem: false,
- hour12: false, // 设置时间为24小时
- },
- slotMinTime: "00:00:00",
- slotMaxTime: "24:00:00",
- allDaySlot: false, //是否显示日历上方的allDay
- moreLinkClassNames: "more-btns",
- },
- currentEvents: [],
- timeSplit: 10,
- recordData: [],
- curTime: "",
- };
- },
- created() {},
- mounted() {
- this.curTime = this.getToday();
- this.$nextTick(async () => {
- this.searchForm.instId = this.$route.query.id * 1;
- this.searchForm.startTimeStart = this.getWeekDate()[0];
- this.searchForm.startTimeEnd = this.getWeekDate()[1];
- await this.getAppointData();
- let calendarFunc = this.$refs["fullCalendar"].getApi().view.calendar;
- calendarFunc.setOption(
- "slotDuration",
- this.setSplitTime(this.timeSplit)
- );
- this.initData();
- });
- },
- methods: {
- getToday() {
- return moment(moment().startOf("day").valueOf()).format("YYYY-MM-DD");
- },
- getWeekDate() {
- // 获取当前周的周一0点
- var startOfWeek = moment(this.curTime)
- .startOf("isoWeek")
- .format("YYYY-MM-DD HH:mm:ss");
- // 获取下一周的周一0点
- var startOfNextWeek = moment(this.curTime)
- .startOf("isoWeek")
- .add(1, "weeks")
- .format("YYYY-MM-DD HH:mm:ss");
- return [startOfWeek, startOfNextWeek];
- },
- async getAppointData() {
- const [err, res] = await to(getAppointListByInst(this.searchForm));
- if (err) return;
- if (res.code == 200) {
- this.recordData = res.data.list;
- }
- },
- // 上周点击
- async prevWeekClick() {
- let calendarApi = this.$refs["fullCalendar"].getApi();
- calendarApi.prev();
- this.curTime = moment(calendarApi.getCurrentData().currentDate).format(
- "YYYY-MM-DD"
- );
- this.searchForm.startTimeStart = this.curTime + " 00:00:00";
- this.searchForm.startTimeEnd = this.getNextWeekDays() + " 00:00:00";
- await this.getAppointData();
- this.initData();
- },
- // 下周点击
- async nextWeekClick() {
- let calendarApi = this.$refs["fullCalendar"].getApi();
- calendarApi.next();
- this.curTime = moment(calendarApi.getCurrentData().currentDate).format(
- "YYYY-MM-DD"
- );
- this.searchForm.startTimeStart = this.curTime + " 00:00:00";
- this.searchForm.startTimeEnd = this.getNextWeekDays() + " 00:00:00";
- await this.getAppointData();
- this.initData();
- },
- // 今天点击
- async todayWeekClick() {
- let calendarApi = this.$refs["fullCalendar"].getApi();
- calendarApi.today();
- const date = moment(calendarApi.getCurrentData().currentDate).format(
- "YYYY-MM-DD"
- );
- const currentMonday = moment(date).startOf("isoWeek");
- const nextMonday = currentMonday.clone().add(1, "week");
- this.searchForm.startTimeStart =
- currentMonday.format("YYYY-MM-DD") + " 00:00:00";
- this.searchForm.startTimeEnd =
- nextMonday.format("YYYY-MM-DD") + " 00:00:00";
- await this.getAppointData();
- this.initData();
- },
- initData() {
- const filterArr = ["10", "20", "50", "60"];
- let appointData = [];
- let status = 1;
- this.recordData
- .filter((item) => filterArr.includes(item.appointStatus))
- .map((item) => {
- appointData.push({
- ...item,
- status,
- start: item.startTime,
- end: item.endTime,
- });
- status++;
- if (status > 3) {
- status = 1;
- }
- });
- let calendarApi = this.$refs["fullCalendar"].getApi();
- let calendarFunc = calendarApi.view.calendar;
- calendarFunc.unselect();
- let getEvents = calendarFunc.getEvents();
- if (getEvents && getEvents.length > 0) {
- //如果日历看板之前有数据,那么删除之前的数据
- getEvents.map((item) => {
- calendarFunc.getEventById(item.id).remove();
- });
- }
- appointData.map((item) => {
- calendarFunc.addEvent(item); //数据填充到日历看板中
- });
- // calendarApi.gotoDate(new Date(this.curTime));
- },
- // 设置一格时间槽代表多长时间
- setSplitTime(time) {
- let split_time = "";
- if (time < 60) {
- split_time = "00:" + (time < 10 ? "0" + time : time) + ":00";
- } else if (time == 60) {
- split_time = "01:00:00";
- }
- return split_time;
- },
- parseTime(date, format) {
- return moment(date).format(format);
- },
- setDiffTime(row) {
- // 计算时间差
- const startTime = moment(row.start);
- const endTime = moment(row.end);
- return (
- moment.duration(endTime.diff(startTime)).asHours().toFixed(1) + "h"
- );
- },
- changeTime(date) {
- const time = moment(date).format("MM:DD").split(":");
- return `${time[0]}月${time[1]}日`;
- },
- getWeek(date) {
- // 参数时间戳
- let week = moment(date).day();
- switch (week) {
- case 1:
- return "周一";
- case 2:
- return "周二";
- case 3:
- return "周三";
- case 4:
- return "周四";
- case 5:
- return "周五";
- case 6:
- return "周六";
- case 0:
- return "周日";
- }
- },
- // // 获取上一周
- getPrevWeekDays() {
- return moment(this.curTime).subtract(1, "week").format("YYYY-MM-DD");
- },
- // // 获取下一周
- getNextWeekDays() {
- return moment(this.curTime).add(1, "week").format("YYYY-MM-DD");
- },
- },
- };
- </script>
- <style lang="scss" scoped>
- :deep(.fc-day-disabled) {
- opacity: 0.5;
- pointer-events: none;
- }
- :deep(.fc-cell-not-allowed) {
- background-color: #eee;
- }
- :deep(.fc-toolbar-chunk) {
- div {
- display: flex;
- }
- }
- :deep(.fc-toolbar-title) {
- font-size: 1.75em;
- margin: 0;
- width: 320px;
- text-align: center;
- }
- :deep(.borderBlue) {
- border-left: 5px solid blue !important;
- border-radius: 0;
- }
- :deep(.borderOrange) {
- border-left: 5px solid yellow !important;
- border-radius: 0;
- }
- :deep(.fc) {
- .fc-day-today {
- background: unset;
- }
- }
- :deep(.fc-past-event) {
- background-color: #e3e3e3;
- }
- :deep(.fc-today-button) {
- margin-left: 10px;
- }
- :deep(.fc .fc-toolbar.fc-header-toolbar) {
- margin-bottom: 20px;
- }
- :deep(.fc .fc-timegrid-slot) {
- height: 2em;
- }
- :deep(.fc-col-header-cell-cushion) {
- font-size: 15px !important;
- color: #333333 !important;
- font-weight: bold !important;
- }
- :deep(.fc-timeGridDay-view) {
- .fc-day-today {
- background: none;
- }
- .st1 {
- border-top: none;
- display: block;
- }
- .fc-timegrid-col-events {
- margin: 0;
- }
- .fc-v-event {
- background: none;
- width: 50%;
- border: none;
- }
- }
- :deep(.fc-timeGridWeek-view) {
- .fc-day-today {
- background: none;
- }
- .st1 {
- border-left: none;
- display: block;
- }
- .fc-timegrid-col-events {
- margin: 0;
- }
- .fc-v-event {
- background: none;
- width: 100%;
- border: none;
- }
- }
- :deep(.fc-dayGridMonth-view) {
- .fc-day {
- height: 85px;
- }
- .st1 {
- border-top: none;
- }
- }
- :deep(.fc-popover-body) {
- .st1 {
- border-top: none;
- }
- }
- .st1 {
- display: flex;
- justify-content: space-between;
- width: 100%;
- height: 100%;
- border-left: 2px solid;
- border-top: 2px solid;
- padding-left: 7px;
- margin-bottom: 2px;
- }
- // :deep(.fc .fc-scroller-liquid-absolute) {
- // overflow: hidden !important;
- // }
- // :deep(.fc .fc-scroller) {
- // overflow: hidden !important;
- // }
- :deep(.fc .fc-daygrid-more-link) {
- color: #b5c1d8 !important;
- }
- :deep(.fc-h-event) {
- border: none;
- }
- :deep(.fc-daygrid-day-number) {
- color: #585858;
- }
- :deep(.fc .fc-timegrid-slot-label) {
- color: #585858;
- }
- :deep(.fc .fc-daygrid-day-top) {
- flex-direction: row;
- }
- :deep(.fc .fc-daygrid-day.fc-day-today) {
- background: none;
- .fc-daygrid-day-number {
- background: #2c78ff;
- border-radius: 12px;
- color: #ffffff;
- }
- }
- :deep(.fc-daygrid-day-number) {
- margin: 3px 0 0 6px;
- }
- :deep(.fc-col-header-cell) {
- .fc-scrollgrid-sync-inner {
- height: 50px;
- display: flex;
- align-items: center;
- justify-content: center;
- .fc-col-header-cell-cushion {
- font-size: 13px;
- color: #585858;
- font-weight: 100;
- }
- }
- }
- .status1 {
- background: #fff6e2;
- border-color: #fdc33e;
- color: #bf743c;
- }
- .status2 {
- background: #f0faf2;
- border-color: #0dda83;
- color: #006e3f;
- }
- .status3 {
- background: #eef3fe;
- border-color: #2c78ff;
- color: #2c78ff;
- }
- .fullcalendar-popover {
- .popover-def-header {
- // width: 268px;
- padding: 8px 12px 0 14px;
- background: linear-gradient(241deg, #2c78ff 0%, #1c9bfd 100%);
- font-size: 12px;
- color: #ffffff;
- .header {
- display: flex;
- justify-content: end;
- }
- }
- .popover-def-content {
- padding: 12px 22px;
- background: #fff;
- .content-felx {
- display: flex;
- .icon-l {
- width: 16px;
- height: 16px;
- display: flex;
- align-items: center;
- justify-content: center;
- margin-right: 6px;
- }
- }
- }
- :deep(.el-popper__arrow) {
- opacity: 0;
- }
- }
- </style>
|