From 4672a243531ccd5de99c75034fcf61660cb446a7 Mon Sep 17 00:00:00 2001 From: zdl <3489966805@qq.com> Date: Fri, 12 Dec 2025 10:58:25 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E6=8A=BD=E5=8F=96=20TabPanelContai?= =?UTF-8?q?ner=20=E9=80=9A=E7=94=A8=E5=AE=B9=E5=99=A8=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 TabPanelContainer 组件,统一处理 loading 状态和 VStack 布局 - ShareholderPanel 使用 TabPanelContainer 替代原有 loading 判断和 VStack - ManagementPanel 使用 TabPanelContainer 替代原有 loading 判断和 VStack - 组件使用 React.memo 优化渲染性能 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .../components/ShareholderPanel.tsx | 12 ++-- .../components/TabPanelContainer.tsx | 56 +++++++++++++++++++ .../BasicInfoTab/components/index.ts | 1 + .../components/management/ManagementPanel.tsx | 11 +--- 4 files changed, 64 insertions(+), 16 deletions(-) create mode 100644 src/views/Company/components/CompanyOverview/BasicInfoTab/components/TabPanelContainer.tsx diff --git a/src/views/Company/components/CompanyOverview/BasicInfoTab/components/ShareholderPanel.tsx b/src/views/Company/components/CompanyOverview/BasicInfoTab/components/ShareholderPanel.tsx index 23c903ba..0343befe 100644 --- a/src/views/Company/components/CompanyOverview/BasicInfoTab/components/ShareholderPanel.tsx +++ b/src/views/Company/components/CompanyOverview/BasicInfoTab/components/ShareholderPanel.tsx @@ -2,7 +2,7 @@ // 股权结构 Tab Panel - 使用拆分后的子组件 import React from "react"; -import { VStack, SimpleGrid, Box } from "@chakra-ui/react"; +import { SimpleGrid, Box } from "@chakra-ui/react"; import { useShareholderData } from "../../hooks/useShareholderData"; import { @@ -10,7 +10,7 @@ import { ConcentrationCard, ShareholdersTable, } from "../../components/shareholder"; -import LoadingState from "./LoadingState"; +import TabPanelContainer from "./TabPanelContainer"; interface ShareholderPanelProps { stockCode: string; @@ -32,12 +32,8 @@ const ShareholderPanel: React.FC = ({ stockCode }) => { loading, } = useShareholderData(stockCode); - if (loading) { - return ; - } - return ( - + {/* 实际控制人 + 股权集中度 左右分布 */} @@ -57,7 +53,7 @@ const ShareholderPanel: React.FC = ({ stockCode }) => { - + ); }; diff --git a/src/views/Company/components/CompanyOverview/BasicInfoTab/components/TabPanelContainer.tsx b/src/views/Company/components/CompanyOverview/BasicInfoTab/components/TabPanelContainer.tsx new file mode 100644 index 00000000..c54d8eee --- /dev/null +++ b/src/views/Company/components/CompanyOverview/BasicInfoTab/components/TabPanelContainer.tsx @@ -0,0 +1,56 @@ +/** + * Tab 面板通用容器组件 + * + * 提供统一的 loading 状态处理和布局包裹 + * 用于 ShareholderPanel、ManagementPanel 等 Tab 面板 + */ + +import React, { memo } from 'react'; +import { VStack } from '@chakra-ui/react'; +import LoadingState from './LoadingState'; + +interface TabPanelContainerProps { + /** 是否处于加载状态 */ + loading?: boolean; + /** 加载状态显示的文案 */ + loadingMessage?: string; + /** 子组件间距,默认 6 */ + spacing?: number; + /** 子组件 */ + children: React.ReactNode; +} + +/** + * Tab 面板通用容器 + * + * 功能: + * 1. 统一处理 loading 状态,显示 LoadingState 组件 + * 2. 提供 VStack 布局包裹,统一 spacing 和 align + * + * @example + * ```tsx + * + * + * + * ``` + */ +const TabPanelContainer: React.FC = memo(({ + loading = false, + loadingMessage = '加载中...', + spacing = 6, + children, +}) => { + if (loading) { + return ; + } + + return ( + + {children} + + ); +}); + +TabPanelContainer.displayName = 'TabPanelContainer'; + +export default TabPanelContainer; diff --git a/src/views/Company/components/CompanyOverview/BasicInfoTab/components/index.ts b/src/views/Company/components/CompanyOverview/BasicInfoTab/components/index.ts index aae3d653..6e91f2a8 100644 --- a/src/views/Company/components/CompanyOverview/BasicInfoTab/components/index.ts +++ b/src/views/Company/components/CompanyOverview/BasicInfoTab/components/index.ts @@ -2,6 +2,7 @@ // 组件导出 export { default as LoadingState } from "./LoadingState"; +export { default as TabPanelContainer } from "./TabPanelContainer"; export { default as ShareholderPanel } from "./ShareholderPanel"; export { ManagementPanel } from "./management"; export { default as AnnouncementsPanel } from "./AnnouncementsPanel"; diff --git a/src/views/Company/components/CompanyOverview/BasicInfoTab/components/management/ManagementPanel.tsx b/src/views/Company/components/CompanyOverview/BasicInfoTab/components/management/ManagementPanel.tsx index 23a72705..fd004b80 100644 --- a/src/views/Company/components/CompanyOverview/BasicInfoTab/components/management/ManagementPanel.tsx +++ b/src/views/Company/components/CompanyOverview/BasicInfoTab/components/management/ManagementPanel.tsx @@ -2,7 +2,6 @@ // 管理团队 Tab Panel(重构版) import React, { useMemo } from "react"; -import { VStack } from "@chakra-ui/react"; import { FaUserTie, FaCrown, @@ -12,7 +11,7 @@ import { import { useManagementData } from "../../../hooks/useManagementData"; import { THEME } from "../../config"; -import LoadingState from "../LoadingState"; +import TabPanelContainer from "../TabPanelContainer"; import CategorySection from "./CategorySection"; import type { ManagementPerson, @@ -78,12 +77,8 @@ const ManagementPanel: React.FC = ({ stockCode }) => { [management] ); - if (loading) { - return ; - } - return ( - + {CATEGORY_ORDER.map((category) => { const config = CATEGORY_CONFIG[category]; const people = categorizedManagement[category]; @@ -98,7 +93,7 @@ const ManagementPanel: React.FC = ({ stockCode }) => { /> ); })} - + ); };