From b4603d2eebfedb68337cb42755597fa7f5d05ed5 Mon Sep 17 00:00:00 2001 From: yuanyi Date: Fri, 19 Sep 2025 18:06:13 +0400 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8DRangePicker=E5=9B=9E?= =?UTF-8?q?=E5=A1=AB=E6=97=B6=E9=97=B4=E6=97=B6=E7=9A=84bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../date-picker/demo/auto-fill-whole-day.vue | 6 +- components/date-picker/demo/index.vue | 3 + .../date-picker/demo/preset-autofill.vue | 154 +++++++++++++++ components/table/hooks/useSorter.tsx | 2 +- components/vc-picker/RangePicker.tsx | 179 +++++++++++++++++- 5 files changed, 334 insertions(+), 10 deletions(-) create mode 100644 components/date-picker/demo/preset-autofill.vue diff --git a/components/date-picker/demo/auto-fill-whole-day.vue b/components/date-picker/demo/auto-fill-whole-day.vue index 4c380a869..75de03449 100644 --- a/components/date-picker/demo/auto-fill-whole-day.vue +++ b/components/date-picker/demo/auto-fill-whole-day.vue @@ -54,7 +54,7 @@ RangePicker supports two new features: diff --git a/components/date-picker/demo/preset-autofill.vue b/components/date-picker/demo/preset-autofill.vue new file mode 100644 index 000000000..c3ed01629 --- /dev/null +++ b/components/date-picker/demo/preset-autofill.vue @@ -0,0 +1,154 @@ + +--- +order: 8 +title: + zh-CN: Preset自动回填 + en-US: Preset Auto Fill +--- + +## zh-CN + +RangePicker 现在支持preset自动回填功能。当传入的value包含preset信息时,会根据preset自动计算对应的日期范围。 + +## en-US + +RangePicker now supports preset auto fill functionality. When the passed value contains preset information, it will automatically calculate the corresponding date range based on the preset. + + + + + + diff --git a/components/table/hooks/useSorter.tsx b/components/table/hooks/useSorter.tsx index 8f307af7e..6406784d4 100644 --- a/components/table/hooks/useSorter.tsx +++ b/components/table/hooks/useSorter.tsx @@ -186,7 +186,7 @@ function injectSorter( const cell = (column.customHeaderCell && column.customHeaderCell(col)) || {}; const originOnClick = cell.onClick; const originOKeyDown = cell.onKeydown; - cell.onClick = (event: MouseEvent) => { + cell.onClick = (event: PointerEvent) => { triggerSorter({ column, key: columnKey, diff --git a/components/vc-picker/RangePicker.tsx b/components/vc-picker/RangePicker.tsx index 145693fd0..648543a5e 100644 --- a/components/vc-picker/RangePicker.tsx +++ b/components/vc-picker/RangePicker.tsx @@ -320,10 +320,64 @@ function RangerPicker() { const [mergedValue, setInnerValue] = useMergedState>(null, { value: toRef(props, 'value'), defaultValue: props.defaultValue, - postState: values => - props.picker === 'time' && !props.order + postState: values => { + // 处理包含preset的value格式 [date, date, preset] + if ( + values && + Array.isArray(values) && + (values as any).length === 3 && + (values as any)[2] + ) { + const preset = (values as any)[2]; + // 如果preset有value属性,使用preset的value作为日期范围 + if (preset.value && Array.isArray(preset.value) && preset.value.length === 2) { + const presetValues = preset.value; + + // 检查preset.value是否是函数,如果是则执行函数获取当前值 + let startValue = + typeof presetValues[0] === 'function' ? presetValues[0]() : presetValues[0]; + let endValue = + typeof presetValues[1] === 'function' ? presetValues[1]() : presetValues[1]; + + // 判断props.isWholeDay是否为true,如果为false,则使用当前时间的时分秒 + if (!props.isWholeDay) { + const now = props.generateConfig.getNow(); + const currentHour = props.generateConfig.getHour(now); + const currentMinute = props.generateConfig.getMinute(now); + const currentSecond = props.generateConfig.getSecond(now); + + startValue = props.generateConfig.setHour( + props.generateConfig.setMinute( + props.generateConfig.setSecond(startValue, currentSecond), + currentMinute, + ), + currentHour, + ); + endValue = props.generateConfig.setHour( + props.generateConfig.setMinute( + props.generateConfig.setSecond(endValue, currentSecond), + currentMinute, + ), + currentHour, + ); + } + + if (startValue && endValue) { + // 设置当前preset + setCurrentPreset(preset); + // 返回preset计算出的日期范围 + return props.picker === 'time' && !props.order + ? [startValue, endValue] + : reorderValues([startValue, endValue], props.generateConfig); + } + } + } + + // 处理普通格式的value + return props.picker === 'time' && !props.order ? values - : reorderValues(values, props.generateConfig), + : reorderValues(values, props.generateConfig); + }, }); // ========================= Current Preset ========================= @@ -597,6 +651,61 @@ function RangerPicker() { values = [startWithTime, endWithTime]; } + // 如果通过preset触发,且preset有value属性,重新计算日期范围 + if ( + fromPreset && + currentPreset.value && + Array.isArray(currentPreset.value) && + currentPreset.value.length === 2 + ) { + const presetValues = currentPreset.value; + // 检查preset.value是否是函数,如果是则执行函数获取当前值 + const presetStartValue = + typeof presetValues[0] === 'function' ? presetValues[0]() : presetValues[0]; + const presetEndValue = + typeof presetValues[1] === 'function' ? presetValues[1]() : presetValues[1]; + + if (presetStartValue && presetEndValue) { + // 如果启用了isWholeDay,应用时间设置 + if (props.isWholeDay && showTime) { + const startWithTime = generateConfig.setHour( + generateConfig.setMinute(generateConfig.setSecond(presetStartValue, 0), 0), + 0, + ); + const endWithTime = generateConfig.setHour( + generateConfig.setMinute(generateConfig.setSecond(presetEndValue, 59), 59), + 23, + ); + values = [startWithTime, endWithTime]; + } else if (showTime) { + // 如果未启用isWholeDay但启用了showTime,使用当前时间的时分秒 + const now = generateConfig.getNow(); + const currentHour = generateConfig.getHour(now); + const currentMinute = generateConfig.getMinute(now); + const currentSecond = generateConfig.getSecond(now); + + const startWithCurrentTime = generateConfig.setHour( + generateConfig.setMinute( + generateConfig.setSecond(presetStartValue, currentSecond), + currentMinute, + ), + currentHour, + ); + const endWithCurrentTime = generateConfig.setHour( + generateConfig.setMinute( + generateConfig.setSecond(presetEndValue, currentSecond), + currentMinute, + ), + currentHour, + ); + values = [startWithCurrentTime, endWithCurrentTime]; + } else { + // 如果没有启用showTime,保持preset的原始时间 + values = [presetStartValue, presetEndValue]; + } + } + } + setSelectedValue(values); // 如果不是通过 preset 触发的,清除 currentPreset @@ -638,9 +747,11 @@ function RangerPicker() { (!isEqual(generateConfig, getValue(mergedValue.value, 0), startValue) || !isEqual(generateConfig, getValue(mergedValue.value, 1), endValue)) ) { + // 如果通过preset触发,传递preset信息 + const presetToPass = fromPreset ? currentPreset.value : currentPreset.value; onChange( - [startValue, endValue, currentPreset.value], - [startStr, endStr, currentPreset.value?.key || null], + [startValue, endValue, presetToPass], + [startStr, endStr, presetToPass?.key || null], ); } } @@ -1247,7 +1358,63 @@ function RangerPicker() { currentPreset={currentPreset.value} onClick={(nextValue, preset) => { setCurrentPreset(preset); - triggerChange(nextValue, null, true); + // 如果preset有value属性,使用preset的value作为日期范围 + let valuesToUse = nextValue; + if (preset.value && Array.isArray(preset.value) && preset.value.length === 2) { + const presetValues = preset.value; + // 检查preset.value是否是函数,如果是则执行函数获取当前值 + const presetStartValue = + typeof presetValues[0] === 'function' ? presetValues[0]() : presetValues[0]; + const presetEndValue = + typeof presetValues[1] === 'function' ? presetValues[1]() : presetValues[1]; + + if (presetStartValue && presetEndValue) { + // 如果启用了isWholeDay,应用时间设置 + if (props.isWholeDay && props.showTime) { + const startWithTime = props.generateConfig.setHour( + props.generateConfig.setMinute( + props.generateConfig.setSecond(presetStartValue, 0), + 0, + ), + 0, + ); + const endWithTime = props.generateConfig.setHour( + props.generateConfig.setMinute( + props.generateConfig.setSecond(presetEndValue, 59), + 59, + ), + 23, + ); + valuesToUse = [startWithTime, endWithTime]; + } else if (props.showTime) { + // 如果未启用isWholeDay但启用了showTime,使用当前时间的时分秒 + const now = props.generateConfig.getNow(); + const currentHour = props.generateConfig.getHour(now); + const currentMinute = props.generateConfig.getMinute(now); + const currentSecond = props.generateConfig.getSecond(now); + + const startWithCurrentTime = props.generateConfig.setHour( + props.generateConfig.setMinute( + props.generateConfig.setSecond(presetStartValue, currentSecond), + currentMinute, + ), + currentHour, + ); + const endWithCurrentTime = props.generateConfig.setHour( + props.generateConfig.setMinute( + props.generateConfig.setSecond(presetEndValue, currentSecond), + currentMinute, + ), + currentHour, + ); + valuesToUse = [startWithCurrentTime, endWithCurrentTime]; + } else { + // 如果没有启用showTime,保持preset的原始时间 + valuesToUse = [presetStartValue, presetEndValue]; + } + } + } + triggerChange(valuesToUse, null, true); triggerOpen(false, mergedActivePickerIndex.value); }} onHover={hoverValue => {