import dayjs, { Dayjs } from 'dayjs' import _flow from 'lodash/flow' import Calendar from '../types' import plugins from './plugins' import * as constant from './constant' const TOTAL = 7 * 6 function getFullItem( item: Partial, options: Calendar.GroupOptions, selectedDate: Calendar.SelectedDate, isShowStatus?: boolean ) { if (!isShowStatus) return item const bindedPlugins = plugins.map(fn => fn.bind(null, { options, selectedDate }) ) return _flow(bindedPlugins)(item) } export default function generateCalendarGroup( options: Calendar.GroupOptions ): ( generateDate: number, selectedDate: Calendar.SelectedDate, isShowStatus?: boolean ) => Calendar.ListInfo { return function ( generateDate: number, selectedDate: Calendar.SelectedDate, isShowStatus?: boolean ): Calendar.ListInfo { const date = dayjs(generateDate) const { format, collapse } = options const list: Calendar.List = [] // 折叠成显示一周 if (collapse) { const firstDateDay = date.day(); // 获取当前周的前几天 for (let i = 1; i <= firstDateDay; i++) { const thisDate = date.subtract(i, 'day').startOf('day'); let item = { marks: [], _value: thisDate, text: thisDate.date(), type: getTypeOfMonth(thisDate, date), value: thisDate.format(format) } item = getFullItem(item, options, selectedDate, isShowStatus) list.push(item) } list.reverse(); let item = { marks: [], _value: date, text: date.date(), type: constant.TYPE_NOW_MONTH, value: date.format(format) } item = getFullItem(item, options, selectedDate, isShowStatus) list.push(item) // 获取当前周的后几天 let i = 1 while (list.length < 7 ) { const thisDate = date.add(i++, 'day').startOf('day') let item = { marks: [], _value: thisDate, text: thisDate.date(), type: getTypeOfMonth(thisDate, date), value: thisDate.format(format) } item = getFullItem(item, options, selectedDate, isShowStatus) list.push(item) } } // 展开成显示一 else { // 获取生成日期的第一天 和 最后一天 const firstDate = date.startOf('month') const lastDate = date.endOf('month') const preMonthDate = date.subtract(1, 'month') const nowMonthDays: number = date.daysInMonth() // 获取这个月有多少天 const preMonthLastDay = preMonthDate.endOf('month').day() // 获取上个月最后一天是周几 // 生成上个月的日期 for (let i = 1; i <= preMonthLastDay + 1; i++) { const thisDate = firstDate.subtract(i, 'day').startOf('day') let item = { marks: [], _value: thisDate, text: thisDate.date(), type: constant.TYPE_PRE_MONTH, value: thisDate.format(format) } item = getFullItem(item, options, selectedDate, isShowStatus) list.push(item) } list.reverse() // 生成这个月的日期 for (let i = 0; i < nowMonthDays; i++) { const thisDate = firstDate.add(i, 'day').startOf('day') let item = { marks: [], _value: thisDate, text: thisDate.date(), type: constant.TYPE_NOW_MONTH, value: thisDate.format(format) } item = getFullItem(item, options, selectedDate, isShowStatus) list.push(item) } // 生成下个月的日期 let i = 1 while (list.length < TOTAL) { const thisDate = lastDate.add(i++, 'day').startOf('day') let item = { marks: [], _value: thisDate, text: thisDate.date(), type: constant.TYPE_NEXT_MONTH, value: thisDate.format(format) } item = getFullItem(item, options, selectedDate, isShowStatus) list.push(item) } } return { list, value: generateDate } } } export function getGenerateDate(date: Calendar.DateArg | undefined): Dayjs { return dayjs(date).startOf('month') } export function getTypeOfMonth(date: dayjs.Dayjs, contrastMonthDate: dayjs.Dayjs): number { const month = date.month(); const contrastMonth = contrastMonthDate.month(); if(month < contrastMonth) { return constant.TYPE_PRE_MONTH; } else if (month > contrastMonth) { return constant.TYPE_NEXT_MONTH; } else { return constant.TYPE_NOW_MONTH; } }