Files
vf_react/src/views/Company/STRUCTURE.md
zdl 39ce365cbf refactor(TradeDataPanel): 原子设计模式拆分重构
- 将 TradeDataPanel.tsx (382行) 拆分为 8 个 TypeScript 文件
- 创建 3 个原子组件: MinuteStats、TradeAnalysis、EmptyState
- 创建 3 个业务组件: KLineChart、MinuteKLineSection、TradeTable
- 主入口组件精简至 ~50 行,降低 87%
- 更新 panels/index.ts 导出子组件
- 更新 STRUCTURE.md 文档

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-16 14:34:45 +08:00

48 KiB
Raw Blame History

Company 目录结构说明

最后更新2025-12-16

目录结构

src/views/Company/
├── index.js                    # 页面入口(纯组合层)
├── STRUCTURE.md                # 本文档
│
├── components/                 # UI 组件
│   │
│   ├── CompanyHeader/          # 页面头部
│   │   ├── index.js            # 组合导出
│   │   └── SearchBar.js        # 股票搜索栏
│   │
│   ├── CompanyTabs/            # Tab 切换容器
│   │   ├── index.js            # Tab 容器(状态管理 + 内容渲染)
│   │   └── TabNavigation.js    # Tab 导航栏
│   │
│   ├── StockQuoteCard/         # 股票行情卡片TypeScript
│   │   ├── index.tsx           # 主组件
│   │   ├── types.ts            # 类型定义
│   │   └── mockData.ts         # Mock 数据
│   │
│   ├── CompanyOverview/        # Tab: 公司概览TypeScript
│   │   ├── index.tsx           # 主组件(组合层)
│   │   ├── types.ts            # 类型定义
│   │   ├── utils.ts            # 格式化工具
│   │   ├── DeepAnalysisTab/    # 深度分析 Tab21 个 TS 文件)
│   │   ├── NewsEventsTab.js    # 新闻事件 Tab
│   │   │
│   │   ├── hooks/              # 数据 Hooks
│   │   │   ├── useBasicInfo.ts           # 基本信息 Hook
│   │   │   ├── useShareholderData.ts     # 股权结构 Hook4 APIs
│   │   │   ├── useManagementData.ts      # 管理团队 Hook
│   │   │   ├── useAnnouncementsData.ts   # 公告数据 Hook
│   │   │   ├── useBranchesData.ts        # 分支机构 Hook
│   │   │   ├── useDisclosureData.ts      # 披露日程 Hook
│   │   │   └── useCompanyOverviewData.ts # [已废弃] 原合并 Hook
│   │   │
│   │   ├── components/         # 股权结构子组件
│   │   │   └── shareholder/
│   │   │       ├── index.ts              # 导出
│   │   │       ├── ActualControlCard.tsx # 实控人卡片
│   │   │       ├── ConcentrationCard.tsx # 股权集中度卡片
│   │   │       └── ShareholdersTable.tsx # 股东表格
│   │   │
│   │   └── BasicInfoTab/       # 基本信息 Tab可配置化
│   │       ├── index.tsx       # 主组件(可配置)
│   │       ├── config.ts       # Tab 配置 + 黑金主题
│   │       ├── utils.ts        # 格式化工具函数
│   │       └── components/     # 子组件
│   │           ├── index.ts              # 组件统一导出
│   │           ├── LoadingState.tsx      # 加载状态组件
│   │           ├── ShareholderPanel.tsx  # 股权结构面板
│   │           ├── AnnouncementsPanel.tsx # 公告信息面板
│   │           ├── BranchesPanel.tsx     # 分支机构面板
│   │           ├── BusinessInfoPanel.tsx # 工商信息面板
│   │           ├── DisclosureSchedulePanel.tsx # 披露日程面板
│   │           └── management/           # 管理团队模块
│   │               ├── index.ts          # 模块导出
│   │               ├── types.ts          # 类型定义
│   │               ├── ManagementPanel.tsx   # 主组件useMemo
│   │               ├── CategorySection.tsx   # 分类区块memo
│   │               └── ManagementCard.tsx    # 人员卡片memo
│   │
│   ├── MarketDataView/         # Tab: 股票行情TypeScript
│   │   ├── index.tsx           # 主组件入口(~285 行Tab 容器)
│   │   ├── types.ts            # 类型定义
│   │   ├── constants.ts        # 主题配置、常量(含黑金主题 darkGoldTheme
│   │   ├── services/
│   │   │   └── marketService.ts   # API 服务层
│   │   ├── hooks/
│   │   │   └── useMarketData.ts   # 数据获取 Hook
│   │   ├── utils/
│   │   │   ├── formatUtils.ts     # 格式化工具函数
│   │   │   └── chartOptions.ts    # ECharts 图表配置
│   │   └── components/
│   │       ├── index.ts           # 组件导出
│   │       ├── ThemedCard.tsx     # 主题化卡片
│   │       ├── MarkdownRenderer.tsx  # Markdown 渲染
│   │       ├── AnalysisModal.tsx  # 涨幅分析模态框
│   │       ├── StockSummaryCard/  # 股票概览卡片(黑金主题 4 列布局)
│   │       │   ├── index.tsx          # 主组件4 列 SimpleGrid 布局)
│   │       │   ├── StockHeaderCard.tsx # 股票信息卡片(名称、价格、涨跌幅)
│   │       │   ├── MetricCard.tsx     # 指标卡片模板
│   │       │   ├── utils.ts           # 状态计算工具函数
│   │       │   └── atoms/             # 原子组件
│   │       │       ├── index.ts       # 原子组件导出
│   │       │       ├── DarkGoldCard.tsx   # 黑金主题卡片容器
│   │       │       ├── CardTitle.tsx      # 卡片标题(图标+标题+副标题)
│   │       │       ├── MetricValue.tsx    # 核心数值展示
│   │       │       ├── PriceDisplay.tsx   # 价格显示(价格+涨跌箭头)
│   │       │       └── StatusTag.tsx      # 状态标签(活跃/健康等)
│   │       └── panels/            # Tab 面板组件
│   │           ├── index.ts       # 面板组件统一导出
│   │           ├── TradeDataPanel/      # 交易数据面板(原子设计模式)
│   │           │   ├── index.tsx        # 主入口组件(~50 行)
│   │           │   ├── KLineChart.tsx   # 日K线图组件~40 行)
│   │           │   ├── MinuteKLineSection.tsx  # 分钟K线区域~95 行)
│   │           │   ├── TradeTable.tsx   # 交易明细表格(~75 行)
│   │           │   └── atoms/           # 原子组件
│   │           │       ├── index.ts     # 统一导出
│   │           │       ├── MinuteStats.tsx     # 分钟数据统计(~80 行)
│   │           │       ├── TradeAnalysis.tsx   # 成交分析(~65 行)
│   │           │       └── EmptyState.tsx      # 空状态组件(~35 行)
│   │           ├── FundingPanel.tsx     # 融资融券面板
│   │           ├── BigDealPanel.tsx     # 大宗交易面板
│   │           ├── UnusualPanel.tsx     # 龙虎榜面板
│   │           └── PledgePanel.tsx      # 股权质押面板
│   │
│   ├── DeepAnalysis/           # Tab: 深度分析
│   │   └── index.js
│   │
│   ├── DynamicTracking/        # Tab: 动态跟踪
│   │   └── index.js
│   │
│   ├── FinancialPanorama/      # Tab: 财务全景TypeScript 模块化)
│   │   ├── index.tsx           # 主组件入口(~400 行)
│   │   ├── types.ts            # TypeScript 类型定义
│   │   ├── constants.ts        # 常量配置(颜色、指标定义)
│   │   ├── hooks/
│   │   │   ├── index.ts        # Hook 统一导出
│   │   │   └── useFinancialData.ts  # 财务数据加载 Hook
│   │   ├── utils/
│   │   │   ├── index.ts        # 工具函数统一导出
│   │   │   ├── calculations.ts # 计算工具(同比变化、单元格颜色)
│   │   │   └── chartOptions.ts # ECharts 图表配置生成器
│   │   └── components/
│   │       ├── index.ts                # 组件统一导出
│   │       ├── StockInfoHeader.tsx     # 股票信息头部
│   │       ├── BalanceSheetTable.tsx   # 资产负债表
│   │       ├── IncomeStatementTable.tsx # 利润表
│   │       ├── CashflowTable.tsx       # 现金流量表
│   │       ├── FinancialMetricsTable.tsx # 财务指标表
│   │       ├── MainBusinessAnalysis.tsx  # 主营业务分析
│   │       ├── IndustryRankingView.tsx   # 行业排名
│   │       ├── StockComparison.tsx       # 股票对比
│   │       └── ComparisonAnalysis.tsx    # 综合对比分析
│   │
│   └── ForecastReport/         # Tab: 盈利预测(待拆分)
│       └── index.js
│
├── hooks/                      # 页面级 Hooks
│   ├── useCompanyStock.js      # 股票代码管理URL 同步)
│   ├── useCompanyWatchlist.js  # 自选股管理Redux 集成)
│   ├── useCompanyEvents.js     # PostHog 事件追踪
│   └── useStockQuote.js        # 股票行情数据 Hook
│
└── constants/                  # 常量定义
    └── index.js                # Tab 配置、Toast 消息、默认值

