From 5efd5986942ae61cef010171c8787527b6ea6def Mon Sep 17 00:00:00 2001 From: zdl <3489966805@qq.com> Date: Thu, 4 Dec 2025 15:57:32 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E6=8F=90=E5=8F=96=20ConceptStocksM?= =?UTF-8?q?odal=20=E4=B8=BA=E9=80=9A=E7=94=A8=E7=BB=84=E4=BB=B6=EF=BC=8C?= =?UTF-8?q?=E7=BB=9F=E4=B8=80=E6=A6=82=E5=BF=B5=E4=B8=AD=E5=BF=83=E5=92=8C?= =?UTF-8?q?=E4=B8=AA=E8=82=A1=E4=B8=AD=E5=BF=83=E5=BC=B9=E7=AA=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将 ConceptStocksModal 从 StockOverview/components 移到 components 目录 - 概念中心复用 ConceptStocksModal,删除冗余的 renderStockTable 函数(约100行) - 统一 H5 端弹窗体验:响应式尺寸、高度限制(70vh)、左右滑动、垂直居中 - 移除重复的底部关闭按钮,只保留右上角关闭按钮 - 添加"板块原因"列,表头改为中文 - 使用 @components 路径别名 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .../ConceptStocksModal/index.tsx} | 38 ++--- src/views/Concept/index.js | 135 ++---------------- src/views/StockOverview/index.js | 2 +- 3 files changed, 31 insertions(+), 144 deletions(-) rename src/{views/StockOverview/components/ConceptStocksModal.tsx => components/ConceptStocksModal/index.tsx} (83%) diff --git a/src/views/StockOverview/components/ConceptStocksModal.tsx b/src/components/ConceptStocksModal/index.tsx similarity index 83% rename from src/views/StockOverview/components/ConceptStocksModal.tsx rename to src/components/ConceptStocksModal/index.tsx index 998f217e..2541cd7d 100644 --- a/src/views/StockOverview/components/ConceptStocksModal.tsx +++ b/src/components/ConceptStocksModal/index.tsx @@ -7,8 +7,6 @@ import { ModalHeader, ModalCloseButton, ModalBody, - ModalFooter, - Button, Table, Thead, Tbody, @@ -22,6 +20,7 @@ import { Icon, Spinner, useColorModeValue, + useBreakpointValue, } from '@chakra-ui/react'; import { FaTable } from 'react-icons/fa'; import marketService from '@services/marketService'; @@ -31,6 +30,8 @@ import { logger } from '@utils/logger'; interface StockInfo { stock_code: string; stock_name: string; + reason?: string; + change_pct?: number; [key: string]: unknown; } @@ -72,6 +73,12 @@ const ConceptStocksModal: React.FC = ({ const cardBg = useColorModeValue('white', '#1a1a1a'); const hoverBg = useColorModeValue('gray.50', '#2a2a2a'); + // 响应式配置 - 添加 fallback 避免首次渲染时返回 undefined 导致弹窗异常 + const isMobile = useBreakpointValue({ base: true, md: false }, { fallback: 'md' }); + // H5 使用 xl 而非 full,配合 maxH 限制高度 + const modalSize = useBreakpointValue({ base: 'xl', md: '4xl' }, { fallback: 'md' }); + const tableMaxH = useBreakpointValue({ base: '45vh', md: '60vh' }, { fallback: 'md' }); + // 批量获取股票行情数据 const fetchStockMarketData = useCallback(async (stocks: StockInfo[]) => { if (!stocks || stocks.length === 0) return; @@ -131,11 +138,12 @@ const ConceptStocksModal: React.FC = ({ - + @@ -156,14 +164,15 @@ const ConceptStocksModal: React.FC = ({ )} - - + +
- - - - + + + + + @@ -210,6 +219,9 @@ const ConceptStocksModal: React.FC = ({ '-' )} + ); })} @@ -219,12 +231,6 @@ const ConceptStocksModal: React.FC = ({ )} - - - - ); diff --git a/src/views/Concept/index.js b/src/views/Concept/index.js index 6432fb22..ea932776 100644 --- a/src/views/Concept/index.js +++ b/src/views/Concept/index.js @@ -86,6 +86,7 @@ import { BsGraphUp, BsLightningFill } from 'react-icons/bs'; import { keyframes } from '@emotion/react'; import ConceptTimelineModal from './ConceptTimelineModal'; import ConceptStatsPanel from './components/ConceptStatsPanel'; +import ConceptStocksModal from '@components/ConceptStocksModal'; // 导航栏已由 MainLayout 提供,无需在此导入 // 导入订阅权限管理 import { useSubscription } from '../../hooks/useSubscription'; @@ -528,109 +529,6 @@ const ConceptCenter = () => { return `https://valuefrontier.cn/company?scode=${seccode}`; }; - // 渲染动态表格列 - const renderStockTable = () => { - if (!selectedConceptStocks || selectedConceptStocks.length === 0) { - return 暂无相关股票数据; - } - - const allFields = new Set(); - selectedConceptStocks.forEach(stock => { - Object.keys(stock).forEach(key => allFields.add(key)); - }); - - // 定义固定的列顺序,包含新增的现价和涨跌幅列 - const orderedFields = ['stock_name', 'stock_code', 'current_price', 'change_percent']; - allFields.forEach(field => { - if (!orderedFields.includes(field)) { - orderedFields.push(field); - } - }); - - return ( - - {loadingStockData && ( - - - - 正在获取行情数据... - - - )} - - -
股票名称股票代码现价涨跌幅股票名称股票代码现价当日涨跌幅板块原因
+ {stock.reason || '-'} +
- - - {orderedFields.map(field => ( - - ))} - - - - {selectedConceptStocks.map((stock, idx) => { - const marketData = stockMarketData[stock.stock_code]; - const companyLink = generateCompanyLink(stock.stock_code); - - return ( - - {orderedFields.map(field => { - let cellContent = stock[field] || '-'; - let cellProps = {}; - - // 处理特殊字段 - if (field === 'current_price') { - cellContent = marketData ? formatPrice(marketData.close) : (loadingStockData ? : '-'); - } else if (field === 'change_percent') { - if (marketData) { - cellContent = formatStockChangePercent(marketData.change_percent); - cellProps.color = `${getStockChangeColor(marketData.change_percent)}.500`; - cellProps.fontWeight = 'bold'; - } else { - cellContent = loadingStockData ? : '-'; - } - } else if (field === 'stock_name' || field === 'stock_code') { - // 添加超链接 - cellContent = ( - - {stock[field] || '-'} - - ); - } - - return ( - - ); - })} - - ); - })} - -
- {field === 'stock_name' ? '股票名称' : - field === 'stock_code' ? '股票代码' : - field === 'current_price' ? '现价' : - field === 'change_percent' ? '当日涨跌幅' : field} -
- {cellContent} -
-
- - ); - }; - // 格式化添加日期显示 const formatAddedDate = (concept) => { // 优先使用 created_at 或 added_date 字段 @@ -1763,32 +1661,15 @@ const ConceptCenter = () => { - {/* 股票详情Modal */} - setIsStockModalOpen(false)} - size="6xl" - scrollBehavior="inside" - > - - - - - - {selectedConceptName} - 相关个股 - - - - - {renderStockTable()} - - - - - - + concept={{ + concept_name: selectedConceptName, + stocks: selectedConceptStocks + }} + /> {/* 时间轴Modal */}