Feat:订单预约日期
This commit is contained in:
@@ -0,0 +1,188 @@
|
||||
<template>
|
||||
<view class="calendar-wrapper">
|
||||
<u-calendar
|
||||
ref="ucalendar"
|
||||
:show="show"
|
||||
:mode="'range'"
|
||||
:maxRange="999"
|
||||
:defaultDate="defaultDate"
|
||||
:minDate="minDate"
|
||||
:disabledDate="disabledDates"
|
||||
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]
|
||||
}
|
||||
// 如果选择的天数小于minDay,提示用户选择至少minDay天
|
||||
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>
|
||||
@@ -47,12 +47,12 @@
|
||||
<view>预</view>
|
||||
<view>约</view>
|
||||
</view>
|
||||
<view v-for="(d) in currentWeek" :key="d.date" class="date-item">
|
||||
<view v-for="(d) in currentWeek" :key="d.date" class="date-item">
|
||||
<view>{{ d.week }}</view>
|
||||
<view class="v12-my-1 v12-primary-text">{{ d.monthDay }}</view>
|
||||
<view>不可预约</view>
|
||||
<view>{{ d.status }}</view>
|
||||
</view>
|
||||
<view class="v12-primary-text v12-font-24 date-item v12-white v12-px-1">
|
||||
<view @click="handleDate" class="v12-primary-text v12-font-24 date-item v12-white v12-px-1">
|
||||
<view>可</view>
|
||||
<view>约</view>
|
||||
<view>日</view>
|
||||
@@ -133,14 +133,22 @@
|
||||
<view class="buy-btn" @click="bookNow">立即购买</view>
|
||||
</view>
|
||||
</view>
|
||||
<Calendar ref="calendar"
|
||||
:minDay="detail.minBookingDays"
|
||||
@dateSelected="handleDateSelected"
|
||||
></Calendar>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getJiaLouProductDetail, getJiaLouCalendar,getJiaLouBookingRules } from '@/api/qianxian'
|
||||
import {getGiftCardSendBackground} from "@/api/gift"
|
||||
import Calendar from '../components/Calendar.vue'
|
||||
export default {
|
||||
name: 'GroupBuyDetails',
|
||||
components: {
|
||||
Calendar
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
webUrl: this.$VUE_APP_RESOURCES_URL,
|
||||
@@ -193,7 +201,8 @@ export default {
|
||||
},
|
||||
calendar: [],
|
||||
currentWeek: [],
|
||||
rules: ""
|
||||
rules: "",
|
||||
rangeDate: {}
|
||||
}
|
||||
},
|
||||
onShow() {
|
||||
@@ -214,6 +223,14 @@ export default {
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
handleDateSelected(dateRange) {
|
||||
console.log(dateRange, 'dateRange');
|
||||
|
||||
this.rangeDate = dateRange
|
||||
},
|
||||
handleDate() {
|
||||
this.$refs.calendar.showCalendar(this.calendar)
|
||||
},
|
||||
/**
|
||||
* 获取产品可预约日期
|
||||
*/
|
||||
@@ -245,6 +262,7 @@ export default {
|
||||
result.push({
|
||||
date: dateStr,
|
||||
week: this.getWeekLabel(dateStr),
|
||||
status: this.findDateStatus(dateStr),
|
||||
monthDay: i === 0 ? '今日' : this.getMonthDay(dateStr)
|
||||
})
|
||||
}
|
||||
@@ -285,8 +303,100 @@ export default {
|
||||
uni.showToast({ title: '已为您接入管家', icon: 'none' })
|
||||
},
|
||||
bookNow() {
|
||||
uni.navigateTo({ url: '/pkg_product/views/submitOrder?id=' + this.id + '&orderStartDate=' + this.currentWeek[0].date + '&orderEndDate=' + this.currentWeek[4].date })
|
||||
}
|
||||
uni.navigateTo({ url: '/pkg_product/views/submitOrder?id=' + this.id + '&orderStartDate=' + this.rangeDate.startDate + '&orderEndDate=' + this.rangeDate.endDate })
|
||||
},
|
||||
/**
|
||||
* 查找指定日期的预约状态
|
||||
* @param {string} dateStr YYYY-MM-DD格式的日期字符串
|
||||
* @returns {string} 预约状态文本:可约、已约、不可约
|
||||
*/
|
||||
findDateStatus(dateStr) {
|
||||
// 在calendar数组中查找匹配的日期
|
||||
const matchedDate = this.calendar.find(item => item.date === dateStr)
|
||||
console.log('未找到匹配日期:', matchedDate)
|
||||
// 如果找到匹配的日期,根据inventoryStatus返回对应文本
|
||||
if (matchedDate) {
|
||||
switch (matchedDate.inventoryStatus) {
|
||||
case 0:
|
||||
return '可订'
|
||||
case 1:
|
||||
return '不可订'
|
||||
case 2:
|
||||
return '不可订'
|
||||
default:
|
||||
return '不可订'
|
||||
}
|
||||
}
|
||||
|
||||
// 如果没有找到匹配的日期,返回不可约
|
||||
return '不可订'
|
||||
},
|
||||
|
||||
/**
|
||||
* 处理日期点击事件
|
||||
* @param {Object} date 日期对象
|
||||
*/
|
||||
handleDateClick(date) {
|
||||
// 如果是不可订的日期,直接返回
|
||||
if (date.status === '不可订') {
|
||||
uni.showToast({
|
||||
title: '该日期不可预订',
|
||||
icon: 'none'
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// 检查是否已选中
|
||||
const index = this.rangeDate.indexOf(date.date)
|
||||
if (index > -1) {
|
||||
// 如果已选中,则取消选中
|
||||
this.rangeDate.splice(index, 1)
|
||||
} else {
|
||||
// 如果未选中,则添加到选中列表
|
||||
this.rangeDate.push(date.date)
|
||||
// 对日期进行排序
|
||||
this.rangeDate.sort()
|
||||
|
||||
// 检查日期连续性
|
||||
if (this.rangeDate.length > 1) {
|
||||
const isConsecutive = this.checkConsecutiveDates(this.rangeDate)
|
||||
if (!isConsecutive) {
|
||||
uni.showToast({
|
||||
title: '请选择连续的日期',
|
||||
icon: 'none'
|
||||
})
|
||||
// 移除最后添加的日期
|
||||
this.rangeDate.pop()
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 检查日期是否被选中
|
||||
* @param {string} date 日期字符串
|
||||
* @returns {boolean} 是否被选中
|
||||
*/
|
||||
isDateSelected(date) {
|
||||
return this.rangeDate.includes(date)
|
||||
},
|
||||
|
||||
/**
|
||||
* 检查日期是否连续
|
||||
* @param {Array} dates 日期数组
|
||||
* @returns {boolean} 是否连续
|
||||
*/
|
||||
checkConsecutiveDates(dates) {
|
||||
for (let i = 1; i < dates.length; i++) {
|
||||
const curr = new Date(dates[i])
|
||||
const prev = new Date(dates[i-1])
|
||||
const diffDays = (curr - prev) / (1000 * 60 * 60 * 24)
|
||||
if (diffDays !== 1) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -383,8 +493,13 @@ export default {
|
||||
color: #333;
|
||||
height: 160rpx;
|
||||
padding: 0 4rpx;
|
||||
|
||||
.selected-date {
|
||||
background-color: #E9BABA;
|
||||
font-weight: bold;
|
||||
border-radius: 100rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.simple-table {
|
||||
margin-top: 12rpx;
|
||||
border: 1rpx solid #FADE9F;
|
||||
|
||||
@@ -108,7 +108,6 @@
|
||||
</view>
|
||||
|
||||
<!-- 日期选择器(简单占位) -->
|
||||
<u-calendar v-model="showCalendar" mode="range" :min-date="minDate" @confirm="onDateConfirm" />
|
||||
<passkeyborad
|
||||
v-if="isShowPayPwdPop"
|
||||
ref='payPwdPop'
|
||||
@@ -118,6 +117,7 @@
|
||||
@close="pwdPopClose"
|
||||
@finish="pwdPopFinish"
|
||||
></passkeyborad>
|
||||
<Calendar ref="calendar"></Calendar>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user