文件职责说明

入口文件

index.js - 页面入口

  • 职责:纯组合层,协调 Hooks 和 Components
  • 代码行数95 行
  • 依赖
    • useCompanyStock - 股票代码状态
    • useCompanyWatchlist - 自选股状态
    • useCompanyEvents - 事件追踪
    • CompanyHeader - 页面头部
    • CompanyTabs - Tab 切换区

Hooks 目录

useCompanyStock.js - 股票代码管理

  • 功能
    • 管理当前股票代码状态
    • 双向同步 URL 参数(支持浏览器前进/后退)
    • 处理搜索输入和提交
  • 返回值
    {
      stockCode,      // 当前确认的股票代码
      inputCode,      // 输入框中的值(未确认)
      setInputCode,   // 更新输入框
      handleSearch,   // 执行搜索
      handleKeyPress, // 处理回车键
    }
    
  • 依赖react-router-dom (useSearchParams)

useCompanyWatchlist.js - 自选股管理

  • 功能
    • 检查当前股票是否在自选股中
    • 提供添加/移除自选股功能
    • 与 Redux stockSlice 同步
  • 返回值
    {
      isInWatchlist,  // 是否在自选股中
      isLoading,      // 操作进行中
      toggle,         // 切换自选状态
    }
    
  • 依赖Redux (stockSlice)、AuthContext、Chakra UI (useToast)

useCompanyEvents.js - 事件追踪

  • 功能
    • 页面浏览追踪
    • 股票搜索追踪
    • Tab 切换追踪
    • 自选股操作追踪
  • 返回值
    {
      trackStockSearched,    // 追踪股票搜索
      trackTabChanged,       // 追踪 Tab 切换
      trackWatchlistAdded,   // 追踪添加自选
      trackWatchlistRemoved, // 追踪移除自选
    }
    
  • 依赖PostHog (usePostHogTrack)

Components 目录

CompanyHeader/ - 页面头部

文件 职责
index.js 组合 SearchBar 和 WatchlistButton
SearchBar.js 股票代码搜索输入框
WatchlistButton.js 自选股添加/移除按钮

