123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601 |
- import Day from './day'
- import WxData from './wxData'
- import Render from './render'
- import CalendarConfig from './config'
- import convertSolarLunar from './convertSolarLunar'
- import { GetDate, Logger, getDateTimeStamp } from './utils'
- const getDate = new GetDate()
- const logger = new Logger()
- class WeekMode extends WxData {
- constructor(component) {
- super(component)
- this.Component = component
- this.getCalendarConfig = CalendarConfig(this.Component).getCalendarConfig
- }
- /**
- * 周、月视图切换
- * @param {string} view 视图 [week, month]
- * @param {object} date {year: 2017, month: 11, day: 1}
- */
- switchWeek(view, date) {
- return new Promise((resolve, reject) => {
- const config = CalendarConfig(this.Component).getCalendarConfig()
- if (config.multi) return logger.warn('多选模式不能切换周月视图')
- const { selectedDay = [], curYear, curMonth } = this.getData('calendar')
- let currentDate = []
- let disableSelected = false
- if (!selectedDay.length) {
- currentDate = getDate.todayDate()
- currentDate.day = currentDate.date
- disableSelected = true
- // return this.__tipsWhenCanNotSwtich();
- } else {
- currentDate = selectedDay[0]
- }
- let selectedDate = date || currentDate
- const { year, month } = selectedDate
- const notInCurrentMonth = curYear !== year || curMonth !== month
- if (view === 'week') {
- if (this.Component.weekMode) return
- if ((selectedDay.length && notInCurrentMonth) || !selectedDay.length) {
- // return this.__tipsWhenCanNotSwtich();
- disableSelected = true
- selectedDate = {
- year: curYear,
- month: curMonth,
- day: selectedDate.day
- }
- }
- this.Component.weekMode = true
- this.setData({
- 'calendarConfig.weekMode': true
- })
- this.jump(selectedDate, disableSelected)
- .then(resolve)
- .catch(reject)
- } else {
- this.Component.weekMode = false
- this.setData({
- 'calendarConfig.weekMode': false
- })
- const disableSelected =
- (selectedDay.length && notInCurrentMonth) || !selectedDay.length
- Render(this.Component)
- .renderCalendar(curYear, curMonth, selectedDate.day, disableSelected)
- .then(resolve)
- .catch(reject)
- }
- })
- }
- /**
- * 更新当前年月
- */
- updateCurrYearAndMonth(type) {
- let { days, curYear, curMonth } = this.getData('calendar')
- const { month: firstMonth } = days[0]
- const { month: lastMonth } = days[days.length - 1]
- const lastDayOfThisMonth = getDate.thisMonthDays(curYear, curMonth)
- const lastDayOfThisWeek = days[days.length - 1]
- const firstDayOfThisWeek = days[0]
- if (
- (lastDayOfThisWeek.day + 7 > lastDayOfThisMonth ||
- (curMonth === firstMonth && firstMonth !== lastMonth)) &&
- type === 'next'
- ) {
- curMonth = curMonth + 1
- if (curMonth > 12) {
- curYear = curYear + 1
- curMonth = 1
- }
- } else if (
- (+firstDayOfThisWeek.day <= 7 ||
- (curMonth === lastMonth && firstMonth !== lastMonth)) &&
- type === 'prev'
- ) {
- curMonth = curMonth - 1
- if (curMonth <= 0) {
- curYear = curYear - 1
- curMonth = 12
- }
- }
- return {
- Uyear: curYear,
- Umonth: curMonth
- }
- }
- /**
- * 计算周视图下当前这一周和当月的最后一天
- */
- calculateLastDay() {
- const { days = [], curYear, curMonth } = this.getData('calendar')
- const lastDayInThisWeek = days[days.length - 1].day
- const lastDayInThisMonth = getDate.thisMonthDays(curYear, curMonth)
- return { lastDayInThisWeek, lastDayInThisMonth }
- }
- /**
- * 计算周视图下当前这一周第一天
- */
- calculateFirstDay() {
- const { days } = this.getData('calendar')
- const firstDayInThisWeek = days[0].day
- return { firstDayInThisWeek }
- }
- /**
- * 当月第一周所有日期范围
- * @param {number} year
- * @param {number} month
- * @param {boolean} firstDayOfWeekIsMon 每周是否配置为以周一开始
- */
- firstWeekInMonth(year, month, firstDayOfWeekIsMon) {
- let firstDay = getDate.dayOfWeek(year, month, 1)
- if (firstDayOfWeekIsMon && firstDay === 0) {
- firstDay = 7
- }
- const [, end] = [0, 7 - firstDay]
- let days = this.getData('calendar.days') || []
- if (this.Component.weekMode) {
- days = Day(this.Component).buildDate(year, month)
- }
- const daysCut = days.slice(0, firstDayOfWeekIsMon ? end + 1 : end)
- return daysCut
- }
- /**
- * 当月最后一周所有日期范围
- * @param {number} year
- * @param {number} month
- * @param {boolean} firstDayOfWeekIsMon 每周是否配置为以周一开始
- */
- lastWeekInMonth(year, month, firstDayOfWeekIsMon) {
- const lastDay = getDate.thisMonthDays(year, month)
- const lastDayWeek = getDate.dayOfWeek(year, month, lastDay)
- const [start, end] = [lastDay - lastDayWeek, lastDay]
- let days = this.getData('calendar.days') || []
- if (this.Component.weekMode) {
- days = Day(this.Component).buildDate(year, month)
- }
- const daysCut = days.slice(firstDayOfWeekIsMon ? start : start - 1, end)
- return daysCut
- }
- __getDisableDateTimestamp(config) {
- const { date, type } = config.disableMode || {}
- let disableDateTimestamp
- 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
- }
- }
- /**
- * 渲染日期之前初始化已选日期
- * @param {array} dates 当前日期数组
- */
- initSelectedDay(dates) {
- let datesCopy = [...dates]
- const { selectedDay = [] } = this.getData('calendar')
- const selectedDayStr = selectedDay.map(
- item => `${+item.year}-${+item.month}-${+item.day}`
- )
- const config = this.getCalendarConfig()
- const {
- disableDateTimestamp,
- disableType
- } = this.__getDisableDateTimestamp(config)
- datesCopy = datesCopy.map(item => {
- if (!item) return {}
- const dateTimestamp = getDateTimeStamp(item)
- let date = { ...item }
- if (
- selectedDayStr.includes(`${+date.year}-${+date.month}-${+date.day}`)
- ) {
- date.choosed = true
- } else {
- date.choosed = false
- }
- if (
- (disableType === 'after' && dateTimestamp > disableDateTimestamp) ||
- (disableType === 'before' && dateTimestamp < disableDateTimestamp)
- ) {
- date.disable = true
- }
- date = this.__setTodoWhenJump(date, config)
- if (config.showLunar) {
- date = this.__setSolarLunar(date)
- }
- if (config.highlightToday) {
- date = this.__highlightToday(date)
- }
- return date
- })
- return datesCopy
- }
- /**
- * 周视图下设置可选日期范围
- * @param {object} days 当前展示的日期
- */
- setEnableAreaOnWeekMode(dates = []) {
- let { enableAreaTimestamp = [], enableDaysTimestamp = [] } = this.getData(
- 'calendar'
- )
- dates.forEach(item => {
- const timestamp = getDate
- .newDate(item.year, item.month, item.day)
- .getTime()
- let setDisable = false
- if (enableAreaTimestamp.length) {
- if (
- (+enableAreaTimestamp[0] > +timestamp ||
- +timestamp > +enableAreaTimestamp[1]) &&
- !enableDaysTimestamp.includes(+timestamp)
- ) {
- setDisable = true
- }
- } else if (
- enableDaysTimestamp.length &&
- !enableDaysTimestamp.includes(+timestamp)
- ) {
- setDisable = true
- }
- if (setDisable) {
- item.disable = true
- item.choosed = false
- }
- const config = CalendarConfig(this.Component).getCalendarConfig()
- const {
- disableDateTimestamp,
- disableType
- } = this.__getDisableDateTimestamp(config)
- if (
- (disableType === 'before' && timestamp < disableDateTimestamp) ||
- (disableType === 'after' && timestamp > disableDateTimestamp)
- ) {
- item.disable = true
- }
- })
- }
- updateYMWhenSwipeCalendarHasSelected(dates) {
- const hasSelectedDate = dates.filter(date => date.choosed)
- if (hasSelectedDate && hasSelectedDate.length) {
- const { year, month } = hasSelectedDate[0]
- return {
- year,
- month
- }
- }
- return {}
- }
- /**
- * 计算下一周的日期
- */
- calculateNextWeekDays() {
- let { lastDayInThisWeek, lastDayInThisMonth } = this.calculateLastDay()
- let { curYear, curMonth } = this.getData('calendar')
- let days = []
- if (lastDayInThisMonth - lastDayInThisWeek >= 7) {
- const { Uyear, Umonth } = this.updateCurrYearAndMonth('next')
- curYear = Uyear
- curMonth = Umonth
- for (let i = lastDayInThisWeek + 1; i <= lastDayInThisWeek + 7; i++) {
- days.push({
- year: curYear,
- month: curMonth,
- day: i,
- week: getDate.dayOfWeek(curYear, curMonth, i)
- })
- }
- } else {
- for (let i = lastDayInThisWeek + 1; i <= lastDayInThisMonth; i++) {
- days.push({
- year: curYear,
- month: curMonth,
- day: i,
- week: getDate.dayOfWeek(curYear, curMonth, i)
- })
- }
- const { Uyear, Umonth } = this.updateCurrYearAndMonth('next')
- curYear = Uyear
- curMonth = Umonth
- for (let i = 1; i <= 7 - (lastDayInThisMonth - lastDayInThisWeek); i++) {
- days.push({
- year: curYear,
- month: curMonth,
- day: i,
- week: getDate.dayOfWeek(curYear, curMonth, i)
- })
- }
- }
- days = this.initSelectedDay(days)
- const {
- year: updateYear,
- month: updateMonth
- } = this.updateYMWhenSwipeCalendarHasSelected(days)
- if (updateYear && updateMonth) {
- curYear = updateYear
- curMonth = updateMonth
- }
- this.setEnableAreaOnWeekMode(days)
- this.setData(
- {
- 'calendar.curYear': curYear,
- 'calendar.curMonth': curMonth,
- 'calendar.days': days
- },
- () => {
- Day(this.Component).setDateStyle()
- }
- )
- }
- /**
- * 计算上一周的日期
- */
- calculatePrevWeekDays() {
- let { firstDayInThisWeek } = this.calculateFirstDay()
- let { curYear, curMonth } = this.getData('calendar')
- let days = []
- if (firstDayInThisWeek - 7 > 0) {
- const { Uyear, Umonth } = this.updateCurrYearAndMonth('prev')
- curYear = Uyear
- curMonth = Umonth
- for (let i = firstDayInThisWeek - 7; i < firstDayInThisWeek; i++) {
- days.push({
- year: curYear,
- month: curMonth,
- day: i,
- week: getDate.dayOfWeek(curYear, curMonth, i)
- })
- }
- } else {
- let temp = []
- for (let i = 1; i < firstDayInThisWeek; i++) {
- temp.push({
- year: curYear,
- month: curMonth,
- day: i,
- week: getDate.dayOfWeek(curYear, curMonth, i)
- })
- }
- const { Uyear, Umonth } = this.updateCurrYearAndMonth('prev')
- curYear = Uyear
- curMonth = Umonth
- const prevMonthDays = getDate.thisMonthDays(curYear, curMonth)
- for (
- let i = prevMonthDays - Math.abs(firstDayInThisWeek - 7);
- i <= prevMonthDays;
- i++
- ) {
- days.push({
- year: curYear,
- month: curMonth,
- day: i,
- week: getDate.dayOfWeek(curYear, curMonth, i)
- })
- }
- days = days.concat(temp)
- }
- days = this.initSelectedDay(days)
- const {
- year: updateYear,
- month: updateMonth
- } = this.updateYMWhenSwipeCalendarHasSelected(days)
- if (updateYear && updateMonth) {
- curYear = updateYear
- curMonth = updateMonth
- }
- this.setEnableAreaOnWeekMode(days)
- this.setData(
- {
- 'calendar.curYear': curYear,
- 'calendar.curMonth': curMonth,
- 'calendar.days': days
- },
- () => {
- Day(this.Component).setDateStyle()
- }
- )
- }
- calculateDatesWhenJump(
- { year, month, day },
- { firstWeekDays, lastWeekDays },
- firstDayOfWeekIsMon
- ) {
- const inFirstWeek = this.__dateIsInWeek({ year, month, day }, firstWeekDays)
- const inLastWeek = this.__dateIsInWeek({ year, month, day }, lastWeekDays)
- let dates = []
- if (inFirstWeek) {
- dates = this.__calculateDatesWhenInFirstWeek(
- firstWeekDays,
- firstDayOfWeekIsMon
- )
- } else if (inLastWeek) {
- dates = this.__calculateDatesWhenInLastWeek(
- lastWeekDays,
- firstDayOfWeekIsMon
- )
- } else {
- dates = this.__calculateDates({ year, month, day }, firstDayOfWeekIsMon)
- }
- return dates
- }
- jump({ year, month, day }, disableSelected) {
- return new Promise(resolve => {
- if (!day) return
- const config = this.getCalendarConfig()
- const firstDayOfWeekIsMon = config.firstDayOfWeek === 'Mon'
- const firstWeekDays = this.firstWeekInMonth(
- year,
- month,
- firstDayOfWeekIsMon
- )
- let lastWeekDays = this.lastWeekInMonth(year, month, firstDayOfWeekIsMon)
- let dates = this.calculateDatesWhenJump(
- { year, month, day },
- {
- firstWeekDays,
- lastWeekDays
- },
- firstDayOfWeekIsMon
- )
- dates = dates.map(d => {
- let date = { ...d }
- if (
- +date.year === +year &&
- +date.month === +month &&
- +date.day === +day &&
- !disableSelected
- ) {
- date.choosed = true
- }
- date = this.__setTodoWhenJump(date, config)
- if (config.showLunar) {
- date = this.__setSolarLunar(date)
- }
- if (config.highlightToday) {
- date = this.__highlightToday(date)
- }
- return date
- })
- this.setEnableAreaOnWeekMode(dates)
- const tmpData = {
- 'calendar.days': dates,
- 'calendar.curYear': year,
- 'calendar.curMonth': month,
- 'calendar.empytGrids': [],
- 'calendar.lastEmptyGrids': []
- }
- if (!disableSelected) {
- tmpData['calendar.selectedDay'] = dates.filter(item => item.choosed)
- }
- this.setData(tmpData, () => {
- Day(this.Component).setDateStyle()
- resolve({ year, month, date: day })
- })
- })
- }
- __setTodoWhenJump(dateInfo) {
- const date = { ...dateInfo }
- const { todoLabels = [], showLabelAlways } = this.getData('calendar')
- const todosStr = todoLabels.map(d => `${+d.year}-${+d.month}-${+d.day}`)
- const idx = todosStr.indexOf(`${+date.year}-${+date.month}-${+date.day}`)
- if (idx !== -1) {
- if (showLabelAlways) {
- date.showTodoLabel = true
- } else {
- date.showTodoLabel = !date.choosed
- }
- const todo = todoLabels[idx] || {}
- if (date.showTodoLabel && todo.todoText) date.todoText = todo.todoText
- if (todo.color) date.color = todo.color
- }
- return date
- }
- __setSolarLunar(dateInfo) {
- const date = { ...dateInfo }
- date.lunar = convertSolarLunar.solar2lunar(
- +date.year,
- +date.month,
- +date.day
- )
- return date
- }
- __highlightToday(dateInfo) {
- const date = { ...dateInfo }
- const today = getDate.todayDate()
- const isToday =
- +today.year === +date.year &&
- +today.month === +date.month &&
- +date.day === +today.date
- date.isToday = isToday
- return date
- }
- __calculateDatesWhenInFirstWeek(firstWeekDays) {
- const dates = [...firstWeekDays]
- if (dates.length < 7) {
- let { year, month } = dates[0]
- let len = 7 - dates.length
- let lastDate
- if (month > 1) {
- month -= 1
- lastDate = getDate.thisMonthDays(year, month)
- } else {
- month = 12
- year -= 1
- lastDate = getDate.thisMonthDays(year, month)
- }
- while (len) {
- dates.unshift({
- year,
- month,
- day: lastDate,
- week: getDate.dayOfWeek(year, month, lastDate)
- })
- lastDate -= 1
- len -= 1
- }
- }
- return dates
- }
- __calculateDatesWhenInLastWeek(lastWeekDays) {
- const dates = [...lastWeekDays]
- if (dates.length < 7) {
- let { year, month } = dates[0]
- let len = 7 - dates.length
- let firstDate = 1
- if (month > 11) {
- month = 1
- year += 1
- } else {
- month += 1
- }
- while (len) {
- dates.push({
- year,
- month,
- day: firstDate,
- week: getDate.dayOfWeek(year, month, firstDate)
- })
- firstDate += 1
- len -= 1
- }
- }
- return dates
- }
- __calculateDates({ year, month, day }, firstDayOfWeekIsMon) {
- const week = getDate.dayOfWeek(year, month, day)
- let range = [day - week, day + (6 - week)]
- if (firstDayOfWeekIsMon) {
- range = [day + 1 - week, day + (7 - week)]
- }
- const dates = Day(this.Component).buildDate(year, month)
- const weekDates = dates.slice(range[0] - 1, range[1])
- return weekDates
- }
- __dateIsInWeek(date, week) {
- return week.find(
- item =>
- +item.year === +date.year &&
- +item.month === +date.month &&
- +item.day === +date.day
- )
- }
- __tipsWhenCanNotSwtich() {
- logger.info(
- '当前月份未选中日期下切换为周视图,不能明确该展示哪一周的日期,故此情况不允许切换'
- )
- }
- }
- export default component => new WeekMode(component)
|