/** * 时间组选择:支持 全部,日,月,年,自定义 类型 props: * onChange: ({dateFrom, dateTo}, model) => {}。切换时间类型或时间会触发onChange,并传递选择的时间范围和类型。 * 注:dateFrom和dateTo都是格式化后的字符串 * format: 格式化字符串格式,默认"YYYY-MM-DD HH:mm:ss",参看moment格式化支持的 */ import React, { useState, useEffect } from 'react'; import { Radio, Space, DatePicker } from 'antd'; import moment from 'moment'; const dateForModel = (model, date = moment()) => { if (!date) { result = { dateFrom: null, dateTo: null }; return result; } let result = { dateFrom: null, dateTo: null }; switch (model) { case 'day': result = { dateFrom: date.clone().startOf('day'), dateTo: date.clone().endOf('day') }; break; case 'week': result = { dateFrom: date.clone().startOf('week'), dateTo: date.clone().endOf('week') }; break; case 'month': result = { dateFrom: date.clone().startOf('month'), dateTo: date.clone().endOf('month') }; break; case 'quarter': result = { dateFrom: date.clone().startOf('quarter'), dateTo: date.clone().endOf('quarter') }; break; case 'year': result = { dateFrom: date.clone().startOf('year'), dateTo: date.clone().endOf('year') }; break; case 'all': default: result = { dateFrom: null, dateTo: null }; break; } return result; }; const textForModel = (model) => { switch (model) { case 'day': return '日'; case 'week': return '周'; case 'month': return '月'; case 'quarter': return '季度'; case 'year': return '年'; case 'all': return '全部'; case 'custom': return '自定义'; default: return model; } }; const useDataGroup = (defaultValue = { dateFrom: null, dateTo: null }, defaultModel = 'all') => { const [model, setModel] = useState(defaultModel); const [value, setValue] = useState(defaultValue); const updateValeu = (_value, _model) => { setModel(_model); setValue(_value); }; return [value, model, updateValeu]; }; const defaultFormat = 'YYYY-MM-DD HH:mm:ss'; const defaultShowModels = ['all', 'week', 'month', 'quarter', 'year', 'custom']; const DatePickerGroup = ({ onChange, format = defaultFormat, showModels = defaultShowModels, defaultModel = 'all', defaultDate, value, dateModel, }) => { const [model, setModel] = useState(defaultModel); const [dateValue, setDateValue] = useState(() => dateForModel(defaultModel, defaultDate)); useEffect(() => { if (value || dateModel) { setModel(dateModel); setDateValue(value); } }, [value, dateModel]); // 切换类型 const changeModel = (e) => { const _model = e.target.value; const _dateValue = dateForModel(_model); if (!value && !dateModel) { setModel(_model); setDateValue(_dateValue); if (_model === 'custom') return; } const _dateFrom = _dateValue && _dateValue.dateFrom ? _dateValue.dateFrom.format(format) : ''; const _dateTo = _dateValue && _dateValue.dateTo ? _dateValue.dateTo.format(format) : ''; onChange && onChange( { dateFrom: _dateFrom, dateTo: _dateTo, }, _model, ); }; // 切换时间 const changeDate = (date, dateString) => { const _dateValue = dateForModel(model, date); const _dateFrom = _dateValue && _dateValue.dateFrom ? _dateValue.dateFrom.format(format) : ''; const _dateTo = _dateValue && _dateValue.dateTo ? _dateValue.dateTo.format(format) : ''; if (!value && !dateModel) { setDateValue(_dateValue); } onChange && onChange( { dateFrom: _dateFrom, dateTo: _dateTo, }, model, ); }; // 切换范围时间 const changeRangeDate = (dates, dateStrings) => { const _dateValue = { dateFrom: dates?.[0], dateTo: dates?.[1] }; const _dateFrom = _dateValue && _dateValue.dateFrom ? _dateValue.dateFrom.format(format) : ''; const _dateTo = _dateValue && _dateValue.dateTo ? _dateValue.dateTo.format(format) : ''; if (!value && !dateModel) { setDateValue(_dateValue); } onChange && onChange( { dateFrom: _dateFrom, dateTo: _dateTo, }, model, ); }; // 渲染时间选择器 const renderDatePicker = () => { let _result = null; switch (model) { case 'day': _result = <DatePicker onChange={changeDate} value={dateValue.dateFrom} />; break; case 'week': _result = <DatePicker picker="week" onChange={changeDate} value={dateValue.dateFrom} />; break; case 'month': _result = <DatePicker picker="month" onChange={changeDate} value={dateValue.dateFrom} />; break; case 'quarter': _result = <DatePicker picker="quarter" onChange={changeDate} value={dateValue.dateFrom} />; break; case 'year': _result = <DatePicker picker="year" onChange={changeDate} value={dateValue.dateFrom} />; break; case 'custom': _result = ( <DatePicker.RangePicker onChange={changeRangeDate} value={[dateValue.dateFrom, dateValue.dateTo]} /> ); break; case 'all': default: _result = null; break; } return _result; }; return ( <Space size={8}> <Radio.Group value={model} onChange={changeModel} style={{ whiteSpace: 'nowrap' }}> {showModels.map((item) => ( <Radio.Button value={item} key={item}> {textForModel(item)} </Radio.Button> ))} </Radio.Group> {renderDatePicker()} </Space> ); }; export { useDataGroup }; export default DatePickerGroup;