From 8d42e2de85247ece3af447a95f6a64da34689d51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=98=BFCai?= Date: Fri, 25 Oct 2024 10:57:22 +0800 Subject: [PATCH 1/3] style(date-picker): extraction and aggregation of duplicate codes --- src/date-picker/DatePicker.tsx | 29 +-- src/date-picker/DatePickerPanel.tsx | 32 +-- src/date-picker/DateRangePicker.tsx | 184 +++++--------- src/date-picker/DateRangePickerPanel.tsx | 179 +++++-------- src/date-picker/utils.ts | 306 +++++++++++++++++++++++ 5 files changed, 445 insertions(+), 285 deletions(-) diff --git a/src/date-picker/DatePicker.tsx b/src/date-picker/DatePicker.tsx index 69c6f9324..23a0475af 100644 --- a/src/date-picker/DatePicker.tsx +++ b/src/date-picker/DatePicker.tsx @@ -18,6 +18,7 @@ import props from './props'; import TSelectInput from '../select-input'; import TSinglePanel from './panel/SinglePanel'; import useFormDisabled from '../hooks/useFormDisabled'; +import { onDatePickerJumperClickSharedFn } from './utils'; export default defineComponent({ name: 'TDatePicker', @@ -122,28 +123,12 @@ export default defineComponent({ // 头部快速切换 function onJumperClick({ trigger }: { trigger: string }) { - const monthCountMap = { - date: 1, - week: 1, - month: 12, - quarter: 12, - year: 120, - }; - const monthCount = monthCountMap[props.mode] || 0; - - const current = new Date(year.value, month.value); - - let next = null; - if (trigger === 'prev') { - next = subtractMonth(current, monthCount); - } else if (trigger === 'current') { - next = new Date(); - } else if (trigger === 'next') { - next = addMonth(current, monthCount); - } - - const nextYear = next.getFullYear(); - const nextMonth = next.getMonth(); + const { nextYear, nextMonth } = onDatePickerJumperClickSharedFn({ + trigger, + mode: props.mode, + month, + year, + }); year.value = nextYear; month.value = nextMonth; diff --git a/src/date-picker/DatePickerPanel.tsx b/src/date-picker/DatePickerPanel.tsx index fe5908b1e..d7c639729 100644 --- a/src/date-picker/DatePickerPanel.tsx +++ b/src/date-picker/DatePickerPanel.tsx @@ -15,6 +15,7 @@ import datePickerPanelProps from './date-picker-panel-props'; import datePickerProps from './props'; import TSinglePanel from './panel/SinglePanel'; +import { onDatePickerJumperClickSharedFn } from './utils'; export default defineComponent({ name: 'TDatePickerPanel', @@ -64,33 +65,18 @@ export default defineComponent({ } // 头部快速切换 - function onJumperClick({ trigger }: { trigger: string }) { + function onJumperClick({ trigger }: { trigger: 'prev' | 'current' | 'next' }) { + const { nextYear, nextMonth } = onDatePickerJumperClickSharedFn({ + trigger, + mode: props.mode, + month, + year, + }); + const triggerMap = { prev: 'arrow-previous', next: 'arrow-next', }; - const monthCountMap = { - date: 1, - week: 1, - month: 12, - quarter: 12, - year: 120, - }; - const monthCount = monthCountMap[props.mode] || 0; - - const current = new Date(year.value, month.value); - - let next = null; - if (trigger === 'prev') { - next = subtractMonth(current, monthCount); - } else if (trigger === 'current') { - next = new Date(); - } else if (trigger === 'next') { - next = addMonth(current, monthCount); - } - - const nextYear = next.getFullYear(); - const nextMonth = next.getMonth(); if (year.value !== nextYear) { props.onYearChange?.({ diff --git a/src/date-picker/DateRangePicker.tsx b/src/date-picker/DateRangePicker.tsx index e2e727943..b22c2c98b 100644 --- a/src/date-picker/DateRangePicker.tsx +++ b/src/date-picker/DateRangePicker.tsx @@ -20,9 +20,14 @@ import { getDefaultFormat, initYearMonthTime, } from '../_common/js/date-picker/format'; -import { subtractMonth, addMonth, extractTimeObj } from '../_common/js/date-picker/utils'; import useFormDisabled from '../hooks/useFormDisabled'; -import { dateCorrection } from './utils'; +import { + onDateRangePickerJumperClickSharedFn, + onDateRangePickerMonthChangeSharedFn, + onDateRangePickerPresetClickSharedFn, + onDateRangePickerTimePickerChangeSharedFn, + onDateRangePickerYearChangeSharedFn, +} from './utils'; export default defineComponent({ name: 'TDateRangePicker', @@ -194,74 +199,48 @@ export default defineComponent({ } // 头部快速切换 - function onJumperClick({ trigger, partial }: { trigger: string; partial: DateRangePickerPartial }) { - const partialIndex = partial === 'start' ? 0 : 1; - - const monthCountMap = { - date: 1, - week: 1, - month: 12, - quarter: 12, - year: 120, - }; - const monthCount = monthCountMap[props.mode] || 0; - const current = new Date(year.value[partialIndex], month.value[partialIndex]); - - let next = null; - if (trigger === 'prev') { - next = subtractMonth(current, monthCount); - } else if (trigger === 'current') { - next = new Date(); - } else if (trigger === 'next') { - next = addMonth(current, monthCount); - } - - let nextYear = [...year.value]; - nextYear[partialIndex] = next.getFullYear(); - let nextMonth = [...month.value]; - nextMonth[partialIndex] = next.getMonth(); - const onlyYearSelect = ['year', 'quarter', 'month'].includes(props.mode); - - // 头部日期切换修正 - const correctedDate = dateCorrection(partialIndex, nextYear, nextMonth, onlyYearSelect); - nextYear = correctedDate.nextYear; - nextMonth = correctedDate.nextMonth; - + function onJumperClick({ + trigger, + partial, + }: { + trigger: 'prev' | 'current' | 'next'; + partial: DateRangePickerPartial; + }) { + const { nextYear, nextMonth } = onDateRangePickerJumperClickSharedFn({ + trigger, + partial, + mode: props.mode, + month, + year, + }); year.value = nextYear; month.value = nextMonth; } // time-picker 点击 function onTimePickerChange(val: string) { - const { - hours, minutes, seconds, milliseconds, meridiem, - } = extractTimeObj(val); - - const nextInputValue = [...(inputValue.value as DateValue[])]; - const changedInputValue = inputValue.value[activeIndex.value]; - const currentDate = !dayjs(changedInputValue, formatRef.value.format).isValid() - ? dayjs().year(year.value[activeIndex.value]).month(month.value[activeIndex.value]) - : dayjs(changedInputValue, formatRef.value.format); - // am pm 12小时制转化 24小时制 - let nextHours = hours; - if (/am/i.test(meridiem) && nextHours === 12) nextHours -= 12; - if (/pm/i.test(meridiem) && nextHours < 12) nextHours += 12; - - const nextDate = currentDate.hour(nextHours).minute(minutes).second(seconds).millisecond(milliseconds) - .toDate(); - nextInputValue[activeIndex.value] = nextDate; - - const nextTime = [...time.value]; - nextTime[activeIndex.value] = val; - time.value = nextTime; + const { nextTime, nextInputValue, isSelectedInstance } = onDateRangePickerTimePickerChangeSharedFn( + { + val, + activeIndex, + formatRef, + year, + month, + time, + }, + inputValue, + ); - isSelected.value = true; inputValue.value = formatDate(nextInputValue, { format: formatRef.value.format, }); + cacheValue.value = formatDate(nextInputValue, { format: formatRef.value.format, }); + + time.value = nextTime; + isSelected.value = isSelectedInstance; } // 确定 @@ -313,81 +292,42 @@ export default defineComponent({ // 预设 function onPresetClick(preset: any, context: any) { - let presetValue = preset; - if (typeof preset === 'function') { - presetValue = preset(); - } - if (!Array.isArray(presetValue)) { - console.error(`preset: ${preset} 预设值必须是数组!`); - } else { - onChange?.( - formatDate(presetValue, { - format: formatRef.value.format, - targetFormat: formatRef.value.valueType, - autoSwap: true, - }) as DateValue[], - { - dayjsValue: presetValue.map((p) => parseToDayjs(p, formatRef.value.format)), - trigger: 'preset', - }, - ); - popupVisible.value = false; - props.onPresetClick?.(context); - emit('preset-click', context); - } + onDateRangePickerPresetClickSharedFn({ + preset, + context, + onChange, + formatRef, + onPresetClick: props.onPresetClick, + emit, + }); + popupVisible.value = false; } function onYearChange(nextVal: number, { partial }: { partial: DateRangePickerPartial }) { - let partialIndex = partial === 'start' ? 0 : 1; - if (props.enableTimePicker) partialIndex = activeIndex.value; - - let nextYear = [...year.value]; - let nextMonth = [...month.value]; - nextYear[partialIndex] = nextVal; - const onlyYearSelect = ['year', 'quarter', 'month'].includes(props.mode); - - // 头部日期切换修正 - const correctedDate = dateCorrection(partialIndex, nextYear, nextMonth, onlyYearSelect); - nextYear = correctedDate.nextYear; - nextMonth = correctedDate.nextMonth; + const { nextYear, nextMonth, onlyYearSelect } = onDateRangePickerYearChangeSharedFn(nextVal, { + partial, + enableTimePicker: props.enableTimePicker, + activeIndex, + mode: props.mode, + month, + year, + }); year.value = nextYear; if (!onlyYearSelect) month.value = nextMonth; } function onMonthChange(nextVal: number, { partial }: { partial: DateRangePickerPartial }) { - let partialIndex = partial === 'start' ? 0 : 1; - if (props.enableTimePicker) partialIndex = activeIndex.value; - - const nextMonth = [...month.value]; - nextMonth[partialIndex] = nextVal; - // 保证左侧时间不大于右侧 - if (year.value[0] === year.value[1]) { - if (partialIndex === 0) { - // 操作了左侧区间, 处理右侧区间小于或等于左侧区间的场景,交互上始终报错右侧比左侧大 1 - if (nextMonth[1] <= nextMonth[0]) { - nextMonth[1] = nextMonth[0] + 1; - if (nextMonth[1] === 12) { - // 处理跨年的边界场景 - nextMonth[1] = 0; - year.value = [year.value?.[0], year.value?.[1] + 1]; - } - } - } - if (partialIndex === 1) { - // 操作了右侧区间, 处理右侧区间小于或等于左侧区间的场景,交互上始终报错左侧比右侧小 1 - nextMonth[0] = Math.min(nextMonth[0], nextMonth[1]); - if (nextMonth[0] >= nextMonth[1]) { - nextMonth[0] -= 1; - if (nextMonth[0] === -1) { - // 处理跨年的边界场景 - nextMonth[0] = 11; - year.value = [year.value?.[0] - 1, year.value?.[1]]; - } - } - } - } + const { nextYear, nextMonth } = onDateRangePickerMonthChangeSharedFn(nextVal, { + partial, + enableTimePicker: props.enableTimePicker, + activeIndex, + mode: props.mode, + month, + year, + }); + year.value = nextYear; month.value = nextMonth; } diff --git a/src/date-picker/DateRangePickerPanel.tsx b/src/date-picker/DateRangePickerPanel.tsx index 125b84a64..6f28cca16 100644 --- a/src/date-picker/DateRangePickerPanel.tsx +++ b/src/date-picker/DateRangePickerPanel.tsx @@ -16,8 +16,13 @@ import { import TRangePanel from './panel/RangePanel'; import useRangeValue from './hooks/useRangeValue'; import { formatDate, getDefaultFormat, parseToDayjs } from '../_common/js/date-picker/format'; -import { subtractMonth, addMonth, extractTimeObj } from '../_common/js/date-picker/utils'; -import { dateCorrection } from './utils'; +import { + onDateRangePickerJumperClickSharedFn, + onDateRangePickerMonthChangeSharedFn, + onDateRangePickerPresetClickSharedFn, + onDateRangePickerTimePickerChangeSharedFn, + onDateRangePickerYearChangeSharedFn, +} from './utils'; export default defineComponent({ name: 'TDateRangePickerPanel', @@ -128,42 +133,25 @@ export default defineComponent({ } // 头部快速切换 - function onJumperClick({ trigger, partial }: { trigger: string; partial: DateRangePickerPartial }) { - const partialIndex = partial === 'start' ? 0 : 1; + function onJumperClick({ + trigger, + partial, + }: { + trigger: 'prev' | 'current' | 'next'; + partial: DateRangePickerPartial; + }) { + const { nextYear, nextMonth, partialIndex } = onDateRangePickerJumperClickSharedFn({ + trigger, + partial, + mode: props.mode, + month, + year, + }); const triggerMap = { prev: 'arrow-previous', next: 'arrow-next', }; - const monthCountMap = { - date: 1, - week: 1, - month: 12, - quarter: 12, - year: 120, - }; - const monthCount = monthCountMap[props.mode] || 0; - const current = new Date(year.value[partialIndex], month.value[partialIndex]); - - let next = null; - if (trigger === 'prev') { - next = subtractMonth(current, monthCount); - } else if (trigger === 'current') { - next = new Date(); - } else if (trigger === 'next') { - next = addMonth(current, monthCount); - } - - let nextYear = [...year.value]; - nextYear[partialIndex] = next.getFullYear(); - let nextMonth = [...month.value]; - nextMonth[partialIndex] = next.getMonth(); - const onlyYearSelect = ['year', 'quarter', 'month'].includes(props.mode); - - // 头部日期切换修正 - const correctedDate = dateCorrection(partialIndex, nextYear, nextMonth, onlyYearSelect); - nextYear = correctedDate.nextYear; - nextMonth = correctedDate.nextMonth; if (year.value.some((y) => !nextYear.includes(y))) { props.onYearChange?.({ @@ -200,29 +188,21 @@ export default defineComponent({ // time-picker 点击 function onTimePickerChange(val: string) { - const { - hours, minutes, seconds, milliseconds, meridiem, - } = extractTimeObj(val); - - const nextInputValue = [...(cacheValue.value as DateValue[])]; - const changedInputValue = cacheValue.value[activeIndex.value]; - const currentDate = !dayjs(changedInputValue, formatRef.value.format).isValid() - ? dayjs().year(year.value[activeIndex.value]).month(month.value[activeIndex.value]) - : dayjs(changedInputValue, formatRef.value.format); - // am pm 12小时制转化 24小时制 - let nextHours = hours; - if (/am/i.test(meridiem) && nextHours === 12) nextHours -= 12; - if (/pm/i.test(meridiem) && nextHours < 12) nextHours += 12; - - const nextDate = currentDate.hour(nextHours).minute(minutes).second(seconds).millisecond(milliseconds) - .toDate(); - nextInputValue[activeIndex.value] = nextDate; - - const nextTime = [...time.value]; - nextTime[activeIndex.value] = val; + const { nextTime, nextInputValue, isSelectedInstance } = onDateRangePickerTimePickerChangeSharedFn( + { + val, + activeIndex, + formatRef, + year, + month, + time, + }, + cacheValue, + ); + time.value = nextTime; - isSelected.value = true; + isSelected.value = isSelectedInstance; cacheValue.value = formatDate(nextInputValue, { format: formatRef.value.format, }); @@ -270,42 +250,27 @@ export default defineComponent({ // 预设 function onPresetClick(preset: any, context: any) { - let presetValue = preset; - if (typeof preset === 'function') { - presetValue = preset(); - } - if (!Array.isArray(presetValue)) { - console.error(`preset: ${preset} 预设值必须是数组!`); - } else { - onChange?.( - formatDate(presetValue, { - format: formatRef.value.format, - autoSwap: true, - }) as DateValue[], - { - dayjsValue: presetValue.map((p) => parseToDayjs(p, formatRef.value.format)), - trigger: 'preset', - }, - ); - props.onPresetClick?.(context); - emit('preset-click', context); - } + onDateRangePickerPresetClickSharedFn({ + preset, + context, + onChange, + formatRef, + onPresetClick: props.onPresetClick, + emit, + }); } function onYearChange(nextVal: number, { partial }: { partial: DateRangePickerPartial }) { - let partialIndex = partial === 'start' ? 0 : 1; - if (props.enableTimePicker) partialIndex = activeIndex.value; - - let nextYear = [...year.value]; - nextYear[partialIndex] = nextVal; - let nextMonth = [...month.value]; - // 年/季度/月份场景下,头部只有年选择器 - const onlyYearSelect = ['year', 'quarter', 'month'].includes(props.mode); - - // 头部日期切换修正 - const correctedDate = dateCorrection(partialIndex, nextYear, nextMonth, onlyYearSelect); - nextYear = correctedDate.nextYear; - nextMonth = correctedDate.nextMonth; + const { + nextYear, nextMonth, onlyYearSelect, partialIndex, + } = onDateRangePickerYearChangeSharedFn(nextVal, { + partial, + enableTimePicker: props.enableTimePicker, + activeIndex, + mode: props.mode, + month, + year, + }); year.value = nextYear; if (!onlyYearSelect) month.value = nextMonth; @@ -325,38 +290,16 @@ export default defineComponent({ } function onMonthChange(nextVal: number, { partial }: { partial: DateRangePickerPartial }) { - let partialIndex = partial === 'start' ? 0 : 1; - if (props.enableTimePicker) partialIndex = activeIndex.value; - - const nextMonth = [...month.value]; - nextMonth[partialIndex] = nextVal; - // 保证左侧时间不大于右侧 - if (year[0] === year[1]) { - if (partialIndex === 0) { - // 操作了左侧区间, 处理右侧区间小于或等于左侧区间的场景,交互上始终报错右侧比左侧大 1 - if (nextMonth[1] <= nextMonth[0]) { - nextMonth[1] = nextMonth[0] + 1; - if (nextMonth[1] === 12) { - // 处理跨年的边界场景 - nextMonth[1] = 0; - year.value = [year.value?.[0], year.value?.[1] + 1]; - } - } - } - if (partialIndex === 1) { - // 操作了右侧区间, 处理右侧区间小于或等于左侧区间的场景,交互上始终报错左侧比右侧小 1 - nextMonth[0] = Math.min(nextMonth[0], nextMonth[1]); - if (nextMonth[0] >= nextMonth[1]) { - nextMonth[0] -= 1; - if (nextMonth[0] === -1) { - // 处理跨年的边界场景 - nextMonth[0] = 11; - year.value = [year.value?.[0] - 1, year.value?.[1]]; - } - } - } - } + const { nextYear, nextMonth, partialIndex } = onDateRangePickerMonthChangeSharedFn(nextVal, { + partial, + enableTimePicker: props.enableTimePicker, + activeIndex, + mode: props.mode, + month, + year, + }); + year.value = nextYear; month.value = nextMonth; props.onMonthChange?.({ diff --git a/src/date-picker/utils.ts b/src/date-picker/utils.ts index 44c3ce2cb..a9e11008e 100644 --- a/src/date-picker/utils.ts +++ b/src/date-picker/utils.ts @@ -1,4 +1,26 @@ // 用于头部日期切换修正 +import { ComputedRef, Ref } from '@vue/composition-api'; +import dayjs from 'dayjs'; +import { formatDate, parseToDayjs } from '../_common/js/date-picker/format'; +import { + subtractMonth, addMonth, DateValue, extractTimeObj, +} from '../_common/js/date-picker/utils'; +import { DateRangePickerPanelProps, TdDateRangePickerProps } from '..'; +import { DateRangePickerPartial } from './type'; + +type FormatRef = ComputedRef< + | { + format: string; + valueType: string; + timeFormat: string; + } + | { + format?: undefined; + valueType?: undefined; + timeFormat?: undefined; + } +>; + // eslint-disable-next-line import/prefer-default-export export function dateCorrection( partialIndex: number, @@ -47,3 +69,287 @@ export function dateCorrection( } return { nextYear, nextMonth }; } + +interface DateRangePickerJumperClickSharedFn { + trigger: 'prev' | 'current' | 'next'; + partial: DateRangePickerPartial; + mode: DateRangePickerPanelProps['mode']; + month: Ref; + year: Ref; +} + +/** + * DateRangePicker/DateRangePickerPanel 的日期选择器跳转公共函数 + */ +export function onDateRangePickerJumperClickSharedFn({ + trigger, + partial, + mode, + month, + year, +}: DateRangePickerJumperClickSharedFn) { + const partialIndex = partial === 'start' ? 0 : 1; + + const monthCountMap = { + date: 1, + week: 1, + month: 12, + quarter: 12, + year: 120, + }; + const monthCount = monthCountMap[mode] || 0; + const current = new Date(year.value[partialIndex], month.value[partialIndex]); + + let next = null; + if (trigger === 'prev') { + next = subtractMonth(current, monthCount); + } else if (trigger === 'current') { + next = new Date(); + } else if (trigger === 'next') { + next = addMonth(current, monthCount); + } + + let nextYear = [...year.value]; + nextYear[partialIndex] = next.getFullYear(); + let nextMonth = [...month.value]; + nextMonth[partialIndex] = next.getMonth(); + const onlyYearSelect = ['year', 'quarter', 'month'].includes(mode); + + // 头部日期切换修正 + const correctedDate = dateCorrection(partialIndex, nextYear, nextMonth, onlyYearSelect); + nextYear = correctedDate.nextYear; + nextMonth = correctedDate.nextMonth; + + return { nextYear, nextMonth, partialIndex }; +} + +interface DateRangePickerTimePickerSharedFn { + val: string; + activeIndex: Ref; + formatRef: FormatRef; + year: Ref; + month: Ref; + time: Ref; +} + +type Input_cacheValue = Ref; + +/** + * DateRangePicker/DateRangePickerPanel 的时间选择切换操作公共函数(当enableTimePicker为true) + */ +export function onDateRangePickerTimePickerChangeSharedFn( + { + val, activeIndex, formatRef, year, month, time, + }: DateRangePickerTimePickerSharedFn, + input_cacheValue: Input_cacheValue, +) { + const { + hours, minutes, seconds, milliseconds, meridiem, + } = extractTimeObj(val); + + const nextInputValue = Array.isArray(input_cacheValue.value) ? [...input_cacheValue.value] : [input_cacheValue.value]; + const changedInputValue = Array.isArray(input_cacheValue.value) ? input_cacheValue.value[activeIndex.value] : null; + const currentDate = !dayjs(changedInputValue, formatRef.value.format).isValid() + ? dayjs().year(year.value[activeIndex.value]).month(month.value[activeIndex.value]) + : dayjs(changedInputValue, formatRef.value.format); + // am pm 12小时制转化 24小时制 + let nextHours = hours; + if (/am/i.test(meridiem) && nextHours === 12) nextHours -= 12; + if (/pm/i.test(meridiem) && nextHours < 12) nextHours += 12; + + const nextDate = currentDate.hour(nextHours).minute(minutes).second(seconds).millisecond(milliseconds) + .toDate(); + nextInputValue[activeIndex.value] = nextDate; + + const nextTime = [...time.value]; + nextTime[activeIndex.value] = val; + + const isSelectedInstance = true; + + return { + nextTime, + nextInputValue, + isSelectedInstance, + }; +} + +interface DateRangePickerPresetClickSharedFn { + preset: any; + context: any; + onChange: TdDateRangePickerProps['onChange']; + formatRef: FormatRef; + onPresetClick: TdDateRangePickerProps['onPresetClick']; + emit: (event: string, context: any) => void; +} + +/** + * DateRangePicker/DateRangePickerPanel 的预设按钮点击公共函数 + */ +export function onDateRangePickerPresetClickSharedFn({ + preset, + context, + onChange, + formatRef, + onPresetClick, + emit, +}: DateRangePickerPresetClickSharedFn) { + let presetValue = preset; + if (typeof preset === 'function') { + presetValue = preset(); + } + if (!Array.isArray(presetValue)) { + console.error(`preset: ${preset} 预设值必须是数组!`); + } else { + onChange?.( + formatDate(presetValue, { + format: formatRef.value.format, + targetFormat: formatRef.value.valueType, + autoSwap: true, + }) as DateValue[], + { + dayjsValue: presetValue.map((p) => parseToDayjs(p, formatRef.value.format)), + trigger: 'preset', + }, + ); + onPresetClick?.(context); + emit('preset-click', context); + } +} + +interface DateRangePickerYearChangeSharedFn { + partial: DateRangePickerPartial; + enableTimePicker: boolean; + activeIndex: Ref; + year: Ref; + month: Ref; + mode: DateRangePickerPanelProps['mode']; +} +/** + * DateRangePicker/DateRangePickerPanel 的年份选择器改变公共函数 + */ +export function onDateRangePickerYearChangeSharedFn( + nextVal: number, + { + partial, enableTimePicker, activeIndex, year, month, mode, + }: DateRangePickerYearChangeSharedFn, +) { + let partialIndex = partial === 'start' ? 0 : 1; + if (enableTimePicker) partialIndex = activeIndex.value; + + let nextYear = [...year.value]; + let nextMonth = [...month.value]; + nextYear[partialIndex] = nextVal; + + // 年/季度/月份场景下,头部只有年选择器 + const onlyYearSelect = ['year', 'quarter', 'month'].includes(mode); + + // 头部日期切换修正 + const correctedDate = dateCorrection(partialIndex, nextYear, nextMonth, onlyYearSelect); + nextYear = correctedDate.nextYear; + nextMonth = correctedDate.nextMonth; + + return { + nextYear, + nextMonth, + onlyYearSelect, + partialIndex, + }; +} + +interface DateRangePickerMonthChangeChangeSharedFn { + partial: DateRangePickerPartial; + enableTimePicker: boolean; + activeIndex: Ref; + year: Ref; + month: Ref; + mode: DateRangePickerPanelProps['mode']; +} +/** + * DateRangePicker/DateRangePickerPanel 的月份选择器改变公共函数 + */ +export function onDateRangePickerMonthChangeSharedFn( + nextVal: number, + { + partial, enableTimePicker, activeIndex, year, month, + }: DateRangePickerMonthChangeChangeSharedFn, +) { + let partialIndex = partial === 'start' ? 0 : 1; + if (enableTimePicker) partialIndex = activeIndex.value; + + let nextYear = [...year.value]; + const nextMonth = [...month.value]; + nextMonth[partialIndex] = nextVal; + // 保证左侧时间不大于右侧 + if (year.value[0] === year.value[1]) { + if (partialIndex === 0) { + // 操作了左侧区间, 处理右侧区间小于或等于左侧区间的场景,交互上始终报错右侧比左侧大 1 + if (nextMonth[1] <= nextMonth[0]) { + nextMonth[1] = nextMonth[0] + 1; + if (nextMonth[1] === 12) { + // 处理跨年的边界场景 + nextMonth[1] = 0; + nextYear = [year.value?.[0], year.value?.[1] + 1]; + } + } + } + if (partialIndex === 1) { + // 操作了右侧区间, 处理右侧区间小于或等于左侧区间的场景,交互上始终报错左侧比右侧小 1 + nextMonth[0] = Math.min(nextMonth[0], nextMonth[1]); + if (nextMonth[0] >= nextMonth[1]) { + nextMonth[0] -= 1; + if (nextMonth[0] === -1) { + // 处理跨年的边界场景 + nextMonth[0] = 11; + nextYear = [year.value?.[0] - 1, year.value?.[1]]; + } + } + } + } + + return { + nextYear, + nextMonth, + partialIndex, + }; +} + +interface DatePickerJumperClickSharedFn { + trigger: string; + mode: DateRangePickerPanelProps['mode']; + month: Ref; + year: Ref; +} + +/** + * DatePicker/DatePickerPanel 的日期选择器跳转公共函数 + */ +export function onDatePickerJumperClickSharedFn({ + trigger, mode, month, year, +}: DatePickerJumperClickSharedFn) { + const monthCountMap = { + date: 1, + week: 1, + month: 12, + quarter: 12, + year: 120, + }; + const monthCount = monthCountMap[mode] || 0; + + const current = new Date(year.value, month.value); + + let next = null; + if (trigger === 'prev') { + next = subtractMonth(current, monthCount); + } else if (trigger === 'current') { + next = new Date(); + } else if (trigger === 'next') { + next = addMonth(current, monthCount); + } + + const nextYear = next.getFullYear(); + const nextMonth = next.getMonth(); + return { + nextYear, + nextMonth, + }; +} From 8740424b4d206e7ea3f80868fd473e4588f2e4c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=98=BFCai?= Date: Fri, 25 Oct 2024 11:06:57 +0800 Subject: [PATCH 2/3] chore: remove unused import --- src/date-picker/DatePicker.tsx | 4 +--- src/date-picker/DatePickerPanel.tsx | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/date-picker/DatePicker.tsx b/src/date-picker/DatePicker.tsx index 23a0475af..a996b1bd0 100644 --- a/src/date-picker/DatePicker.tsx +++ b/src/date-picker/DatePicker.tsx @@ -9,9 +9,7 @@ import useSingle from './hooks/useSingle'; import { parseToDayjs, getDefaultFormat, formatTime, formatDate, } from '../_common/js/date-picker/format'; -import { - subtractMonth, addMonth, extractTimeObj, covertToDate, -} from '../_common/js/date-picker/utils'; +import { extractTimeObj, covertToDate } from '../_common/js/date-picker/utils'; import type { DateValue } from './type'; import props from './props'; diff --git a/src/date-picker/DatePickerPanel.tsx b/src/date-picker/DatePickerPanel.tsx index d7c639729..2a8694a10 100644 --- a/src/date-picker/DatePickerPanel.tsx +++ b/src/date-picker/DatePickerPanel.tsx @@ -3,7 +3,7 @@ import dayjs from 'dayjs'; import useSingleValue from './hooks/useSingleValue'; import { formatDate, getDefaultFormat, parseToDayjs } from '../_common/js/date-picker/format'; -import { subtractMonth, addMonth, extractTimeObj } from '../_common/js/date-picker/utils'; +import { extractTimeObj } from '../_common/js/date-picker/utils'; import type { DateValue, TdDatePickerPanelProps, From 3d79cd83f217016186894b03ab7822aba639e4e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=98=BF=E8=8F=9C=20Cai?= Date: Thu, 31 Oct 2024 03:22:29 +0800 Subject: [PATCH 3/3] =?UTF-8?q?style:=20=E6=A0=87=E6=B3=A8=20type=20?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=E5=BC=95=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/date-picker/utils.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/date-picker/utils.ts b/src/date-picker/utils.ts index a9e11008e..ed37094c3 100644 --- a/src/date-picker/utils.ts +++ b/src/date-picker/utils.ts @@ -1,12 +1,12 @@ // 用于头部日期切换修正 -import { ComputedRef, Ref } from '@vue/composition-api'; +import { ComputedRef } from '@vue/composition-api'; +import type { Ref } from '@vue/composition-api'; import dayjs from 'dayjs'; import { formatDate, parseToDayjs } from '../_common/js/date-picker/format'; import { subtractMonth, addMonth, DateValue, extractTimeObj, } from '../_common/js/date-picker/utils'; -import { DateRangePickerPanelProps, TdDateRangePickerProps } from '..'; -import { DateRangePickerPartial } from './type'; +import type { DateRangePickerPartial, TdDateRangePickerProps, TdDateRangePickerPanelProps } from './type'; type FormatRef = ComputedRef< | { @@ -73,7 +73,7 @@ export function dateCorrection( interface DateRangePickerJumperClickSharedFn { trigger: 'prev' | 'current' | 'next'; partial: DateRangePickerPartial; - mode: DateRangePickerPanelProps['mode']; + mode: TdDateRangePickerPanelProps['mode']; month: Ref; year: Ref; } @@ -222,7 +222,7 @@ interface DateRangePickerYearChangeSharedFn { activeIndex: Ref; year: Ref; month: Ref; - mode: DateRangePickerPanelProps['mode']; + mode: TdDateRangePickerPanelProps['mode']; } /** * DateRangePicker/DateRangePickerPanel 的年份选择器改变公共函数 @@ -262,7 +262,7 @@ interface DateRangePickerMonthChangeChangeSharedFn { activeIndex: Ref; year: Ref; month: Ref; - mode: DateRangePickerPanelProps['mode']; + mode: TdDateRangePickerPanelProps['mode']; } /** * DateRangePicker/DateRangePickerPanel 的月份选择器改变公共函数 @@ -315,7 +315,7 @@ export function onDateRangePickerMonthChangeSharedFn( interface DatePickerJumperClickSharedFn { trigger: string; - mode: DateRangePickerPanelProps['mode']; + mode: TdDateRangePickerPanelProps['mode']; month: Ref; year: Ref; }