Props 接口

<CompanyHeader
  stockCode={string}           // 当前股票代码
  inputCode={string}           // 输入框值
  onInputChange={func}         // 输入变化回调
  onSearch={func}              // 搜索回调
  onKeyPress={func}            // 键盘事件回调
  isInWatchlist={bool}         // 是否在自选中
  isWatchlistLoading={bool}    // 自选操作加载中
  onWatchlistToggle={func}     // 自选切换回调
  bgColor={string}             // 背景色
/>

CompanyTabs/ - Tab 切换

文件 职责
index.js Tab 容器,管理切换状态,渲染 Tab 内容
TabNavigation.js Tab 导航栏4个 Tab 按钮)

Props 接口

<CompanyTabs
  stockCode={string}     // 当前股票代码
  onTabChange={func}     // Tab 变更回调 (index, tabName, prevIndex)
  bgColor={string}       // 背景色
/>

Constants 目录

constants/index.js - 常量配置

  • COMPANY_TABS - Tab 配置数组key, name, icon
  • TAB_SELECTED_STYLE - Tab 选中样式
  • TOAST_MESSAGES - Toast 消息配置
  • DEFAULT_STOCK_CODE - 默认股票代码 ('000001')
  • URL_PARAM_NAME - URL 参数名 ('scode')
  • getTabNameByIndex() - 根据索引获取 Tab 名称

Tab 内容组件(components/ 目录下)

组件 Tab 名称 职责 代码行数
CompanyOverview/ 公司概览 公司基本信息、相关事件 -
MarketDataView/ 股票行情 K线图、实时行情 -
FinancialPanorama/ 财务全景 财务报表、指标分析 2153 行
ForecastReport/ 盈利预测 分析师预测、目标价 161 行

📌 所有 Tab 内容组件已文件夹化并统一放置在 components/ 目录下


数据流示意

┌─────────────────────────────────────────────────────────────┐
│                    index.js (页面入口)                       │
│                                                             │
│  ┌─────────────────┐  ┌─────────────────┐  ┌─────────────┐ │
│  │ useCompanyStock │  │useCompanyWatchlist│ │useCompanyEvents│
│  │                 │  │                 │  │             │ │
│  │ • stockCode     │  │ • isInWatchlist │  │ • track*    │ │
│  │ • inputCode     │  │ • toggle        │  │   functions │ │
│  │ • handleSearch  │  │                 │  │             │ │
│  └────────┬────────┘  └────────┬────────┘  └──────┬──────┘ │
│           │                    │                   │        │
│           └──────────┬─────────┴───────────────────┘        │
│                      ▼                                      │
│  ┌───────────────────────────────────────────────────────┐ │
│  │              CompanyHeader                             │ │
│  │  ┌─────────────┐  ┌──────────────────┐               │ │
│  │  │  SearchBar  │  │  WatchlistButton │               │ │
│  │  └─────────────┘  └──────────────────┘               │ │
│  └───────────────────────────────────────────────────────┘ │
│                      ▼                                      │
│  ┌───────────────────────────────────────────────────────┐ │
│  │              CompanyTabs                               │ │
│  │  ┌─────────────────────────────────────────────────┐ │ │
│  │  │              TabNavigation                       │ │ │
│  │  │  [概览] [行情] [财务] [预测]                     │ │ │
│  │  └─────────────────────────────────────────────────┘ │ │
│  │  ┌─────────────────────────────────────────────────┐ │ │
│  │  │              TabPanels                          │ │ │
│  │  │  • CompanyOverview                              │ │ │
│  │  │  • MarketDataView                               │ │ │
│  │  │  • FinancialPanorama                            │ │ │
│  │  │  • ForecastReport                               │ │ │
│  │  └─────────────────────────────────────────────────┘ │ │
│  └───────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘

重构记录

2025-12-09 重构

改动概述

  • index.js349 行 精简至 95 行(减少 73%
  • 提取 3 个自定义 Hooks
  • 提取 2 个组件目录CompanyHeader、CompanyTabs
  • 抽离常量到 constants/index.js

修复的问题

  1. 无限循环 BuguseCompanyWatchlist 中使用 useRef 防止重复初始化
  2. Hook 调用顺序:确保 useCompanyEventsuseCompanyStock 之后调用(依赖 stockCode
  3. 类型检查CompanyOverview.jsevent.keywords 渲染时添加类型检查,支持字符串和对象两种格式

设计原则

  • 关注点分离:每个 Hook 只负责单一职责
  • 纯组合层index.js 不包含业务逻辑,只负责组合
  • Props 透传:通过 Props 将状态和回调传递给子组件

2025-12-09 文件夹化

改动概述

  • 所有 4 个 Tab 内容组件统一移动到 components/ 目录
  • CompanyOverview.jscomponents/CompanyOverview/index.js
  • MarketDataView.jscomponents/MarketDataView/index.js
  • FinancialPanorama.jscomponents/FinancialPanorama/index.js2153 行)
  • ForecastReport.jscomponents/ForecastReport/index.js161 行)
  • 更新 CompanyTabs/index.js 中的导入路径

目的

  • 统一目录结构,所有组件都在 components/
  • 为后期组件拆分做准备便于添加子组件、hooks、utils 等

2025-12-10 CompanyOverview 拆分TypeScript

