docs: 更新 STRUCTURE.md 和 mock 数据
- STRUCTURE.md 添加 MarketDataView Panel 拆分记录 - 更新目录结构说明,包含 panels/ 子目录 - 更新 company.js 和 market.js mock 数据 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -42,6 +42,72 @@ export const PINGAN_BANK_DATA = {
|
|||||||
employees: 42099,
|
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: [
|
actualControl: [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -24,8 +24,9 @@ export const generateMarketData = (stockCode) => {
|
|||||||
low: parseFloat(low.toFixed(2)),
|
low: parseFloat(low.toFixed(2)),
|
||||||
volume: Math.floor(Math.random() * 500000000) + 100000000, // 1-6亿股
|
volume: Math.floor(Math.random() * 500000000) + 100000000, // 1-6亿股
|
||||||
amount: Math.floor(Math.random() * 7000000000) + 1300000000, // 13-80亿元
|
amount: Math.floor(Math.random() * 7000000000) + 1300000000, // 13-80亿元
|
||||||
turnover_rate: (Math.random() * 2 + 0.5).toFixed(2), // 0.5-2.5%
|
turnover_rate: parseFloat((Math.random() * 2 + 0.5).toFixed(2)), // 0.5-2.5%
|
||||||
change_pct: (Math.random() * 6 - 3).toFixed(2) // -3% to +3%
|
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: {
|
pledgeData: {
|
||||||
success: true,
|
success: true,
|
||||||
data: {
|
data: Array(12).fill(null).map((_, i) => {
|
||||||
total_pledged: 25.6, // 质押比例%
|
const date = new Date();
|
||||||
major_shareholders: [
|
date.setMonth(date.getMonth() - (11 - i));
|
||||||
{ name: '中国平安保险集团', pledged_shares: 0, total_shares: 10168542300, pledge_ratio: 0 },
|
return {
|
||||||
{ name: '深圳市投资控股', pledged_shares: 50000000, total_shares: 382456100, pledge_ratio: 13.08 }
|
end_date: date.toISOString().split('T')[0].slice(0, 7) + '-01',
|
||||||
],
|
unrestricted_pledge: Math.floor(Math.random() * 1000000000) + 500000000,
|
||||||
update_date: '2024-09-30'
|
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: {
|
summaryData: {
|
||||||
success: true,
|
success: true,
|
||||||
data: {
|
data: {
|
||||||
current_price: basePrice,
|
stock_code: stockCode,
|
||||||
change: 0.25,
|
stock_name: stockCode === '000001' ? '平安银行' : '示例股票',
|
||||||
change_pct: 1.89,
|
latest_trade: {
|
||||||
open: 13.35,
|
close: basePrice,
|
||||||
high: 13.68,
|
change_percent: 1.89,
|
||||||
low: 13.28,
|
volume: 345678900,
|
||||||
volume: 345678900,
|
amount: 4678900000,
|
||||||
amount: 4678900000,
|
turnover_rate: 1.78,
|
||||||
turnover_rate: 1.78,
|
pe_ratio: 4.96
|
||||||
pe_ratio: 4.96,
|
},
|
||||||
pb_ratio: 0.72,
|
latest_funding: {
|
||||||
total_market_cap: 262300000000,
|
financing_balance: 5823000000,
|
||||||
circulating_market_cap: 262300000000
|
securities_balance: 125600000
|
||||||
|
},
|
||||||
|
latest_pledge: {
|
||||||
|
pledge_ratio: 8.25
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -131,26 +141,57 @@ export const generateMarketData = (stockCode) => {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
// 最新分时数据
|
// 最新分时数据 - 匹配 MinuteData 类型
|
||||||
latestMinuteData: {
|
latestMinuteData: {
|
||||||
success: true,
|
success: true,
|
||||||
data: Array(240).fill(null).map((_, i) => {
|
data: (() => {
|
||||||
const minute = 9 * 60 + 30 + i; // 从9:30开始
|
const minuteData = [];
|
||||||
const hour = Math.floor(minute / 60);
|
// 上午 9:30-11:30 (120分钟)
|
||||||
const min = minute % 60;
|
for (let i = 0; i < 120; i++) {
|
||||||
const time = `${hour.toString().padStart(2, '0')}:${min.toString().padStart(2, '0')}`;
|
const hour = 9 + Math.floor((30 + i) / 60);
|
||||||
const randomChange = (Math.random() - 0.5) * 0.1;
|
const min = (30 + i) % 60;
|
||||||
return {
|
const time = `${hour.toString().padStart(2, '0')}:${min.toString().padStart(2, '0')}`;
|
||||||
time,
|
const randomChange = (Math.random() - 0.5) * 0.1;
|
||||||
price: (basePrice + randomChange).toFixed(2),
|
const open = parseFloat((basePrice + randomChange).toFixed(2));
|
||||||
volume: Math.floor(Math.random() * 2000000) + 500000,
|
const close = parseFloat((basePrice + randomChange + (Math.random() - 0.5) * 0.05).toFixed(2));
|
||||||
avg_price: (basePrice + randomChange * 0.8).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,
|
code: stockCode,
|
||||||
name: stockCode === '000001' ? '平安银行' : '示例股票',
|
name: stockCode === '000001' ? '平安银行' : '示例股票',
|
||||||
trade_date: new Date().toISOString().split('T')[0],
|
trade_date: new Date().toISOString().split('T')[0],
|
||||||
type: 'minute'
|
type: '1min'
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Company 目录结构说明
|
# Company 目录结构说明
|
||||||
|
|
||||||
> 最后更新:2025-12-11
|
> 最后更新:2025-12-12
|
||||||
|
|
||||||
## 目录结构
|
## 目录结构
|
||||||
|
|
||||||
@@ -67,7 +67,7 @@ src/views/Company/
|
|||||||
│ │ └── ManagementCard.tsx # 人员卡片(memo)
|
│ │ └── ManagementCard.tsx # 人员卡片(memo)
|
||||||
│ │
|
│ │
|
||||||
│ ├── MarketDataView/ # Tab: 股票行情(TypeScript)
|
│ ├── MarketDataView/ # Tab: 股票行情(TypeScript)
|
||||||
│ │ ├── index.tsx # 主组件入口
|
│ │ ├── index.tsx # 主组件入口(~285 行,Tab 容器)
|
||||||
│ │ ├── types.ts # 类型定义
|
│ │ ├── types.ts # 类型定义
|
||||||
│ │ ├── constants.ts # 主题配置、常量
|
│ │ ├── constants.ts # 主题配置、常量
|
||||||
│ │ ├── services/
|
│ │ ├── services/
|
||||||
@@ -82,7 +82,14 @@ src/views/Company/
|
|||||||
│ │ ├── ThemedCard.tsx # 主题化卡片
|
│ │ ├── ThemedCard.tsx # 主题化卡片
|
||||||
│ │ ├── MarkdownRenderer.tsx # Markdown 渲染
|
│ │ ├── MarkdownRenderer.tsx # Markdown 渲染
|
||||||
│ │ ├── StockSummaryCard.tsx # 股票概览卡片
|
│ │ ├── StockSummaryCard.tsx # 股票概览卡片
|
||||||
│ │ └── AnalysisModal.tsx # 涨幅分析模态框
|
│ │ ├── AnalysisModal.tsx # 涨幅分析模态框
|
||||||
|
│ │ └── panels/ # Tab 面板组件
|
||||||
|
│ │ ├── index.ts # 面板组件统一导出
|
||||||
|
│ │ ├── TradeDataPanel.tsx # 交易数据(K线图、分钟图、表格)
|
||||||
|
│ │ ├── FundingPanel.tsx # 融资融券面板
|
||||||
|
│ │ ├── BigDealPanel.tsx # 大宗交易面板
|
||||||
|
│ │ ├── UnusualPanel.tsx # 龙虎榜面板
|
||||||
|
│ │ └── PledgePanel.tsx # 股权质押面板
|
||||||
│ │
|
│ │
|
||||||
│ ├── DeepAnalysis/ # Tab: 深度分析
|
│ ├── DeepAnalysis/ # Tab: 深度分析
|
||||||
│ │ └── index.js
|
│ │ └── index.js
|
||||||
@@ -451,7 +458,7 @@ CompanyOverview/
|
|||||||
**拆分后文件结构**:
|
**拆分后文件结构**:
|
||||||
```
|
```
|
||||||
MarketDataView/
|
MarketDataView/
|
||||||
├── index.tsx # 主组件入口(~1049 行)
|
├── index.tsx # 主组件入口(~285 行,Tab 容器)
|
||||||
├── types.ts # 类型定义(~383 行)
|
├── types.ts # 类型定义(~383 行)
|
||||||
├── constants.ts # 主题配置、常量(~49 行)
|
├── constants.ts # 主题配置、常量(~49 行)
|
||||||
├── services/
|
├── services/
|
||||||
@@ -466,14 +473,21 @@ MarketDataView/
|
|||||||
├── ThemedCard.tsx # 主题化卡片(~32 行)
|
├── ThemedCard.tsx # 主题化卡片(~32 行)
|
||||||
├── MarkdownRenderer.tsx # Markdown 渲染(~65 行)
|
├── MarkdownRenderer.tsx # Markdown 渲染(~65 行)
|
||||||
├── StockSummaryCard.tsx # 股票概览卡片(~133 行)
|
├── 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 等) |
|
| `types.ts` | ~383 | 所有 TypeScript 类型定义(Theme、TradeDayData、MinuteData、FundingData 等) |
|
||||||
| `constants.ts` | ~49 | 主题配置(light/dark)、周期选项常量 |
|
| `constants.ts` | ~49 | 主题配置(light/dark)、周期选项常量 |
|
||||||
| `marketService.ts` | ~173 | API 服务封装(getMarketData、getMinuteData、getBigDealData 等) |
|
| `marketService.ts` | ~173 | API 服务封装(getMarketData、getMinuteData、getBigDealData 等) |
|
||||||
@@ -780,4 +794,44 @@ index.tsx
|
|||||||
- **Hook 数据层**:`useFinancialData` 封装 9 个 API 并行加载
|
- **Hook 数据层**:`useFinancialData` 封装 9 个 API 并行加载
|
||||||
- **组件解耦**:每个表格/分析视图独立为组件
|
- **组件解耦**:每个表格/分析视图独立为组件
|
||||||
- **常量配置化**:指标定义可维护、可扩展
|
- **常量配置化**:指标定义可维护、可扩展
|
||||||
- **工具函数复用**:计算和图表配置统一管理
|
- **工具函数复用**:计算和图表配置统一管理
|
||||||
|
|
||||||
|
### 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 类型定义
|
||||||
Reference in New Issue
Block a user