Files
vf_react/src/views/Company/STRUCTURE.md
zdl a8b57dd3eb docs: 更新 STRUCTURE.md 目录结构说明
- 添加 BasicInfoTab/ 目录结构详情
- 补充各子组件功能注释:
  - LoadingState: 加载状态组件
  - ShareholderPanel: 股权结构面板
  - ManagementPanel: 管理团队面板
  - AnnouncementsPanel: 公告信息面板
  - BranchesPanel: 分支机构面板
  - BusinessInfoPanel: 工商信息面板

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

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

22 KiB
Raw Blame History

Company 目录结构说明

最后更新2025-12-10

目录结构

src/views/Company/
├── index.js                    # 页面入口95行纯组合层
├── STRUCTURE.md                # 本文档
│
├── components/                 # UI 组件
│   ├── CompanyHeader/          # 页面头部
│   │   ├── index.js            # 组合导出
│   │   ├── SearchBar.js        # 股票搜索栏
│   │   └── WatchlistButton.js  # 自选股按钮
│   │
│   ├── CompanyTabs/            # Tab 切换容器
│   │   ├── index.js            # Tab 容器(状态管理 + 内容渲染)
│   │   └── TabNavigation.js    # Tab 导航栏
│   │
│   ├── CompanyOverview/        # Tab: 公司概览TypeScript 拆分)
│   │   ├── index.tsx           # 主组件(组合层,约 50 行)
│   │   ├── CompanyHeaderCard.tsx  # 头部卡片组件(黑金主题,约 200 行)
│   │   ├── BasicInfoTab/       # 基本信息 TabTypeScript 可配置化重构)
│   │   │   ├── index.tsx       # 主组件(可配置,约 120 行)
│   │   │   ├── config.ts       # Tab 配置 + 黑金主题(约 90 行)
│   │   │   ├── utils.ts        # 格式化工具函数(约 50 行)
│   │   │   └── components/     # 子组件
│   │   │       ├── index.ts              # 组件统一导出
│   │   │       ├── LoadingState.tsx      # 加载状态组件(黑金主题 Spinner
│   │   │       ├── ShareholderPanel.tsx  # 股权结构面板(实控人、十大股东、股权集中度)
│   │   │       ├── ManagementPanel.tsx   # 管理团队面板(高管列表表格)
│   │   │       ├── AnnouncementsPanel.tsx # 公告信息面板(公告列表 + 披露日程)
│   │   │       ├── BranchesPanel.tsx     # 分支机构面板(分支列表表格)
│   │   │       └── BusinessInfoPanel.tsx # 工商信息面板(注册资本、成立日期等)
│   │   ├── DeepAnalysisTab.js  # 深度分析 Tab
│   │   ├── NewsEventsTab.js    # 新闻事件 Tab
│   │   ├── types.ts            # 类型定义(约 120 行)
│   │   ├── utils.ts            # 格式化工具(约 20 行)
│   │   └── hooks/
│   │       └── useCompanyOverviewData.ts  # 数据 Hook约 100 行)
│   │
│   ├── MarketDataView/         # Tab: 股票行情TypeScript 拆分)
│   │   ├── index.tsx           # 主组件入口(~1049 行)
│   │   ├── types.ts            # 类型定义(~383 行)
│   │   ├── constants.ts        # 主题配置、常量
│   │   ├── services/
│   │   │   └── marketService.ts   # API 服务层
│   │   ├── hooks/
│   │   │   └── useMarketData.ts   # 数据获取 Hook
│   │   ├── utils/
│   │   │   ├── formatUtils.ts     # 格式化工具函数
│   │   │   └── chartOptions.ts    # ECharts 图表配置生成器
│   │   └── components/
│   │       ├── index.ts           # 组件导出
│   │       ├── ThemedCard.tsx     # 主题化卡片
│   │       ├── MarkdownRenderer.tsx  # Markdown 渲染
│   │       ├── StockSummaryCard.tsx  # 股票概览卡片
│   │       └── AnalysisModal.tsx  # 涨幅分析模态框
│   │
│   ├── FinancialPanorama/      # Tab: 财务全景2153 行,待拆分)
│   │   └── index.js
│   │
│   └── ForecastReport/         # Tab: 盈利预测161 行,待拆分)
│       └── index.js
│
├── hooks/                      # 自定义 Hooks
│   ├── useCompanyStock.js      # 股票代码管理URL 同步)
│   ├── useCompanyWatchlist.js  # 自选股管理Redux 集成)
│   └── useCompanyEvents.js     # PostHog 事件追踪
│
└── 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.js             # 深度分析 Tab
├── 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              # 主组件入口(~1049 行)
├── 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 行)

文件职责说明

文件 行数 职责
index.tsx ~1049 主组件,包含 5 个 Tab 面板(交易数据、融资融券、大宗交易、龙虎榜、股权质押)
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可在其他模块使用