import React, { useState, useRef, useEffect } from 'react'; import './RangeQuickPicker.css'; function fmt(d) { return d.getFullYear() + '-' + String(d.getMonth() + 1).padStart(2, '0') + '-' + String(d.getDate()).padStart(2, '0'); } function presetRange(p) { let end = new Date(); end.setHours(0, 0, 0, 0); let start = new Date(end); if (p.year === 'this') start = new Date(end.getFullYear(), 0, 1); else if (p.month === 'this') start = new Date(end.getFullYear(), end.getMonth(), 1); else if (p.month === 'last') { start = new Date(end.getFullYear(), end.getMonth() - 1, 1); end = new Date(end.getFullYear(), end.getMonth(), 0); } else { start.setDate(end.getDate() + (p.days || 0)); if (p.len) start.setDate(end.getDate() - (p.len - 1)); } return { start: fmt(start), end: fmt(end) }; } const DEFAULT_PRESETS = [ { label: '今天', days: 0 }, { label: '昨天', days: -1, len: 1 }, { label: '近7天', days: -6 }, { label: '近30天', days: -29 }, { label: '本月', month: 'this' }, { label: '上月', month: 'last' }, { label: '本年', year: 'this' } ]; export default function RangeQuickPicker({ modelValue = { start: '', end: '' }, presets = DEFAULT_PRESETS, onChange }) { const root = useRef(null); const [open, setOpen] = useState(false); const [start, setStart] = useState(modelValue.start); const [end, setEnd] = useState(modelValue.end); const [activeIndex, setActiveIndex] = useState(-1); useEffect(() => { function onDoc(e) { if (root.current && !root.current.contains(e.target)) { setOpen(false); setActiveIndex(-1); } } document.addEventListener('click', onDoc); return () => document.removeEventListener('click', onDoc); }, []); const applyPreset = (i) => { const r = presetRange(presets[i]); setStart(r.start); setEnd(r.end); setActiveIndex(i); }; const confirm = () => { if (onChange) onChange({ start, end }); setOpen(false); setActiveIndex(-1); }; return (
setOpen((o) => !o)}> {modelValue.start && modelValue.end ? ( {modelValue.start} ~ {modelValue.end} ) : ( 请选择时间范围 )}
{open && (
{presets.map((p, i) => ( ))}
setStart(e.target.value)} /> ~ setEnd(e.target.value)} />
)}
); }