123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375 |
- import Day from './day'
- import Todo from './todo'
- import WxData from './wxData'
- import convertSolarLunar from './convertSolarLunar'
- import {
- Logger,
- GetDate,
- delRepeatedEnableDay,
- getDateTimeStamp,
- converEnableDaysToTimestamp
- } from './utils'
- const getDate = new GetDate()
- const logger = new Logger()
- class Calendar extends WxData {
- constructor(component) {
- super(component)
- this.Component = component
- }
- getCalendarConfig() {
- return this.Component.config
- }
- /**
- * 渲染日历
- * @param {number} curYear 年份
- * @param {number} curMonth 月份
- * @param {number} curDate 日期
- * @param {boolean} disableSelect 是否禁用选中
- */
- renderCalendar(curYear, curMonth, curDate, disableSelect) {
- return new Promise(resolve => {
- const config = this.getCalendarConfig()
- this.calculateEmptyGrids(curYear, curMonth)
- this.calculateDays(curYear, curMonth, curDate, disableSelect).then(() => {
- const { todoLabels, specialStyleDates, enableDays, selectedDay } =
- this.getData('calendar') || {}
- if (
- todoLabels &&
- todoLabels.find(
- item => +item.month === +curMonth && +item.year === +curYear
- )
- ) {
- Todo(this.Component).setTodoLabels()
- }
- if (
- specialStyleDates &&
- specialStyleDates.length &&
- specialStyleDates.find(
- item => +item.month === +curMonth && +item.year === +curYear
- )
- ) {
- Day(this.Component).setDateStyle(specialStyleDates)
- }
- if (
- enableDays &&
- enableDays.length &&
- enableDays.find(item => {
- let ymd = item.split('-')
- return +ymd[1] === +curMonth && +ymd[0] === +curYear
- })
- ) {
- Day(this.Component).enableDays(enableDays)
- }
- if (
- selectedDay &&
- selectedDay.length &&
- selectedDay.find(
- item => +item.month === +curMonth && +item.year === +curYear
- ) &&
- config.mulit
- ) {
- Day(this.Component).setSelectedDays(selectedDay)
- }
- if (!this.Component.firstRender) {
- resolve({
- firstRender: true
- })
- } else {
- resolve({
- firstRender: false
- })
- }
- })
- })
- }
- /**
- * 计算当前月份前后两月应占的格子
- * @param {number} year 年份
- * @param {number} month 月份
- */
- calculateEmptyGrids(year, month) {
- this.calculatePrevMonthGrids(year, month)
- this.calculateNextMonthGrids(year, month)
- }
- /**
- * 计算上月应占的格子
- * @param {number} year 年份
- * @param {number} month 月份
- */
- calculatePrevMonthGrids(year, month) {
- let empytGrids = []
- const prevMonthDays = getDate.thisMonthDays(year, month - 1)
- let firstDayOfWeek = getDate.firstDayOfWeek(year, month)
- const config = this.getCalendarConfig() || {}
- if (config.firstDayOfWeek === 'Mon') {
- if (firstDayOfWeek === 0) {
- firstDayOfWeek = 6
- } else {
- firstDayOfWeek -= 1
- }
- }
- if (firstDayOfWeek > 0) {
- const len = prevMonthDays - firstDayOfWeek
- const { onlyShowCurrentMonth } = config
- const { showLunar } = this.getCalendarConfig()
- for (let i = prevMonthDays; i > len; i--) {
- if (onlyShowCurrentMonth) {
- empytGrids.push('')
- } else {
- empytGrids.push({
- day: i,
- lunar: showLunar
- ? convertSolarLunar.solar2lunar(year, month - 1, i)
- : null
- })
- }
- }
- this.setData({
- 'calendar.empytGrids': empytGrids.reverse()
- })
- } else {
- this.setData({
- 'calendar.empytGrids': null
- })
- }
- }
- /**
- * 计算下一月日期是否需要多展示的日期
- * 某些月份日期为5排,某些月份6排,统一为6排
- * @param {number} year
- * @param {number} month
- * @param {object} config
- */
- calculateExtraEmptyDate(year, month, config) {
- let extDate = 0
- if (+month === 2) {
- extDate += 7
- let firstDayofMonth = getDate.dayOfWeek(year, month, 1)
- if (config.firstDayOfWeek === 'Mon') {
- if (+firstDayofMonth === 1) extDate += 7
- } else {
- if (+firstDayofMonth === 0) extDate += 7
- }
- } else {
- let firstDayofMonth = getDate.dayOfWeek(year, month, 1)
- if (config.firstDayOfWeek === 'Mon') {
- if (firstDayofMonth !== 0 && firstDayofMonth < 6) {
- extDate += 7
- }
- } else {
- if (firstDayofMonth <= 5) {
- extDate += 7
- }
- }
- }
- return extDate
- }
- /**
- * 计算下月应占的格子
- * @param {number} year 年份
- * @param {number} month 月份
- */
- calculateNextMonthGrids(year, month) {
- let lastEmptyGrids = []
- const thisMonthDays = getDate.thisMonthDays(year, month)
- let lastDayWeek = getDate.dayOfWeek(year, month, thisMonthDays)
- const config = this.getCalendarConfig() || {}
- if (config.firstDayOfWeek === 'Mon') {
- if (lastDayWeek === 0) {
- lastDayWeek = 6
- } else {
- lastDayWeek -= 1
- }
- }
- let len = 7 - (lastDayWeek + 1)
- const { onlyShowCurrentMonth, showLunar } = config
- if (!onlyShowCurrentMonth) {
- len = len + this.calculateExtraEmptyDate(year, month, config)
- }
- for (let i = 1; i <= len; i++) {
- if (onlyShowCurrentMonth) {
- lastEmptyGrids.push('')
- } else {
- lastEmptyGrids.push({
- day: i,
- lunar: showLunar
- ? convertSolarLunar.solar2lunar(year, month + 1, i)
- : null
- })
- }
- }
- this.setData({
- 'calendar.lastEmptyGrids': lastEmptyGrids
- })
- }
- /**
- * 日历初始化将默认值写入 selectDay
- * @param {number} year
- * @param {number} month
- * @param {number} curDate
- */
- setSelectedDay(year, month, curDate) {
- let selectedDay = []
- const config = this.getCalendarConfig()
- if (config.noDefault) {
- selectedDay = []
- config.noDefault = false
- } else {
- const data = this.getData('calendar') || {}
- const { showLunar } = this.getCalendarConfig()
- selectedDay = curDate
- ? [
- {
- year,
- month,
- day: curDate,
- choosed: true,
- week: getDate.dayOfWeek(year, month, curDate),
- lunar: showLunar
- ? convertSolarLunar.solar2lunar(year, month, curDate)
- : null
- }
- ]
- : data.selectedDay
- }
- return selectedDay
- }
- __getDisableDateTimestamp() {
- let disableDateTimestamp
- const { date, type } = this.getCalendarConfig().disableMode || {}
- if (date) {
- const t = date.split('-')
- if (t.length < 3) {
- logger.warn('配置 disableMode.date 格式错误')
- return {}
- }
- disableDateTimestamp = getDateTimeStamp({
- year: +t[0],
- month: +t[1],
- day: +t[2]
- })
- }
- return {
- disableDateTimestamp,
- disableType: type
- }
- }
- resetDates() {
- this.setData({
- 'calendar.days': []
- })
- }
- /**
- * 设置日历面板数据
- * @param {number} year 年份
- * @param {number} month 月份
- * @param {number} curDate 日期
- * @param {boolean} disableSelect 是否禁用选中
- */
- calculateDays(year, month, curDate, disableSelect) {
- return new Promise(resolve => {
- // 避免切换日期时样式残影
- this.resetDates()
- let days = []
- const {
- disableDays = [],
- chooseAreaTimestamp = [],
- selectedDay: selectedDates = []
- } = this.getData('calendar')
- days = Day(this.Component).buildDate(year, month)
- let selectedDay = selectedDates
- if (!disableSelect) {
- selectedDay = this.setSelectedDay(year, month, curDate)
- }
- const selectedDayStr = selectedDay.map(d => getDate.toTimeStr(d))
- const disableDaysStr = disableDays.map(d => getDate.toTimeStr(d))
- const [areaStart, areaEnd] = chooseAreaTimestamp
- days.forEach(item => {
- const cur = getDate.toTimeStr(item)
- const timestamp = getDateTimeStamp(item)
- if (selectedDayStr.includes(cur) && !disableSelect) {
- item.choosed = true
- if (timestamp > areaEnd || timestamp < areaStart) {
- const idx = selectedDay.findIndex(
- selectedDate =>
- getDate.toTimeStr(selectedDate) === getDate.toTimeStr(item)
- )
- selectedDay.splice(idx, 1)
- }
- } else if (
- areaStart &&
- areaEnd &&
- timestamp >= areaStart &&
- timestamp <= areaEnd &&
- !disableSelect
- ) {
- item.choosed = true
- selectedDay.push(item)
- }
- if (disableDaysStr.includes(cur)) item.disable = true
- const {
- disableDateTimestamp,
- disableType
- } = this.__getDisableDateTimestamp()
- let disabelByConfig = false
- if (disableDateTimestamp) {
- if (
- (disableType === 'before' && timestamp < disableDateTimestamp) ||
- (disableType === 'after' && timestamp > disableDateTimestamp)
- ) {
- disabelByConfig = true
- }
- }
- const isDisable = disabelByConfig || this.__isDisable(timestamp)
- if (isDisable) {
- item.disable = true
- item.choosed = false
- }
- })
- this.setData(
- {
- 'calendar.days': days,
- 'calendar.selectedDay': [...selectedDay] || []
- },
- () => {
- resolve()
- }
- )
- })
- }
- __isDisable(timestamp) {
- const {
- enableArea = [],
- enableDays = [],
- enableAreaTimestamp = []
- } = this.getData('calendar')
- let setDisable = false
- let expectEnableDaysTimestamp = converEnableDaysToTimestamp(enableDays)
- if (enableArea.length) {
- expectEnableDaysTimestamp = delRepeatedEnableDay(enableDays, enableArea)
- }
- if (enableAreaTimestamp.length) {
- if (
- (+enableAreaTimestamp[0] > +timestamp ||
- +timestamp > +enableAreaTimestamp[1]) &&
- !expectEnableDaysTimestamp.includes(+timestamp)
- ) {
- setDisable = true
- }
- } else if (
- expectEnableDaysTimestamp.length &&
- !expectEnableDaysTimestamp.includes(+timestamp)
- ) {
- setDisable = true
- }
- return setDisable
- }
- }
- export default component => new Calendar(component)
|