|
@@ -1,12 +1,28 @@
|
|
-import { Calendar, Icon } from 'vant'
|
|
|
|
|
|
+import { Button, Calendar, Icon, Image, Popup, Tag, Toast } from 'vant'
|
|
import { defineComponent } from 'vue'
|
|
import { defineComponent } from 'vue'
|
|
import dayjs from 'dayjs'
|
|
import dayjs from 'dayjs'
|
|
import styles from './index.module.less'
|
|
import styles from './index.module.less'
|
|
import IconArrow from '@/common/images/icon_arrow.png'
|
|
import IconArrow from '@/common/images/icon_arrow.png'
|
|
|
|
+import IconClock from '@/common/images/icon_clock.png'
|
|
|
|
|
|
export default defineComponent({
|
|
export default defineComponent({
|
|
name: 'calendar',
|
|
name: 'calendar',
|
|
props: {
|
|
props: {
|
|
|
|
+ selectList: {
|
|
|
|
+ type: Array,
|
|
|
|
+ default: []
|
|
|
|
+ },
|
|
|
|
+ list: {
|
|
|
|
+ type: Object,
|
|
|
|
+ default: {}
|
|
|
|
+ },
|
|
|
|
+ /**
|
|
|
|
+ * 每天选择课程最大数
|
|
|
|
+ */
|
|
|
|
+ maxDays: {
|
|
|
|
+ type: [Number, String],
|
|
|
|
+ default: 0
|
|
|
|
+ },
|
|
/**
|
|
/**
|
|
* 点击并选中任意日期时触发
|
|
* 点击并选中任意日期时触发
|
|
*/
|
|
*/
|
|
@@ -27,6 +43,10 @@ export default defineComponent({
|
|
nextMonth: {
|
|
nextMonth: {
|
|
type: Function,
|
|
type: Function,
|
|
default: (date: Date) => {}
|
|
default: (date: Date) => {}
|
|
|
|
+ },
|
|
|
|
+ selectDay: {
|
|
|
|
+ type: Function,
|
|
|
|
+ default: (obj: any) => {}
|
|
}
|
|
}
|
|
},
|
|
},
|
|
data() {
|
|
data() {
|
|
@@ -34,49 +54,126 @@ export default defineComponent({
|
|
minDate: new Date(),
|
|
minDate: new Date(),
|
|
maxDate: new Date(),
|
|
maxDate: new Date(),
|
|
currentDate: new Date(), // 当前日历日期
|
|
currentDate: new Date(), // 当前日历日期
|
|
- subtitle: ''
|
|
|
|
|
|
+ subtitle: '',
|
|
|
|
+ show: false,
|
|
|
|
+ dayList: [],
|
|
|
|
+ selectDays: [] as any
|
|
}
|
|
}
|
|
},
|
|
},
|
|
computed: {
|
|
computed: {
|
|
arrowStatus() {
|
|
arrowStatus() {
|
|
// 上月箭头状态
|
|
// 上月箭头状态
|
|
- // console.log(dayjs().subtract(1, 'date').format('YYYY年MM月DD日'))
|
|
|
|
- // console.log(dayjs().isBefore(dayjs(this.currentDate), 'month'))
|
|
|
|
return !dayjs().isBefore(dayjs(this.currentDate), 'month')
|
|
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() {
|
|
mounted() {
|
|
// 初始化标题和最大显示日期
|
|
// 初始化标题和最大显示日期
|
|
this.subtitle = dayjs().format('YYYY年MM月')
|
|
this.subtitle = dayjs().format('YYYY年MM月')
|
|
- this.maxDate = new Date(dayjs().endOf('month').toDate())
|
|
|
|
|
|
+ this.maxDate = dayjs().endOf('month').toDate()
|
|
|
|
+ this.minDate = dayjs().add(1, 'day').toDate()
|
|
|
|
+
|
|
|
|
+ // 初始化日历
|
|
|
|
+ // console.log(this.list, 323, this.maxDays)
|
|
},
|
|
},
|
|
methods: {
|
|
methods: {
|
|
formatter(date: any) {
|
|
formatter(date: any) {
|
|
- // console.log(date)
|
|
|
|
- // date.bottomInfo = '满'
|
|
|
|
- // date.className = 'full'
|
|
|
|
|
|
+ const dateStr = dayjs(date.date).format('YYYY-MM-DD')
|
|
|
|
+ const dateObj = this.list[dateStr]
|
|
|
|
+ if (dateObj && dateObj.fullCourse) {
|
|
|
|
+ date.bottomInfo = '满'
|
|
|
|
+ date.className = 'full'
|
|
|
|
+ }
|
|
|
|
+ date.type = date.type === 'selected' ? '' : date.type
|
|
return date
|
|
return date
|
|
},
|
|
},
|
|
- onDateSelect(date: any) {
|
|
|
|
- console.log(date)
|
|
|
|
- this.onSelect && this.onSelect(date)
|
|
|
|
- },
|
|
|
|
onPrevMonth() {
|
|
onPrevMonth() {
|
|
|
|
+ // 上一月
|
|
if (this.arrowStatus) return
|
|
if (this.arrowStatus) return
|
|
const tempDate = dayjs(this.currentDate).subtract(1, 'month')
|
|
const tempDate = dayjs(this.currentDate).subtract(1, 'month')
|
|
this._monthChange(tempDate)
|
|
this._monthChange(tempDate)
|
|
- this.prevMonth && this.prevMonth(tempDate.toDate())
|
|
|
|
|
|
+ this.prevMonth && this.prevMonth(this.minDate)
|
|
},
|
|
},
|
|
onNextMonth() {
|
|
onNextMonth() {
|
|
|
|
+ // 下一月
|
|
const tempDate = dayjs(this.currentDate).add(1, 'month')
|
|
const tempDate = dayjs(this.currentDate).add(1, 'month')
|
|
this._monthChange(tempDate)
|
|
this._monthChange(tempDate)
|
|
- this.nextMonth && this.nextMonth(tempDate.toDate())
|
|
|
|
|
|
+ this.nextMonth && this.nextMonth(this.minDate)
|
|
},
|
|
},
|
|
_monthChange(date: any) {
|
|
_monthChange(date: any) {
|
|
- this.minDate = date.startOf('month').toDate()
|
|
|
|
|
|
+ // 月份改变
|
|
|
|
+ // 需要判断是否是当月,需要单独处理最小时间
|
|
|
|
+ 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.maxDate = date.endOf('month').toDate()
|
|
this.currentDate = date.toDate()
|
|
this.currentDate = date.toDate()
|
|
this.subtitle = date.format('YYYY年MM月')
|
|
this.subtitle = date.format('YYYY年MM月')
|
|
|
|
+ },
|
|
|
|
+ onSelectDay(item: any) {
|
|
|
|
+ // 选择某个时间段
|
|
|
|
+ if (this.selectDays.length < this.maxDays) {
|
|
|
|
+ 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) {
|
|
|
|
+ // 选择日历上某一个日期
|
|
|
|
+ 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.selectList?.some(
|
|
|
|
+ (course: any) => course.startTime === item.startTime
|
|
|
|
+ )
|
|
|
|
+ item.checked = isExist
|
|
|
|
+ })
|
|
|
|
+ this.dayList = dataList
|
|
|
|
+ this.currentDate = date // 更新当前日期
|
|
|
|
+ this.show = true
|
|
}
|
|
}
|
|
},
|
|
},
|
|
render() {
|
|
render() {
|
|
@@ -89,7 +186,7 @@ export default defineComponent({
|
|
showConfirm={false}
|
|
showConfirm={false}
|
|
showMark={false}
|
|
showMark={false}
|
|
firstDayOfWeek={1}
|
|
firstDayOfWeek={1}
|
|
- rowHeight={50}
|
|
|
|
|
|
+ rowHeight={60}
|
|
minDate={this.minDate}
|
|
minDate={this.minDate}
|
|
maxDate={this.maxDate}
|
|
maxDate={this.maxDate}
|
|
color="var(--van-primary)"
|
|
color="var(--van-primary)"
|
|
@@ -116,6 +213,82 @@ export default defineComponent({
|
|
// 'bottom-info': (date: any) => <span>{date.type}</span>
|
|
// '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
|
|
|
|
+ style={{ width: '33.33%', 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>
|
|
</>
|
|
</>
|
|
)
|
|
)
|
|
}
|
|
}
|