| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365 | import { Button, Calendar, Dialog, Icon, Image, Popup, Tag, Toast } from 'vant'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 isToday from 'dayjs/plugin/isToday'dayjs.extend(isToday)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: dayjs().add(1, 'day').toDate(), // 当前日历日期      subtitle: '',      show: false,      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")    // for(const key in this.list) {    //   console.log(key, this.list[key])    //   let dataList = [] as any    //   if (this.list[key] && Array.isArray(this.list[key].courseTime)) {    //     dataList = [...this.list[key].courseTime].filter(n =>    //       dayjs().isBefore(dayjs(n.startTime))    //     )    //   }    //   this.list[key].courseTime = dataList    // }    // 初始化日历    // 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]      // 格式化选择的时间      let courseTime = [] as any      if (dateObj && Array.isArray(dateObj.courseTime)) {        courseTime = [...dateObj.courseTime].filter(n =>          dayjs().isBefore(dayjs(n.startTime))        )      }      date.type = ''      // 判断是否有课程 并且 时间在当前时间之后      if (dateObj && dayjs().subtract(1, 'day').isBefore(dayjs(date.date))) {        // fullCourse当天是否排满 0: 未,1:满 , courseTime 当天没有课程        if (          dateObj.fullCourse ||          !courseTime ||          courseTime?.length <= 0        ) {          date.bottomInfo = '满'          date.className = 'full'          date.type = 'disabled'        }      } else {        date.type = 'disabled'      }      // console.log(date)      if((this.$route.name == 'liveCreate' || this.$route.name == 'groupCreate') && dayjs(date.date).isToday()) {        date.type = 'disabled'      }      // 是否是节假日      if (dateObj && this.isSkipHolidays && dateObj.holiday) {        // date.bottomInfo = '节假日'        date.type = 'disabled'      }      // date.type = date.type === 'selected' ? 'selected' : date.type      // console.log(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 {        Toast('最多选择' + 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) {      // 选择日历上某一个日期      // console.log([...this.selectList])      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 = [] as any      if (this.list[dateStr] && Array.isArray(this.list[dateStr].courseTime)) {        dataList = [...this.list[dateStr].courseTime].filter(n =>          dayjs().isBefore(dayjs(n.startTime))        )      }      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 (      <>        <Calendar          class={styles.calendar}          showTitle={false}          poppable={false}          showConfirm={false}          showMark={false}          firstDayOfWeek={1}          rowHeight={56}          minDate={this.minDate}          maxDate={this.maxDate}          color="var(--van-primary)"          formatter={this.formatter}          onSelect={this.onDateSelect}          v-slots={{            subtitle: () => (              <div class={styles.subtitle}>                <Icon                  name={IconArrow}                  size={22}                  class={this.arrowStatus && styles.disabled}                  onClick={this.onPrevMonth}                />                <span>{this.subtitle}</span>                <Icon                  name={IconArrow}                  size={22}                  class={styles.right}                  onClick={this.onNextMonth}                />              </div>            )            // 'bottom-info': (date: any) => <span>{date.type}</span>          }}        />        <Popup show={this.show} class={styles.calenderPopup}>          <div class={styles.popup}>            <div class={styles.title}>              {/* <Button                type="primary"                plain                style={{ border: 0 }}                size="small"                disabled={this.isPrevDay}                onClick={this.onPrevDay}              >                上一日              </Button> */}              <span>{this.selectDayTitle}</span>              {/* <Button                type="primary"                plain                style={{ border: 0 }}                size="small"                disabled={this.isNextDay}                onClick={this.onNextDay}              >                下一日              </Button> */}            </div>            <div class={styles.container}>              {this.dayList.map((item: any) => (                <div>                  <Tag                    round                    class={[styles.tag, item.checked ? styles.active : '']}                    size="large"                    plain                    onClick={() => this.onSelectDay(item)}                  >                    {item.start}~{item.end}                  </Tag>                </div>              ))}              {this.dayList.length <= 0 && (                <div class={styles.noDay}>                  <Image src={IconClock} class={styles.clock} fit="cover" />                  <span>今日已约满</span>                </div>              )}            </div>            <div class={styles.dayBtn}>              <Button                round                plain                block                style={{ marginRight: '10px' }}                onClick={() => {                  this.show = false                  this.selectDays = []                }}              >                取消              </Button>              <Button                type="primary"                block                round                disabled={!(this.selectDays.length > 0)}                onClick={() => {                  this.selectDay && this.selectDay(this.selectDays)                  this.show = false                }}              >                确认              </Button>            </div>          </div>        </Popup>      </>    )  }})
 |