index.js 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. import React, { Component } from 'react';
  2. import moment from 'moment';
  3. import './index.less';
  4. import { DatePicker, Calendar, Icon } from 'antd';
  5. export default class extends Component {
  6. constructor(props) {
  7. super(props);
  8. this.state = { key: 0 };
  9. this.loading = false;
  10. }
  11. dateRender(date) {
  12. const { dateRender, checkRefresh } = this.props;
  13. if (!this.loading && checkRefresh) {
  14. if (checkRefresh(date, () => this.needRefresh())) {
  15. this.loading = true;
  16. }
  17. }
  18. if (dateRender) return dateRender(date);
  19. return <div className="ant-calendar-date">{date.get('date')}</div>;
  20. }
  21. needRefresh() {
  22. this.setState({ key: this.state.key + 1 });
  23. this.loading = false;
  24. setTimeout(() => {
  25. this.setState({ key: this.state.key + 1 });
  26. }, 1);
  27. }
  28. render() {
  29. const { show, hideInput, disabledDate, theme = '', value, onChange } = this.props;
  30. return (
  31. <div
  32. ref={ref => {
  33. if (!this.ref) {
  34. this.ref = ref;
  35. this.setState({ load: false });
  36. }
  37. }}
  38. className={`g-date-block ${hideInput ? 'hide-input' : ''}`}
  39. >
  40. <DatePicker
  41. open={show && this.ref}
  42. value={value}
  43. getCalendarContainer={() => this.ref.parentNode}
  44. dropdownClassName={`g-date ${theme} ${hideInput ? 'hide-input' : ''}`}
  45. disabledDate={disabledDate}
  46. dateRender={date => this.dateRender(date)}
  47. onChange={date => onChange(date)}
  48. />
  49. </div>
  50. );
  51. }
  52. }
  53. export class TwoDate extends Component {
  54. constructor(props) {
  55. super(props);
  56. const today = moment();
  57. this.state = {
  58. key: 0,
  59. value: null,
  60. leftValue: today.clone().subtract(1, 'month'),
  61. rightValue: today,
  62. };
  63. }
  64. dateRender(date) {
  65. const { checkRefresh } = this.props;
  66. if (!this.loading && checkRefresh) {
  67. if (checkRefresh(date, () => this.needRefresh())) {
  68. this.loading = true;
  69. }
  70. }
  71. return this.renderItem(date);
  72. }
  73. needRefresh() {
  74. this.setState({ key: this.state.key + 1 });
  75. this.loading = false;
  76. setTimeout(() => {
  77. this.setState({ key: this.state.key + 1 });
  78. }, 1);
  79. }
  80. renderItem(date) {
  81. const { value } = this.state;
  82. const { getType } = this.props;
  83. return (
  84. <div
  85. className={`ant-fullcalendar-date ${getType ? getType(date) : ''} ${value && value.diff(date) === 0 ? 'selected' : ''}`}
  86. >
  87. <div className="ant-fullcalendar-value">{date.get('date')}</div>
  88. </div>
  89. );
  90. }
  91. onLeftSelect(date) {
  92. const { onChange, startDate } = this.props;
  93. if (startDate && date.isBefore(startDate)) return;
  94. this.setState({
  95. value: date,
  96. leftValue: date,
  97. rightValue: date.clone().add(1, 'month'),
  98. });
  99. if (onChange) onChange(date);
  100. }
  101. onRightSelect(date) {
  102. const { onChange, endDate } = this.props;
  103. if (endDate && date.isAfter(endDate)) return;
  104. this.setState({
  105. value: date,
  106. rightValue: date,
  107. leftValue: date.clone().subtract(1, 'month'),
  108. });
  109. if (onChange) onChange(date);
  110. }
  111. leftHeadRender() {
  112. const { leftValue } = this.state;
  113. const { extendInfo } = this.props;
  114. return (
  115. <div className="t-c">
  116. <div style={{ left: 15, top: 0 }} className="p-a">
  117. <Icon
  118. className="m-r-5"
  119. type="double-left"
  120. onClick={() => this.onLeftSelect(leftValue.clone().subtract(1, 'year'))}
  121. />
  122. <Icon type="left" onClick={() => this.onLeftSelect(leftValue.clone().subtract(1, 'month'))} />
  123. </div>
  124. <span>{leftValue.year()}年 </span>
  125. <span>{leftValue.month() + 1}月 </span>
  126. <span className="t-4">{extendInfo && extendInfo(leftValue)}</span>
  127. </div>
  128. );
  129. }
  130. rightHeadRender() {
  131. const { rightValue } = this.state;
  132. const { extendInfo } = this.props;
  133. return (
  134. <div className="t-c">
  135. <span>{rightValue.year()}年 </span>
  136. <span>{rightValue.month() + 1}月 </span>
  137. <span className="t-4">{extendInfo && extendInfo(rightValue)}</span>
  138. <div style={{ right: 15, top: 0 }} className="p-a">
  139. <Icon type="right" onClick={() => this.onRightSelect(rightValue.clone().add(1, 'month'))} />
  140. <Icon
  141. className="m-l-5"
  142. type="double-right"
  143. onClick={() => this.onRightSelect(rightValue.clone().add(1, 'year'))}
  144. />
  145. </div>
  146. </div>
  147. );
  148. }
  149. render() {
  150. const { disabledDate } = this.props;
  151. const { leftValue, rightValue } = this.state;
  152. return (
  153. <div className="g-two-date">
  154. <div className="g-two-head">
  155. {this.leftHeadRender()}
  156. {this.rightHeadRender()}
  157. </div>
  158. <div className="g-two-body">
  159. <Calendar
  160. fullscreen={false}
  161. headerRender={data => this.leftHeadRender(data)}
  162. value={leftValue}
  163. disabledDate={disabledDate}
  164. dateFullCellRender={date => this.dateRender(date)}
  165. onSelect={date => this.onLeftSelect(date)}
  166. onPanelChange={date => this.onLeftSelect(date)}
  167. />
  168. <Calendar
  169. fullscreen={false}
  170. headerRender={data => this.rightHeadRender(data)}
  171. value={rightValue}
  172. disabledDate={disabledDate}
  173. dateFullCellRender={date => this.dateRender(date)}
  174. onSelect={date => this.onRightSelect(date)}
  175. onPanelChange={date => this.onRightSelect(date)}
  176. />
  177. </div>
  178. </div>
  179. );
  180. }
  181. }