|  | @@ -0,0 +1,192 @@
 | 
	
		
			
				|  |  | +import { Button, Calendar, Dialog, Icon, Image, Popup, showToast, Tag, Toast } from 'vant'
 | 
	
		
			
				|  |  | +import { defineComponent } from 'vue'
 | 
	
		
			
				|  |  | +import dayjs from 'dayjs'
 | 
	
		
			
				|  |  | +import styles from './index.module.less'
 | 
	
		
			
				|  |  | +import IconArrow from '../../images/icon_arrow.png'
 | 
	
		
			
				|  |  | +import IconArrowDefault from '../../images/icon_arrow_default.png'
 | 
	
		
			
				|  |  | +import isToday from 'dayjs/plugin/isToday'
 | 
	
		
			
				|  |  | +import OHeader from '@/components/o-header'
 | 
	
		
			
				|  |  | +dayjs.extend(isToday)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +export default defineComponent({
 | 
	
		
			
				|  |  | +  name: 'calendar',
 | 
	
		
			
				|  |  | +  props: {
 | 
	
		
			
				|  |  | +    calendarDate: {
 | 
	
		
			
				|  |  | +      type: String,
 | 
	
		
			
				|  |  | +      default: ''
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  | +    // 接口数据
 | 
	
		
			
				|  |  | +    list: {
 | 
	
		
			
				|  |  | +      type: Array,
 | 
	
		
			
				|  |  | +      default: () => []
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  | +    /**
 | 
	
		
			
				|  |  | +     * 点击并选中任意日期时触发
 | 
	
		
			
				|  |  | +     */
 | 
	
		
			
				|  |  | +    onSelect: {
 | 
	
		
			
				|  |  | +      type: Function,
 | 
	
		
			
				|  |  | +      default: (date: Date) => {}
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  | +    /**
 | 
	
		
			
				|  |  | +     * 上一月,不能小于当月
 | 
	
		
			
				|  |  | +     */
 | 
	
		
			
				|  |  | +    prevMonth: {
 | 
	
		
			
				|  |  | +      type: Function,
 | 
	
		
			
				|  |  | +      default: (date: Date) => {}
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  | +    /**
 | 
	
		
			
				|  |  | +     * 下一月,暂无限制
 | 
	
		
			
				|  |  | +     */
 | 
	
		
			
				|  |  | +    nextMonth: {
 | 
	
		
			
				|  |  | +      type: Function,
 | 
	
		
			
				|  |  | +      default: (date: Date) => {}
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  | +    /**
 | 
	
		
			
				|  |  | +     * 日期选择结束时触发
 | 
	
		
			
				|  |  | +     */
 | 
	
		
			
				|  |  | +    selectDay: {
 | 
	
		
			
				|  |  | +      type: Function,
 | 
	
		
			
				|  |  | +      default: (obj: any) => {}
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  },
 | 
	
		
			
				|  |  | +  data() {
 | 
	
		
			
				|  |  | +    return {
 | 
	
		
			
				|  |  | +      minDate: new Date(),
 | 
	
		
			
				|  |  | +      maxDate: new Date(),
 | 
	
		
			
				|  |  | +      currentDate: dayjs().add(1, 'day').toDate(), // 当前日历日期
 | 
	
		
			
				|  |  | +      subtitle: '',
 | 
	
		
			
				|  |  | +      dayList: [],
 | 
	
		
			
				|  |  | +      selectDays: [] as any
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  },
 | 
	
		
			
				|  |  | +  computed: {
 | 
	
		
			
				|  |  | +    arrowStatus() {
 | 
	
		
			
				|  |  | +      // 上月箭头状态
 | 
	
		
			
				|  |  | +      return !dayjs().add(1, 'day').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().add(1, 'day').format('YYYY年MM月')
 | 
	
		
			
				|  |  | +    this.maxDate = dayjs().add(1, 'day').endOf('month').toDate()
 | 
	
		
			
				|  |  | +    this.minDate = dayjs().add(1, 'day').toDate()
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    console.log(this.list, 'this.list')
 | 
	
		
			
				|  |  | +  },
 | 
	
		
			
				|  |  | +  methods: {
 | 
	
		
			
				|  |  | +    formatter(date: any) {
 | 
	
		
			
				|  |  | +      const dateStr = dayjs(date.date).format('YYYY-MM-DD')
 | 
	
		
			
				|  |  | +      let isActive = false // 是否可选
 | 
	
		
			
				|  |  | +      this.list.forEach((item: any) => {
 | 
	
		
			
				|  |  | +        if (item.calendarDate === dateStr) {
 | 
	
		
			
				|  |  | +          isActive = true
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +      })
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      // 判断是否有课程 并且 时间在当前时间之后
 | 
	
		
			
				|  |  | +      if (isActive && dayjs().isBefore(dayjs(date.date))) {
 | 
	
		
			
				|  |  | +        date.bottomInfo = '可选'
 | 
	
		
			
				|  |  | +        if (dayjs(dateStr).isSame(this.calendarDate)) {
 | 
	
		
			
				|  |  | +          date.type = 'selected'
 | 
	
		
			
				|  |  | +        } else {
 | 
	
		
			
				|  |  | +          date.type = ''
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +      } else {
 | 
	
		
			
				|  |  | +        date.type = 'disabled'
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +      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.maxDate = date.endOf('month').toDate()
 | 
	
		
			
				|  |  | +      this.currentDate = date.toDate()
 | 
	
		
			
				|  |  | +      this.$emit('update:calendarDate', date.toDate())
 | 
	
		
			
				|  |  | +      this.subtitle = date.format('YYYY年MM月')
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  | +    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._dayChange(date)
 | 
	
		
			
				|  |  | +      this.onSelect && this.onSelect(date)
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  | +    _dayChange(date: Date) {
 | 
	
		
			
				|  |  | +      this.currentDate = date // 更新当前日期
 | 
	
		
			
				|  |  | +      this.$emit('update:calendarDate', dayjs(date).format('YYYY-MM-DD'))
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  },
 | 
	
		
			
				|  |  | +  render() {
 | 
	
		
			
				|  |  | +    return (
 | 
	
		
			
				|  |  | +      <div class={styles.calendarContainer}>
 | 
	
		
			
				|  |  | +        <OHeader title="训练日期" border={false} background="transparent" />
 | 
	
		
			
				|  |  | +        <Calendar
 | 
	
		
			
				|  |  | +          class={styles.calendar}
 | 
	
		
			
				|  |  | +          showTitle={false}
 | 
	
		
			
				|  |  | +          poppable={false}
 | 
	
		
			
				|  |  | +          showConfirm={false}
 | 
	
		
			
				|  |  | +          showMark={false}
 | 
	
		
			
				|  |  | +          firstDayOfWeek={1}
 | 
	
		
			
				|  |  | +          rowHeight={62}
 | 
	
		
			
				|  |  | +          minDate={this.minDate}
 | 
	
		
			
				|  |  | +          maxDate={this.maxDate}
 | 
	
		
			
				|  |  | +          color="var(--van-primary)"
 | 
	
		
			
				|  |  | +          formatter={this.formatter}
 | 
	
		
			
				|  |  | +          onSelect={this.onDateSelect}
 | 
	
		
			
				|  |  | +          v-slots={{
 | 
	
		
			
				|  |  | +            subtitle: () => (
 | 
	
		
			
				|  |  | +              <div class={styles.subtitle}>
 | 
	
		
			
				|  |  | +                <span>{this.subtitle}</span>
 | 
	
		
			
				|  |  | +                <div>
 | 
	
		
			
				|  |  | +                  <Icon
 | 
	
		
			
				|  |  | +                    name={this.arrowStatus ? IconArrowDefault : IconArrow}
 | 
	
		
			
				|  |  | +                    size={22}
 | 
	
		
			
				|  |  | +                    class={[styles.right]}
 | 
	
		
			
				|  |  | +                    onClick={this.onPrevMonth}
 | 
	
		
			
				|  |  | +                  />
 | 
	
		
			
				|  |  | +                  <Icon name={IconArrow} size={22} onClick={this.onNextMonth} />
 | 
	
		
			
				|  |  | +                </div>
 | 
	
		
			
				|  |  | +              </div>
 | 
	
		
			
				|  |  | +            )
 | 
	
		
			
				|  |  | +          }}
 | 
	
		
			
				|  |  | +        />
 | 
	
		
			
				|  |  | +      </div>
 | 
	
		
			
				|  |  | +    )
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +})
 |