From 6272e50348054e20412c81fff45e86545a28ca8d Mon Sep 17 00:00:00 2001 From: zdl <3489966805@qq.com> Date: Fri, 5 Dec 2025 12:11:14 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E6=8A=BD=E5=8F=96=20EventFormModal?= =?UTF-8?q?=20=E9=80=9A=E7=94=A8=E5=BC=B9=E7=AA=97=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=EF=BC=8C=E4=BF=AE=E5=A4=8D=E8=A7=86=E5=9B=BE=E5=88=87=E6=8D=A2?= =?UTF-8?q?=E5=BC=B9=E7=AA=97=E8=87=AA=E5=8A=A8=E6=89=93=E5=BC=80=20bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新建 EventFormModal.tsx 通用弹窗组件(约 500 行) - 支持通过 props 配置字段显示(日期、类型、状态、重要度、标签) - 支持两种 API 端点(investment-plans / calendar/events) - 支持两种股票输入模式(tag 标签形式 / text 逗号分隔) - 重构 EventPanel.tsx 使用 EventFormModal - 使用 useRef 修复弹窗自动打开 bug(视图切换时不再误触发) - 移除内联 Modal 代码,减少约 200 行 - 重构 CalendarPanel.tsx 使用 EventFormModal - 添加事件功能改用 EventFormModal - 保留详情弹窗(只读展示当日事件列表) - 移除内联表单代码,减少约 100 行 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .../Dashboard/components/CalendarPanel.tsx | 197 ++----- .../Dashboard/components/EventFormModal.tsx | 496 ++++++++++++++++++ src/views/Dashboard/components/EventPanel.tsx | 305 ++--------- 3 files changed, 575 insertions(+), 423 deletions(-) create mode 100644 src/views/Dashboard/components/EventFormModal.tsx diff --git a/src/views/Dashboard/components/CalendarPanel.tsx b/src/views/Dashboard/components/CalendarPanel.tsx index 3f0a3730..230dd4d2 100644 --- a/src/views/Dashboard/components/CalendarPanel.tsx +++ b/src/views/Dashboard/components/CalendarPanel.tsx @@ -25,11 +25,6 @@ import { Center, Tooltip, Icon, - Input, - FormControl, - FormLabel, - Textarea, - Select, Tag, TagLabel, TagLeftIcon, @@ -50,23 +45,13 @@ import dayjs, { Dayjs } from 'dayjs'; import 'dayjs/locale/zh-cn'; import { usePlanningData } from './PlanningContext'; -import type { InvestmentEvent, EventType } from '@/types'; +import { EventFormModal } from './EventFormModal'; +import type { InvestmentEvent } from '@/types'; import { logger } from '@/utils/logger'; import { getApiBase } from '@/utils/apiConfig'; dayjs.locale('zh-cn'); -/** - * 新事件表单数据类型 - */ -interface NewEventForm { - title: string; - description: string; - type: EventType; - importance: number; - stocks: string; -} - /** * FullCalendar 事件类型 */ @@ -96,18 +81,13 @@ export const CalendarPanel: React.FC = () => { secondaryText, } = usePlanningData(); + // 详情弹窗 const { isOpen, onOpen, onClose } = useDisclosure(); - const { isOpen: isAddOpen, onOpen: onAddOpen, onClose: onAddClose } = useDisclosure(); + // 添加弹窗状态 + const [isAddModalOpen, setIsAddModalOpen] = useState(false); const [selectedDate, setSelectedDate] = useState(null); const [selectedDateEvents, setSelectedDateEvents] = useState([]); - const [newEvent, setNewEvent] = useState({ - title: '', - description: '', - type: 'plan', - importance: 3, - stocks: '', - }); // 转换数据为 FullCalendar 格式 const calendarEvents: CalendarEvent[] = allEvents.map(event => ({ @@ -149,61 +129,15 @@ export const CalendarPanel: React.FC = () => { onOpen(); }; - // 添加新事件 - const handleAddEvent = async (): Promise => { - try { - const base = getApiBase(); + // 打开添加弹窗 + const handleOpenAddModal = (): void => { + onClose(); // 先关闭详情弹窗 + setIsAddModalOpen(true); + }; - const eventData = { - ...newEvent, - event_date: (selectedDate ? selectedDate.format('YYYY-MM-DD') : dayjs().format('YYYY-MM-DD')), - stocks: newEvent.stocks.split(',').map(s => s.trim()).filter(s => s), - }; - - const response = await fetch(base + '/api/account/calendar/events', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - credentials: 'include', - body: JSON.stringify(eventData), - }); - - if (response.ok) { - const data = await response.json(); - if (data.success) { - logger.info('CalendarPanel', '添加事件成功', { - eventTitle: eventData.title, - eventDate: eventData.event_date - }); - toast({ - title: '添加成功', - description: '投资计划已添加', - status: 'success', - duration: 3000, - }); - onAddClose(); - loadAllData(); - setNewEvent({ - title: '', - description: '', - type: 'plan', - importance: 3, - stocks: '', - }); - } - } - } catch (error) { - logger.error('CalendarPanel', 'handleAddEvent', error, { - eventTitle: newEvent?.title - }); - toast({ - title: '添加失败', - description: '无法添加投资计划', - status: 'error', - duration: 3000, - }); - } + // 关闭添加弹窗 + const handleCloseAddModal = (): void => { + setIsAddModalOpen(false); }; // 删除事件 @@ -300,10 +234,7 @@ export const CalendarPanel: React.FC = () => { size="sm" colorScheme="purple" leftIcon={} - onClick={() => { - onClose(); - onAddOpen(); - }} + onClick={handleOpenAddModal} > 添加投资计划 @@ -397,88 +328,24 @@ export const CalendarPanel: React.FC = () => { )} - {/* 添加投资计划 Modal */} - {isAddOpen && ( - - - - - 添加投资计划 - - - - - - 标题 - setNewEvent({ ...newEvent, title: e.target.value })} - placeholder="例如:关注半导体板块" - /> - - - - 描述 -