import React, { useState, useEffect, useRef } from "react"; import CommonPopup from "@/components/CommonPopup"; import { View } from "@tarojs/components"; import Taro from "@tarojs/taro"; import CalendarUI, { CalendarUIRef, } from "@/components/Picker/CalendarUI/CalendarUI"; import { PickerCommon, PickerCommonRef } from "@/components/Picker"; import dayjs from "dayjs"; import styles from "./index.module.scss"; export interface DialogCalendarCardProps { value?: Date | Date[]; searchType?: "single" | "range" | "multiple"; onChange?: (date: Date | Date[]) => void; visible: boolean; onClose: () => void; title?: React.ReactNode; } const DialogCalendarCard: React.FC = ({ visible, searchType, onClose, title, value, onChange, }) => { const [selected, setSelected] = useState(value || new Date()); const [selectedBackup, setSelectedBackup] = useState( Array.isArray(value) ? [...(value as Date[])] : [value as Date] ); const [current, setCurrent] = useState(new Date()); const [delta, setDelta] = useState(0); const calendarRef = useRef(null); const [type, setType] = useState<"year" | "month" | "time">("year"); const [selectedHour, setSelectedHour] = useState(8); const [selectedMinute, setSelectedMinute] = useState(0); const pickerRef = useRef(null); const hourMinutePickerRef = useRef(null); const [pendingJump, setPendingJump] = useState<{ year: number; month: number; } | null>(null); const handleConfirm = () => { if (type === "year") { if (searchType === "range") { if (onChange) onChange(selected); onClose(); return; } if (!selected) { Taro.showToast({ title: '请选择日期', icon: "none", }); return; } // 年份选择完成后,进入月份选择 setType("time"); } else if (type === "month") { // 月份选择完成后,进入时间选择 const value = pickerRef.current?.getValue(); if (value) { const year = value[0] as number; const month = value[1] as number; setPendingJump({ year, month }); setType("year"); if (searchType === "range") { calculateMonthDifference( current, new Date(year, month - 1, 1) ); return; } setSelected(new Date(year, month - 1, 1)); } } else if (type === "time") { // 时间选择完成后,调用onNext回调 const value = hourMinutePickerRef.current?.getValue(); if (value) { const hour = value[0] as number; const minute = value[1] as number; setSelectedHour(hour); setSelectedMinute(minute); const hours = hour.toString().padStart(2, "0"); const minutes = minute.toString().padStart(2, "0"); const finalDate = new Date( dayjs(selected as Date).format("YYYY-MM-DD") + " " + hours + ":" + minutes ); if (onChange) onChange(finalDate); } onClose(); } }; const dialogClose = () => { setType("year"); onClose(); } const calculateMonthDifference = (date1, date2) => { if (!(date1 instanceof Date) || !(date2 instanceof Date)) { throw new Error("Both arguments must be Date objects"); } setCurrent(date1) let months = (date2.getFullYear() - date1.getFullYear()) * 12; months -= date1.getMonth(); months += date2.getMonth(); setDelta(months); }; const handleChange = (d: Date | Date[]) => { if (searchType === "range") { if (Array.isArray(d)) { if (d.length === 2) { return; } else if (d.length === 1) { if (selectedBackup.length === 0 || selectedBackup.length === 2) { setSelected([...d]); setSelectedBackup([...d]); } else { setSelected( [...selectedBackup, d[0]].sort( (a, b) => a.getTime() - b.getTime() ) ); setSelectedBackup([]); } } return; } } if (Array.isArray(d)) { setSelected(d[0]); } else { setSelected(d); } }; const onHeaderClick = (date: Date) => { console.log("onHeaderClick", date); setSelected(date); setType("month"); }; const getConfirmText = () => { if (type === "time" || type === "month" || searchType === "range") return "完成"; return "下一步"; }; const handleDateTimePickerChange = (value: (string | number)[]) => { const year = value[0] as number; const month = value[1] as number; setSelected(new Date(year, month - 1, 1)); }; const onCancel = () => { if (type === "month") { setType("year"); } else if (type === "time") { setType("year"); } else { onClose(); } }; useEffect(() => { calendarRef.current?.gotoMonth(delta); }, [delta]) useEffect(() => { if (visible && value) { setSelected(value || new Date()); setSelectedHour(value ? dayjs(value as Date).hour() : 8); setSelectedMinute(value ? dayjs(value as Date).minute() : 0); } }, [value, visible]); useEffect(() => { if (type === "year" && pendingJump && calendarRef.current) { calendarRef.current.jumpTo(pendingJump.year, pendingJump.month); setPendingJump(null); } }, [type, pendingJump]); console.log([selectedHour, selectedMinute], visible,type, "selectedHour, selectedMinute"); return ( {type === "year" && ( )} {type === "month" && ( )} {type === "time" && ( )} ); }; export default DialogCalendarCard;