From b66c1585f79a22aafea4a5732bb655fc0cf4c909 Mon Sep 17 00:00:00 2001 From: zdl <3489966805@qq.com> Date: Thu, 4 Dec 2025 16:20:58 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=8F=90=E5=8F=96=E6=97=A5=E5=8E=86?= =?UTF-8?q?=E9=80=89=E6=8B=A9=E5=99=A8=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/TradeDatePicker/index.tsx | 130 +++++++++++++++++++++++ src/views/Concept/index.js | 50 +++------ 2 files changed, 146 insertions(+), 34 deletions(-) create mode 100644 src/components/TradeDatePicker/index.tsx diff --git a/src/components/TradeDatePicker/index.tsx b/src/components/TradeDatePicker/index.tsx new file mode 100644 index 00000000..ff749a95 --- /dev/null +++ b/src/components/TradeDatePicker/index.tsx @@ -0,0 +1,130 @@ +import React from 'react'; +import { + HStack, + Input, + Text, + Icon, + Tooltip, + useColorModeValue, +} from '@chakra-ui/react'; +import { InfoIcon } from '@chakra-ui/icons'; +import { FaCalendarAlt } from 'react-icons/fa'; + +export interface TradeDatePickerProps { + /** 当前选中的日期 */ + value: Date | null; + /** 日期变化回调 */ + onChange: (date: Date) => void; + /** 默认日期(组件初始化时使用) */ + defaultDate?: Date; + /** 最新交易日期(用于显示提示) */ + latestTradeDate?: Date | null; + /** 最大可选日期,默认今天 */ + maxDate?: Date; + /** 标签文字,默认"交易日期" */ + label?: string; + /** 输入框宽度 */ + inputWidth?: string | object; + /** 是否显示标签图标 */ + showIcon?: boolean; +} + +/** + * 交易日期选择器组件 + * + * 提供日期输入框和最新交易日期提示,供概念中心、个股中心等页面复用。 + * 快捷按钮(今天、昨天等)由各页面自行实现。 + */ +const TradeDatePicker: React.FC = ({ + value, + onChange, + defaultDate, + latestTradeDate, + maxDate, + label = '交易日期', + inputWidth = { base: '100%', lg: '200px' }, + showIcon = true, +}) => { + // 颜色主题 + const labelColor = useColorModeValue('purple.700', 'purple.300'); + const iconColor = useColorModeValue('purple.500', 'purple.400'); + const inputBorderColor = useColorModeValue('purple.200', 'purple.600'); + const tipBg = useColorModeValue('blue.50', 'blue.900'); + const tipBorderColor = useColorModeValue('blue.200', 'blue.600'); + const tipTextColor = useColorModeValue('blue.600', 'blue.200'); + const tipIconColor = useColorModeValue('blue.500', 'blue.300'); + + // 使用默认日期初始化(仅在 value 为 null 且有 defaultDate 时) + React.useEffect(() => { + if (value === null && defaultDate) { + onChange(defaultDate); + } + }, []); // eslint-disable-line react-hooks/exhaustive-deps + + // 处理日期变化 + const handleDateChange = (e: React.ChangeEvent) => { + const dateStr = e.target.value; + if (dateStr) { + const date = new Date(dateStr); + onChange(date); + } + }; + + // 格式化日期为 YYYY-MM-DD + const formatDateValue = (date: Date | null): string => { + if (!date) return ''; + return date.toISOString().split('T')[0]; + }; + + // 计算最大日期 + const maxDateStr = maxDate + ? formatDateValue(maxDate) + : new Date().toISOString().split('T')[0]; + + return ( + <> + {/* 标签 */} + + {showIcon && } + + {label}: + + + + {/* 日期输入框 */} + + + {/* 最新交易日期提示 */} + {latestTradeDate && ( + + + + + 最新: {latestTradeDate.toLocaleDateString('zh-CN')} + + + + )} + + ); +}; + +export default TradeDatePicker; diff --git a/src/views/Concept/index.js b/src/views/Concept/index.js index ea932776..ad159e46 100644 --- a/src/views/Concept/index.js +++ b/src/views/Concept/index.js @@ -87,6 +87,7 @@ import { keyframes } from '@emotion/react'; import ConceptTimelineModal from './ConceptTimelineModal'; import ConceptStatsPanel from './components/ConceptStatsPanel'; import ConceptStocksModal from '@components/ConceptStocksModal'; +import TradeDatePicker from '@components/TradeDatePicker'; // 导航栏已由 MainLayout 提供,无需在此导入 // 导入订阅权限管理 import { useSubscription } from '../../hooks/useSubscription'; @@ -1082,23 +1083,23 @@ const ConceptCenter = () => { align={{ base: 'stretch', lg: 'center' }} gap={4} > - - - 交易日期: - - - { + const dateStr = date.toISOString().split('T')[0]; + const previousDate = selectedDate ? selectedDate.toISOString().split('T')[0] : null; + trackFilterApplied('date', dateStr, previousDate); + setSelectedDate(date); + setCurrentPage(1); + updateUrlParams({ date: dateStr, page: 1 }); + fetchConcepts(searchQuery, 1, date, sortBy); + }} + latestTradeDate={latestTradeDate} + label="交易日期" /> + {/* 快捷按钮保留在页面内 */} - - {latestTradeDate && ( - - - - - 最新: {latestTradeDate.toLocaleDateString('zh-CN')} - - - - )} );