From c61d58b0e31cafedcfdca55de5911eda0c858fce Mon Sep 17 00:00:00 2001 From: zdl <3489966805@qq.com> Date: Tue, 9 Dec 2025 15:01:16 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0Company=20=E9=A1=B5?= =?UTF-8?q?=E9=9D=A2=20Tab=20=E5=88=87=E6=8D=A2=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/CompanyTabs/TabNavigation.js | 45 ++++++++ .../Company/components/CompanyTabs/index.js | 100 ++++++++++++++++++ src/views/Company/constants/index.js | 53 ++++++++++ 3 files changed, 198 insertions(+) create mode 100644 src/views/Company/components/CompanyTabs/TabNavigation.js create mode 100644 src/views/Company/components/CompanyTabs/index.js create mode 100644 src/views/Company/constants/index.js diff --git a/src/views/Company/components/CompanyTabs/TabNavigation.js b/src/views/Company/components/CompanyTabs/TabNavigation.js new file mode 100644 index 00000000..bfdf7c4c --- /dev/null +++ b/src/views/Company/components/CompanyTabs/TabNavigation.js @@ -0,0 +1,45 @@ +// src/views/Company/components/CompanyTabs/TabNavigation.js +// Tab 导航组件 - 动态渲染 Tab 按钮 + +import React from 'react'; +import { + TabList, + Tab, + HStack, + Icon, + Text, +} from '@chakra-ui/react'; + +import { COMPANY_TABS, TAB_SELECTED_STYLE } from '../../constants'; + +/** + * Tab 导航组件 + * + * @param {Object} props + * @param {string} props.tabBg - Tab 列表背景色 + * @param {string} props.activeBg - 激活状态背景色 + */ +const TabNavigation = ({ tabBg, activeBg }) => { + return ( + + {COMPANY_TABS.map((tab, index) => ( + + + + {tab.name} + + + ))} + + ); +}; + +export default TabNavigation; diff --git a/src/views/Company/components/CompanyTabs/index.js b/src/views/Company/components/CompanyTabs/index.js new file mode 100644 index 00000000..10ae3a2e --- /dev/null +++ b/src/views/Company/components/CompanyTabs/index.js @@ -0,0 +1,100 @@ +// src/views/Company/components/CompanyTabs/index.js +// Tab 容器组件 - 管理 Tab 切换和内容渲染 + +import React, { useState } from 'react'; +import { + Card, + CardBody, + Tabs, + TabPanels, + TabPanel, + Divider, + useColorModeValue, +} from '@chakra-ui/react'; + +import TabNavigation from './TabNavigation'; +import { COMPANY_TABS, getTabNameByIndex } from '../../constants'; + +// 子组件导入 +import FinancialPanorama from '../../FinancialPanorama'; +import ForecastReport from '../../ForecastReport'; +import MarketDataView from '../../MarketDataView'; +import CompanyOverview from '../../CompanyOverview'; + +/** + * Tab 组件映射 + * key 与 COMPANY_TABS 中的 key 对应 + */ +const TAB_COMPONENTS = { + overview: CompanyOverview, + market: MarketDataView, + financial: FinancialPanorama, + forecast: ForecastReport, +}; + +/** + * Tab 容器组件 + * + * 功能: + * - 管理 Tab 切换状态 + * - 动态渲染 Tab 导航和内容 + * - 触发 Tab 变更追踪 + * + * @param {Object} props + * @param {string} props.stockCode - 当前股票代码 + * @param {Function} props.onTabChange - Tab 变更回调 (index, tabName, prevIndex) => void + * @param {string} props.bgColor - 背景颜色 + */ +const CompanyTabs = ({ stockCode, onTabChange, bgColor }) => { + const [currentIndex, setCurrentIndex] = useState(0); + + // 主题相关颜色 + const tabBg = useColorModeValue('gray.50', 'gray.700'); + const activeBg = useColorModeValue('blue.500', 'blue.400'); + + /** + * 处理 Tab 切换 + */ + const handleTabChange = (index) => { + const tabName = getTabNameByIndex(index); + + // 触发追踪回调 + onTabChange?.(index, tabName, currentIndex); + + // 更新状态 + setCurrentIndex(index); + }; + + return ( + + + + {/* Tab 导航 */} + + + + + {/* Tab 内容面板 */} + + {COMPANY_TABS.map((tab) => { + const Component = TAB_COMPONENTS[tab.key]; + return ( + + + + ); + })} + + + + + ); +}; + +export default CompanyTabs; diff --git a/src/views/Company/constants/index.js b/src/views/Company/constants/index.js new file mode 100644 index 00000000..078ae702 --- /dev/null +++ b/src/views/Company/constants/index.js @@ -0,0 +1,53 @@ +// src/views/Company/constants/index.js +// 公司详情页面常量配置 + +import { FaChartLine, FaMoneyBillWave, FaChartBar, FaInfoCircle } from 'react-icons/fa'; + +/** + * Tab 配置 + * @type {Array<{key: string, name: string, icon: React.ComponentType}>} + */ +export const COMPANY_TABS = [ + { key: 'overview', name: '公司概览', icon: FaInfoCircle }, + { key: 'market', name: '股票行情', icon: FaChartLine }, + { key: 'financial', name: '财务全景', icon: FaMoneyBillWave }, + { key: 'forecast', name: '盈利预测', icon: FaChartBar }, +]; + +/** + * Tab 选中状态样式 + */ +export const TAB_SELECTED_STYLE = { + transform: 'scale(1.02)', + transition: 'all 0.2s', +}; + +/** + * Toast 消息配置 + */ +export const TOAST_MESSAGES = { + WATCHLIST_ADD: { title: '已加入自选', status: 'success', duration: 1500 }, + WATCHLIST_REMOVE: { title: '已从自选移除', status: 'info', duration: 1500 }, + WATCHLIST_ERROR: { title: '操作失败,请稍后重试', status: 'error', duration: 2000 }, + INVALID_CODE: { title: '无效的股票代码', status: 'error', duration: 2000 }, + LOGIN_REQUIRED: { title: '请先登录后再加入自选', status: 'warning', duration: 2000 }, +}; + +/** + * 默认股票代码 + */ +export const DEFAULT_STOCK_CODE = '000001'; + +/** + * URL 参数名 + */ +export const URL_PARAM_NAME = 'scode'; + +/** + * 根据索引获取 Tab 名称 + * @param {number} index - Tab 索引 + * @returns {string} Tab 名称 + */ +export const getTabNameByIndex = (index) => { + return COMPANY_TABS[index]?.name || 'Unknown'; +};