import { getDaysInDate } from './getDaysInDate'; import type { Mode } from './index'; export interface Data { label: string; value: string | number; children?: Data[]; } interface Params { minDate: Date; maxDate: Date; mode: Mode; } interface DateData { /** 只触发了最小时间 */ min: Data[]; /** 只触发了最大时间 */ max: Data[]; /** 最小和最大都没触发 */ normal: Data[]; /** 同时触发了最小和最大 */ between: Data[]; } /** 创建范围数据 */ function createRangeData(min: number, max: number, unit: string, children?: Data[]): Data[] { const data: Data[] = []; for (let i = min; i <= max; i++) { data.push({ label: i + unit, value: i, children }); } return data; } /** 获取分钟的数据 */ function getMinuteData(minDate: Date, maxDate: Date): DateData { const unit = '分'; return { min: createRangeData(minDate.getMinutes(), 59, unit), max: createRangeData(0, maxDate.getMinutes(), unit), normal: createRangeData(0, 59, unit), between: createRangeData(minDate.getMinutes(), maxDate.getMinutes(), unit) }; } /** 获取小时的数据 */ function getHourData(minDate: Date, maxDate: Date): DateData { const unit = '时'; return { min: createRangeData(minDate.getHours(), 23, unit), max: createRangeData(0, maxDate.getHours(), unit), normal: createRangeData(0, 23, unit), between: createRangeData(minDate.getHours(), maxDate.getHours(), unit) }; } /** 获取年份的数据 */ function getYearData(minDate: Date, maxDate: Date): DateData { const unit = '年'; return { min: [], max: [], normal: [], between: createRangeData(minDate.getFullYear(), maxDate.getFullYear(), unit) }; } /** 获取月份的数据 */ function getMonthData(minDate: Date, maxDate: Date): DateData { const unit = '月'; return { min: createRangeData(minDate.getMonth() + 1, 12, unit), max: createRangeData(1, maxDate.getMonth() + 1, unit), normal: createRangeData(1, 12, unit), between: createRangeData(minDate.getMonth() + 1, maxDate.getMonth() + 1, unit) }; } /** 获取联合类型的数据 */ function getUnionData(parent: Data[], children: DateData): Data[] { const minSlice = children.min; const maxSlice = children.max; const normalSlice = children.normal; const betweenSlice = children.between; if (parent.length > 1) { for (let i = 0; i < parent.length; i++) { if (i === 0) { parent[i].children = minSlice; } else if (i === parent.length - 1) { parent[i].children = maxSlice; } else { parent[i].children = normalSlice; } } } else { parent[0].children = betweenSlice; } return parent; } /** 获取年月日类型的数据 */ function getDateData(minDate: Date, maxDate: Date): Data[] { const yearData = getYearData(minDate, maxDate).between; const monthData = getMonthData(minDate, maxDate); // 为了解决闰年也是28天的问题 const yearmonth = JSON.parse(JSON.stringify(getUnionData(yearData, monthData))); const unit = '日'; for (let i = 0; i < yearmonth.length; i++) { const month = yearmonth[i].children; if (month && month.length) { for (let l = 0; l < month.length; l++) { const date = new Date(yearmonth[i].value as number, month[l].value as number - 1); const child = month[l].children; if (minDate.getFullYear() === yearmonth[i].value && minDate.getMonth() + 1 === month[l].value && month.length === 1) { month[l].children = createRangeData(minDate.getDate(), getDaysInDate(minDate).length, unit); } else if (i === 0 && l === 0) { month[l].children = createRangeData(minDate.getDate(), getDaysInDate(minDate).length, unit); } else if (i === yearmonth.length - 1 && l === month.length - 1) { month[l].children = createRangeData(1, maxDate.getDate(), unit); } else if ((child && child.length === 0) || child === undefined) { month[l].children = createRangeData(1, getDaysInDate(date).length, unit); } } } else { month[0].children = createRangeData(getDaysInDate(minDate).length, getDaysInDate(maxDate).length, unit); } } return yearmonth; } /** 生成时间范围的数据 */ export function createRangeDate(params: Params): Data[] { const { minDate, maxDate, mode } = params; let yearData!: Data[]; let monthData!: DateData; let hourData!: DateData | Data[]; let minuteData!: DateData; switch (mode) { case 'HHmm': hourData = getHourData(minDate, maxDate).between; minuteData = getMinuteData(minDate, maxDate); return getUnionData(hourData, minuteData); case 'yyMM': yearData = getYearData(minDate, maxDate).between; monthData = getMonthData(minDate, maxDate); return getUnionData(yearData, monthData); case 'yyMMdd': return getDateData(minDate, maxDate); case 'yyMMddHHmm': const yearmonth = getDateData(minDate, maxDate); hourData = getHourData(minDate, maxDate); minuteData = getMinuteData(minDate, maxDate); const hourEach = (type: 'min' | 'max' | 'normal' | 'between', parent: Data[]) => { if (parent.length) { for (let i = 0; i < parent.length; i++) { if (i === 0 && type === 'min') { parent[i].children = minuteData.min; } else if (i === parent.length - 1 && type === 'max') { parent[i].children = minuteData.max; } else { parent[i].children = minuteData.normal; } } } else if (type === 'between') { parent[0].children = minuteData.between; } }; for (let y = 0; y < yearmonth.length; y++) { const month = yearmonth[y].children as Data[]; for (let m = 0; m < month.length; m++) { const day = month[m].children as Data[]; if (day.length) { for (let d = 0; d < day.length; d++) { if (d === 0 && y === 0 && m === 0) { day[d].children = hourData.min; hourEach('min', hourData.min); } else if (d === day.length - 1 && y === yearmonth.length - 1 && m === month.length - 1) { day[d].children = hourData.max; hourEach('max', hourData.max); } else { day[d].children = hourData.normal; hourEach('normal', hourData.normal); } } } else { day[0].children = hourData.between; hourEach('between', hourData.between); } } } return yearmonth; default: return []; } }