From 3052c6b92083c17933cd01800e45d7bbab8cbd9a Mon Sep 17 00:00:00 2001 From: linxi <957440651@qq.com> Date: Thu, 30 Oct 2025 14:55:17 +0800 Subject: [PATCH] =?UTF-8?q?Fix=EF=BC=9A4297=20=E3=80=90=E6=97=85=E5=B1=85?= =?UTF-8?q?=E5=95=86=E5=9F=8E=E5=B0=8F=E7=A8=8B=E5=BA=8F=E3=80=91=E6=97=85?= =?UTF-8?q?=E5=B1=85=E4=B8=8B=E5=8D=95=E9=80=89=E6=8B=A9=E6=97=A5=E6=9C=9F?= =?UTF-8?q?=E7=9A=84=E4=BA=A4=E4=BA=92=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DateRangePicker/DateRangePicker.vue | 113 ++++++++++++++++-- 1 file changed, 102 insertions(+), 11 deletions(-) diff --git a/components/DateRangePicker/DateRangePicker.vue b/components/DateRangePicker/DateRangePicker.vue index e128c2e..1c2c7ce 100644 --- a/components/DateRangePicker/DateRangePicker.vue +++ b/components/DateRangePicker/DateRangePicker.vue @@ -31,6 +31,7 @@ 'in-range': isInRange(day), 'start-date': isStartDate(day), 'end-date': isEndDate(day), + 'selecting-start': isSelectingStart(day), 'disabled': isDisabled(day), 'booked': getDateStatus(day) === 1, 'unavailable': getDateStatus(day) === 2, @@ -97,7 +98,8 @@ export default { activeCalendar: 'start', // 'start' or 'end' tempStartDate: null, tempEndDate: null, - dateStatusMap: {} // 存储日期状态 + dateStatusMap: {}, // 存储日期状态 + selectionState: 'initial' // 'initial' | 'selecting' | 'completed' } }, @@ -204,6 +206,19 @@ export default { initDates() { this.tempStartDate = this.startDate 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) { this.currentYear = this.startDate.getFullYear() this.currentMonth = this.startDate.getMonth() @@ -278,37 +293,62 @@ export default { 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) { if (!day || this.isDisabled(day)) return 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()) { this.tempStartDate = null this.tempEndDate = null this.activeCalendar = 'start' + this.selectionState = 'initial' return } + // 如果点击已选择的结束日期,则只清除结束日期 if (this.tempEndDate && selectedDate.getTime() === this.tempEndDate.getTime()) { this.tempEndDate = null + this.activeCalendar = 'end' + this.selectionState = 'selecting' return } - if (this.activeCalendar === 'start') { - if (this.tempEndDate && selectedDate > this.tempEndDate) { - // 如果选择的开始日期大于结束日期,清空结束日期 - this.tempEndDate = null - } + if (this.activeCalendar === 'start' || this.selectionState === 'initial') { + // 选择开始日期 this.tempStartDate = selectedDate + this.tempEndDate = null this.activeCalendar = 'end' - } else { + this.selectionState = 'selecting' + } else if (this.activeCalendar === 'end') { if (selectedDate < this.tempStartDate) { // 如果选择的结束日期小于开始日期,将其设为开始日期 this.tempStartDate = selectedDate + this.tempEndDate = null + this.selectionState = 'selecting' } else { + // 设置结束日期,完成选择 this.tempEndDate = selectedDate + this.selectionState = 'completed' } } }, @@ -317,6 +357,7 @@ export default { this.tempStartDate = null this.tempEndDate = null this.activeCalendar = 'start' + this.selectionState = 'initial' }, confirmSelect() { @@ -358,19 +399,31 @@ export default { // 验证通过,更新日期并关闭弹窗 this.startDate = this.tempStartDate this.endDate = this.tempEndDate + this.selectionState = 'completed' this.$emit('input', [ this.startDate ? this.formatDate(this.startDate) : null, this.endDate ? this.formatDate(this.endDate) : null ]) - this.handleClose(true) + this.handleClose(false) }, - handleClose(shouldClear = true) { + handleClose(shouldClear = false) { if (shouldClear) { this.clearDates() this.startDate = 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('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 { 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); + } +} \ No newline at end of file