|
@@ -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>
|
|
|
+ )
|
|
|
+ }
|
|
|
+})
|