|
|
@@ -0,0 +1,866 @@
|
|
|
+<template>
|
|
|
+ <div v-if="visible">
|
|
|
+ <el-dialog
|
|
|
+ :title="title"
|
|
|
+ :visible.sync="visible"
|
|
|
+ :close-on-click-modal="false"
|
|
|
+ @close="dialogClose"
|
|
|
+ width="1200px"
|
|
|
+ >
|
|
|
+ <div>
|
|
|
+ <FullCalendar ref="fullCalendar" :options="calendarOptions">
|
|
|
+ <template v-slot:eventContent="arg">
|
|
|
+ <div
|
|
|
+ style="height: 100%; width: 100%"
|
|
|
+ :title="showTitlt(arg.event)"
|
|
|
+ >
|
|
|
+ <div
|
|
|
+ v-if="
|
|
|
+ arg.event.extendedProps.appointStatus &&
|
|
|
+ arg.event.extendedProps.appointStatus != 999
|
|
|
+ "
|
|
|
+ style="color: #ffffff; margin: 0px"
|
|
|
+ >
|
|
|
+ <div class="appoint-details">
|
|
|
+ {{ arg.event.extendedProps.userName
|
|
|
+ }}{{ "--" + arg.event.extendedProps.tel }}
|
|
|
+ </div>
|
|
|
+ <div class="appoint-details" v-if="showAllInfo(arg.event, 2)">
|
|
|
+ {{
|
|
|
+ parseTime(arg.event.start, "{m}月{d}日") ==
|
|
|
+ parseTime(arg.event.end, "{m}月{d}日")
|
|
|
+ ? parseTime(arg.event.start, "{h}:{i}")
|
|
|
+ : parseTime(arg.event.start, "{m}月{d}日 {h}:{i}")
|
|
|
+ }}
|
|
|
+ -
|
|
|
+ {{
|
|
|
+ parseTime(arg.event.end, "{m}月{d}日") ==
|
|
|
+ parseTime(arg.event.start, "{m}月{d}日")
|
|
|
+ ? parseTime(arg.event.end, "{h}:{i}")
|
|
|
+ : parseTime(arg.event.end, "{m}月{d}日 {h}:{i}")
|
|
|
+ }}
|
|
|
+ </div>
|
|
|
+ <div class="appoint-details" v-if="showAllInfo(arg.event, 3)">
|
|
|
+ {{
|
|
|
+ arg.event.extendedProps.projectName ||
|
|
|
+ arg.event.extendedProps.serviceName
|
|
|
+ }}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div
|
|
|
+ v-else-if="
|
|
|
+ arg.event.extendedProps.appointStatus &&
|
|
|
+ arg.event.extendedProps.appointStatus == 999
|
|
|
+ "
|
|
|
+ style="color: #61616e; margin: 0px"
|
|
|
+ >
|
|
|
+ 不允许预约
|
|
|
+ </div>
|
|
|
+ <div v-else style="color: #ffffff; margin: 0px">
|
|
|
+ {{
|
|
|
+ parseTime(arg.event.start, "{m}月{d}日") ==
|
|
|
+ parseTime(arg.event.end, "{m}月{d}日")
|
|
|
+ ? parseTime(arg.event.start, "{h}:{i}")
|
|
|
+ : parseTime(arg.event.start, "{m}月{d}日 {h}:{i}")
|
|
|
+ }}
|
|
|
+ -
|
|
|
+ {{
|
|
|
+ parseTime(arg.event.end, "{m}月{d}日") ==
|
|
|
+ parseTime(arg.event.start, "{m}月{d}日")
|
|
|
+ ? parseTime(arg.event.end, "{h}:{i}")
|
|
|
+ : parseTime(arg.event.end, "{m}月{d}日 {h}:{i}")
|
|
|
+ }}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </FullCalendar>
|
|
|
+ </div>
|
|
|
+ <template #footer>
|
|
|
+ <div class="dialog-footer">
|
|
|
+ <el-button @click="dialogClose()" size="small ">取 消</el-button>
|
|
|
+ <el-button
|
|
|
+ :disabled="!form.startTime"
|
|
|
+ type="primary"
|
|
|
+ size="small "
|
|
|
+ @click="nextStep"
|
|
|
+ >
|
|
|
+ 确认
|
|
|
+ </el-button>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-dialog>
|
|
|
+ <appointCreate ref="appointCreateRef"></appointCreate>
|
|
|
+ <!-- <create-sub ref="sub" @refresh="emitData"></create-sub> -->
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script lang="ts">
|
|
|
+ // import CreateSub from "/@/views/instr/component/appoint/createSub.vue";
|
|
|
+ import FullCalendar from "@fullcalendar/vue";
|
|
|
+ import dayGridPlugin from "@fullcalendar/daygrid";
|
|
|
+ import interactionPlugin from "@fullcalendar/interaction";
|
|
|
+ import timeGridPlugin from "@fullcalendar/timegrid";
|
|
|
+ import to from "await-to-js";
|
|
|
+ import _ from "lodash";
|
|
|
+ import moment from "moment";
|
|
|
+ import appointCreate from "./appoint-create.vue";
|
|
|
+ import {
|
|
|
+ getSettingDetail,
|
|
|
+ getAppointInfo,
|
|
|
+ checkInBlacklist,
|
|
|
+ } from "@/api/instr/index";
|
|
|
+ export default {
|
|
|
+ name: "FrontendWebTest",
|
|
|
+ components: {
|
|
|
+ FullCalendar,
|
|
|
+ appointCreate,
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ title: "",
|
|
|
+ visible: false,
|
|
|
+ form: {
|
|
|
+ startTime: "",
|
|
|
+ endTime: "",
|
|
|
+ instId: 0,
|
|
|
+ instName: "",
|
|
|
+ createForm: "",
|
|
|
+ appointJump: false,
|
|
|
+ appointJumpLink: "",
|
|
|
+ appointJumpType: "",
|
|
|
+ assetNumber: "",
|
|
|
+ instHeadId: "",
|
|
|
+ },
|
|
|
+ show: false,
|
|
|
+ split_time: 0,
|
|
|
+ calendarOptions: {
|
|
|
+ plugins: [dayGridPlugin, interactionPlugin, timeGridPlugin],
|
|
|
+ initialView: "timeGridWeek", // 默认为那个视图(月:dayGridMonth,周:timeGridWeek,日:timeGridDay)
|
|
|
+ // validRange: this.setValidRange, //日期有效范围
|
|
|
+ allDaySlot: false, //是否显示日历上方的allDay
|
|
|
+ dayMaxEvents: true, // allow "more" link when too many events,只能选中或拖动一次
|
|
|
+ firstDay: 1, //new Date().getDay(), // 设置一周中显示的第一天是哪天,周日是0,周一是1,类推 new Date().getDay()当前天
|
|
|
+ locale: "zh-cn", // 切换语言,当前为中文
|
|
|
+ unselectAuto: false, //当点击页⾯⽇历以外的位置时,是否⾃动取消当前的选中状态。false是不取消
|
|
|
+ customButtons: {
|
|
|
+ prev: {
|
|
|
+ click: () => {
|
|
|
+ this.prevWeekClick();
|
|
|
+ },
|
|
|
+ },
|
|
|
+ next: {
|
|
|
+ click: () => {
|
|
|
+ this.nextWeekClick();
|
|
|
+ },
|
|
|
+ },
|
|
|
+ today: {
|
|
|
+ text: "本周",
|
|
|
+ click: () => {
|
|
|
+ this.todayWeekClick();
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ height: 600,
|
|
|
+ dragScroll: true,
|
|
|
+ headerToolbar: {
|
|
|
+ left: null,
|
|
|
+ center: "prev,title,next,today",
|
|
|
+ right: null,
|
|
|
+ },
|
|
|
+ events: [], //事件事件+文本
|
|
|
+ slotLabelFormat: {
|
|
|
+ hour: "2-digit",
|
|
|
+ minute: "2-digit",
|
|
|
+ meridiem: false,
|
|
|
+ hour12: false, // 设置时间为24小时
|
|
|
+ },
|
|
|
+ editable: false,
|
|
|
+ selectable: true,
|
|
|
+ eventConstraint: {
|
|
|
+ // 设置可以拖放的时间段为当下到100年后
|
|
|
+ start: new Date(), // 只允许选择当前时间之后的时间段
|
|
|
+ },
|
|
|
+ selectConstraint: {
|
|
|
+ start: new Date(),
|
|
|
+ end: "",
|
|
|
+ },
|
|
|
+ selectOverlap: false, //选择重叠
|
|
|
+ businessHours: [],
|
|
|
+ selectMirror: true,
|
|
|
+ weekends: true,
|
|
|
+ select: this.handleDateSelect, //当用户拖拽日期或时间时传递的参数
|
|
|
+ },
|
|
|
+ furtherLimit: "",
|
|
|
+ };
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ emitData() {
|
|
|
+ this.dialogClose();
|
|
|
+ },
|
|
|
+ // 打开设备预约
|
|
|
+ async openDialog(row) {
|
|
|
+ const [err, res] = await to(checkInBlacklist());
|
|
|
+ if (err) return;
|
|
|
+ if (res.data) {
|
|
|
+ return this.$message.warning(
|
|
|
+ "您已被拉入黑名单,无法预约,请联系管理人员"
|
|
|
+ );
|
|
|
+ }
|
|
|
+ if (row.appointJump && row.appointJumpType == "10") {
|
|
|
+ return window.open(row.appointJumpLink, "_blank");
|
|
|
+ }
|
|
|
+ this.$nextTick(async () => {
|
|
|
+ this.form.instId = row.id;
|
|
|
+ this.form.instName = row.instName;
|
|
|
+ this.form.appointJump = row.appointJump;
|
|
|
+ this.form.appointJumpLink = row.appointJumpLink;
|
|
|
+ this.form.appointJumpType = row.appointJumpType;
|
|
|
+ this.form.assetNumber = row.assetNumber;
|
|
|
+ this.form.instHeadId = row.instHeadId;
|
|
|
+ this.title = "正在发起对" + row.instName + "的预约申请";
|
|
|
+ this.visible = true;
|
|
|
+ const params = {
|
|
|
+ instId: row.id,
|
|
|
+ code: "InstCfgAppoint",
|
|
|
+ };
|
|
|
+ const [err, res] = await to(getSettingDetail({ ...params }));
|
|
|
+ if (err) return;
|
|
|
+ if (res.code == 200) {
|
|
|
+ this.show = true;
|
|
|
+ this.split_time = res.data.config.timeSplit;
|
|
|
+ this.form.createForm = res.data.config.createForm;
|
|
|
+ let calendarFunc =
|
|
|
+ this.$refs["fullCalendar"].getApi().view.calendar;
|
|
|
+ calendarFunc.setOption(
|
|
|
+ "slotDuration",
|
|
|
+ this.setSplitTime(this.split_time)
|
|
|
+ );
|
|
|
+ this.getAppointData();
|
|
|
+ }
|
|
|
+ // this.initData();
|
|
|
+ // await this.getAppointData();
|
|
|
+ });
|
|
|
+ },
|
|
|
+ // 设置一格时间槽代表多长时间
|
|
|
+ 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;
|
|
|
+ },
|
|
|
+ // 预约信息
|
|
|
+ getAppointData() {
|
|
|
+ this.$nextTick(async () => {
|
|
|
+ const calendar = await this.$refs.fullCalendar.getApi(); // 获取 FullCalendar 实例
|
|
|
+ let params = {
|
|
|
+ dateType: "week",
|
|
|
+ instId: this.form.instId,
|
|
|
+ date: moment(calendar.getCurrentData().currentDate).format(
|
|
|
+ "YYYY-MM-DD"
|
|
|
+ ),
|
|
|
+ };
|
|
|
+ const [err, res] = await to(getAppointInfo({ ...params }));
|
|
|
+ if (err) return;
|
|
|
+ if (res.code == 200) {
|
|
|
+ const { appoint, unavailable, furtherLimit } = res.data;
|
|
|
+ this.furtherLimit = furtherLimit
|
|
|
+ ? moment(furtherLimit).format("YYYY-MM-DD HH:mm")
|
|
|
+ : "";
|
|
|
+ let arr = [...(appoint || []), ...(unavailable || [])];
|
|
|
+ this.setBusinessHours(calendar);
|
|
|
+ this.initBoard(arr);
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.calendarOptions.selectConstraint = {
|
|
|
+ start: new Date(),
|
|
|
+ end: this.furtherLimit
|
|
|
+ ? moment(this.furtherLimit).format("YYYY-MM-DD HH:mm")
|
|
|
+ : "",
|
|
|
+ };
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
+ // 上周点击
|
|
|
+ prevWeekClick() {
|
|
|
+ let calendarApi = this.$refs.fullCalendar.getApi();
|
|
|
+ calendarApi.prev();
|
|
|
+ this.getAppointData();
|
|
|
+ },
|
|
|
+ // 下周点击
|
|
|
+ nextWeekClick() {
|
|
|
+ let calendarApi = this.$refs.fullCalendar.getApi();
|
|
|
+ calendarApi.next();
|
|
|
+ this.getAppointData();
|
|
|
+ },
|
|
|
+ // 今天点击
|
|
|
+ todayWeekClick() {
|
|
|
+ let calendarApi = this.$refs.fullCalendar.getApi();
|
|
|
+ calendarApi.today();
|
|
|
+ this.getAppointData();
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 设置工作时间
|
|
|
+ * */
|
|
|
+ // 设置工作时间(可预约时间)
|
|
|
+ setBusinessHours(calendar) {
|
|
|
+ // 获取当前视图所显示的日期范围
|
|
|
+ const viewStart = calendar.view.activeStart;
|
|
|
+ const viewEnd = calendar.view.activeEnd;
|
|
|
+ // 获取今天的日期
|
|
|
+ const today = new Date();
|
|
|
+ // 判断今天是否在当前周里
|
|
|
+ if (today >= viewStart && today <= viewEnd) {
|
|
|
+ // 当前周
|
|
|
+ this.handleSetHours("currentWeek");
|
|
|
+ } else if (today < viewStart) {
|
|
|
+ // 未来的周
|
|
|
+ this.handleSetHours("featureWeek");
|
|
|
+ } else {
|
|
|
+ // 过去的周
|
|
|
+ this.handleSetHours("pastWeek");
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 设置不同周的工作时间
|
|
|
+ /**
|
|
|
+ * @param {*} weekType 周类型: 当前周 未来周 之前周
|
|
|
+ * @description 设置每周的可预约时间
|
|
|
+ * 优先预约权限的用户 过去周全天不可以预约、未来周全天可预约、当前周今天当前时间之前的时间不可预约
|
|
|
+ * 非优先预约权限的用户 过去周 全天不可以预约 、当前周(包括未来周)的过去时间不可以预约、现在及以后的时间根据提前预约时长设置限制是否可预约
|
|
|
+ * */
|
|
|
+ handleSetHours(weekType) {
|
|
|
+ let businessHours = [];
|
|
|
+ // 获取当前时间
|
|
|
+ const now = moment();
|
|
|
+ // 根据当前天输出三个数组
|
|
|
+ const currentDay = now.day(); //当前天 周四 [4]
|
|
|
+ const lodashRangeDay = currentDay === 0 ? 7 : now.day();
|
|
|
+ const pastDays = _.range(1, lodashRangeDay); //过去的时间 [1,2,3]
|
|
|
+ const futureDays = _.range(lodashRangeDay + 1, 8)
|
|
|
+ .concat()
|
|
|
+ .map((num) => (num === 7 ? 0 : num));
|
|
|
+ //未来的时间 [5,6,0]
|
|
|
+ const startTime = now.format("YYYY-MM-DD HH:mm");
|
|
|
+ const endTime = moment(this.furtherLimit).format("YYYY-MM-DD HH:mm"); //当前时间增加1小时
|
|
|
+ // 仪器可预约时间为从当前时间开始(startTime)往后推到(endTime)
|
|
|
+ const businessDateRange = [startTime, endTime];
|
|
|
+ // 预约日期的周日期
|
|
|
+ const Monday = moment(
|
|
|
+ this.$refs.fullCalendar.getApi().currentData.dateProfile.activeRange
|
|
|
+ .start
|
|
|
+ ).format("YYYY-MM-DD");
|
|
|
+ // 根据当前预约日历的周获取周一
|
|
|
+ const Tuesday = moment(Monday).add(1, "days").format("YYYY-MM-DD"); // 周二日期
|
|
|
+
|
|
|
+ const Wednesday = moment(Monday).add(2, "days").format("YYYY-MM-DD"); // 周三日期
|
|
|
+ const Thursday = moment(Monday).add(3, "days").format("YYYY-MM-DD"); // 周四日期
|
|
|
+ const Friday = moment(Monday).add(4, "days").format("YYYY-MM-DD"); // 周五日期
|
|
|
+ const Saturday = moment(Monday).add(5, "days").format("YYYY-MM-DD"); // 周六日期
|
|
|
+ const Sunday = moment(Monday).add(6, "days").format("YYYY-MM-DD"); // 周日日期
|
|
|
+ const weeks = [
|
|
|
+ Monday,
|
|
|
+ Tuesday,
|
|
|
+ Wednesday,
|
|
|
+ Thursday,
|
|
|
+ Friday,
|
|
|
+ Saturday,
|
|
|
+ Sunday,
|
|
|
+ ];
|
|
|
+ if (weekType == "currentWeek") {
|
|
|
+ if (this.furtherLimit) {
|
|
|
+ businessHours = this.calcBusinessList(weeks, businessDateRange);
|
|
|
+ } else {
|
|
|
+ businessHours = [
|
|
|
+ {
|
|
|
+ daysOfWeek: pastDays,
|
|
|
+ startTime: "00:00",
|
|
|
+ endTime: "00:00",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ daysOfWeek: [currentDay],
|
|
|
+ startTime: this.getCurrentAppointDate().split(" ")[1],
|
|
|
+ endTime: "24:00",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ daysOfWeek: futureDays,
|
|
|
+ startTime: "00:00",
|
|
|
+ endTime: "24:00",
|
|
|
+ },
|
|
|
+ ];
|
|
|
+ console.log("businessHours", businessHours);
|
|
|
+ }
|
|
|
+ } else if (weekType == "pastWeek") {
|
|
|
+ businessHours = [
|
|
|
+ {
|
|
|
+ daysOfWeek: [1, 2, 3, 4, 5, 6, 0],
|
|
|
+ startTime: "00:00",
|
|
|
+ endTime: "00:00",
|
|
|
+ },
|
|
|
+ ];
|
|
|
+ } else if (weekType == "featureWeek") {
|
|
|
+ if (this.furtherLimit) {
|
|
|
+ businessHours = this.calcBusinessList(weeks, businessDateRange);
|
|
|
+ } else {
|
|
|
+ businessHours = [
|
|
|
+ {
|
|
|
+ daysOfWeek: [1, 2, 3, 4, 5, 6, 0],
|
|
|
+ startTime: "00:00",
|
|
|
+ endTime: "24:00",
|
|
|
+ },
|
|
|
+ ];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ let calendarApi = this.$refs["fullCalendar"].getApi();
|
|
|
+ let calendarFunc = calendarApi.view.calendar;
|
|
|
+ calendarFunc.setOption("businessHours", businessHours);
|
|
|
+ },
|
|
|
+ calcBusinessList(weeksRange, businessRange) {
|
|
|
+ const businessWorkList = [];
|
|
|
+ // 预约时间的开始日期是否在当前周
|
|
|
+ const businessStartInCurrentWeek = moment(
|
|
|
+ moment(businessRange[0]).format("YYYY-MM-DD")
|
|
|
+ ).isBetween(moment(weeksRange[0]), moment(weeksRange[6]), null, "[]");
|
|
|
+ // 预约时间的结束日期是否在当前周
|
|
|
+ const businessEndInCurrentWeek = moment(
|
|
|
+ moment(businessRange[1]).format("YYYY-MM-DD")
|
|
|
+ ).isBetween(moment(weeksRange[0]), moment(weeksRange[6]), null, "[]");
|
|
|
+ // 预约时间的结束日期和开始日期是否为同一天
|
|
|
+ const businesStartSameEnd =
|
|
|
+ moment(businessRange[0]).format("YYYY-MM-DD") ==
|
|
|
+ moment(businessRange[1]).format("YYYY-MM-DD");
|
|
|
+ // 可预约开始时间在当前周
|
|
|
+ if (businessStartInCurrentWeek) {
|
|
|
+ /**
|
|
|
+ * 如果可预约的开始时间在当前周
|
|
|
+ * 首先找出是在哪天
|
|
|
+ * 其次找出结束时间是否在当前周,如果不在开始时间之前全部置灰、之后的不置灰
|
|
|
+ */
|
|
|
+ // 可预约结束时间在当前周
|
|
|
+ if (businessEndInCurrentWeek) {
|
|
|
+ // 可预约结束时间和开始时间是同一天
|
|
|
+ if (businesStartSameEnd) {
|
|
|
+ let startIndex = 0;
|
|
|
+ weeksRange.map((item, index) => {
|
|
|
+ // 找出开始时间是当前周的哪一天
|
|
|
+ if (item == moment(businessRange[0]).format("YYYY-MM-DD")) {
|
|
|
+ startIndex = index;
|
|
|
+ businessWorkList.push(
|
|
|
+ // 开始之前
|
|
|
+ {
|
|
|
+ daysOfWeek: this.generateNumberArray(1, index),
|
|
|
+ startTime: "00:00",
|
|
|
+ endTime: "00:00",
|
|
|
+ },
|
|
|
+ // 开始当天
|
|
|
+ {
|
|
|
+ daysOfWeek: [index + 1],
|
|
|
+ startTime: this.getCurrentAppointDate().split(" ")[1],
|
|
|
+ endTime: moment(businessRange[1]).format("HH:mm"),
|
|
|
+ }
|
|
|
+ );
|
|
|
+ }
|
|
|
+ });
|
|
|
+ if (startIndex != 6) {
|
|
|
+ businessWorkList.push({
|
|
|
+ daysOfWeek: this.generateNumberArray(startIndex + 1, 7),
|
|
|
+ startTime: "00:00",
|
|
|
+ endTime: "00:00",
|
|
|
+ });
|
|
|
+ }
|
|
|
+ // END
|
|
|
+ } else {
|
|
|
+ // 可预约结束时间和开始时间不是同一天
|
|
|
+ let startIndex = 0;
|
|
|
+ let endIndex = 0;
|
|
|
+ weeksRange.map((item, index) => {
|
|
|
+ // 找出开始时间是当前周的哪一天
|
|
|
+ if (item == moment(businessRange[0]).format("YYYY-MM-DD")) {
|
|
|
+ startIndex = index;
|
|
|
+ businessWorkList.push(
|
|
|
+ // 开始之前
|
|
|
+ {
|
|
|
+ daysOfWeek: this.generateNumberArray(1, index),
|
|
|
+ startTime: "00:00",
|
|
|
+ endTime: "00:00",
|
|
|
+ },
|
|
|
+ // 开始当天
|
|
|
+ {
|
|
|
+ daysOfWeek: [index + 1],
|
|
|
+ startTime: this.getCurrentAppointDate().split(" ")[1],
|
|
|
+ endTime: "24:00",
|
|
|
+ }
|
|
|
+ );
|
|
|
+ }
|
|
|
+ });
|
|
|
+ weeksRange.map((item, index) => {
|
|
|
+ // 找出开始时间是当前周的哪一天
|
|
|
+ if (item == moment(businessRange[1]).format("YYYY-MM-DD")) {
|
|
|
+ endIndex = index;
|
|
|
+ businessWorkList.push(
|
|
|
+ {
|
|
|
+ daysOfWeek: this.generateRangeArray(
|
|
|
+ startIndex + 1,
|
|
|
+ endIndex + 1
|
|
|
+ ),
|
|
|
+ startTime: "00:00",
|
|
|
+ endTime: "24:00",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ daysOfWeek: [endIndex + 1],
|
|
|
+ startTime: "00:00",
|
|
|
+ endTime: moment(businessRange[1]).format("HH:mm"),
|
|
|
+ }
|
|
|
+ );
|
|
|
+ }
|
|
|
+ });
|
|
|
+ if (endIndex != 6) {
|
|
|
+ businessWorkList.push({
|
|
|
+ daysOfWeek: this.generateNumberArray(endIndex + 2, 7),
|
|
|
+ startTime: "00:00",
|
|
|
+ endTime: "00:00",
|
|
|
+ });
|
|
|
+ }
|
|
|
+ // END
|
|
|
+ }
|
|
|
+ // END
|
|
|
+ } else if (!businessEndInCurrentWeek) {
|
|
|
+ // 可预约结束时间不在当前周
|
|
|
+ let startIndex = 0;
|
|
|
+ weeksRange.map((item, index) => {
|
|
|
+ // 找出开始时间是当前周的哪一天
|
|
|
+ if (item == moment(businessRange[0]).format("YYYY-MM-DD")) {
|
|
|
+ startIndex = index + 1;
|
|
|
+ businessWorkList.push(
|
|
|
+ // 开始之前
|
|
|
+ {
|
|
|
+ daysOfWeek: this.generateNumberArray(1, index),
|
|
|
+ startTime: "00:00",
|
|
|
+ endTime: "00:00",
|
|
|
+ },
|
|
|
+ // 开始当天
|
|
|
+ {
|
|
|
+ daysOfWeek: [index + 1],
|
|
|
+ startTime: this.getCurrentAppointDate().split(" ")[1],
|
|
|
+ endTime: "24:00",
|
|
|
+ }
|
|
|
+ );
|
|
|
+ }
|
|
|
+ });
|
|
|
+ if (startIndex != 6) {
|
|
|
+ businessWorkList.push({
|
|
|
+ daysOfWeek: this.generateNumberArray(startIndex + 1, 7),
|
|
|
+ startTime: "00:00",
|
|
|
+ endTime: "24:00",
|
|
|
+ });
|
|
|
+ }
|
|
|
+ // END
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (businessEndInCurrentWeek) {
|
|
|
+ // 结束时间在当前周
|
|
|
+ let endIndex = 0;
|
|
|
+ weeksRange.map((item, index) => {
|
|
|
+ // 找出开始时间是当前周的哪一天
|
|
|
+ if (item == moment(businessRange[1]).format("YYYY-MM-DD")) {
|
|
|
+ endIndex = index + 1;
|
|
|
+ businessWorkList.push(
|
|
|
+ // 结束之前
|
|
|
+ {
|
|
|
+ daysOfWeek: this.generateNumberArray(1, index),
|
|
|
+ startTime: "00:00",
|
|
|
+ endTime: "24:00",
|
|
|
+ },
|
|
|
+ // 结束当天
|
|
|
+ {
|
|
|
+ daysOfWeek: [index + 1],
|
|
|
+ startTime: "00:00",
|
|
|
+ endTime: moment(businessRange[1]).format("HH:mm"),
|
|
|
+ }
|
|
|
+ );
|
|
|
+ }
|
|
|
+ });
|
|
|
+ if (endIndex != 6) {
|
|
|
+ businessWorkList.push({
|
|
|
+ daysOfWeek: this.generateNumberArray(endIndex + 1, 7),
|
|
|
+ startTime: "00:00",
|
|
|
+ endTime: "00:00",
|
|
|
+ });
|
|
|
+ }
|
|
|
+ // END
|
|
|
+ } else {
|
|
|
+ return [
|
|
|
+ {
|
|
|
+ daysOfWeek: [1, 2, 3, 4, 5, 6, 0],
|
|
|
+ startTime: "00:00",
|
|
|
+ endTime: "00:00",
|
|
|
+ },
|
|
|
+ ];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ const result = businessWorkList.filter(
|
|
|
+ (item) => item.daysOfWeek.length > 0
|
|
|
+ );
|
|
|
+ return result;
|
|
|
+ },
|
|
|
+ // 获取两个数字的区间数组
|
|
|
+ generateRangeArray(start, end) {
|
|
|
+ if (start > end) {
|
|
|
+ [start, end] = [end, start]; // 如果开始数字大于结束数字,交换它们的值
|
|
|
+ }
|
|
|
+
|
|
|
+ const result = [];
|
|
|
+ for (let i = start + 1; i < end; i++) {
|
|
|
+ result.push(i);
|
|
|
+ }
|
|
|
+ // 找到数字 7 的索引
|
|
|
+ const indexOfSeven = result.indexOf(7);
|
|
|
+ // 如果找到了数字 7 的索引,则替换为 0
|
|
|
+ if (indexOfSeven !== -1) {
|
|
|
+ result[indexOfSeven] = 0;
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ },
|
|
|
+ // 获取两个数字数组包括本身
|
|
|
+ generateNumberArray(start, end) {
|
|
|
+ const result = [];
|
|
|
+ for (let i = start; i <= end; i++) {
|
|
|
+ result.push(i);
|
|
|
+ }
|
|
|
+ // 找到数字 7 的索引
|
|
|
+ const indexOfSeven = result.indexOf(7);
|
|
|
+
|
|
|
+ // 如果找到了数字 7 的索引,则替换为 0
|
|
|
+ if (indexOfSeven !== -1) {
|
|
|
+ result[indexOfSeven] = 0;
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ },
|
|
|
+ // 获取最近可预约时间段
|
|
|
+ getCurrentAppointDate() {
|
|
|
+ const interval = this.split_time; // 时间间隔(单位:分钟)
|
|
|
+ const now = moment(); // 当前时间
|
|
|
+
|
|
|
+ // 将当前时间向上取整到最近的 interval 的倍数
|
|
|
+ const roundedNow = moment(
|
|
|
+ Math.ceil(now.valueOf() / (interval * 60 * 1000)) *
|
|
|
+ interval *
|
|
|
+ 60 *
|
|
|
+ 1000
|
|
|
+ );
|
|
|
+
|
|
|
+ // 如果当前时间已经超过了最近可预约时间,则将最近可预约时间增加一个 interval 的时间间隔
|
|
|
+ if (now.isAfter(roundedNow)) {
|
|
|
+ roundedNow.add(interval, "minutes");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 将最近可预约时间格式化为 HH:mm:ss 格式
|
|
|
+ const nearestAvailableTime = roundedNow.format("YYYY-MM-DD HH:mm");
|
|
|
+ return nearestAvailableTime;
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 设置工作时间相关代码 END
|
|
|
+ * */
|
|
|
+ // 更新预约内容视图
|
|
|
+ initBoard(datas) {
|
|
|
+ let data = datas;
|
|
|
+ if (!data) return;
|
|
|
+ let newD = data.map((item, index) => {
|
|
|
+ //根据返回的status判断当前是待审核 已预约的颜色
|
|
|
+ return {
|
|
|
+ id: index,
|
|
|
+ start: item.id ? item.startTime : item.start,
|
|
|
+ end: item.id ? item.endTime : item.end,
|
|
|
+ color:
|
|
|
+ item.appointStatus == "20"
|
|
|
+ ? "skyblue"
|
|
|
+ : !item.appointStatus
|
|
|
+ ? "#ccc"
|
|
|
+ : "",
|
|
|
+ projectName: item.projectName || "",
|
|
|
+ serviceName: item.serviceName || "",
|
|
|
+ tel: item.userContact || "",
|
|
|
+ appointStatus: item.appointStatus || 999,
|
|
|
+ userName: item.userName || "",
|
|
|
+ };
|
|
|
+ });
|
|
|
+ this.pushData(newD);
|
|
|
+ },
|
|
|
+ // 数据填充到日历
|
|
|
+ pushData(newD) {
|
|
|
+ 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();
|
|
|
+ });
|
|
|
+ }
|
|
|
+ newD.map((item) => {
|
|
|
+ calendarFunc.addEvent(item); //数据填充到日历看板中
|
|
|
+ });
|
|
|
+ // this.$nextTick(() => {
|
|
|
+ // document.querySelector('.fc-scroller-liquid-absolute').scrollTop = 0;
|
|
|
+ // });
|
|
|
+ },
|
|
|
+ showTitlt(event) {
|
|
|
+ let str = `预约时间: ${
|
|
|
+ this.parseTime(event.start, "{m}月{d}日") ==
|
|
|
+ this.parseTime(event.end, "{m}月{d}日")
|
|
|
+ ? this.parseTime(event.start, "{h}:{i}")
|
|
|
+ : this.parseTime(event.start, "{m}月{d}日 {h}:{i}")
|
|
|
+ }-${
|
|
|
+ this.parseTime(event.end, "{m}月{d}日") ==
|
|
|
+ this.parseTime(event.start, "{m}月{d}日")
|
|
|
+ ? this.parseTime(event.end, "{h}:{i}")
|
|
|
+ : this.parseTime(event.end, "{m}月{d}日 {h}:{i}")
|
|
|
+ }`;
|
|
|
+ if (
|
|
|
+ event.extendedProps.appointStatus &&
|
|
|
+ event.extendedProps.appointStatus != 999
|
|
|
+ ) {
|
|
|
+ str += `\n课题组/服务: ${
|
|
|
+ event.extendedProps.projectName || event.extendedProps.serviceName
|
|
|
+ }\n预约人: ${event.extendedProps.userName}\n联系电话: ${
|
|
|
+ event.extendedProps.tel
|
|
|
+ }`;
|
|
|
+ }
|
|
|
+ return str;
|
|
|
+ },
|
|
|
+ //判断是否显示全部内容
|
|
|
+ showAllInfo(ev, cnt) {
|
|
|
+ var start = new Date(ev.start);
|
|
|
+ var end = new Date(ev.end);
|
|
|
+ var minutesDiff = (end - start) / (1000 * 60); // 计算分钟差
|
|
|
+ var intervals = Math.floor(minutesDiff / this.split_time); // 计算间隔数量
|
|
|
+ if (cnt <= intervals) {
|
|
|
+ return true;
|
|
|
+ } else {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 日期格式化
|
|
|
+ parseTime(time, pattern) {
|
|
|
+ if (arguments.length === 0 || !time) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ const format = pattern || "{y}-{m}-{d} {h}:{i}:{s}";
|
|
|
+ let date;
|
|
|
+ if (typeof time === "object") {
|
|
|
+ date = time;
|
|
|
+ } else {
|
|
|
+ if (typeof time === "string" && /^[0-9]+$/.test(time)) {
|
|
|
+ time = parseInt(time);
|
|
|
+ } else if (typeof time === "string") {
|
|
|
+ time = time.replace(new RegExp(/-/gm), "/");
|
|
|
+ }
|
|
|
+ if (typeof time === "number" && time.toString().length === 10) {
|
|
|
+ time = time * 1000;
|
|
|
+ }
|
|
|
+ date = new Date(time);
|
|
|
+ }
|
|
|
+ const formatObj = {
|
|
|
+ y: date.getFullYear(),
|
|
|
+ m: date.getMonth() + 1,
|
|
|
+ d: date.getDate(),
|
|
|
+ h: date.getHours(),
|
|
|
+ i: date.getMinutes(),
|
|
|
+ s: date.getSeconds(),
|
|
|
+ a: date.getDay(),
|
|
|
+ };
|
|
|
+ const time_str = format.replace(
|
|
|
+ /{(y|m|d|h|i|s|a)+}/g,
|
|
|
+ (result, key) => {
|
|
|
+ let value = formatObj[key];
|
|
|
+ // Note: getDay() returns 0 on Sunday
|
|
|
+ if (key === "a") {
|
|
|
+ return ["日", "一", "二", "三", "四", "五", "六"][value];
|
|
|
+ }
|
|
|
+ if (result.length > 0 && value < 10) {
|
|
|
+ value = "0" + value;
|
|
|
+ }
|
|
|
+ return value || 0;
|
|
|
+ }
|
|
|
+ );
|
|
|
+ return time_str;
|
|
|
+ },
|
|
|
+ // 当选择结束的时候获取开始和结束时间
|
|
|
+ handleDateSelect(info) {
|
|
|
+ this.form.startTime = moment(info.startStr).format(
|
|
|
+ "YYYY-MM-DD HH:mm:ss"
|
|
|
+ );
|
|
|
+ this.form.endTime = moment(info.endStr).format("YYYY-MM-DD HH:mm:ss");
|
|
|
+ },
|
|
|
+ // 关闭
|
|
|
+ dialogClose() {
|
|
|
+ this.visible = false;
|
|
|
+ this.form = { startTime: "", endTime: "", instId: 0, instName: "" };
|
|
|
+ this.show = false;
|
|
|
+ },
|
|
|
+ // 预约下一步
|
|
|
+ nextStep() {
|
|
|
+ this.$refs.appointCreateRef.openDialog(this.form);
|
|
|
+ },
|
|
|
+ },
|
|
|
+ };
|
|
|
+</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-event-main) {
|
|
|
+ overflow: hidden;
|
|
|
+ }
|
|
|
+ .appoint-details {
|
|
|
+ margin-left: 10px;
|
|
|
+ margin-bottom: 3px;
|
|
|
+ line-height: 2em;
|
|
|
+ }
|
|
|
+ :deep(.el-dialog__body) {
|
|
|
+ padding-top: 10px;
|
|
|
+ }
|
|
|
+</style>
|