Fix:4297 【旅居商城小程序】旅居下单选择日期的交互调整

This commit is contained in:
linxi
2025-10-30 14:55:17 +08:00
parent 4ff143ab29
commit 3052c6b920
+102 -11
View File
@@ -31,6 +31,7 @@
'in-range': isInRange(day), 'in-range': isInRange(day),
'start-date': isStartDate(day), 'start-date': isStartDate(day),
'end-date': isEndDate(day), 'end-date': isEndDate(day),
'selecting-start': isSelectingStart(day),
'disabled': isDisabled(day), 'disabled': isDisabled(day),
'booked': getDateStatus(day) === 1, 'booked': getDateStatus(day) === 1,
'unavailable': getDateStatus(day) === 2, 'unavailable': getDateStatus(day) === 2,
@@ -97,7 +98,8 @@ export default {
activeCalendar: 'start', // 'start' or 'end' activeCalendar: 'start', // 'start' or 'end'
tempStartDate: null, tempStartDate: null,
tempEndDate: null, tempEndDate: null,
dateStatusMap: {} // 存储日期状态 dateStatusMap: {}, // 存储日期状态
selectionState: 'initial' // 'initial' | 'selecting' | 'completed'
} }
}, },
@@ -204,6 +206,19 @@ export default {
initDates() { initDates() {
this.tempStartDate = this.startDate this.tempStartDate = this.startDate
this.tempEndDate = this.endDate this.tempEndDate = this.endDate
// 根据当前选择状态设置selectionState
if (this.tempStartDate && this.tempEndDate) {
this.selectionState = 'completed'
this.activeCalendar = 'start'
} else if (this.tempStartDate) {
this.selectionState = 'selecting'
this.activeCalendar = 'end'
} else {
this.selectionState = 'initial'
this.activeCalendar = 'start'
}
if (this.startDate) { if (this.startDate) {
this.currentYear = this.startDate.getFullYear() this.currentYear = this.startDate.getFullYear()
this.currentMonth = this.startDate.getMonth() this.currentMonth = this.startDate.getMonth()
@@ -278,37 +293,62 @@ export default {
return date > this.tempStartDate && date < this.tempEndDate return date > this.tempStartDate && date < this.tempEndDate
}, },
isSelectingStart(day) {
if (!day || !this.tempStartDate || this.tempEndDate) return false
// 只有在选择状态且只有开始日期时才显示特殊样式
if (this.selectionState !== 'selecting') return false
const date = this.getDateFromDay(day)
return date.getTime() === this.tempStartDate.getTime()
},
selectDate(day) { selectDate(day) {
if (!day || this.isDisabled(day)) return if (!day || this.isDisabled(day)) return
const selectedDate = this.getDateFromDay(day) const selectedDate = this.getDateFromDay(day)
// 如果点击已选择的日期,则取消选择 // 如果已有完整的日期区间(开始日期和结束日期都存在),重置选择
if (this.tempStartDate && this.tempEndDate && this.selectionState === 'completed') {
// 重置选择状态,将点击的日期作为新的开始日期
this.tempStartDate = selectedDate
this.tempEndDate = null
this.activeCalendar = 'end'
this.selectionState = 'selecting'
return
}
// 如果点击已选择的开始日期,则取消选择
if (this.tempStartDate && selectedDate.getTime() === this.tempStartDate.getTime()) { if (this.tempStartDate && selectedDate.getTime() === this.tempStartDate.getTime()) {
this.tempStartDate = null this.tempStartDate = null
this.tempEndDate = null this.tempEndDate = null
this.activeCalendar = 'start' this.activeCalendar = 'start'
this.selectionState = 'initial'
return return
} }
// 如果点击已选择的结束日期,则只清除结束日期
if (this.tempEndDate && selectedDate.getTime() === this.tempEndDate.getTime()) { if (this.tempEndDate && selectedDate.getTime() === this.tempEndDate.getTime()) {
this.tempEndDate = null this.tempEndDate = null
this.activeCalendar = 'end'
this.selectionState = 'selecting'
return return
} }
if (this.activeCalendar === 'start') { if (this.activeCalendar === 'start' || this.selectionState === 'initial') {
if (this.tempEndDate && selectedDate > this.tempEndDate) { // 选择开始日期
// 如果选择的开始日期大于结束日期,清空结束日期
this.tempEndDate = null
}
this.tempStartDate = selectedDate this.tempStartDate = selectedDate
this.tempEndDate = null
this.activeCalendar = 'end' this.activeCalendar = 'end'
} else { this.selectionState = 'selecting'
} else if (this.activeCalendar === 'end') {
if (selectedDate < this.tempStartDate) { if (selectedDate < this.tempStartDate) {
// 如果选择的结束日期小于开始日期,将其设为开始日期 // 如果选择的结束日期小于开始日期,将其设为开始日期
this.tempStartDate = selectedDate this.tempStartDate = selectedDate
this.tempEndDate = null
this.selectionState = 'selecting'
} else { } else {
// 设置结束日期,完成选择
this.tempEndDate = selectedDate this.tempEndDate = selectedDate
this.selectionState = 'completed'
} }
} }
}, },
@@ -317,6 +357,7 @@ export default {
this.tempStartDate = null this.tempStartDate = null
this.tempEndDate = null this.tempEndDate = null
this.activeCalendar = 'start' this.activeCalendar = 'start'
this.selectionState = 'initial'
}, },
confirmSelect() { confirmSelect() {
@@ -358,19 +399,31 @@ export default {
// 验证通过,更新日期并关闭弹窗 // 验证通过,更新日期并关闭弹窗
this.startDate = this.tempStartDate this.startDate = this.tempStartDate
this.endDate = this.tempEndDate this.endDate = this.tempEndDate
this.selectionState = 'completed'
this.$emit('input', [ this.$emit('input', [
this.startDate ? this.formatDate(this.startDate) : null, this.startDate ? this.formatDate(this.startDate) : null,
this.endDate ? this.formatDate(this.endDate) : null this.endDate ? this.formatDate(this.endDate) : null
]) ])
this.handleClose(true) this.handleClose(false)
}, },
handleClose(shouldClear = true) { handleClose(shouldClear = false) {
if (shouldClear) { if (shouldClear) {
this.clearDates() this.clearDates()
this.startDate = null this.startDate = null
this.endDate = null this.endDate = null
// this.$emit('input', [null, null]) this.$emit('input', [null, null])
} else {
// 恢复到原始状态
this.tempStartDate = this.startDate
this.tempEndDate = this.endDate
if (this.startDate && this.endDate) {
this.selectionState = 'completed'
} else if (this.startDate) {
this.selectionState = 'selecting'
} else {
this.selectionState = 'initial'
}
} }
this.$emit('update:show', false) this.$emit('update:show', false)
this.$emit('close') this.$emit('close')
@@ -516,6 +569,29 @@ export default {
} }
} }
&.selecting-start {
background: #4B97EB;
color: #FFFFFF;
border-radius: 8rpx;
position: relative;
&::after {
content: '';
position: absolute;
top: -2rpx;
left: -2rpx;
right: -2rpx;
bottom: -2rpx;
border: 2rpx solid #4B97EB;
border-radius: 10rpx;
animation: pulse 1.5s infinite;
}
.status-dot {
background: #FFFFFF;
}
}
&.in-range { &.in-range {
background: rgba(197, 39, 51, 0.1); background: rgba(197, 39, 51, 0.1);
} }
@@ -572,4 +648,19 @@ export default {
} }
} }
} }
@keyframes pulse {
0% {
opacity: 1;
transform: scale(1);
}
50% {
opacity: 0.7;
transform: scale(1.05);
}
100% {
opacity: 1;
transform: scale(1);
}
}
</style> </style>