UNPKG

sard-uniapp

Version:

sard-uniapp 是一套基于 Uniapp + Vue3 框架开发的兼容多端的 UI 组件库

271 lines (270 loc) 10.3 kB
import { formatDate, getLunarDayName, getLunarLeapMonth, getLunarLeapMonthDays, getLunarMonthDays, getLunarMonthName, getDaysInMonth, isDate, clamp, solarToLunar, toDate, } from '../../utils'; import { defaultConfig } from '../config'; export const defaultDatetimePickerProps = defaultConfig.datetimePicker; export const getMinDate = () => { return new Date(new Date().getFullYear() - 10, 0, 1, 0, 0, 0); }; export const getMaxDate = () => { return new Date(new Date().getFullYear() + 10, 11, 31, 23, 59, 59); }; export const strategies = { y: [0, 4, 0, 0, (d) => d.getFullYear(), (d, val) => d.setFullYear(val)], M: [1, 2, 1, 12, (d) => d.getMonth() + 1, (d, val) => d.setMonth(val - 1)], d: [2, 2, 1, 31, (d) => d.getDate(), (d, val) => d.setDate(val)], h: [3, 2, 0, 23, (d) => d.getHours(), (d, val) => d.setHours(val)], m: [4, 2, 0, 59, (d) => d.getMinutes(), (d, val) => d.setMinutes(val)], s: [5, 2, 0, 59, (d) => d.getSeconds(), (d, val) => d.setSeconds(val)], }; export const letterArray = ['y', 'M', 'd', 'h', 'm', 's']; function getSolarBoundaryValue(isMax, endDate, currentDate) { const currEvery = [endDate.getFullYear()]; const minOrMaxIndex = isMax ? 3 : 2; let aside = true; let prevGetter = strategies.y[4]; letterArray.slice(1).forEach((letter, index) => { const strategy = strategies[letter]; let minOrMax = strategy[minOrMaxIndex]; if (isMax && letter === 'd') { minOrMax = getDaysInMonth(currentDate.getFullYear(), currentDate.getMonth()); } aside = aside && currEvery[index] === prevGetter(currentDate); currEvery[index + 1] = aside ? strategy[4](endDate) : minOrMax; prevGetter = strategy[4]; }); return currEvery; } function getLunarBoundaryValue(isMax, endDate, currentDate) { const lunarDate = solarToLunar(currentDate.getFullYear(), currentDate.getMonth() + 1, currentDate.getDate()); const lunarEndDate = solarToLunar(endDate.getFullYear(), endDate.getMonth() + 1, endDate.getDate()); const currEvery = [lunarEndDate.year]; const minOrMaxIndex = isMax ? 3 : 2; let aside = true; let prevGetter = strategies.y[4]; letterArray.slice(1).forEach((letter, index) => { const prevValue = currEvery[index]; const strategy = strategies[letter]; const currGetter = strategy[4]; let minOrMax = strategy[minOrMaxIndex]; if (isMax && letter === 'd') { minOrMax = lunarDate.month < 0 ? getLunarLeapMonthDays(lunarDate.year) : getLunarMonthDays(lunarDate.year, lunarDate.month); } let asideValue = 0; if (aside) { if (letter === 'M') { aside = lunarDate.year === prevValue; if (aside) { asideValue = lunarEndDate.month; } } else if (letter === 'd') { aside = lunarDate.month === prevValue; if (aside) { asideValue = lunarEndDate.day; } } else { aside = prevGetter(currentDate) === prevValue; if (aside) { asideValue = currGetter(currentDate); } } } currEvery[index + 1] = aside ? asideValue : minOrMax; prevGetter = currGetter; }); return currEvery; } export function getBoundaryValue(calendar, isMax, endDate, currentDate) { return calendar === 'solar' ? getSolarBoundaryValue(isMax, endDate, currentDate) : getLunarBoundaryValue(isMax, endDate, currentDate); } export function correctSolarDate(date, minDate, maxDate) { let minAside = true; let maxAside = true; let prevGetter = strategies.y[4]; letterArray.slice(1).forEach((letter, index) => { const strategy = strategies[letter]; let minValue = strategy[2]; let maxValue = strategy[3]; if (letter === 'd') { maxValue = getDaysInMonth(date[0], date[1] - 1); } const currGetter = strategy[4]; if ((minAside = minAside && prevGetter(minDate) === date[index])) { minValue = currGetter(minDate); } if ((maxAside = maxAside && prevGetter(maxDate) === date[index])) { maxValue = currGetter(maxDate); } date[index + 1] = clamp(date[index + 1], minValue, maxValue); prevGetter = currGetter; }); } export function correctLunarDate(date, minDate, maxDate) { const lunarMinDate = solarToLunar(minDate.getFullYear(), minDate.getMonth() + 1, minDate.getDate()); const lunarMaxDate = solarToLunar(maxDate.getFullYear(), maxDate.getMonth() + 1, maxDate.getDate()); const range = [ { value: 0, edge: true, date: minDate, lunarDate: lunarMinDate, }, { value: 0, edge: true, date: maxDate, lunarDate: lunarMaxDate, }, ]; let prevGetter = strategies.y[4]; letterArray.slice(1).forEach((letter, index) => { const prevValue = date[index]; const currIndex = index + 1; const currValue = date[currIndex]; const strategy = strategies[letter]; range[0].value = strategy[2]; range[1].value = strategy[3]; if (letter === 'd') { range[1].value = date[1] < 0 ? getLunarLeapMonthDays(date[0]) : getLunarMonthDays(date[0], date[1]); } let currGetter = strategy[4]; range.forEach((point) => { if (point.edge) { if (letter === 'M') { point.edge = point.lunarDate.year === prevValue; if (point.edge) { point.value = point.lunarDate.month; } } else if (letter === 'd') { point.edge = point.lunarDate.month === prevValue; if (point.edge) { point.value = point.lunarDate.day; } } else { point.edge = prevGetter(point.date) === prevValue; if (point.edge) { point.value = currGetter(point.date); } } } }); if (letter === 'M') { let min = range[0].value; let max = range[1].value; let value = currValue; if (min < 0) { min = Math.abs(min) + 0.5; } else if (max < 0) { max = Math.abs(max) + 0.5; } if (value < 0) { value = Math.abs(value) + 0.5; } value = clamp(value, min, max); date[currIndex] = value % 1 === 0.5 ? ~~value * -1 : value; } else { date[currIndex] = clamp(currValue, range[0].value, range[1].value); } if (letter === 'd') { currGetter = (date) => { return date === minDate ? lunarMinDate.day : lunarMaxDate.day; }; } prevGetter = currGetter; }); } export function correctDate(calendar, date, minDate, maxDate) { if (calendar === 'solar') { correctSolarDate(date, minDate, maxDate); } else { correctLunarDate(date, minDate, maxDate); } } export const getColumnData = (calendar, min, max, length, letter, currentDate, translate, filter, formatter) => { const lunarDate = solarToLunar(currentDate.getFullYear(), currentDate.getMonth() + 1, currentDate.getDate()); let column = Array(Math.abs(max) - Math.abs(min) + 1) .fill(0) .map((_, i) => ({ value: i + Math.abs(min), })); if (calendar === 'lunar' && letter === 'M') { if (min < 0) { column[0].value = min; } else if (max < 0) { column.push({ value: max, }); } else { const leapMonth = getLunarLeapMonth(lunarDate.year); if (leapMonth > 0 && leapMonth > min && leapMonth < max) { column.splice(column.findIndex((item) => item.value === leapMonth) + 1, 0, { value: -leapMonth, }); } } } if (filter) { column = column.filter((option, i) => filter(letter, option.value, currentDate, i)); } column.forEach((option) => { option.zerofill = String(option.value).padStart(length, '0'); if (calendar === 'solar') { option.label = option.zerofill + translate(letter); } else { switch (letter) { case 'M': option.label = getLunarMonthName(Math.abs(option.value), option.value < 0); break; case 'd': option.label = getLunarDayName(option.value); break; default: option.label = option.zerofill + translate(letter); break; } } }); if (formatter) { column.forEach((option, i) => { option.label = formatter(letter, option, currentDate, i) ?? option.label; }); } return column; }; export function getInitialValue(minDate, maxDate) { const value = new Date(); return value.getTime() < minDate.getTime() ? new Date(minDate) : value.getTime() > maxDate.getTime() ? new Date(maxDate) : value; } export const normalizeRangeValue = (minDate, maxDate, value, valueFormat) => { const [start, end] = value || []; const startValue = start || getInitialValue(minDate, maxDate); const endValue = end || getInitialValue(toDate(startValue, valueFormat), maxDate); return [ valueFormat && isDate(startValue) ? formatDate(startValue, valueFormat) : startValue, valueFormat && isDate(endValue) ? formatDate(endValue, valueFormat) : endValue, ]; };