改动概述

  • CompanyOverview/index.js330 行 精简至 50 行(减少 85%
  • 采用 TypeScript 进行拆分,提高类型安全性
  • 提取 1 个自定义 HookuseCompanyOverviewData
  • 提取 1 个子组件CompanyHeaderCard
  • 抽离类型定义到 types.ts
  • 抽离工具函数到 utils.ts

拆分后文件结构

CompanyOverview/
├── index.tsx                      # 主组件(组合层,约 60 行)
├── CompanyHeaderCard.tsx          # 头部卡片组件(约 130 行)
├── BasicInfoTab.js                # 基本信息 Tab懒加载版本约 994 行)
├── DeepAnalysisTab/               # 深度分析 Tab21 个 TS 文件,见 2025-12-11 重构记录)
├── NewsEventsTab.js               # 新闻事件 Tab
├── types.ts                       # 类型定义(约 50 行)
├── utils.ts                       # 格式化工具(约 20 行)
└── hooks/
    ├── useBasicInfo.ts            # 基本信息 Hook1 API
    ├── useShareholderData.ts      # 股权结构 Hook4 APIs
    ├── useManagementData.ts       # 管理团队 Hook1 API
    ├── useAnnouncementsData.ts    # 公告数据 Hook1 API
    ├── useBranchesData.ts         # 分支机构 Hook1 API
    ├── useDisclosureData.ts       # 披露日程 Hook1 API
    └── useCompanyOverviewData.ts  # [已废弃] 原合并 Hook

懒加载架构2025-12-10 优化):

  • index.tsx 只加载 useBasicInfo1 个 API用于头部卡片
  • BasicInfoTab.js 使用 isLazy + 独立子组件实现懒加载
  • 每个内层 Tab 使用独立 Hook点击时才加载数据

Hooks 说明

Hook API 数量 用途
useBasicInfo 1 公司基本信息(头部卡片 + 工商信息 Tab
useShareholderData 4 实控人、股权集中度、十大股东、十大流通股东
useManagementData 1 管理团队数据
useAnnouncementsData 1 公司公告列表
useBranchesData 1 分支机构列表
useDisclosureData 1 财报披露日程

类型定义types.ts

  • BasicInfo - 公司基本信息
  • ActualControl - 实际控制人
  • Concentration - 股权集中度
  • Management - 管理层信息
  • Shareholder - 股东信息
  • Branch - 分支机构
  • Announcement - 公告信息
  • DisclosureSchedule - 披露计划
  • CompanyOverviewData - Hook 返回值类型
  • CompanyOverviewProps - 组件 Props 类型
  • CompanyHeaderCardProps - 头部卡片 Props 类型

工具函数utils.ts

  • formatRegisteredCapital(value) - 格式化注册资本(万元/亿元)
  • formatDate(dateString) - 格式化日期

设计原则

  • 渐进式 TypeScript 迁移:新拆分的文件使用 TypeScript旧文件暂保持 JS
  • 关注点分离:数据加载逻辑提取到 HookUI 逻辑保留在组件
  • 类型复用:统一的类型定义便于在多个文件间共享
  • 懒加载优化:减少首屏 API 请求,按需加载数据

2025-12-10 懒加载优化

改动概述

  • useCompanyOverviewData9 个 API拆分为 6 个独立 Hook
  • CompanyOverview/index.tsx 只加载 useBasicInfo1 个 API
  • BasicInfoTab.js 使用 5 个懒加载子组件,配合 isLazy 实现按需加载
  • 页面初次加载从 9 个 API 减少到 1 个 API

懒加载子组件BasicInfoTab.js 内部):

子组件 Hook 功能
ShareholderTabPanel useShareholderData 股权结构4 APIs
ManagementTabPanel useManagementData 管理团队
AnnouncementsTabPanel useAnnouncementsData + useDisclosureData 公告 + 披露日程
BranchesTabPanel useBranchesData 分支机构
BusinessInfoTabPanel - 工商信息(使用父组件传入的 basicInfo

实现原理

  • Chakra UI TabsisLazy 属性延迟渲染 TabPanel
  • 每个 TabPanel 使用独立子组件,组件内调用 Hook
  • 子组件只在首次激活时渲染,此时 Hook 才执行并发起 API 请求
Tab 模块 中文名称 功能说明
CompanyOverview 公司概览 公司基本信息、股权结构、管理层、公告等9个接口
DeepAnalysis 深度分析 公司深度研究报告、投资逻辑分析
MarketDataView 股票行情 K线图、实时行情、技术指标
FinancialPanorama 财务全景 财务报表(资产负债表、利润表、现金流)、财务指标分析
ForecastReport 盈利预测 分析师预测、目标价、评级
DynamicTracking 动态跟踪 相关事件、新闻动态、投资日历

2025-12-10 MarketDataView TypeScript 拆分

改动概述

  • MarketDataView/index.js2060 行 拆分为 12 个 TypeScript 文件
  • 采用 TypeScript 进行重构,提高类型安全性
  • 提取 1 个自定义 HookuseMarketData
  • 提取 4 个子组件ThemedCard、MarkdownRenderer、StockSummaryCard、AnalysisModal
  • 抽离 API 服务到 services/marketService.ts
  • 抽离图表配置到 utils/chartOptions.ts

拆分后文件结构

MarketDataView/
├── index.tsx              # 主组件入口(~285 行Tab 容器)
├── types.ts               # 类型定义(~383 行)
├── constants.ts           # 主题配置、常量(~49 行)
├── services/
│   └── marketService.ts   # API 服务层(~173 行)
├── hooks/
│   └── useMarketData.ts   # 数据获取 Hook~193 行)
├── utils/
│   ├── formatUtils.ts     # 格式化工具函数(~175 行)
│   └── chartOptions.ts    # ECharts 图表配置生成器(~698 行)
└── components/
    ├── index.ts           # 组件导出(~8 行)
    ├── ThemedCard.tsx     # 主题化卡片(~32 行)
    ├── MarkdownRenderer.tsx  # Markdown 渲染(~65 行)
    ├── StockSummaryCard.tsx  # 股票概览卡片(~133 行)
    ├── AnalysisModal.tsx  # 涨幅分析模态框(~188 行)
    └── panels/            # Tab 面板组件2025-12-12 拆分)
        ├── index.ts       # 面板组件统一导出
        ├── TradeDataPanel.tsx   # 交易数据面板(~381 行)
        ├── FundingPanel.tsx     # 融资融券面板(~113 行)
        ├── BigDealPanel.tsx     # 大宗交易面板(~143 行)
        ├── UnusualPanel.tsx     # 龙虎榜面板(~163 行)
        └── PledgePanel.tsx      # 股权质押面板(~124 行)

文件职责说明

文件 行数 职责
index.tsx ~285 主组件Tab 容器和状态管理,导入使用 5 个 Panel 组件
types.ts ~383 所有 TypeScript 类型定义Theme、TradeDayData、MinuteData、FundingData 等)
constants.ts ~49 主题配置light/dark、周期选项常量
marketService.ts ~173 API 服务封装getMarketData、getMinuteData、getBigDealData 等)
useMarketData.ts ~193 数据获取 Hook管理所有市场数据状态
formatUtils.ts ~175 数字/日期/涨跌幅格式化工具
chartOptions.ts ~698 ECharts 配置生成器K线图、分钟图、融资融券图、质押图
ThemedCard.tsx ~32 主题化卡片容器组件
MarkdownRenderer.tsx ~65 Markdown 内容渲染组件
StockSummaryCard.tsx ~133 股票概览卡片(价格、涨跌幅、成交量等)
AnalysisModal.tsx ~188 涨幅分析详情模态框

