king
2021-09-01 31ec63f0419895876cbaba99637a884a32d33d0d
src/tabviews/zshare/calendar/index.jsx
@@ -1,10 +1,9 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import { Select, Radio, Row, Col, Popover, Badge } from 'antd'
import { Select, Radio, Row, Col, Popover, Badge, Spin } from 'antd'
import moment from 'moment'
// import Utils from '@/utils/utils.js'
import './index.scss'
const { Option } = Select
@@ -12,7 +11,10 @@
class Calendar extends Component {
  static propTpyes = {
    data: PropTypes.any,            // 事件数据
    levels: PropTypes.any
    calendar: PropTypes.any,
    changeDate: PropTypes.func,
    triggerDate: PropTypes.func,
    loading: false
  }
  state = {
@@ -22,11 +24,11 @@
    selectYear: moment().format('YYYY'),
    selectMonth: moment().format('MM'),
    datelist: null,
    monthlist: null,
    monthlist: null
  }
  UNSAFE_componentWillMount() {
    const { levels } = this.props
    const { calendar, data } = this.props
    let yearlist = []
    let _selectYear = +this.state.selectYear
@@ -38,19 +40,16 @@
    }
    let datelist = this.getDateList(this.state.selectYear)
    let _levels = null
    if (!levels) {
      _levels = ['day', 'month', 'year']
    } else {
      _levels = levels
    if (data && data.length > 0) {
      datelist = this.mountdata(datelist, data)
    }
    let _levels = calendar.levels
    let level = _levels[0]
    let monthlist = null
    level = 'month'
    if (_levels.includes('month')) {
    if (_levels.includes('month') || _levels.includes('year')) {
      monthlist = datelist.filter(item => item.month === moment().format('MM'))[0]
    }
@@ -65,12 +64,110 @@
  UNSAFE_componentWillReceiveProps(nextProps) {
    if (!is(fromJS(this.props.data), fromJS(nextProps.data))) {
      let datelist = this.getDateList(this.state.selectYear)
      let monthlist = null
      
      datelist = this.mountdata(datelist, nextProps.data)
      if (this.state.levels.includes('month') || this.state.levels.includes('year')) {
        monthlist = datelist.filter(item => item.month === this.state.selectMonth)[0]
      }
      this.setState({
        datelist: datelist,
        monthlist
      })
    } else if (!is(fromJS(this.props.calendar), fromJS(nextProps.calendar))) {
      this.setState({
        levels: nextProps.calendar.levels
      })
    }
  }
  shouldComponentUpdate (nextProps, nextState) {
    return !is(fromJS(this.state), fromJS(nextState))
    return !is(fromJS(this.props.loading), fromJS(nextProps.loading)) || !is(fromJS(this.state), fromJS(nextState))
  }
  mountdata = (datelist, data) => {
    const { calendar } = this.props
    let datalist = []
    let colors = {
      transparent: 'rgba(0, 0, 0, 0)',
      red: 'rgba(208, 2, 27, 1)',
      orange: 'rgba(245, 166, 35, 1)',
      yellow: 'rgba(248, 231, 28, 1)',
      green: 'rgba(126, 211, 33, 1)',
      cyan: 'rgba(80, 227, 194, 1)',
      blue: 'rgba(24, 144, 255, 1)',
      purple: 'rgba(189, 16, 224, 1)',
      gray: 'rgba(155, 155, 155, 1)'
    }
    data && data.forEach(item => {
      let startTime = item[calendar.startfield]
      let endTime = item[calendar.endfield]
      let color = item[calendar.colorfield]
      if (!startTime || !/^(1|2)\d{3}(-|\/)\d{2}(-|\/)\d{2}/.test(startTime)) return
      if (!endTime || !/^(1|2)\d{3}(-|\/)\d{2}(-|\/)\d{2}/.test(endTime)) return
      if (!item[calendar.remarkfield]) return
      let equal = endTime.substr(0, 4) === startTime.substr(0, 4)
      datalist.push({
        color: colors[color] || color,
        remark: item[calendar.remarkfield],
        startMonth: startTime.substr(0, 4) + startTime.substr(5, 2),
        endMonth: endTime.substr(0, 4) + endTime.substr(5, 2),
        start: startTime.substr(0, 4) + startTime.substr(5, 2) + startTime.substr(8, 2),
        startTime: equal ? `${startTime.substr(5, 2)}-${startTime.substr(8, 2)}` : `${startTime.substr(0, 4)}-${startTime.substr(5, 2)}-${startTime.substr(8, 2)}`,
        end: endTime.substr(0, 4) + endTime.substr(5, 2) + endTime.substr(8, 2),
        endTime: equal ?  `${endTime.substr(5, 2)}-${endTime.substr(8, 2)}` : `${endTime.substr(0, 4)}-${endTime.substr(5, 2)}-${endTime.substr(8, 2)}`
      })
    })
    return datelist.map(month => {
      month.subData = []
      datalist.forEach(item => {
        if (item.startMonth <= month.time && item.endMonth >= month.time) {
          month.subData.push(item)
        }
      })
      month.style = this.getStyle(month.subData[0])
      month.sublist = month.sublist.map(week => {
        week.sublist = week.sublist.map(day => {
          if (!day) return null
          day.subData = []
          datalist.forEach(item => {
            if (item.start <= day.time && item.end >= day.time) {
              day.subData.push(item)
            }
          })
          day.style = this.getStyle(day.subData[0])
          return day
        })
        return week
      })
      return month
    })
  }
  getStyle = (item ) => {
    if (!item || !item.color) return null
    let style = {background: item.color}
    if (/rgb/ig.test(item.color)) {
      try {
        let colors = item.color.match(/\d+/g)
        if ((colors[0] * 0.299 + colors[1] * 0.578 + colors[2] * 0.114) * colors[3] < 192) {
          style.color = '#ffffff'
        }
      } catch (e) {}
    }
    return style
  }
  getDateList = (selectYear) => {
@@ -91,23 +188,27 @@
      }
      for (let i = 1; i <= end; i++) {
        let _day = i < 10 ? `0${i}` : `${i}`
        if (_weeklist[_weeklist.length - 1].sublist.length < 7) {
          _weeklist[_weeklist.length - 1].sublist.push({day: i < 10 ? `0${i}` : `${i}`, label: i})
          _weeklist[_weeklist.length - 1].sublist.push({day: _day, time: selectYear + month + _day, label: i, subData: []})
        } else {
          let _week = {week: _weeklist.length + 1, sublist: [{day: i < 10 ? `0${i}` : `${i}`, label: i}]}
          let _week = {week: _weeklist.length + 1, sublist: [{day: _day, time: selectYear + month + _day, label: i, subData: []}]}
          _weeklist.push(_week)
        }
      }
      let re = 7 - _weeklist[_weeklist.length - 1].sublist.length
      let re = 7 - _weeklist.slice(-1)[0].sublist.length
      for (let i = 0; i < re; i++) {
        _weeklist[_weeklist.length - 1].sublist.push(null)
      }
      datelist.push({
        month: month,
        time: selectYear + month,
        label: monthName[month],
        sublist: _weeklist
        sublist: _weeklist,
        subData: []
      })
    })
@@ -119,41 +220,59 @@
  }
  yearChange = (value) => {
    const { calendar, data } = this.props
    const { levels, selectMonth } = this.state
    let datelist = this.getDateList(value)
    let monthlist = null
    if (levels.includes('month')) {
    if (levels.includes('month') || levels.includes('year')) {
      monthlist = datelist.filter(item => item.month === selectMonth)[0]
    }
    if (calendar.refresh !== 'true') {
      datelist = this.mountdata(datelist, data)
    this.setState({ selectYear: value, datelist, monthlist })
      this.setState({ selectYear: value, datelist, monthlist })
    } else {
      this.setState({ selectYear: value, datelist, monthlist }, () => {
        this.props.changeDate(value)
      })
    }
  }
  monthChange = (value) => {
    const { datelist } = this.state
    const { datelist, levels, selectYear } = this.state
    if (!levels.includes('month')) {
      if (this.props.triggerDate) {
        this.props.triggerDate({
          time: `${selectYear}${value}01`
        })
      }
      return
    }
    this.setState({
      level: 'month',
      selectMonth: value,
      monthlist: datelist.filter(item => item.month === value)[0]
    })
  }
  triggerDay = (item) => {
    if (this.props.triggerDate) {
      this.props.triggerDate(item)
    }
  }
  render() {
    const { loading } = this.props
    const { level, selectMonth, selectYear, yearlist, levels, datelist, monthlist } = this.state
    const _levelName = {day: '日', month: '月', year: '年'}
    const listData = [
      { type: 'orange', content: 'This is error event 2.' },
      { type: 'cyan', content: 'This is error event 3.' },
      { type: 'green', content: 'This is error event 4.' },
    ]
    return (
      <div className="mk-calendar">
        {loading ? <div className="loading-data"><Spin /></div> : null}
        <div className="mk-calendar-control">
          <Select value={selectYear} onChange={this.yearChange}>
            {yearlist.map(item => (<Option key={item} value={item}>{item}年</Option>))}
@@ -194,12 +313,17 @@
                      <tr key={cell.week}>
                        {cell.sublist.map((d, i) => (
                          <td key={i}>
                            {d ? <div className={'day-wrap ' + d.class} onClick={() => this.triggerDay(d)}>
                              {d.label ? <Popover mouseEnterDelay={0.3} overlayClassName="calendar-day-pop" content={
                            {d ? <div className="day-wrap" style={d.style || null} onClick={() => this.triggerDay(d)}>
                              {d.subData.length > 0 ? <Popover mouseEnterDelay={0.3} overlayClassName="calendar-day-pop" content={
                                <div>
                                  {listData.map((data, index) => (
                                  {d.subData.map((data, index) => (
                                    <div key={index} className="message">
                                      <Badge color={data.type} text={data.content} />
                                      <Badge color={data.color} text={
                                        <span>
                                          {data.remark}
                                          <span style={{color: 'rgba(0,0,0,.45)'}}>({data.startTime + ' ~ ' + data.endTime})</span>
                                        </span>}
                                      />
                                    </div>
                                  ))}
                                </div>
@@ -228,14 +352,14 @@
                  <tr key={cell.week}>
                    {cell.sublist.map((d, i) => (
                      <td key={i}>
                        {d ? <div className="month-wrap" onClick={() => this.triggerDay(d)}>
                        {d ? <div className="month-wrap" style={d.style || null} onClick={() => this.triggerDay(d)}>
                          <div className="header">
                            {d.label}
                          </div>
                          <ul className="content">
                            {[1,3,7,18,22].includes(d.label) && listData.map((data, index) => (
                              <li key={index} className="message" title={data.content}>
                                <Badge color={data.type} text={data.content} />
                            {d.subData.map((data, index) => (
                              <li key={index} className="message">
                                <Badge color={d.style ? (data.color === d.style.background ? '#ffffff' : data.color) : data.color} text={data.remark} />
                              </li>
                            ))}
                          </ul>
@@ -250,14 +374,14 @@
          {level === 'year' && monthlist ? <Row className="year-calendar">
            {datelist.map(item => (
              <Col span={8} key={item.month}>
                <div className="year-wrap">
                  <div className="header">
                <div className="year-wrap" style={item.style || null} onClick={() => this.monthChange(item.month)}>
                  <div className="header" style={item.style ? null : {color: '#1890ff'}}>
                    {item.label}
                  </div>
                  <ul className="content">
                    {['01', '05', '10'].includes(item.month) && listData.map((data, index) => (
                      <li key={index} className="message" title={data.content}>
                        <Badge color={data.type} text={data.content} />
                    {item.subData.map((data, index) => (
                      <li key={index} className="message">
                        <Badge color={item.style ? (data.color === item.style.background ? '#ffffff' : data.color) : data.color} text={`${data.remark} (${data.startTime} ~ ${data.endTime})`}/>
                      </li>
                    ))}
                  </ul>