时间控制插件调用接口

客官°小女子只卖身不卖艺 2022-10-07 01:58 239阅读 0赞

(1)一个时间控制插件:

需求,根据时间组件选择的时间,来根据选择的这个时间段去”搞事情“;
在这里插入图片描述

在这里插入图片描述

(2)组件的代码分析

组件的js和样式代码如下

index.js

  1. /** * * DurationSelector * */
  2. import React from 'react';
  3. import { Button, DatePicker, message } from 'antd';
  4. import moment from 'moment';
  5. import PropTypes from 'prop-types';
  6. import './index.scss';
  7. moment.updateLocale('en',
  8. {
  9. week: {
  10. dow: 1, // First day of week is Monday
  11. },
  12. });
  13. const { RangePicker } = DatePicker;
  14. const TODAY = moment();
  15. // export const DEFAULT_SHORTCUTS = 'D30';
  16. export const DEFAULT_SHORTCUTS = 'D7';
  17. // 这里都统计截止到昨日、上周、上月的折线图数据
  18. export const SHORTCUTMAP = {
  19. D1: {
  20. name: '1天',
  21. duration: [moment().add(-1, 'd'), moment().add(-1, 'd')],
  22. // calcDuration: momentDate => [momentDate.clone(), momentDate],
  23. },
  24. D7: {
  25. name: '7天',
  26. duration: [moment().add(-7, 'd'), moment().add(-1, 'd')],
  27. // calcDuration: momentDate => [momentDate.clone().add(-6, 'd'), momentDate],
  28. },
  29. D30: {
  30. name: '30天',
  31. duration: [moment().add(-30, 'd'), moment().add(-1, 'd')],
  32. // calcDuration: momentDate => [momentDate.clone().add(-29, 'd'), momentDate],
  33. },
  34. // WEEK: {
  35. // name: '周',
  36. // duration: [moment().add(-12, 'w').startOf('week'), moment().add(-1, 'w').endOf('week')],
  37. // addition: '上周',
  38. // calcDuration: (momentDate) => {
  39. // const date1 = momentDate.clone().add(-11, 'w').startOf('week');
  40. // const date2 = momentDate.clone().startOf('year').startOf('week');
  41. // return [date1.isSameOrBefore(date2) ? date2 : date1, momentDate.endOf('week')];
  42. // },
  43. // },
  44. // MONTH: {
  45. // name: '月',
  46. // duration: [moment().add(-12, 'M').startOf('Month'), moment().add(-1, 'M').endOf('Month')],
  47. // addition: '上月',
  48. // calcDuration: momentDate => [momentDate.clone().add(-11, 'M').startOf('Month'), momentDate.endOf('Month')],
  49. // },
  50. WHATDIDFOXSAY: {
  51. name: '自定义',
  52. duration: [],
  53. },
  54. };
  55. // 日期空间中校验日期是否可选
  56. const getDisabledDate = currentDate => currentDate.isSameOrAfter(TODAY, 'day') || currentDate.isBefore(moment('2019-11-11'), 'day');
  57. // 是否是同一个时间段
  58. const isSameDuration = (originDuration, targetDuration) => {
  59. if (!originDuration.length) return false;
  60. let perfectMatch = true;
  61. for (let j = 0; j < originDuration.length; j++) {
  62. if (!originDuration[j] || !originDuration[j].isSame(targetDuration[j], 'day')) {
  63. perfectMatch = false;
  64. break;
  65. }
  66. }
  67. return perfectMatch;
  68. };
  69. // 日期和快捷方式联动
  70. const reflectShortCuts = (duration, shortCutMap) => {
  71. let targetKey = '';
  72. const keys = Object.keys(shortCutMap);
  73. for (let i = 0; i < keys.length; i++) {
  74. const shortcutItem = shortCutMap[keys[i]];
  75. const _isSameDuration = isSameDuration(shortcutItem.duration, duration);
  76. if (_isSameDuration) {
  77. targetKey = keys[i];
  78. break;
  79. }
  80. }
  81. // if (targetKey === 'D1') targetKey = 'D7'; // D7 和 D1 时间周期一样, 默认匹配给 'D7'
  82. return targetKey || 'WHATDIDFOXSAY';
  83. };
  84. export default class DurationSelector extends React.Component {
  85. static defaultProps = {
  86. className: '',
  87. disabled: false,
  88. // shortCutMap: {},
  89. dataEndDate: '',
  90. tip: '',
  91. };
  92. static propTypes = {
  93. dateChange: PropTypes.func.isRequired,
  94. className: PropTypes.string,
  95. disabled: PropTypes.bool,
  96. // shortCutMap: PropTypes.object,
  97. dataEndDate: PropTypes.string,
  98. tip: PropTypes.string,
  99. };
  100. static getDerivedStateFromProps(nextProps, prevState) {
  101. if (!prevState.duration.length) {
  102. const duration = SHORTCUTMAP[DEFAULT_SHORTCUTS].duration;
  103. nextProps.dateChange(duration, prevState.activeShortcuts);
  104. return {
  105. duration,
  106. };
  107. }
  108. // if (nextProps.dataEndDate && !nextProps.disabled) {
  109. // const calc = SHORTCUTMAP[prevState.activeShortcuts].calcDuration;
  110. // if (!calc) return null;
  111. // return {
  112. // duration: calc(moment(nextProps.dataEndDate, 'YYYYMMDD')),
  113. // };
  114. // }
  115. return null;
  116. }
  117. state = {
  118. duration: [],
  119. activeShortcuts: DEFAULT_SHORTCUTS,
  120. rangePickerOpen: false,
  121. reset: false,
  122. };
  123. // 选择完快捷方式,和日期联动
  124. selectShortcuts = (e) => {
  125. if (this.props.disabled) return;
  126. if (!e || !e.target || !e.target.dataset || !e.target.dataset.type) return;
  127. const type = e.target.dataset.type;
  128. if (type === 'WHATDIDFOXSAY') {
  129. this.setState({
  130. rangePickerOpen: true,
  131. });
  132. } else {
  133. // 非自定义的情况下
  134. // 避免重复点击
  135. if (type === this.state.activeShortcuts) return;
  136. // 设置时间段
  137. this.setState({
  138. duration: SHORTCUTMAP[type].duration,
  139. });
  140. // 触发父级 dateChange 方法
  141. this.props.dateChange(SHORTCUTMAP[type].duration, type);
  142. }
  143. this.setState({
  144. activeShortcuts: type,
  145. reset: false,
  146. });
  147. };
  148. // 选择完日期,处理和快捷方式的联动
  149. rangePickerChange = (durationList) => {
  150. // 日期选择空间删除了日期
  151. if (!durationList || !durationList.length) {
  152. return this.setState({
  153. duration: [],
  154. reset: false,
  155. activeShortcuts: DEFAULT_SHORTCUTS,
  156. });
  157. }
  158. let start = durationList[0];
  159. const end = durationList[1];
  160. // 处理和快捷方式的联动
  161. const targetKey = reflectShortCuts([start, end], SHORTCUTMAP);
  162. this.setState({ activeShortcuts: targetKey });
  163. if (
  164. targetKey === 'WHATDIDFOXSAY' &&
  165. moment.duration(end - start).asMonths() > 3
  166. ) {
  167. message.error('自定义时间不能超过3个月');
  168. start = end.clone().add(-3, 'M');
  169. }
  170. // 校验和现有的是否是同一时间段,如果是则不通知父级元素
  171. const _isSameDuration = isSameDuration(this.state.duration, durationList);
  172. if (!_isSameDuration) {
  173. this.setState({ duration: [start, end], reset: false });
  174. this.props.dateChange([start, end], targetKey);
  175. }
  176. };
  177. // 日期选择框打开和关闭的回调
  178. rangePickerOpenChange = (status) => {
  179. this.setState({ rangePickerOpen: status });
  180. };
  181. // 重置选择
  182. resetDuration = () => {
  183. if (this.state.reset === false) {
  184. this.setState({
  185. duration: SHORTCUTMAP[DEFAULT_SHORTCUTS].duration,
  186. activeShortcuts: DEFAULT_SHORTCUTS,
  187. rangePickerOpen: false,
  188. reset: true,
  189. });
  190. this.props.dateChange(SHORTCUTMAP.D7.duration, DEFAULT_SHORTCUTS);
  191. }
  192. };
  193. render() {
  194. return (
  195. <div className={ `duration-selector ${ this.props.className}`}>
  196. <div className="duration-main">
  197. <span style={ { color: '#666' }}>统计时间:</span>
  198. <RangePicker
  199. open={ this.state.rangePickerOpen}
  200. onOpenChange={ this.rangePickerOpenChange}
  201. onChange={ this.rangePickerChange}
  202. value={ this.state.duration}
  203. style={ { width: 240 }}
  204. disabledDate={ getDisabledDate}
  205. />
  206. <span onClick={ this.selectShortcuts}>
  207. { Object.keys(SHORTCUTMAP).map((key) => (
  208. <Button
  209. key={ key}
  210. className={ `shortcut-btn ${ this.state.activeShortcuts === key ? 'active' : '' }`}
  211. data-type={ key}
  212. >
  213. { SHORTCUTMAP[key].name}
  214. </Button>
  215. ))}
  216. </span>
  217. </div>
  218. <div className="duration-operation">
  219. <Button
  220. className={ `reset-btn ${ this.state.reset ? 'active' : ''}`}
  221. onClick={ this.resetDuration}
  222. >
  223. 重置
  224. </Button>
  225. </div>
  226. { this.props.tip && !this.props.disabled && (
  227. <div className="duration-tip">{ this.props.tip}</div>
  228. )}
  229. </div>
  230. );
  231. }
  232. }

