UNPKG

qm-bus

Version:

千米公有云业务组件库

250 lines (229 loc) 6.84 kB
import React, { Component } from 'react' import { Input, Icon } from 'antd' import moment, { Moment } from 'moment' import 'moment/locale/zh-cn' import './time-select.less' moment.updateLocale('zh-cn', { week: { dow: 1, // 周一是一周的第一天 }, }) const add0 = (n) => (n < 10 ? `0${n}` : n) /** 根据moment(xx) 返回 xxxx年xx月 第x周 和 weekList */ function _computed(date) { const crtValue = date ? moment(date) : moment() // 先获取到本月的第一天 let firstDay = moment(crtValue).startOf('month') // 开始的日期 let startTime = firstDay.weekday() == 0 ? firstDay : firstDay.weekday(7) // 如果当前比本月的第一个数组还小,退回到上一个月去计算 if (crtValue.isBefore(startTime)) { firstDay = moment(crtValue.subtract(1, 'months')).startOf('month') startTime = firstDay.weekday() == 0 ? firstDay : firstDay.weekday(7) } const weekList = [] let endTime let weekIndex = 1 // 如果还在当前月份内 while (startTime.month() == crtValue.month()) { endTime = moment(startTime).weekday(6) weekList.push([moment(startTime), moment(endTime)]) if (date && !startTime.isAfter(date)) { weekIndex = weekList.length } startTime.add(7, 'days') } const month = crtValue.format('MM') const year = crtValue.format('YYYY') return { weekList, weekIndex, month, year, } } /** 根据xxxx年xx月 第x周 返回当前日期 如果x超过了最大 默认未最大周 */ function _getDate({ weekIndex, month, year }) { const firstDay = moment(year + '-' + add0(month), 'YYYY-MM') console.log(firstDay.isValid()) // 第一周初始值 let startTime = firstDay.weekday() == 0 ? firstDay : firstDay.weekday(7) return startTime.add(weekIndex - 1, 'weeks') } /** 显示这里有个格式化 */ function _formatDate({ month, year, weekIndex }, format = 'YYYY-MM 第w周') { month = Number(month) const dateString = format.replace( /([y]{2,4})(.+?)([m]{1,2})(.+?)([w]{1,2})(.+?)/i, (match, y, s1, m, s2, w, s3) => { let _y = y.length === 4 ? year : year.slice(2) let _m = m.length === 2 ? (month >= 10 ? month : `0${month}`) : month let _w = w.length === 2 ? `0${weekIndex}` : weekIndex return `${_y}${s1}${_m}${s2}${_w}${s3}` } ) return dateString } export default class WeekPicker extends Component { constructor(props) { super(props) this.container = null const { weekList, weekIndex, month, year } = _computed(props.value) this.state = { /** 日历弹窗是否展开 */ open: false, weekList, weekIndex, year, month, } } /** 显示日历弹窗 */ showPicker = () => { const { weekList, weekIndex, month, year } = _computed(this.props.value) this.setState({ open: true, weekList, weekIndex, year, month, }) } hidePicker = () => { this.setState({ open: false, }) } /** 上个月 */ prevMonth = () => { let { weekIndex } = this.state let month = Number(this.state.month) let year = Number(this.state.year) if (month == 1) { year-- month = 12 } else { month-- } const crtValue = _getDate({ month, year, weekIndex }) const { weekList, month: newMonth, year: newYear } = _computed(crtValue) this.setState({ month: newMonth, year: newYear, weekList, }) } /** 下个月 */ nextMonth = () => { let { weekIndex } = this.state let month = Number(this.state.month) let year = Number(this.state.year) if (month == 12) { year++ month = 1 } else { month++ } const crtValue = _getDate({ month, year, weekIndex }) const { weekList, month: newMonth, year: newYear } = _computed(crtValue) this.setState({ month: newMonth, year: newYear, weekList, }) } /** 选择某一周 */ selectHandle = (monday) => { const { weekList, weekIndex, month, year } = _computed(monday) this.props.onChange(monday) this.setState({ open: false, weekList, weekIndex, month, year, }) } render() { const { open, weekList, weekIndex, year, month } = this.state const { disabledDate, format, value } = this.props // 这里展示的内容 应该是根据props传递过来的 const dataString = _formatDate(_computed(value), format) return ( <span className="week-pick-box" style={this.props.style}> <Input placeholder="请选择日期" value={value ? dataString : null} onClick={this.showPicker} /> <Icon className="picker-suffix" type="calendar" /> {open && ( <Pick prevMonth={this.prevMonth} nextMonth={this.nextMonth} disabledDate={disabledDate} weekList={weekList} selectHandle={this.selectHandle} weekIndex={weekIndex} hidePicker={this.hidePicker} title={`${year}${month}`} /> )} </span> ) } } class Pick extends Component { componentDidMount() { document.addEventListener('click', this.clickOutsideHandle) } componentWillUnmount() { document.removeEventListener('click', this.clickOutsideHandle) } // 点击其他区域 需要关闭日期选择框 clickOutsideHandle = (e) => { if (e.target.offsetParent !== this.container) { this.props.hidePicker() } } render() { const { weekList, prevMonth, nextMonth, selectHandle, disabledDate, title, weekIndex, } = this.props return ( <div className="week-picker" ref={(el) => (this.container = el)}> <div className="picker-header"> <div className="pre-month" onClick={prevMonth}> <Icon type="double-left" /> </div> <div className="current-month">{title}</div> <div className="next-month" onClick={nextMonth}> <Icon type="double-right" /> </div> </div> <div className="picker-body"> {weekList.map((week, index) => { const [monday, sunday] = week let className = weekIndex === index + 1 ? 'text current' : 'text' const isDisabled = disabledDate(week) || false if (isDisabled) className += ' disabled' return ( <div className="picker-item"> <div onClick={!isDisabled && (() => selectHandle(monday))} className={className}>{`第${index + 1}周`}</div> <div className="range">{`${monday.format('MM.DD')}-${sunday.format('MM.DD')}`}</div> </div> ) })} </div> </div> ) } }