feat(Calendar): 概念条点击改为弹出当天弹窗

- FullCalendarPro: 根据点击位置计算具体日期(支持跨天概念条)
- CombinedCalendar: handleEventClick 改为调用 handleDateClick 弹出弹窗
- 移除无用的 getConceptHtmlUrl import

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
zdl
2026-01-16 18:08:14 +08:00
parent 94ba16f59d
commit 7e2d1bbeb2
2 changed files with 36 additions and 13 deletions

View File

@@ -49,6 +49,7 @@ export interface FullCalendarProProps {
start: Date; start: Date;
end: Date; end: Date;
dates: string[]; dates: string[];
clickedDate: string;
}) => void; }) => void;
/** 月份变化回调 */ /** 月份变化回调 */
onMonthChange?: (year: number, month: number) => void; onMonthChange?: (year: number, month: number) => void;
@@ -372,16 +373,33 @@ export const FullCalendarPro: React.FC<FullCalendarProProps> = ({
[onDateClick] [onDateClick]
); );
// 处理事件点击 // 处理事件点击(计算点击的具体日期)
const handleEventClick = useCallback( const handleEventClick = useCallback(
(arg: EventClickArg) => { (arg: EventClickArg) => {
const { extendedProps } = arg.event; const { extendedProps } = arg.event;
if (arg.event.start && arg.event.end) { const dates = extendedProps.dates as string[];
if (arg.event.start && dates?.length > 0) {
// 计算点击的是哪一天
let clickedDate = dates[0]; // 默认第一天
if (dates.length > 1) {
const rect = arg.el.getBoundingClientRect();
const clickX = arg.jsEvent.clientX - rect.left;
const dayWidth = rect.width / dates.length;
const dayIndex = Math.min(
Math.floor(clickX / dayWidth),
dates.length - 1
);
clickedDate = dates[dayIndex];
}
onEventClick?.({ onEventClick?.({
title: arg.event.title, title: arg.event.title,
start: arg.event.start, start: arg.event.start,
end: arg.event.end, end: arg.event.end,
dates: extendedProps.dates as string[], dates: dates,
clickedDate: clickedDate,
}); });
} }
}, },

View File

@@ -14,7 +14,6 @@ import dayjs from "dayjs";
import { GLASS_BLUR } from "@/constants/glassConfig"; import { GLASS_BLUR } from "@/constants/glassConfig";
import { eventService } from "@services/eventService"; import { eventService } from "@services/eventService";
import { getApiBase } from "@utils/apiConfig"; import { getApiBase } from "@utils/apiConfig";
import { getConceptHtmlUrl } from "@utils/textUtils";
import { textColors } from "../constants"; import { textColors } from "../constants";
import { formatDateStr } from "../utils"; import { formatDateStr } from "../utils";
@@ -146,15 +145,21 @@ const CombinedCalendar = memo(({ DetailModal }) => {
setCurrentMonth(new Date(year, month - 1, 1)); setCurrentMonth(new Date(year, month - 1, 1));
}, []); }, []);
// 处理概念条点击 - 打开概念详情页 // 处理概念条点击 - 弹出当天弹窗
const handleEventClick = useCallback((event) => { const handleEventClick = useCallback(
// event.title 格式: "概念名 (N天)" 或 "概念名" (event) => {
const conceptName = event.title.replace(/\s*\(\d+天\)$/, ""); // 使用 clickedDateYYYYMMDD 格式)构造 Date 对象
const url = getConceptHtmlUrl(conceptName); const dateStr = event.clickedDate || event.dates?.[0];
if (url) { if (dateStr) {
window.open(url, "_blank"); const year = parseInt(dateStr.slice(0, 4), 10);
} const month = parseInt(dateStr.slice(4, 6), 10) - 1;
}, []); const day = parseInt(dateStr.slice(6, 8), 10);
const date = new Date(year, month, day);
handleDateClick(date);
}
},
[handleDateClick]
);
return ( return (
<> <>