From 276b280cb90789175a943ec1b1099db89d0d32ab Mon Sep 17 00:00:00 2001 From: zdl <3489966805@qq.com> Date: Fri, 12 Dec 2025 18:11:03 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E6=9B=B4=E6=96=B0=20STRUCTURE.md=20?= =?UTF-8?q?=E5=92=8C=20mock=20=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - STRUCTURE.md 添加 MarketDataView Panel 拆分记录 - 更新目录结构说明,包含 panels/ 子目录 - 更新 company.js 和 market.js mock 数据 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- src/mocks/data/company.js | 66 ++++++++++++++++++ src/mocks/data/market.js | 121 ++++++++++++++++++++++----------- src/views/Company/STRUCTURE.md | 68 ++++++++++++++++-- 3 files changed, 208 insertions(+), 47 deletions(-) diff --git a/src/mocks/data/company.js b/src/mocks/data/company.js index f0f55290..9d5477c6 100644 --- a/src/mocks/data/company.js +++ b/src/mocks/data/company.js @@ -42,6 +42,72 @@ export const PINGAN_BANK_DATA = { employees: 42099, }, + // 市场概览数据 - StockSummaryCard 使用 + marketSummary: { + stock_code: '000001', + stock_name: '平安银行', + latest_trade: { + close: 11.28, + change_percent: 2.35, + volume: 58623400, + amount: 659800000, + turnover_rate: 0.30, + pe_ratio: 4.92 + }, + latest_funding: { + financing_balance: 5823000000, + securities_balance: 125600000 + }, + latest_pledge: { + pledge_ratio: 8.25 + } + }, + + // 当日分钟K线数据 - MinuteKLineChart 使用 + minuteData: { + code: '000001', + name: '平安银行', + trade_date: '2024-12-12', + type: '1min', + data: [ + // 上午交易时段 9:30 - 11:30 + { time: '09:30', open: 11.02, close: 11.05, high: 11.06, low: 11.01, volume: 1856000, amount: 20458000 }, + { time: '09:31', open: 11.05, close: 11.08, high: 11.09, low: 11.04, volume: 1423000, amount: 15782000 }, + { time: '09:32', open: 11.08, close: 11.06, high: 11.10, low: 11.05, volume: 1125000, amount: 12468000 }, + { time: '09:33', open: 11.06, close: 11.10, high: 11.11, low: 11.05, volume: 1678000, amount: 18623000 }, + { time: '09:34', open: 11.10, close: 11.12, high: 11.14, low: 11.09, volume: 2134000, amount: 23725000 }, + { time: '09:35', open: 11.12, close: 11.15, high: 11.16, low: 11.11, volume: 1892000, amount: 21082000 }, + { time: '09:40', open: 11.15, close: 11.18, high: 11.20, low: 11.14, volume: 1567000, amount: 17523000 }, + { time: '09:45', open: 11.18, close: 11.16, high: 11.19, low: 11.15, volume: 1234000, amount: 13782000 }, + { time: '09:50', open: 11.16, close: 11.20, high: 11.21, low: 11.15, volume: 1456000, amount: 16298000 }, + { time: '09:55', open: 11.20, close: 11.22, high: 11.24, low: 11.19, volume: 1789000, amount: 20068000 }, + { time: '10:00', open: 11.22, close: 11.25, high: 11.26, low: 11.21, volume: 2012000, amount: 22635000 }, + { time: '10:10', open: 11.25, close: 11.23, high: 11.26, low: 11.22, volume: 1345000, amount: 15123000 }, + { time: '10:20', open: 11.23, close: 11.26, high: 11.28, low: 11.22, volume: 1678000, amount: 18912000 }, + { time: '10:30', open: 11.26, close: 11.24, high: 11.27, low: 11.23, volume: 1123000, amount: 12645000 }, + { time: '10:40', open: 11.24, close: 11.27, high: 11.28, low: 11.23, volume: 1456000, amount: 16412000 }, + { time: '10:50', open: 11.27, close: 11.25, high: 11.28, low: 11.24, volume: 1234000, amount: 13902000 }, + { time: '11:00', open: 11.25, close: 11.28, high: 11.30, low: 11.24, volume: 1567000, amount: 17689000 }, + { time: '11:10', open: 11.28, close: 11.26, high: 11.29, low: 11.25, volume: 1089000, amount: 12278000 }, + { time: '11:20', open: 11.26, close: 11.28, high: 11.29, low: 11.25, volume: 1234000, amount: 13912000 }, + { time: '11:30', open: 11.28, close: 11.27, high: 11.29, low: 11.26, volume: 987000, amount: 11134000 }, + // 下午交易时段 13:00 - 15:00 + { time: '13:00', open: 11.27, close: 11.30, high: 11.31, low: 11.26, volume: 1456000, amount: 16456000 }, + { time: '13:10', open: 11.30, close: 11.28, high: 11.31, low: 11.27, volume: 1123000, amount: 12689000 }, + { time: '13:20', open: 11.28, close: 11.32, high: 11.33, low: 11.27, volume: 1789000, amount: 20245000 }, + { time: '13:30', open: 11.32, close: 11.30, high: 11.33, low: 11.29, volume: 1345000, amount: 15212000 }, + { time: '13:40', open: 11.30, close: 11.33, high: 11.35, low: 11.29, volume: 1678000, amount: 18978000 }, + { time: '13:50', open: 11.33, close: 11.31, high: 11.34, low: 11.30, volume: 1234000, amount: 13956000 }, + { time: '14:00', open: 11.31, close: 11.34, high: 11.36, low: 11.30, volume: 1567000, amount: 17789000 }, + { time: '14:10', open: 11.34, close: 11.32, high: 11.35, low: 11.31, volume: 1123000, amount: 12712000 }, + { time: '14:20', open: 11.32, close: 11.30, high: 11.33, low: 11.29, volume: 1456000, amount: 16478000 }, + { time: '14:30', open: 11.30, close: 11.28, high: 11.31, low: 11.27, volume: 1678000, amount: 18956000 }, + { time: '14:40', open: 11.28, close: 11.26, high: 11.29, low: 11.25, volume: 1345000, amount: 15167000 }, + { time: '14:50', open: 11.26, close: 11.28, high: 11.30, low: 11.25, volume: 1892000, amount: 21345000 }, + { time: '15:00', open: 11.28, close: 11.28, high: 11.29, low: 11.27, volume: 2345000, amount: 26478000 } + ] + }, + // 实际控制人信息(数组格式) actualControl: [ { diff --git a/src/mocks/data/market.js b/src/mocks/data/market.js index 19e4a23f..23f27a4c 100644 --- a/src/mocks/data/market.js +++ b/src/mocks/data/market.js @@ -24,8 +24,9 @@ export const generateMarketData = (stockCode) => { low: parseFloat(low.toFixed(2)), volume: Math.floor(Math.random() * 500000000) + 100000000, // 1-6亿股 amount: Math.floor(Math.random() * 7000000000) + 1300000000, // 13-80亿元 - turnover_rate: (Math.random() * 2 + 0.5).toFixed(2), // 0.5-2.5% - change_pct: (Math.random() * 6 - 3).toFixed(2) // -3% to +3% + turnover_rate: parseFloat((Math.random() * 2 + 0.5).toFixed(2)), // 0.5-2.5% + change_percent: parseFloat((Math.random() * 6 - 3).toFixed(2)), // -3% to +3% + pe_ratio: parseFloat((Math.random() * 3 + 4).toFixed(2)) // 4-7 }; }) }, @@ -78,36 +79,45 @@ export const generateMarketData = (stockCode) => { })) }, - // 股权质押 + // 股权质押 - 匹配 PledgeData[] 类型 pledgeData: { success: true, - data: { - total_pledged: 25.6, // 质押比例% - major_shareholders: [ - { name: '中国平安保险集团', pledged_shares: 0, total_shares: 10168542300, pledge_ratio: 0 }, - { name: '深圳市投资控股', pledged_shares: 50000000, total_shares: 382456100, pledge_ratio: 13.08 } - ], - update_date: '2024-09-30' - } + data: Array(12).fill(null).map((_, i) => { + const date = new Date(); + date.setMonth(date.getMonth() - (11 - i)); + return { + end_date: date.toISOString().split('T')[0].slice(0, 7) + '-01', + unrestricted_pledge: Math.floor(Math.random() * 1000000000) + 500000000, + restricted_pledge: Math.floor(Math.random() * 200000000) + 50000000, + total_pledge: Math.floor(Math.random() * 1200000000) + 550000000, + total_shares: 19405918198, + pledge_ratio: parseFloat((Math.random() * 3 + 6).toFixed(2)), // 6-9% + pledge_count: Math.floor(Math.random() * 50) + 100 // 100-150 + }; + }) }, - // 市场摘要 + // 市场摘要 - 匹配 MarketSummary 类型 summaryData: { success: true, data: { - current_price: basePrice, - change: 0.25, - change_pct: 1.89, - open: 13.35, - high: 13.68, - low: 13.28, - volume: 345678900, - amount: 4678900000, - turnover_rate: 1.78, - pe_ratio: 4.96, - pb_ratio: 0.72, - total_market_cap: 262300000000, - circulating_market_cap: 262300000000 + stock_code: stockCode, + stock_name: stockCode === '000001' ? '平安银行' : '示例股票', + latest_trade: { + close: basePrice, + change_percent: 1.89, + volume: 345678900, + amount: 4678900000, + turnover_rate: 1.78, + pe_ratio: 4.96 + }, + latest_funding: { + financing_balance: 5823000000, + securities_balance: 125600000 + }, + latest_pledge: { + pledge_ratio: 8.25 + } } }, @@ -131,26 +141,57 @@ export const generateMarketData = (stockCode) => { }) }, - // 最新分时数据 + // 最新分时数据 - 匹配 MinuteData 类型 latestMinuteData: { success: true, - data: Array(240).fill(null).map((_, i) => { - const minute = 9 * 60 + 30 + i; // 从9:30开始 - const hour = Math.floor(minute / 60); - const min = minute % 60; - const time = `${hour.toString().padStart(2, '0')}:${min.toString().padStart(2, '0')}`; - const randomChange = (Math.random() - 0.5) * 0.1; - return { - time, - price: (basePrice + randomChange).toFixed(2), - volume: Math.floor(Math.random() * 2000000) + 500000, - avg_price: (basePrice + randomChange * 0.8).toFixed(2) - }; - }), + data: (() => { + const minuteData = []; + // 上午 9:30-11:30 (120分钟) + for (let i = 0; i < 120; i++) { + const hour = 9 + Math.floor((30 + i) / 60); + const min = (30 + i) % 60; + const time = `${hour.toString().padStart(2, '0')}:${min.toString().padStart(2, '0')}`; + const randomChange = (Math.random() - 0.5) * 0.1; + const open = parseFloat((basePrice + randomChange).toFixed(2)); + const close = parseFloat((basePrice + randomChange + (Math.random() - 0.5) * 0.05).toFixed(2)); + const high = parseFloat(Math.max(open, close, open + Math.random() * 0.05).toFixed(2)); + const low = parseFloat(Math.min(open, close, close - Math.random() * 0.05).toFixed(2)); + minuteData.push({ + time, + open, + close, + high, + low, + volume: Math.floor(Math.random() * 2000000) + 500000, + amount: Math.floor(Math.random() * 30000000) + 5000000 + }); + } + // 下午 13:00-15:00 (120分钟) + for (let i = 0; i < 120; i++) { + const hour = 13 + Math.floor(i / 60); + const min = i % 60; + const time = `${hour.toString().padStart(2, '0')}:${min.toString().padStart(2, '0')}`; + const randomChange = (Math.random() - 0.5) * 0.1; + const open = parseFloat((basePrice + randomChange).toFixed(2)); + const close = parseFloat((basePrice + randomChange + (Math.random() - 0.5) * 0.05).toFixed(2)); + const high = parseFloat(Math.max(open, close, open + Math.random() * 0.05).toFixed(2)); + const low = parseFloat(Math.min(open, close, close - Math.random() * 0.05).toFixed(2)); + minuteData.push({ + time, + open, + close, + high, + low, + volume: Math.floor(Math.random() * 1500000) + 400000, + amount: Math.floor(Math.random() * 25000000) + 4000000 + }); + } + return minuteData; + })(), code: stockCode, name: stockCode === '000001' ? '平安银行' : '示例股票', trade_date: new Date().toISOString().split('T')[0], - type: 'minute' + type: '1min' } }; }; diff --git a/src/views/Company/STRUCTURE.md b/src/views/Company/STRUCTURE.md index 25bb5b4f..ec7d9dba 100644 --- a/src/views/Company/STRUCTURE.md +++ b/src/views/Company/STRUCTURE.md @@ -1,6 +1,6 @@ # Company 目录结构说明 -> 最后更新:2025-12-11 +> 最后更新:2025-12-12 ## 目录结构 @@ -67,7 +67,7 @@ src/views/Company/ │ │ └── ManagementCard.tsx # 人员卡片(memo) │ │ │ ├── MarketDataView/ # Tab: 股票行情(TypeScript) -│ │ ├── index.tsx # 主组件入口 +│ │ ├── index.tsx # 主组件入口(~285 行,Tab 容器) │ │ ├── types.ts # 类型定义 │ │ ├── constants.ts # 主题配置、常量 │ │ ├── services/ @@ -82,7 +82,14 @@ src/views/Company/ │ │ ├── ThemedCard.tsx # 主题化卡片 │ │ ├── MarkdownRenderer.tsx # Markdown 渲染 │ │ ├── StockSummaryCard.tsx # 股票概览卡片 -│ │ └── AnalysisModal.tsx # 涨幅分析模态框 +│ │ ├── AnalysisModal.tsx # 涨幅分析模态框 +│ │ └── panels/ # Tab 面板组件 +│ │ ├── index.ts # 面板组件统一导出 +│ │ ├── TradeDataPanel.tsx # 交易数据(K线图、分钟图、表格) +│ │ ├── FundingPanel.tsx # 融资融券面板 +│ │ ├── BigDealPanel.tsx # 大宗交易面板 +│ │ ├── UnusualPanel.tsx # 龙虎榜面板 +│ │ └── PledgePanel.tsx # 股权质押面板 │ │ │ ├── DeepAnalysis/ # Tab: 深度分析 │ │ └── index.js @@ -451,7 +458,7 @@ CompanyOverview/ **拆分后文件结构**: ``` MarketDataView/ -├── index.tsx # 主组件入口(~1049 行) +├── index.tsx # 主组件入口(~285 行,Tab 容器) ├── types.ts # 类型定义(~383 行) ├── constants.ts # 主题配置、常量(~49 行) ├── services/ @@ -466,14 +473,21 @@ MarketDataView/ ├── ThemedCard.tsx # 主题化卡片(~32 行) ├── MarkdownRenderer.tsx # Markdown 渲染(~65 行) ├── StockSummaryCard.tsx # 股票概览卡片(~133 行) - └── AnalysisModal.tsx # 涨幅分析模态框(~188 行) + ├── 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` | ~1049 | 主组件,包含 5 个 Tab 面板(交易数据、融资融券、大宗交易、龙虎榜、股权质押) | +| `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 等) | @@ -780,4 +794,44 @@ index.tsx - **Hook 数据层**:`useFinancialData` 封装 9 个 API 并行加载 - **组件解耦**:每个表格/分析视图独立为组件 - **常量配置化**:指标定义可维护、可扩展 -- **工具函数复用**:计算和图表配置统一管理 \ No newline at end of file +- **工具函数复用**:计算和图表配置统一管理 + +### 2025-12-12 MarketDataView Panel 拆分 + +**改动概述**: +- `MarketDataView/index.tsx` 从 **1,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 类型定义 \ No newline at end of file