index.scss

  1. .duration-selector {
  2. position: relative;
  3. display: flex;
  4. align-items: center;
  5. justify-content: space-between;
  6. padding: 24px 18px 24px 0; .duration-main {
  7. .ant-calendar-picker {
  8. margin-right: 32px;
  9. }
  10. .shortcut-btn {
  11. color: #999;
  12. border-radius: 16px; &:hover {
  13. color: #29a2ff;
  14. background-color: #fff;
  15. border-color: #29a2ff;
  16. }
  17. &:focus, &.active {
  18. color: #fff;
  19. background-color: #0086ff;
  20. border-color: #0086ff;
  21. }
  22. & + .shortcut-btn {
  23. margin-left: 12px;
  24. }
  25. }
  26. }
  27. .duration-operation {
  28. .reset-btn {
  29. color: #999; &:hover {
  30. color: #29a2ff;
  31. background-color: #fff;
  32. border-color: #29a2ff;
  33. }
  34. &:focus, &.active {
  35. color: #999;
  36. border-color: #d9d9d9;
  37. cursor: not-allowed;
  38. opacity: 0.5;
  39. }
  40. }
  41. }
  42. .duration-tip {
  43. position: absolute;
  44. bottom: 2px;
  45. left: 0;
  46. color: #7f7f7f;
  47. font-size: 12px;
  48. }
  49. }

