From 03be49a459f39173b092513bd79a3b5a22dc6b86 Mon Sep 17 00:00:00 2001 From: zzlgreat Date: Wed, 7 Jan 2026 12:35:15 +0800 Subject: [PATCH] =?UTF-8?q?community=E5=A2=9E=E5=8A=A0=E4=BA=8B=E4=BB=B6?= =?UTF-8?q?=E8=AF=A6=E6=83=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/Community/components/HeroPanel.js | 327 ++++++++++++++------ 1 file changed, 237 insertions(+), 90 deletions(-) diff --git a/src/views/Community/components/HeroPanel.js b/src/views/Community/components/HeroPanel.js index a4d163e4..b3bbfe20 100644 --- a/src/views/Community/components/HeroPanel.js +++ b/src/views/Community/components/HeroPanel.js @@ -409,11 +409,13 @@ CalendarCell.displayName = 'CalendarCell'; const DetailModal = ({ isOpen, onClose, selectedDate, ztDetail, events, loading }) => { const [detailDrawerVisible, setDetailDrawerVisible] = useState(false); const [selectedContent, setSelectedContent] = useState(null); + const [ztViewMode, setZtViewMode] = useState('sector'); // 'sector' | 'stock' // 板块数据处理 - 必须在条件返回之前调用所有hooks const sectorList = useMemo(() => { if (!ztDetail?.sector_data) return []; return Object.entries(ztDetail.sector_data) + .filter(([name]) => name !== '其他') .map(([name, data]) => ({ name, count: data.count, @@ -422,6 +424,21 @@ const DetailModal = ({ isOpen, onClose, selectedDate, ztDetail, events, loading .sort((a, b) => b.count - a.count); }, [ztDetail]); + // 股票详情数据处理 + const stockList = useMemo(() => { + if (!ztDetail?.stock_infos) return []; + return ztDetail.stock_infos.map(stock => ({ + ...stock, + key: stock.scode, + })); + }, [ztDetail]); + + // 热门关键词 + const hotKeywords = useMemo(() => { + if (!ztDetail?.word_freq_data) return []; + return ztDetail.word_freq_data.slice(0, 12); + }, [ztDetail]); + // 条件返回必须在所有hooks之后 if (!selectedDate) return null; @@ -456,28 +473,33 @@ const DetailModal = ({ isOpen, onClose, selectedDate, ztDetail, events, loading { title: '排名', key: 'rank', - width: 60, + width: 55, + align: 'center', render: (_, __, index) => ( - + {index + 1} ), }, { - title: '板块名称', + title: '板块', dataIndex: 'name', key: 'name', - render: (name) => {name}, + width: 120, + render: (name) => ( + {name} + ), }, { title: '涨停数', dataIndex: 'count', key: 'count', - width: 100, + width: 80, + align: 'center', render: (count) => ( - = 10 ? 'red' : count >= 5 ? 'orange' : 'blue'} style={{ fontSize: '14px' }}> - - {count}家 + = 8 ? 'red' : count >= 5 ? 'volcano' : count >= 3 ? 'orange' : 'blue'}> + + {count} ), }, @@ -485,27 +507,127 @@ const DetailModal = ({ isOpen, onClose, selectedDate, ztDetail, events, loading title: '涨停股票', dataIndex: 'stocks', key: 'stocks', - render: (stocks) => ( - - {stocks.slice(0, 8).map((code) => ( - - { + // 根据股票代码查找股票名称 + const getStockName = (code) => { + const stockInfo = stockList.find(s => s.scode === code); + return stockInfo?.sname || code; + }; + return ( + + {stocks.slice(0, 6).map((code) => ( + - {code} - - - ))} - {stocks.length > 8 && +{stocks.length - 8}} - - ), + + {getStockName(code)} + + + ))} + {stocks.length > 6 && ( + +{stocks.length - 6} + )} + + ); + }, }, ]; - // 事件表格列(参考投资日历) + // 涨停股票详情表格列 + const stockColumns = [ + { + title: '股票', + key: 'stock', + width: 120, + fixed: 'left', + render: (_, record) => ( + + {record.sname} + + ), + }, + { + title: '涨停时间', + dataIndex: 'formatted_time', + key: 'time', + width: 85, + align: 'center', + render: (time) => ( + + {time?.substring(0, 5) || '-'} + + ), + }, + { + title: '连板', + dataIndex: 'continuous_days', + key: 'continuous', + width: 75, + align: 'center', + render: (text) => { + if (!text || text === '首板') return 首板; + const match = text.match(/(\d+)/); + const days = match ? parseInt(match[1]) : 1; + return ( + = 5 ? 'red' : days >= 3 ? 'volcano' : days >= 2 ? 'orange' : 'default'}> + {text} + + ); + }, + }, + { + title: '核心板块', + dataIndex: 'core_sectors', + key: 'sectors', + width: 180, + render: (sectors) => ( + + {(sectors || []).slice(0, 3).map((sector, idx) => ( + + {sector} + + ))} + + ), + }, + { + title: '涨停简报', + dataIndex: 'brief', + key: 'brief', + ellipsis: true, + render: (text) => { + if (!text) return -; + // 移除HTML标签 + const cleanText = text.replace(//gi, ' ').replace(/<[^>]+>/g, ''); + return ( + + + + ); + }, + }, + ]; + + // 事件表格列(参考投资日历)- 去掉相关概念列 const eventColumns = [ { title: '时间', @@ -599,30 +721,6 @@ const DetailModal = ({ isOpen, onClose, selectedDate, ztDetail, events, loading ); }, }, - { - title: '相关概念', - dataIndex: 'concepts', - key: 'concepts', - width: 200, - render: (concepts) => ( - - {concepts && concepts.length > 0 ? ( - concepts.slice(0, 3).map((concept, index) => ( - }> - {typeof concept === 'string' - ? concept - : (concept?.concept || concept?.name || '未知')} - - )) - ) : ( - - )} - {concepts && concepts.length > 3 && ( - +{concepts.length - 3} - )} - - ), - }, ]; return ( @@ -696,15 +794,88 @@ const DetailModal = ({ isOpen, onClose, selectedDate, ztDetail, events, loading key="zt" disabled={!ztDetail} > - {sectorList.length > 0 ? ( - + {(sectorList.length > 0 || stockList.length > 0) ? ( + + {/* 热门关键词 */} + {hotKeywords.length > 0 && ( + + + + + 今日热词 + + + + {hotKeywords.map((kw, idx) => ( + + {kw.name} + + ))} + + + )} + + {/* 视图切换按钮 */} + + + + + + + 共 {ztDetail?.total_stocks || 0} 只涨停 + + + + {/* 板块视图 */} + {ztViewMode === 'sector' && ( +
+ )} + + {/* 个股视图 */} + {ztViewMode === 'stock' && ( +
+ )} + ) : (
@@ -727,38 +898,14 @@ const DetailModal = ({ isOpen, onClose, selectedDate, ztDetail, events, loading disabled={!events?.length} > {events?.length > 0 ? ( - - -
- - e.type === 'event').length})`} key="eventType"> -
e.type === 'event')} - columns={eventColumns} - rowKey="id" - size="middle" - pagination={false} - scroll={{ x: 1000, y: 400 }} - /> - - e.type === 'data').length})`} key="data"> -
e.type === 'data')} - columns={eventColumns} - rowKey="id" - size="middle" - pagination={false} - scroll={{ x: 1000, y: 400 }} - /> - - +
) : (