类型定义types.ts

  • Theme - 主题配置类型
  • TradeDayData - 日线交易数据
  • MinuteData - 分钟线数据
  • FundingDayData - 融资融券数据
  • BigDealData / BigDealDayStats - 大宗交易数据
  • UnusualData / UnusualDayData - 龙虎榜数据
  • PledgeData - 股权质押数据
  • RiseAnalysis - 涨幅分析数据
  • MarketSummary - 市场概览数据
  • VerificationReport - 验证报告数据
  • 各组件 Props 类型

Hook 返回值useMarketData

{
  loading: boolean;
  summary: MarketSummary | null;
  tradeData: TradeDayData[];
  minuteData: MinuteData | null;
  minuteLoading: boolean;
  fundingData: FundingDayData[];
  bigDealData: BigDealData | null;
  unusualData: UnusualData | null;
  pledgeData: PledgeData | null;
  analysisMap: Record<number, RiseAnalysis>;
  refetch: () => Promise<void>;
  loadMinuteData: () => Promise<void>;
}

设计原则

  • TypeScript 类型安全:所有数据结构有完整类型定义
  • 服务层分离API 调用统一在 marketService.ts 中管理
  • 图表配置抽离:复杂的 ECharts 配置集中在 chartOptions.ts
  • 组件复用通用组件ThemedCard、MarkdownRenderer可在其他模块使用

2025-12-10 ManagementPanel 拆分重构