(3)在别的地方使用该组件

  1. <!--引用该组件 -->
  2. <DurationSelector
  3. className="duration-selector-wrapper"
  4. dateChange={ handleDurationChange}
  5. />
  6. import DurationSelector, {
  7. SHORTCUTMAP,
  8. DEFAULT_SHORTCUTS,
  9. } from './index.js'; // 根据自己路径引入上述时间插件
  10. const [filterParams, setFilterParams] = useState<any>({
  11. beginTime: new Date(date[0]).getTime(),
  12. endTime: new Date(date[1]).getTime(),
  13. });
  14. useEffect(() => {
  15. handleFetch();
  16. }, []);
  17. // 区间选择器
  18. const handleDurationChange = (data): void => {
  19. const params = {
  20. beginTime: new Date(data[0]).getTime(),
  21. endTime: new Date(data[1]).getTime(),
  22. };
  23. setFilterParams({
  24. ...filterParams,
  25. ...params,
  26. });
  27. };
  28. const handleFetch = async () => {
  29. const params = {
  30. beginTime: filterParams.beginTime,
  31. endTime: filterParams.endTime,
  32. channel,
  33. };
  34. };
  35. const data = await queryYourPortData(params); //或者做一些根据时间,做接口数据处理

发表评论

表情:
评论列表 (有 0 条评论,239人围观)

还没有评论,来说两句吧...

相关阅读