186 lines
5.0 KiB
Vue
186 lines
5.0 KiB
Vue
<template>
|
|
<view class="calendar-wrapper">
|
|
<u-calendar
|
|
ref="ucalendar"
|
|
:show="show"
|
|
:mode="'range'"
|
|
:maxRange="999"
|
|
:defaultDate="defaultDate"
|
|
:minDate="minDate"
|
|
color="#C52733"
|
|
@confirm="handleDateChange"
|
|
@close="hideCalendar"
|
|
:monthNum="1"
|
|
>
|
|
<view slot="tooltip" class="calendar-tooltip">
|
|
{{ tooltipText }}
|
|
</view>
|
|
</u-calendar>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
export default {
|
|
name: 'Calendar',
|
|
props: {
|
|
minDay: {
|
|
type: Number,
|
|
default: 1
|
|
}
|
|
},
|
|
data() {
|
|
return {
|
|
show: false,
|
|
defaultDate: null,
|
|
minDate: new Date().getTime(),
|
|
disabledDates: [], // 存储禁用日期
|
|
tooltipText: '请选择入住日期(最多连续5天)',
|
|
selectedRange: {
|
|
startDate: null,
|
|
endDate: null
|
|
},
|
|
dateList: []
|
|
}
|
|
},
|
|
onReady() {
|
|
// 如果需要兼容微信小程序的话,需要用此写法
|
|
this.$refs.ucalendar.setFormatter(this.formatter)
|
|
},
|
|
methods: {
|
|
formatter(day) {
|
|
// 将day.date转换为yyyy-MM-dd格式,用于与dateList中的日期比较
|
|
const currentDate = new Date(day.date)
|
|
const dateStr = `${currentDate.getFullYear()}-${String(currentDate.getMonth() + 1).padStart(2, '0')}-${String(currentDate.getDate()).padStart(2, '0')}`
|
|
|
|
// 在dateList中查找匹配的日期
|
|
const matchedDate = this.dateList.find(item => item.date === dateStr)
|
|
|
|
if (matchedDate) {
|
|
// 根据inventoryStatus设置bottomInfo和disabled状态
|
|
switch (matchedDate.inventoryStatus) {
|
|
case -1:
|
|
day.bottomInfo = '不可预约'
|
|
day.disabled = true
|
|
break
|
|
case 0:
|
|
day.bottomInfo = '可预约'
|
|
day.disabled = false
|
|
break
|
|
case 1:
|
|
day.bottomInfo = '已被预约'
|
|
day.disabled = true
|
|
break
|
|
case 2:
|
|
day.bottomInfo = '不可预约'
|
|
day.disabled = true
|
|
break
|
|
}
|
|
}
|
|
|
|
return day
|
|
},
|
|
showCalendar(days) {
|
|
this.show = true
|
|
this.dateList = days
|
|
},
|
|
hideCalendar() {
|
|
this.show = false
|
|
},
|
|
// 处理日期选择变化
|
|
handleDateChange(e) {
|
|
// e是选中的日期数组 ["2025-10-21", "2025-10-22", "2025-10-23", "2025-10-24", "2025-10-25"]
|
|
|
|
// 检查是否有不可选的日期
|
|
const hasInvalidDate = e.some(date => {
|
|
const matchedDate = this.dateList.find(item => item.date === date)
|
|
return matchedDate && (matchedDate.inventoryStatus === 1 || matchedDate.inventoryStatus === 2 || matchedDate.inventoryStatus === -1)
|
|
})
|
|
|
|
if (hasInvalidDate) {
|
|
uni.showToast({
|
|
title: '所选日期包含不可预约日期',
|
|
icon: 'none'
|
|
})
|
|
this.resetSelection()
|
|
return
|
|
}
|
|
|
|
// 更新选择状态
|
|
this.selectedRange = {
|
|
startDate: e[0],
|
|
endDate: e[e.length - 1]
|
|
}
|
|
if (e.length !== this.minDay) {
|
|
uni.showToast({
|
|
title: `团购天数必须为${this.minDay}天`,
|
|
icon: 'none'
|
|
})
|
|
this.resetSelection()
|
|
return
|
|
}
|
|
// 触发父组件事件
|
|
this.$emit('dateSelected', this.selectedRange)
|
|
this.hideCalendar()
|
|
},
|
|
|
|
// 检查日期范围内是否有不可预约的日期
|
|
checkInvalidDatesInRange(start, end) {
|
|
// 遍历日期范围内的每一天
|
|
for (let d = new Date(start); d <= end; d.setDate(d.getDate() + 1)) {
|
|
const dateStr = `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`
|
|
const matchedDate = this.dateList.find(item => item.date === dateStr)
|
|
|
|
// 如果找到匹配的日期,且状态为已被预约(1)或不可预约(2)
|
|
if (matchedDate && (matchedDate.inventoryStatus === 1 || matchedDate.inventoryStatus === 2)) {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
},
|
|
|
|
// 检查选择范围内是否有禁用日期
|
|
checkDisabledDatesInRange(start, end) {
|
|
return this.disabledDates.some(date => {
|
|
const disabledDate = new Date(date)
|
|
return disabledDate >= start && disabledDate <= end
|
|
})
|
|
},
|
|
|
|
// 重置选择
|
|
resetSelection() {
|
|
this.selectedRange = {
|
|
startDate: null,
|
|
endDate: null
|
|
}
|
|
this.defaultDate = null
|
|
},
|
|
|
|
// 处理月份切换
|
|
handleMonthSwitch(e) {
|
|
// 可以在这里处理月份切换逻辑,例如加载该月的禁用日期
|
|
this.$emit('monthChange', e)
|
|
},
|
|
|
|
// 设置禁用日期
|
|
setDisabledDates(dates) {
|
|
this.disabledDates = dates
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.calendar-wrapper {
|
|
width: 100%;
|
|
background-color: #fff;
|
|
border-radius: 12rpx;
|
|
overflow: hidden;
|
|
|
|
.calendar-tooltip {
|
|
padding: 20rpx;
|
|
font-size: 28rpx;
|
|
color: #666;
|
|
text-align: center;
|
|
}
|
|
}
|
|
</style> |