改动概述

  • ManagementPanel.tsx180 行 拆分为 5 个 TypeScript 文件
  • 创建 management/ 子目录,模块化管理
  • 添加性能优化(useMemoReact.memo

拆分后文件结构

components/management/
├── index.ts              # 模块导出
├── types.ts              # 类型定义(~35 行)
├── ManagementPanel.tsx   # 主组件(~105 行useMemo 优化)
├── CategorySection.tsx   # 分类区块组件(~65 行memo
└── ManagementCard.tsx    # 人员卡片组件(~100 行memo

类型定义types.ts

  • ManagementPerson - 管理人员信息
  • ManagementCategory - 分类类型(高管/董事/监事/其他)
  • CategorizedManagement - 分类后的数据结构
  • CategoryConfig - 分类配置(图标、颜色)

性能优化

  • useMemo - 缓存 categorizeManagement() 分类计算结果
  • React.memo - ManagementCardCategorySection 使用 memo 包装
  • 常量提取 - CATEGORY_CONFIGCATEGORY_ORDER 提取到组件外部

设计原则

  • 职责分离:卡片渲染、分类区块、数据处理各自独立
  • 类型安全:消除 any 类型,完整的 TypeScript 类型定义
  • 可复用性ManagementCard 可独立使用

2025-12-11 DeepAnalysisTab 模块化拆分TypeScript

改动概述

  • DeepAnalysisTab.js1,796 行 拆分为 21 个 TypeScript 文件
  • 采用原子设计模式atoms/components/organisms组织代码
  • 完整 TypeScript 类型定义
  • 格式化工具合并到全局 src/utils/priceFormatters.js

拆分后文件结构

DeepAnalysisTab/
├── index.tsx                          # 主入口组件,组合所有 Card 子组件
├── types.ts                           # TypeScript 类型定义(接口、数据结构)
├── atoms/                             # 原子组件(基础 UI 元素)
│   ├── index.ts                       # 原子组件统一导出
│   ├── DisclaimerBox.tsx              # 免责声明警告框(黄色 Alert用 6 次)
│   ├── ScoreBar.tsx                   # 评分进度条(带颜色渐变,用 8 次)
│   ├── BusinessTreeItem.tsx           # 业务结构树形项(递归组件)
│   └── KeyFactorCard.tsx              # 关键因素卡片(带影响方向图标)
├── components/                        # Card 容器组件(页面区块)
│   ├── index.ts                       # Card 组件统一导出
│   ├── CorePositioningCard.tsx        # 核心定位卡片(行业地位、核心优势)
│   ├── CompetitiveAnalysisCard.tsx    # 竞争地位分析卡片(雷达图 + 评分条)
│   ├── BusinessStructureCard.tsx      # 业务结构分析卡片(树形展示)
│   ├── ValueChainCard.tsx             # 产业链分析卡片Tabs: 上游/中游/下游)
│   ├── KeyFactorsCard.tsx             # 关键因素卡片Accordion 折叠面板)
│   ├── TimelineCard.tsx               # 发展时间线卡片(正面/负面事件统计)
│   ├── BusinessSegmentsCard.tsx       # 业务板块详情卡片(可展开/折叠)
│   └── StrategyAnalysisCard.tsx       # 战略分析卡片(战略方向 + 战略举措)
├── organisms/                         # 复杂组件(含状态管理和 API 调用)
│   ├── ValueChainNodeCard/            # 产业链节点组件
│   │   ├── index.tsx                  # 产业链节点卡片(点击展开详情)
│   │   └── RelatedCompaniesModal.tsx  # 相关公司模态框API 获取公司列表)
│   └── TimelineComponent/             # 时间线组件
│       ├── index.tsx                  # 时间线主组件(事件列表渲染)
│       └── EventDetailModal.tsx       # 事件详情模态框(查看完整事件信息)
└── utils/
    └── chartOptions.ts                # ECharts 图表配置(雷达图、桑基图)

组件依赖关系

index.tsx
├── CorePositioningCard
├── CompetitiveAnalysisCard
│   ├── ScoreBar (atom)
│   ├── DisclaimerBox (atom)
│   └── ReactECharts (雷达图)
├── BusinessStructureCard
│   └── BusinessTreeItem (atom, 递归)
├── ValueChainCard
│   └── ValueChainNodeCard (organism)
│       └── RelatedCompaniesModal
├── KeyFactorsCard
│   └── KeyFactorCard (atom)
├── TimelineCard
│   └── TimelineComponent (organism)
│       └── EventDetailModal
├── BusinessSegmentsCard
└── StrategyAnalysisCard
    └── DisclaimerBox (atom)

类型定义types.ts

  • DeepAnalysisTabProps - 主组件 Props
  • QualitativeAnalysis - 定性分析数据
  • CompetitivePosition - 竞争地位数据
  • BusinessStructureItem - 业务结构项
  • ValueChainData - 产业链数据
  • ValueChainNode - 产业链节点
  • KeyFactor - 关键因素
  • DevelopmentTimeline - 发展时间线
  • TimelineEvent - 时间线事件
  • BusinessSegment - 业务板块
  • Strategy - 战略分析

工具函数位置

函数 文件位置 说明
formatCurrency src/utils/priceFormatters.js 货币格式化
formatBusinessRevenue src/utils/priceFormatters.js 营收格式化(亿/万)
formatPercentage src/utils/priceFormatters.js 百分比格式化
getRadarChartOption DeepAnalysisTab/utils/chartOptions.ts 雷达图 ECharts 配置
getSankeyChartOption DeepAnalysisTab/utils/chartOptions.ts 桑基图 ECharts 配置

优化效果

指标 优化前 优化后 改善
主文件行数 1,796 ~117 -93%
文件数量 1 (.js) 21 (.tsx/.ts) 模块化 + TS
可复用组件 0 4 原子 + 2 复杂 提升
类型安全 完整 TypeScript

设计原则

  • 原子设计模式atoms基础元素→ components区块→ organisms复杂交互
  • TypeScript 类型安全:完整的接口定义,消除 any 类型
  • 职责分离UI 渲染与 API 调用分离,模态框独立管理
  • 代码复用DisclaimerBox、ScoreBar 等原子组件多处复用

2025-12-12 FinancialPanorama 模块化拆分TypeScript

改动概述

  • FinancialPanorama/index.js2,150 行 拆分为 21 个 TypeScript 文件
  • 提取 1 个自定义 HookuseFinancialData
  • 提取 9 个子组件(表格组件 + 分析组件)
  • 抽离类型定义到 types.ts
  • 抽离常量配置到 constants.ts
  • 抽离工具函数到 utils/

拆分后文件结构

FinancialPanorama/
├── index.tsx                          # 主入口组件(~400 行)
├── types.ts                           # TypeScript 类型定义(~441 行)
├── constants.ts                       # 常量配置(颜色、指标定义)
├── hooks/
│   ├── index.ts                       # Hook 统一导出
│   └── useFinancialData.ts            # 财务数据加载 Hook9 API 并行加载)
├── utils/
│   ├── index.ts                       # 工具函数统一导出
│   ├── calculations.ts                # 计算工具(同比变化率、单元格背景色)
│   └── chartOptions.ts                # ECharts 图表配置生成器
└── components/
    ├── index.ts                       # 组件统一导出
    ├── StockInfoHeader.tsx            # 股票信息头部(~95 行)
    ├── BalanceSheetTable.tsx          # 资产负债表(~220 行,可展开分组)
    ├── IncomeStatementTable.tsx       # 利润表(~205 行,可展开分组)
    ├── CashflowTable.tsx              # 现金流量表(~140 行)
    ├── FinancialMetricsTable.tsx      # 财务指标表(~260 行7 分类切换)
    ├── MainBusinessAnalysis.tsx       # 主营业务分析(~180 行,饼图 + 表格)
    ├── IndustryRankingView.tsx        # 行业排名(~110 行)
    ├── StockComparison.tsx            # 股票对比(~210 行,含独立数据加载)
    └── ComparisonAnalysis.tsx         # 综合对比分析(~40 行)

组件依赖关系

index.tsx
├── useFinancialData (hook)              # 数据加载
├── StockInfoHeader                      # 股票基本信息展示
├── ComparisonAnalysis                   # 营收与利润趋势图
├── FinancialMetricsTable                # 财务指标表7 分类)
├── BalanceSheetTable                    # 资产负债表(可展开)
├── IncomeStatementTable                 # 利润表(可展开)
├── CashflowTable                        # 现金流量表
├── MainBusinessAnalysis                 # 主营业务(饼图)
├── IndustryRankingView                  # 行业排名
└── StockComparison                      # 股票对比(独立状态)

类型定义types.ts

  • StockInfo - 股票基本信息
  • BalanceSheetData - 资产负债表数据
  • IncomeStatementData - 利润表数据
  • CashflowData - 现金流量表数据
  • FinancialMetricsData - 财务指标数据7 分类)
  • ProductClassification / IndustryClassification - 主营业务分类
  • IndustryRankData - 行业排名数据
  • ForecastData - 业绩预告数据
  • ComparisonData - 对比数据
  • MetricConfig / MetricSectionConfig - 指标配置类型
  • 各组件 Props 类型

