..
This commit is contained in:
@@ -1,17 +1,19 @@
|
|||||||
import React, { useState, useEffect, useRef } from 'react'
|
import React, { useState, useEffect, useRef } from "react";
|
||||||
import CommonPopup from '@/components/CommonPopup'
|
import CommonPopup from "@/components/CommonPopup";
|
||||||
import { View } from '@tarojs/components'
|
import { View } from "@tarojs/components";
|
||||||
import CalendarUI, { CalendarUIRef } from '@/components/Picker/CalendarUI/CalendarUI'
|
import CalendarUI, {
|
||||||
import { PickerCommon, PickerCommonRef } from '@/components/Picker'
|
CalendarUIRef,
|
||||||
import dayjs from 'dayjs'
|
} from "@/components/Picker/CalendarUI/CalendarUI";
|
||||||
import styles from './index.module.scss'
|
import { PickerCommon, PickerCommonRef } from "@/components/Picker";
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
import styles from "./index.module.scss";
|
||||||
export interface DialogCalendarCardProps {
|
export interface DialogCalendarCardProps {
|
||||||
value?: Date | Date[]
|
value?: Date | Date[];
|
||||||
searchType?: 'single' | 'range' | 'multiple'
|
searchType?: "single" | "range" | "multiple";
|
||||||
onChange?: (date: Date | Date[]) => void
|
onChange?: (date: Date | Date[]) => void;
|
||||||
visible: boolean
|
visible: boolean;
|
||||||
onClose: () => void
|
onClose: () => void;
|
||||||
title?: React.ReactNode
|
title?: React.ReactNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
const DialogCalendarCard: React.FC<DialogCalendarCardProps> = ({
|
const DialogCalendarCard: React.FC<DialogCalendarCardProps> = ({
|
||||||
@@ -22,61 +24,73 @@ const DialogCalendarCard: React.FC<DialogCalendarCardProps> = ({
|
|||||||
value,
|
value,
|
||||||
onChange,
|
onChange,
|
||||||
}) => {
|
}) => {
|
||||||
const [selected, setSelected] = useState<Date | Date[]>(value || new Date())
|
const [selected, setSelected] = useState<Date | Date[]>(value || new Date());
|
||||||
|
const [selectedBackup, setSelectedBackup] = useState<Date[]>(
|
||||||
|
Array.isArray(value) ? [...(value as Date[])] : [value as Date]
|
||||||
|
);
|
||||||
const calendarRef = useRef<CalendarUIRef>(null);
|
const calendarRef = useRef<CalendarUIRef>(null);
|
||||||
const [type, setType] = useState<'year' | 'month' | 'time'>('year');
|
const [type, setType] = useState<"year" | "month" | "time">("year");
|
||||||
const [selectedHour, setSelectedHour] = useState(8)
|
const [selectedHour, setSelectedHour] = useState(8);
|
||||||
const [selectedMinute, setSelectedMinute] = useState(0)
|
const [selectedMinute, setSelectedMinute] = useState(0);
|
||||||
const pickerRef = useRef<PickerCommonRef>(null);
|
const pickerRef = useRef<PickerCommonRef>(null);
|
||||||
const hourMinutePickerRef = useRef<PickerCommonRef>(null);
|
const hourMinutePickerRef = useRef<PickerCommonRef>(null);
|
||||||
const [pendingJump, setPendingJump] = useState<{ year: number; month: number } | null>(null)
|
const [pendingJump, setPendingJump] = useState<{
|
||||||
|
year: number;
|
||||||
|
month: number;
|
||||||
|
} | null>(null);
|
||||||
const handleConfirm = () => {
|
const handleConfirm = () => {
|
||||||
if (type === 'year') {
|
if (type === "year") {
|
||||||
if (searchType === 'range') {
|
if (searchType === "range") {
|
||||||
if (onChange) onChange(selected);
|
if (onChange) onChange(selected);
|
||||||
onClose();
|
onClose();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 年份选择完成后,进入月份选择
|
// 年份选择完成后,进入月份选择
|
||||||
setType('time')
|
setType("time");
|
||||||
} else if (type === 'month') {
|
} else if (type === "month") {
|
||||||
// 月份选择完成后,进入时间选择
|
// 月份选择完成后,进入时间选择
|
||||||
const value = pickerRef.current?.getValue()
|
const value = pickerRef.current?.getValue();
|
||||||
if (value) {
|
if (value) {
|
||||||
const year = value[0] as number
|
const year = value[0] as number;
|
||||||
const month = value[1] as number
|
const month = value[1] as number;
|
||||||
if (searchType === 'range') {
|
setPendingJump({ year, month });
|
||||||
const delta = calculateMonthDifference(selected as Date, new Date(year, month - 1, 1))
|
setType("year");
|
||||||
console.log('xxxxx', calendarRef.current)
|
if (searchType === "range") {
|
||||||
setTimeout(() => {
|
const delta = calculateMonthDifference(
|
||||||
calendarRef.current?.gotoMonth(delta)
|
selected as Date,
|
||||||
}, 50)
|
new Date(year, month - 1, 1)
|
||||||
} else {
|
);
|
||||||
setSelected(new Date(year, month - 1, 1))
|
calendarRef.current?.gotoMonth(delta);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
setPendingJump({ year, month })
|
setSelected(new Date(year, month - 1, 1));
|
||||||
}
|
}
|
||||||
setType('year')
|
} else if (type === "time") {
|
||||||
} else if (type === 'time') {
|
|
||||||
// 时间选择完成后,调用onNext回调
|
// 时间选择完成后,调用onNext回调
|
||||||
const value = hourMinutePickerRef.current?.getValue()
|
const value = hourMinutePickerRef.current?.getValue();
|
||||||
if (value) {
|
if (value) {
|
||||||
const hour = value[0] as number
|
const hour = value[0] as number;
|
||||||
const minute = value[1] as number
|
const minute = value[1] as number;
|
||||||
setSelectedHour(hour)
|
setSelectedHour(hour);
|
||||||
setSelectedMinute(minute)
|
setSelectedMinute(minute);
|
||||||
const hours = hour.toString().padStart(2, '0')
|
const hours = hour.toString().padStart(2, "0");
|
||||||
const minutes = minute.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)
|
const finalDate = new Date(
|
||||||
if (onChange) onChange(finalDate)
|
dayjs(selected as Date).format("YYYY-MM-DD") +
|
||||||
}
|
" " +
|
||||||
onClose()
|
hours +
|
||||||
|
":" +
|
||||||
|
minutes
|
||||||
|
);
|
||||||
|
if (onChange) onChange(finalDate);
|
||||||
}
|
}
|
||||||
|
onClose();
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const calculateMonthDifference = (date1, date2) => {
|
const calculateMonthDifference = (date1, date2) => {
|
||||||
if (!(date1 instanceof Date) || !(date2 instanceof Date)) {
|
if (!(date1 instanceof Date) || !(date2 instanceof Date)) {
|
||||||
throw new Error('Both arguments must be Date objects');
|
throw new Error("Both arguments must be Date objects");
|
||||||
}
|
}
|
||||||
|
|
||||||
let months = (date2.getFullYear() - date1.getFullYear()) * 12;
|
let months = (date2.getFullYear() - date1.getFullYear()) * 12;
|
||||||
@@ -84,63 +98,76 @@ const DialogCalendarCard: React.FC<DialogCalendarCardProps> = ({
|
|||||||
months += date2.getMonth();
|
months += date2.getMonth();
|
||||||
|
|
||||||
return months;
|
return months;
|
||||||
}
|
};
|
||||||
|
|
||||||
const handleChange = (d: Date | Date[]) => {
|
const handleChange = (d: Date | Date[]) => {
|
||||||
console.log('handleChange', d)
|
if (searchType === "range") {
|
||||||
if (searchType === 'range') {
|
|
||||||
if (Array.isArray(d)) {
|
if (Array.isArray(d)) {
|
||||||
if (d.length === 2) {
|
if (d.length === 2) {
|
||||||
setSelected(d as Date[])
|
return;
|
||||||
return
|
} else if (d.length === 1) {
|
||||||
|
debugger;
|
||||||
|
if (selectedBackup.length === 0 || selectedBackup.length === 2) {
|
||||||
|
setSelected([]);
|
||||||
|
setSelectedBackup([...d]);
|
||||||
|
} else {
|
||||||
|
setSelected(
|
||||||
|
[...selectedBackup, d[0]].sort(
|
||||||
|
(a, b) => a.getTime() - b.getTime()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
setSelectedBackup([]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (Array.isArray(d)) {
|
if (Array.isArray(d)) {
|
||||||
setSelected(d[0])
|
setSelected(d[0]);
|
||||||
} else {
|
} else {
|
||||||
setSelected(d)
|
setSelected(d);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
const onHeaderClick = (date: Date) => {
|
const onHeaderClick = (date: Date) => {
|
||||||
console.log('onHeaderClick', date)
|
console.log("onHeaderClick", date);
|
||||||
setSelected(date)
|
setSelected(date);
|
||||||
setType('month')
|
setType("month");
|
||||||
}
|
};
|
||||||
const getConfirmText = () => {
|
const getConfirmText = () => {
|
||||||
if (type === 'time' || type === 'month') return '完成'
|
if (type === "time" || type === "month" || searchType === "range")
|
||||||
return '下一步'
|
return "完成";
|
||||||
}
|
return "下一步";
|
||||||
|
};
|
||||||
const handleDateTimePickerChange = (value: (string | number)[]) => {
|
const handleDateTimePickerChange = (value: (string | number)[]) => {
|
||||||
const year = value[0] as number
|
const year = value[0] as number;
|
||||||
const month = value[1] as number
|
const month = value[1] as number;
|
||||||
setSelected(new Date(year, month - 1, 1))
|
setSelected(new Date(year, month - 1, 1));
|
||||||
}
|
};
|
||||||
const dialogClose = () => {
|
const dialogClose = () => {
|
||||||
if (type === 'month') {
|
if (type === "month") {
|
||||||
setType('year')
|
setType("year");
|
||||||
} else if (type === 'time') {
|
} else if (type === "time") {
|
||||||
setType('year')
|
setType("year");
|
||||||
} else {
|
} else {
|
||||||
onClose()
|
onClose();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (visible && value) {
|
if (visible && value) {
|
||||||
setSelected(value || new Date())
|
setSelected(value || new Date());
|
||||||
setSelectedHour(value ? dayjs(value as Date).hour() : 8)
|
setSelectedHour(value ? dayjs(value as Date).hour() : 8);
|
||||||
setSelectedMinute(value ? dayjs(value as Date).minute() : 0)
|
setSelectedMinute(value ? dayjs(value as Date).minute() : 0);
|
||||||
}
|
}
|
||||||
}, [value, visible])
|
}, [value, visible]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (type === 'year' && pendingJump && calendarRef.current) {
|
if (type === "year" && pendingJump && calendarRef.current) {
|
||||||
calendarRef.current.jumpTo(pendingJump.year, pendingJump.month)
|
calendarRef.current.jumpTo(pendingJump.year, pendingJump.month);
|
||||||
setPendingJump(null)
|
setPendingJump(null);
|
||||||
}
|
}
|
||||||
}, [type, pendingJump])
|
}, [type, pendingJump]);
|
||||||
|
|
||||||
console.log([selectedHour, selectedMinute], 'selectedHour, selectedMinute');
|
console.log([selectedHour, selectedMinute], "selectedHour, selectedMinute");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<CommonPopup
|
<CommonPopup
|
||||||
@@ -149,16 +176,15 @@ const DialogCalendarCard: React.FC<DialogCalendarCardProps> = ({
|
|||||||
showHeader={!!title}
|
showHeader={!!title}
|
||||||
title={title}
|
title={title}
|
||||||
hideFooter={false}
|
hideFooter={false}
|
||||||
cancelText='取消'
|
cancelText="取消"
|
||||||
confirmText={getConfirmText()}
|
confirmText={getConfirmText()}
|
||||||
onConfirm={handleConfirm}
|
onConfirm={handleConfirm}
|
||||||
position='bottom'
|
position="bottom"
|
||||||
round
|
round
|
||||||
zIndex={1000}
|
zIndex={1000}
|
||||||
>
|
>
|
||||||
{
|
{type === "year" && (
|
||||||
type === 'year' &&
|
<View className={styles["calendar-container"]}>
|
||||||
<View className={styles['calendar-container']}>
|
|
||||||
<CalendarUI
|
<CalendarUI
|
||||||
ref={calendarRef}
|
ref={calendarRef}
|
||||||
type={searchType}
|
type={searchType}
|
||||||
@@ -166,27 +192,29 @@ const DialogCalendarCard: React.FC<DialogCalendarCardProps> = ({
|
|||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
showQuickActions={false}
|
showQuickActions={false}
|
||||||
onHeaderClick={onHeaderClick}
|
onHeaderClick={onHeaderClick}
|
||||||
/></View>
|
/>
|
||||||
}
|
</View>
|
||||||
{
|
)}
|
||||||
type === 'month' && <PickerCommon
|
{type === "month" && (
|
||||||
|
<PickerCommon
|
||||||
ref={pickerRef}
|
ref={pickerRef}
|
||||||
onChange={handleDateTimePickerChange}
|
onChange={handleDateTimePickerChange}
|
||||||
type="month"
|
type="month"
|
||||||
value={[(selected as Date).getFullYear(), (selected as Date).getMonth() + 1]}
|
value={[
|
||||||
|
(selected as Date).getFullYear(),
|
||||||
|
(selected as Date).getMonth() + 1,
|
||||||
|
]}
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
}
|
{type === "time" && (
|
||||||
{
|
<PickerCommon
|
||||||
type === 'time' && <PickerCommon
|
|
||||||
ref={hourMinutePickerRef}
|
ref={hourMinutePickerRef}
|
||||||
type="hour"
|
type="hour"
|
||||||
value={[selectedHour, selectedMinute]}
|
value={[selectedHour, selectedMinute]}
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
}
|
|
||||||
</CommonPopup>
|
</CommonPopup>
|
||||||
)
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
export default DialogCalendarCard
|
export default DialogCalendarCard;
|
||||||
|
|||||||
@@ -1,34 +1,42 @@
|
|||||||
import React, { useState, useEffect, useRef, useImperativeHandle } from 'react'
|
import React, { useState, useEffect, useRef, useImperativeHandle } from "react";
|
||||||
import { CalendarCard } from '@nutui/nutui-react-taro'
|
import { CalendarCard } from "@nutui/nutui-react-taro";
|
||||||
import { View, Text, Image } from '@tarojs/components'
|
import { View, Text, Image } from "@tarojs/components";
|
||||||
import images from '@/config/images'
|
import images from "@/config/images";
|
||||||
import styles from './index.module.scss'
|
import styles from "./index.module.scss";
|
||||||
import { getMonth, getWeekend, getWeekendOfCurrentWeek } from '@/utils/timeUtils'
|
import {
|
||||||
import { PopupPicker } from '@/components/Picker/index'
|
getMonth,
|
||||||
import dayjs from 'dayjs'
|
getWeekend,
|
||||||
|
getWeekendOfCurrentWeek,
|
||||||
|
} from "@/utils/timeUtils";
|
||||||
|
import { PopupPicker } from "@/components/Picker/index";
|
||||||
|
import dayjs from "dayjs";
|
||||||
interface NutUICalendarProps {
|
interface NutUICalendarProps {
|
||||||
type?: 'single' | 'range' | 'multiple'
|
type?: "single" | "range" | "multiple";
|
||||||
value?: string | Date | String[] | Date[]
|
value?: string | Date | String[] | Date[];
|
||||||
defaultValue?: string | string[]
|
defaultValue?: string | string[];
|
||||||
onChange?: (value: Date | Date[]) => void,
|
onChange?: (value: Date | Date[]) => void;
|
||||||
isBorder?: boolean
|
isBorder?: boolean;
|
||||||
showQuickActions?: boolean,
|
showQuickActions?: boolean;
|
||||||
onHeaderClick?: (date: Date) => void
|
onHeaderClick?: (date: Date) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CalendarUIRef {
|
export interface CalendarUIRef {
|
||||||
jumpTo: (year: number, month: number) => void,
|
jumpTo: (year: number, month: number) => void;
|
||||||
gotoMonth: (delta: number) => void,
|
gotoMonth: (delta: number) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const NutUICalendar = React.forwardRef<CalendarUIRef, NutUICalendarProps>(({
|
const NutUICalendar = React.forwardRef<CalendarUIRef, NutUICalendarProps>(
|
||||||
type = 'single',
|
(
|
||||||
|
{
|
||||||
|
type = "single",
|
||||||
value,
|
value,
|
||||||
onChange,
|
onChange,
|
||||||
isBorder = false,
|
isBorder = false,
|
||||||
showQuickActions = true,
|
showQuickActions = true,
|
||||||
onHeaderClick
|
onHeaderClick,
|
||||||
}, ref) => {
|
},
|
||||||
|
ref
|
||||||
|
) => {
|
||||||
// 根据类型初始化选中值
|
// 根据类型初始化选中值
|
||||||
// const getInitialValue = (): Date | Date[] => {
|
// const getInitialValue = (): Date | Date[] => {
|
||||||
// console.log(value,defaultValue,'today')
|
// console.log(value,defaultValue,'today')
|
||||||
@@ -51,157 +59,208 @@ const NutUICalendar = React.forwardRef<CalendarUIRef, NutUICalendarProps>(({
|
|||||||
// }
|
// }
|
||||||
// return today
|
// return today
|
||||||
// }
|
// }
|
||||||
const startOfMonth = (date: Date) => new Date(date.getFullYear(), date.getMonth(), 1)
|
const startOfMonth = (date: Date) =>
|
||||||
|
new Date(date.getFullYear(), date.getMonth(), 1);
|
||||||
|
|
||||||
const [selectedValue, setSelectedValue] = useState<Date | Date[]>()
|
const [selectedValue, setSelectedValue] = useState<Date | Date[]>();
|
||||||
const [current, setCurrent] = useState<Date>(startOfMonth(new Date()))
|
const [current, setCurrent] = useState<Date>(startOfMonth(new Date()));
|
||||||
const calendarRef = useRef<any>(null)
|
const calendarRef = useRef<any>(null);
|
||||||
const [visible, setvisible] = useState(false)
|
const [visible, setvisible] = useState(false);
|
||||||
console.log('current', current)
|
console.log("current", current);
|
||||||
// 当外部 value 变化时更新内部状态
|
// 当外部 value 变化时更新内部状态
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (Array.isArray(value) && value.length > 0) {
|
if (Array.isArray(value) && value.length > 0) {
|
||||||
setSelectedValue(value.map(item => new Date(item)))
|
setSelectedValue(value.map((item) => new Date(item)));
|
||||||
setCurrent(new Date(value[0] as Date))
|
setCurrent(new Date(value[0] as Date));
|
||||||
}
|
}
|
||||||
if ((typeof value === 'string' || value instanceof Date) && value) {
|
if ((typeof value === "string" || value instanceof Date) && value) {
|
||||||
setSelectedValue(new Date(value))
|
setSelectedValue(new Date(value));
|
||||||
setCurrent(new Date(value))
|
setCurrent(new Date(value));
|
||||||
}
|
}
|
||||||
}, [value])
|
}, [value]);
|
||||||
|
|
||||||
useImperativeHandle(ref, () => ({
|
useImperativeHandle(ref, () => ({
|
||||||
jumpTo: (year: number, month: number) => {
|
jumpTo: (year: number, month: number) => {
|
||||||
calendarRef.current?.jumpTo(year, month)
|
calendarRef.current?.jumpTo(year, month);
|
||||||
},
|
},
|
||||||
gotoMonth: (delta: number) => {
|
gotoMonth: (delta: number) => {
|
||||||
gotoMonth(delta)
|
gotoMonth(delta);
|
||||||
}
|
},
|
||||||
}))
|
}));
|
||||||
|
|
||||||
const handleDateChange = (newValue: any) => {
|
const handleDateChange = (newValue: any) => {
|
||||||
setSelectedValue(newValue)
|
console.log("aaaaaaaaaaaaaaaaaaaaaa", newValue);
|
||||||
onChange?.(newValue as any)
|
setSelectedValue(newValue);
|
||||||
}
|
onChange?.(newValue as any);
|
||||||
const formatHeader = (date: Date) => `${getMonth(date)}`
|
};
|
||||||
|
const formatHeader = (date: Date) => `${getMonth(date)}`;
|
||||||
|
|
||||||
const handlePageChange = (data: { year: number; month: number }) => {
|
const handlePageChange = (data: { year: number; month: number }) => {
|
||||||
// 月份切换时的处理逻辑,如果需要的话
|
// 月份切换时的处理逻辑,如果需要的话
|
||||||
console.log('月份切换:', data)
|
console.log("月份切换:", data);
|
||||||
}
|
};
|
||||||
|
|
||||||
|
const handleDayClick = (day: any) => {
|
||||||
|
const { type, year, month, date } = day;
|
||||||
|
if (type === "next") return;
|
||||||
|
onChange?.([new Date(year, month - 1, date)]);
|
||||||
|
};
|
||||||
|
|
||||||
const gotoMonth = (delta: number) => {
|
const gotoMonth = (delta: number) => {
|
||||||
console.log('aaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbb', delta)
|
const base = current instanceof Date ? new Date(current) : new Date();
|
||||||
const base = current instanceof Date ? new Date(current) : new Date()
|
base.setMonth(base.getMonth() + delta);
|
||||||
base.setMonth(base.getMonth() + delta)
|
const next = startOfMonth(base);
|
||||||
const next = startOfMonth(base)
|
setCurrent(next);
|
||||||
setCurrent(next)
|
|
||||||
// 同步底部 CalendarCard 的月份
|
// 同步底部 CalendarCard 的月份
|
||||||
try {
|
try {
|
||||||
calendarRef.current?.jump?.(delta)
|
calendarRef.current?.jump?.(delta);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn('CalendarCardRef jump 调用失败', e)
|
console.warn("CalendarCardRef jump 调用失败", e);
|
||||||
}
|
|
||||||
handlePageChange({ year: next.getFullYear(), month: next.getMonth() + 1 })
|
|
||||||
}
|
}
|
||||||
|
handlePageChange({
|
||||||
|
year: next.getFullYear(),
|
||||||
|
month: next.getMonth() + 1,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const handleHeaderClick = () => {
|
const handleHeaderClick = () => {
|
||||||
console.log('handleHeaderClick', current)
|
onHeaderClick && onHeaderClick(current);
|
||||||
onHeaderClick && onHeaderClick(current)
|
setvisible(true);
|
||||||
setvisible(true)
|
};
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const syncMonthTo = (anchor: Date) => {
|
const syncMonthTo = (anchor: Date) => {
|
||||||
// 计算从 current 到目标 anchor 所在月份的偏移,调用 jump(delta)
|
// 计算从 current 到目标 anchor 所在月份的偏移,调用 jump(delta)
|
||||||
const monthsDelta = (anchor.getFullYear() - current.getFullYear()) * 12 + (anchor.getMonth() - current.getMonth())
|
const monthsDelta =
|
||||||
|
(anchor.getFullYear() - current.getFullYear()) * 12 +
|
||||||
|
(anchor.getMonth() - current.getMonth());
|
||||||
if (monthsDelta !== 0) {
|
if (monthsDelta !== 0) {
|
||||||
gotoMonth(monthsDelta)
|
gotoMonth(monthsDelta);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
const renderDay = (day: any) => {
|
const renderDay = (day: any) => {
|
||||||
const { date, month, year } = day;
|
const { date, month, year } = day;
|
||||||
const today = new Date()
|
const today = new Date();
|
||||||
if (date === today.getDate() && month === today.getMonth() + 1 && year === today.getFullYear()) {
|
if (
|
||||||
return (
|
date === today.getDate() &&
|
||||||
<View className="day-container">
|
month === today.getMonth() + 1 &&
|
||||||
{date}
|
year === today.getFullYear()
|
||||||
</View>
|
) {
|
||||||
)
|
return <View className="day-container">{date}</View>;
|
||||||
}
|
|
||||||
return date
|
|
||||||
}
|
}
|
||||||
|
return date;
|
||||||
|
};
|
||||||
|
|
||||||
const selectWeekend = () => {
|
const selectWeekend = () => {
|
||||||
const [start, end] = getWeekend()
|
const [start, end] = getWeekend();
|
||||||
setSelectedValue([start, end])
|
setSelectedValue([start, end]);
|
||||||
syncMonthTo(start)
|
syncMonthTo(start);
|
||||||
onChange?.([start, end])
|
onChange?.([start, end]);
|
||||||
}
|
};
|
||||||
const selectWeek = () => {
|
const selectWeek = () => {
|
||||||
const dayList = getWeekendOfCurrentWeek(7)
|
const dayList = getWeekendOfCurrentWeek(7);
|
||||||
setSelectedValue(dayList)
|
setSelectedValue(dayList);
|
||||||
syncMonthTo(dayList[0])
|
syncMonthTo(dayList[0]);
|
||||||
onChange?.(dayList)
|
onChange?.(dayList);
|
||||||
}
|
};
|
||||||
const selectMonth = () => {
|
const selectMonth = () => {
|
||||||
const dayList = getWeekendOfCurrentWeek(30)
|
const dayList = getWeekendOfCurrentWeek(30);
|
||||||
setSelectedValue(dayList)
|
setSelectedValue(dayList);
|
||||||
syncMonthTo(dayList[0])
|
syncMonthTo(dayList[0]);
|
||||||
onChange?.(dayList)
|
onChange?.(dayList);
|
||||||
}
|
};
|
||||||
|
|
||||||
const handleMonthChange = (value: any) => {
|
const handleMonthChange = (value: any) => {
|
||||||
const [year, month] = value;
|
const [year, month] = value;
|
||||||
const newDate = new Date(year, month - 1, 1);
|
const newDate = new Date(year, month - 1, 1);
|
||||||
setCurrent(newDate);
|
setCurrent(newDate);
|
||||||
calendarRef.current?.jumpTo(year, month)
|
calendarRef.current?.jumpTo(year, month);
|
||||||
}
|
};
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View>
|
<View>
|
||||||
{/* 快速操作行 */}
|
{/* 快速操作行 */}
|
||||||
{
|
{showQuickActions && (
|
||||||
showQuickActions &&
|
<View className={styles["quick-actions"]}>
|
||||||
<View className={styles['quick-actions']}>
|
<View className={styles["quick-action"]} onClick={selectWeekend}>
|
||||||
<View className={styles['quick-action']} onClick={selectWeekend}>本周末</View>
|
本周末
|
||||||
<View className={styles['quick-action']} onClick={selectWeek}>一周内</View>
|
|
||||||
<View className={styles['quick-action']} onClick={selectMonth}>一个月</View>
|
|
||||||
</View>
|
</View>
|
||||||
}
|
<View className={styles["quick-action"]} onClick={selectWeek}>
|
||||||
<View className={`${styles['calendar-card']} ${isBorder ? styles['border'] : ''}`}>
|
一周内
|
||||||
{
|
</View>
|
||||||
type === 'range' && (
|
<View className={styles["quick-action"]} onClick={selectMonth}>
|
||||||
<View className={styles['date-range-container']}>
|
一个月
|
||||||
<Text className={`${styles['date-text-placeholder']} ${value?.[0] ? styles['date-text'] : ''}`}>{value?.[0] ? dayjs(value?.[0] as Date).format('YYYY-MM-DD') : '起始时间'}</Text>
|
</View>
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
|
<View
|
||||||
|
className={`${styles["calendar-card"]} ${
|
||||||
|
isBorder ? styles["border"] : ""
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{type === "range" && (
|
||||||
|
<View className={styles["date-range-container"]}>
|
||||||
|
<Text
|
||||||
|
className={`${styles["date-text-placeholder"]} ${
|
||||||
|
(value as Date[]).length === 2 ? styles["date-text"] : ""
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{(value as Date[]).length === 2
|
||||||
|
? dayjs(value?.[0] as Date).format("YYYY-MM-DD")
|
||||||
|
: "起始时间"}
|
||||||
|
</Text>
|
||||||
<Text>至</Text>
|
<Text>至</Text>
|
||||||
<Text className={`${styles['date-text-placeholder']} ${value?.[1] ? styles['date-text'] : ''}`}>{value?.[1] ? dayjs(value?.[1] as Date).format('YYYY-MM-DD') : '结束时间'}</Text>
|
<Text
|
||||||
|
className={`${styles["date-text-placeholder"]} ${
|
||||||
|
(value as Date[]).length === 2 ? styles["date-text"] : ""
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{(value as Date[]).length === 2
|
||||||
|
? dayjs(value?.[1] as Date).format("YYYY-MM-DD")
|
||||||
|
: "结束时间"}
|
||||||
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
)
|
)}
|
||||||
}
|
|
||||||
{/* 自定义头部显示周一到周日 */}
|
{/* 自定义头部显示周一到周日 */}
|
||||||
<View className={styles['header']}>
|
<View className={styles["header"]}>
|
||||||
<View className={styles['header-left']} onClick={handleHeaderClick}>
|
<View className={styles["header-left"]} onClick={handleHeaderClick}>
|
||||||
<Text className={styles['header-text']}>{formatHeader(current as Date)}</Text>
|
<Text className={styles["header-text"]}>
|
||||||
<Image src={images.ICON_RIGHT_MAX} className={`${styles['month-arrow']}`} onClick={() => gotoMonth(1)} />
|
{formatHeader(current as Date)}
|
||||||
|
</Text>
|
||||||
|
<Image
|
||||||
|
src={images.ICON_RIGHT_MAX}
|
||||||
|
className={`${styles["month-arrow"]}`}
|
||||||
|
onClick={() => gotoMonth(1)}
|
||||||
|
/>
|
||||||
</View>
|
</View>
|
||||||
<View className={styles['header-actions']}>
|
<View className={styles["header-actions"]}>
|
||||||
<View className={styles['arrow-left-container']} onClick={() => gotoMonth(-1)}>
|
<View
|
||||||
<Image src={images.ICON_RIGHT_MAX} className={`${styles['arrow']} ${styles['left']}`} />
|
className={styles["arrow-left-container"]}
|
||||||
|
onClick={() => gotoMonth(-1)}
|
||||||
|
>
|
||||||
|
<Image
|
||||||
|
src={images.ICON_RIGHT_MAX}
|
||||||
|
className={`${styles["arrow"]} ${styles["left"]}`}
|
||||||
|
/>
|
||||||
</View>
|
</View>
|
||||||
<View className={styles['arrow-right-container']} onClick={() => gotoMonth(1)}>
|
<View
|
||||||
<Image src={images.ICON_RIGHT_MAX} className={`${styles['arrow']}`} />
|
className={styles["arrow-right-container"]}
|
||||||
|
onClick={() => gotoMonth(1)}
|
||||||
|
>
|
||||||
|
<Image
|
||||||
|
src={images.ICON_RIGHT_MAX}
|
||||||
|
className={`${styles["arrow"]}`}
|
||||||
|
/>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
<View className={styles['week-header']}>
|
<View className={styles["week-header"]}>
|
||||||
{['周日', '周一', '周二', '周三', '周四', '周五', '周六'].map((day) => (
|
{["周日", "周一", "周二", "周三", "周四", "周五", "周六"].map(
|
||||||
<Text key={day} className={styles['week-day']}>
|
(day) => (
|
||||||
|
<Text key={day} className={styles["week-day"]}>
|
||||||
{day}
|
{day}
|
||||||
</Text>
|
</Text>
|
||||||
))}
|
)
|
||||||
|
)}
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
{/* NutUI CalendarCard 组件 */}
|
{/* NutUI CalendarCard 组件 */}
|
||||||
@@ -212,16 +271,21 @@ const NutUICalendar = React.forwardRef<CalendarUIRef, NutUICalendarProps>(({
|
|||||||
renderDay={renderDay}
|
renderDay={renderDay}
|
||||||
onChange={handleDateChange}
|
onChange={handleDateChange}
|
||||||
onPageChange={handlePageChange}
|
onPageChange={handlePageChange}
|
||||||
|
onDayClick={handleDayClick}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
{visible && <PopupPicker
|
{visible && (
|
||||||
|
<PopupPicker
|
||||||
visible={visible}
|
visible={visible}
|
||||||
setvisible={setvisible}
|
setvisible={setvisible}
|
||||||
value={[current.getFullYear(), current.getMonth() + 1]}
|
value={[current.getFullYear(), current.getMonth() + 1]}
|
||||||
type="month"
|
type="month"
|
||||||
onChange={(value) => handleMonthChange(value)} />}
|
onChange={(value) => handleMonthChange(value)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</View>
|
</View>
|
||||||
)
|
);
|
||||||
})
|
}
|
||||||
|
);
|
||||||
|
|
||||||
export default NutUICalendar
|
export default NutUICalendar;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
import { View, Text, Button } from "@tarojs/components";
|
import { View, Text, Button } from "@tarojs/components";
|
||||||
import Taro, { useDidShow } from "@tarojs/taro";
|
import Taro, { useDidShow } from "@tarojs/taro";
|
||||||
import dayjs from 'dayjs'
|
import dayjs from "dayjs";
|
||||||
|
|
||||||
import "./index.scss";
|
import "./index.scss";
|
||||||
import { DialogCalendarCard } from "@/components/index";
|
import { DialogCalendarCard } from "@/components/index";
|
||||||
@@ -40,6 +40,13 @@ const DownloadBill: React.FC = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const selectDateRange = (range: string) => {
|
const selectDateRange = (range: string) => {
|
||||||
|
if (dateType === range) {
|
||||||
|
if (range === "custom") {
|
||||||
|
setVisible(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
switch (range) {
|
switch (range) {
|
||||||
case "week":
|
case "week":
|
||||||
setDateType("week");
|
setDateType("week");
|
||||||
@@ -56,7 +63,9 @@ const DownloadBill: React.FC = () => {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const [currentTimeValue, setCurrentTimeValue] = useState<Date | Date[]>(new Date());
|
const [currentTimeValue, setCurrentTimeValue] = useState<Date | Date[]>(
|
||||||
|
new Date()
|
||||||
|
);
|
||||||
const handleConfirm = (val: Date[]) => {
|
const handleConfirm = (val: Date[]) => {
|
||||||
setCurrentTimeValue(val);
|
setCurrentTimeValue(val);
|
||||||
const [start, end] = val;
|
const [start, end] = val;
|
||||||
|
|||||||
Reference in New Issue
Block a user