import { Button, Calendar, Icon, Image, Popup, Tag } from 'vant' import 'vant/es/calendar/style' import { defineComponent } from 'vue' import dayjs from 'dayjs' import styles from './index.module.less' import IconArrow from '@/common/images/icon_arrow.png' import IconClock from '@/common/images/icon_clock.png' import { ElButton, ElDialog, ElMessage } from 'element-plus' export default defineComponent({ name: 'calendar', props: { calendarDate: { type: Date, default: () => new Date() }, // 选中的数据 selectList: { type: Array, default: [] }, // 接口数据 list: { type: Object, default: {} }, /** * 每天选择课程最大数 */ maxDays: { type: [Number, String], default: 0 }, /** * 点击并选中任意日期时触发 */ onSelect: { type: Function, default: (date: Date) => {} }, /** * 上一月,不能小于当月 */ prevMonth: { type: Function, default: (date: Date) => {} }, /** * 下一月,暂无限制 */ nextMonth: { type: Function, default: (date: Date) => {} }, /** * 日期选择结束时触发 */ selectDay: { type: Function, default: (obj: any) => {} }, isSkipHolidays: { // 是否跳过节假日 type: Boolean, default: false } }, data() { return { minDate: new Date(), maxDate: new Date(), currentDate: new Date(), // 当前日历日期 subtitle: '', show: false, dayList: [], selectDays: [] as any } }, computed: { arrowStatus() { // 上月箭头状态 return !dayjs().isBefore(dayjs(this.currentDate), 'month') }, selectDayTitle() { // 选中日期标题 return dayjs(this.currentDate).format('YYYY-MM-DD') }, isPrevDay() { // 是否可以点击上一天 return dayjs(this.currentDate) .subtract(1, 'day') .isBefore(dayjs(this.minDate), 'day') }, isNextDay() { // 是否可以点击下一天 return dayjs(this.currentDate) .add(1, 'day') .isAfter(dayjs(this.maxDate), 'day') } }, mounted() { // 初始化标题和最大显示日期 this.subtitle = dayjs().format('YYYY年MM月') this.maxDate = dayjs().endOf('month').toDate() this.minDate = dayjs().add(1, 'day').toDate() // 初始化日历 // console.log(this.list, 323, this.maxDays) }, methods: { formatter(date: any) { const dateStr = dayjs(date.date).format('YYYY-MM-DD') const dateObj = this.list[dateStr] // 判断是否有课程 并且 时间在当前时间之后 if (dateObj && dayjs().isBefore(dayjs(date.date))) { if ( dateObj && (dateObj.fullCourse || !dateObj?.courseTime || dateObj?.courseTime?.length <= 0) ) { date.bottomInfo = '满' date.className = 'full' date.type = 'disabled' } } else { date.type = 'disabled' } if (dateObj && this.isSkipHolidays && dateObj.holiday) { // date.bottomInfo = '节假日' date.type = 'disabled' } date.type = date.type === 'selected' ? '' : date.type return date }, onPrevMonth() { // 上一月 if (this.arrowStatus) return const tempDate = dayjs(this.currentDate).subtract(1, 'month') this._monthChange(tempDate) this.prevMonth && this.prevMonth(this.minDate) }, onNextMonth() { // 下一月 const tempDate = dayjs(this.currentDate).add(1, 'month') this._monthChange(tempDate) this.nextMonth && this.nextMonth(this.minDate) }, _monthChange(date: any) { // 月份改变 // 需要判断是否是当月,需要单独处理最小时间 const currentMinDate = dayjs().add(1, 'day').toDate() const monthMinDate = date.startOf('month').toDate() this.minDate = dayjs(currentMinDate).isAfter(monthMinDate) ? currentMinDate : monthMinDate // this.minDate = date.startOf('month').toDate() this.maxDate = date.endOf('month').toDate() this.currentDate = date.toDate() this.$emit('update:calendarDate', date.toDate()) this.subtitle = date.format('YYYY年MM月') }, onSelectDay(item: any) { // 选择某个时间段 const index = this.selectDays.findIndex((days: any) => { return days.startTime === item.startTime }) if (this.selectDays.length < this.maxDays || index !== -1) { const index = this.selectDays.findIndex( (days: any) => days.startTime === item.startTime ) item.checked = !item.checked if (index === -1) { this.selectDays.push({ ...item }) } else { this.selectDays.splice(index, 1) } } else { ElMessage.info('最多选择' + this.maxDays + '个时间段') } }, onPrevDay() { // 获取上一天的数据 const tempDate = dayjs(this.currentDate).subtract(1, 'day') this._dayChange(tempDate.toDate()) }, onNextDay() { // 获取下一天的数据 const tempDate = dayjs(this.currentDate).add(1, 'day') this._dayChange(tempDate.toDate()) }, onDateSelect(date: any) { // 选择日历上某一个日期 this.selectDays = [...this.selectList] // 初始化用户选中的值 this._dayChange(date) this.onSelect && this.onSelect(date) }, _dayChange(date: Date) { const dateStr = dayjs(date).format('YYYY-MM-DD') let dataList = (this.list[dateStr] && this.list[dateStr].courseTime) || [] dataList.forEach((item: any) => { item.start = dayjs(item.startTime).format('HH:mm') item.end = dayjs(item.endTime).format('HH:mm') const isExist = this.selectDays?.some( (course: any) => course.startTime === item.startTime ) item.checked = isExist }) this.dayList = dataList this.currentDate = date // 更新当前日期 this.$emit('update:calendarDate', date) this.show = true } }, render() { return ( <> (
{this.subtitle}
) // 'bottom-info': (date: any) => {date.type} }} /> (this.show = e)} class={styles.calenderPopup} >
{this.selectDayTitle}
{this.dayList.map((item: any) => (
this.onSelectDay(item)} > {item.start}~{item.end}
))} {this.dayList.length <= 0 && (
今日已约满
)}
{ this.show = false this.selectDays = [] }} > 取消 0)} onClick={() => { this.selectDay && this.selectDay(this.selectDays) this.show = false }} > 确认
{/*
{this.selectDayTitle}
{this.dayList.map((item: any) => (
this.onSelectDay(item)} > {item.start}~{item.end}
))} {this.dayList.length <= 0 && (
今日已约满
)}
*/} ) } })