常量配置constants.ts

  • COLORS - 颜色配置(中国市场:红涨绿跌)
  • CURRENT_ASSETS_METRICS / NON_CURRENT_ASSETS_METRICS 等 - 资产负债表指标
  • INCOME_STATEMENT_SECTIONS - 利润表分组配置
  • CASHFLOW_METRICS - 现金流量表指标
  • FINANCIAL_METRICS_CATEGORIES - 财务指标 7 大分类
  • RANKING_METRICS / COMPARE_METRICS - 排名和对比指标

工具函数utils/

函数 文件 说明
calculateYoYChange calculations.ts 计算同比变化率和强度
getCellBackground calculations.ts 根据变化率返回单元格背景色
getValueByPath calculations.ts 从嵌套对象获取值
isNegativeIndicator calculations.ts 判断是否为负向指标
getMetricChartOption chartOptions.ts 指标趋势图配置
getComparisonChartOption chartOptions.ts 营收与利润对比图配置
getMainBusinessPieOption chartOptions.ts 主营业务饼图配置
getCompareBarChartOption chartOptions.ts 股票对比柱状图配置

Hook 返回值useFinancialData

{
  // 数据状态
  stockInfo: StockInfo | null;
  balanceSheet: BalanceSheetData[];
  incomeStatement: IncomeStatementData[];
  cashflow: CashflowData[];
  financialMetrics: FinancialMetricsData[];
  mainBusiness: MainBusinessData | null;
  forecast: ForecastData | null;
  industryRank: IndustryRankData[];
  comparison: ComparisonData[];

  // 加载状态
  loading: boolean;
  error: string | null;

  // 操作方法
  refetch: () => Promise<void>;
  setStockCode: (code: string) => void;
  setSelectedPeriods: (periods: number) => void;

  // 当前参数
  currentStockCode: string;
  selectedPeriods: number;
}

优化效果

指标 优化前 优化后 改善
主文件行数 2,150 ~400 -81%
文件数量 1 (.js) 21 (.tsx/.ts) 模块化 + TS
可复用组件 0内联 9 个独立组件 提升
类型安全 完整 TypeScript

设计原则

  • TypeScript 类型安全:完整的接口定义,消除 any 类型
  • Hook 数据层useFinancialData 封装 9 个 API 并行加载
  • 组件解耦:每个表格/分析视图独立为组件
  • 常量配置化:指标定义可维护、可扩展
  • 工具函数复用:计算和图表配置统一管理

2025-12-12 MarketDataView Panel 拆分

改动概述

  • MarketDataView/index.tsx1,049 行 精简至 285 行(减少 73%
  • 将 5 个 TabPanel 拆分为独立的面板组件
  • 创建 components/panels/ 子目录

拆分后文件结构

MarketDataView/components/panels/
├── index.ts               # 面板组件统一导出
├── TradeDataPanel.tsx     # 交易数据面板(~381 行)
├── FundingPanel.tsx       # 融资融券面板(~113 行)
├── BigDealPanel.tsx       # 大宗交易面板(~143 行)
├── UnusualPanel.tsx       # 龙虎榜面板(~163 行)
└── PledgePanel.tsx        # 股权质押面板(~124 行)

面板组件职责

组件 行数 功能
TradeDataPanel ~381 K线图、分钟K线图、交易明细表格
FundingPanel ~113 融资融券图表和数据卡片
BigDealPanel ~143 大宗交易记录表格
UnusualPanel ~163 龙虎榜数据(买入/卖出前五)
PledgePanel ~124 股权质押图表和明细表格

优化效果

指标 优化前 优化后 改善
主文件行数 1,049 285 -73%
面板组件 内联 5 个独立文件 模块化
可维护性 每个面板独立维护

设计原则

  • 职责分离:主组件只负责 Tab 容器和状态管理
  • 组件复用:面板组件可独立测试和维护
  • 类型安全:每个面板组件有独立的 Props 类型定义

2025-12-16 StockSummaryCard 黑金主题重构

改动概述

  • StockSummaryCard.tsx 从单文件重构为原子设计模式的目录结构
  • 布局从 1+3(头部+三卡片)改为 4 列横向排列
  • 新增黑金主题darkGoldTheme
  • 提取 5 个原子组件 + 2 个业务组件

拆分后文件结构

StockSummaryCard/
├── index.tsx              # 主组件4 列 SimpleGrid 布局)
├── StockHeaderCard.tsx    # 股票信息卡片(名称、价格、涨跌幅、走势)
├── MetricCard.tsx         # 指标卡片模板组件
├── utils.ts               # 状态计算工具函数
└── atoms/                 # 原子组件
    ├── index.ts           # 统一导出
    ├── DarkGoldCard.tsx   # 黑金主题卡片容器(渐变背景、金色边框)
    ├── CardTitle.tsx      # 卡片标题(图标+标题+副标题)
    ├── MetricValue.tsx    # 核心数值展示(标签+数值+后缀)
    ├── PriceDisplay.tsx   # 价格显示(价格+涨跌箭头+百分比)
    └── StatusTag.tsx      # 状态标签(活跃/健康/警惕等)

4 列布局设计

┌──────────────┐  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐
│ 股票信息      │  │ 交易热度      │  │ 估值VS安全    │  │ 情绪与风险    │
│ 平安银行      │  │ (流动性)      │  │ (便宜否)      │  │ (资金面)      │
│ (000001)     │  │              │  │              │  │              │
│ 13.50 ↗+1.89%│  │ 成交额 46.79亿│  │ PE 4.96      │  │ 融资 58.23亿  │
│ 走势:小幅上涨 │  │ 成交量|换手率 │  │ 质押率(健康)  │  │ 融券 1.26亿   │
└──────────────┘  └──────────────┘  └──────────────┘  └──────────────┘

黑金主题配置constants.ts

export const darkGoldTheme = {
  bgCard: 'linear-gradient(135deg, #1a1a2e 0%, #0f0f1a 100%)',
  border: 'rgba(212, 175, 55, 0.3)',
  gold: '#D4AF37',
  orange: '#FF9500',
  green: '#00C851',
  red: '#FF4444',
  textPrimary: '#FFFFFF',
  textMuted: 'rgba(255, 255, 255, 0.6)',
};

状态计算工具utils.ts

函数 功能
getTrendDescription 根据涨跌幅返回走势描述(强势上涨/小幅下跌等)
getTurnoverStatus 换手率状态≥3% 活跃, ≥1% 正常, <1% 冷清)
getPEStatus 市盈率估值评级(极低估值/合理/偏高/泡沫风险)
getPledgeStatus 质押率健康状态(<10% 健康, <30% 正常, <50% 偏高, ≥50% 警惕)
getPriceColor 根据涨跌返回颜色(红涨绿跌)

原子组件说明

组件 行数 用途 可复用场景
DarkGoldCard ~40 黑金主题卡片容器 任何需要黑金风格的卡片
CardTitle ~30 卡片标题行 带图标的标题展示
MetricValue ~45 核心数值展示 各种指标数值展示
PriceDisplay ~55 价格+涨跌幅 股票价格展示
StatusTag ~20 状态标签 各种状态文字标签

响应式断点

  • lg (≥992px): 4 列
  • md (≥768px): 2 列
  • base (<768px): 1 列

类型定义更新types.ts

  • StockSummaryCardProps.theme 改为可选参数,组件内置使用 darkGoldTheme

优化效果

指标 优化前 优化后 改善
主文件行数 ~350 ~115 -67%
文件数量 1 8 原子设计模式
可复用组件 0 5 原子 + 2 业务 提升
主题支持 依赖传入 内置黑金主题 独立

设计原则

  • 原子设计模式atoms基础元素→ 业务组件MetricCard、StockHeaderCard→ 页面组件index.tsx
  • 主题独立StockSummaryCard 使用内置黑金主题,不依赖外部传入
  • 职责分离:状态计算逻辑提取到 utils.tsUI 与逻辑解耦
  • 组件复用:原子组件可在其他黑金主题场景复用

2025-12-16 TradeDataPanel 原子设计模式拆分

改动概述

  • TradeDataPanel.tsx382 行 拆分为 8 个 TypeScript 文件
  • 采用原子设计模式组织代码
  • 提取 3 个原子组件 + 3 个业务组件

拆分后文件结构

TradeDataPanel/
├── index.tsx              # 主入口组件(~50 行,组合 3 个子组件)
├── KLineChart.tsx         # 日K线图组件~40 行)
├── MinuteKLineSection.tsx # 分钟K线区域~95 行,含加载/空状态处理)
├── TradeTable.tsx         # 交易明细表格(~75 行)
└── atoms/                 # 原子组件
    ├── index.ts           # 统一导出
    ├── MinuteStats.tsx    # 分钟数据统计(~80 行4 个 Stat 卡片)
    ├── TradeAnalysis.tsx  # 成交分析(~65 行,活跃时段/平均价格等)
    └── EmptyState.tsx     # 空状态组件(~35 行,可复用)

组件依赖关系

index.tsx
├── KLineChart            # 日K线图ECharts
├── MinuteKLineSection    # 分钟K线区域
│   ├── MinuteStats (atom)    # 开盘/当前/最高/最低价统计
│   ├── TradeAnalysis (atom)  # 成交数据分析
│   └── EmptyState (atom)     # 空状态提示
└── TradeTable            # 交易明细表格(最近 10 天)

组件职责

组件 行数 功能
index.tsx ~50 主入口,组合 3 个子组件
KLineChart ~40 日K线图渲染支持图表点击事件
MinuteKLineSection ~95 分钟K线区域含加载状态、空状态、统计数据
TradeTable ~75 最近 10 天交易明细表格
MinuteStats ~80 分钟数据四宫格统计(开盘/当前/最高/最低价)
TradeAnalysis ~65 成交数据分析(活跃时段、平均价格、数据点数)
EmptyState ~35 通用空状态组件(可配置标题和描述)

优化效果

指标 优化前 优化后 改善
主文件行数 382 ~50 -87%
文件数量 1 8 原子设计模式
可复用组件 0 3 原子 + 3 业务 提升

设计原则

  • 原子设计模式atomsMinuteStats、TradeAnalysis、EmptyState→ 业务组件KLineChart、MinuteKLineSection、TradeTable→ 主组件
  • 职责分离:图表、统计、表格各自独立
  • 组件复用EmptyState 可在其他场景复用
  • 类型安全:完整的 Props 类型定义和导出