Merge branch 'feature_2025/251209_stock_pref' into feature_bugfix/251217_stock

* feature_2025/251209_stock_pref: (133 commits)
  chore(StockQuoteCard): 删除未使用的 mockData.ts
  refactor(marketService): 移除 apiRequest 包装函数,统一使用 axios.get
  docs(Company): 添加 API 接口清单到 STRUCTURE.md
  refactor(Company): 提取共享的 useStockSearch Hook
  fix(hooks): 添加 AbortController 解决竞态条件问题
  fix(SubTabContainer): 修复 Tab 懒加载失效问题
  chore(CompanyOverview): 移除未使用的 CompanyOverviewData 类型定义
  fix(CompanyOverview): 修复 useBasicInfo 重复调用问题
  refactor(Company): fetch 请求迁移至 axios
  docs(Company): 更新 STRUCTURE.md 添加数据下沉优化记录
  refactor(StockQuoteCard): 数据下沉优化,Props 从 11 个精简为 4 个
  feat(StockQuoteCard): 新增内部数据获取 hooks
  fix(MarketDataView): 添加缺失的 VStack 导入
  fix(MarketDataView): loading 背景色改为深色与整体一致
  refactor(Company): 统一所有 Tab 的 loading 状态组件
  style(ForecastReport): 详细数据表格 UI 优化
  style(ForecastReport): 盈利预测图表优化
  fix(ValueChainCard): 视图切换按钮始终靠右显示
  refactor(CompanyOverview): 优化多个面板显示逻辑
  style(DetailTable): 简化布局,标题+表格无嵌套
  ...
This commit is contained in:
zdl
2025-12-17 16:06:43 +08:00
182 changed files with 24855 additions and 7624 deletions

View File

@@ -387,6 +387,68 @@ export const stockHandlers = [
}
}),
// 获取股票业绩预告
http.get('/api/stock/:stockCode/forecast', async ({ params }) => {
await delay(200);
const { stockCode } = params;
console.log('[Mock Stock] 获取业绩预告:', { stockCode });
// 生成股票列表用于查找名称
const stockList = generateStockList();
const stockInfo = stockList.find(s => s.code === stockCode.replace(/\.(SH|SZ)$/i, ''));
const stockName = stockInfo?.name || `股票${stockCode}`;
// 业绩预告类型列表
const forecastTypes = ['预增', '预减', '略增', '略减', '扭亏', '续亏', '首亏', '续盈'];
// 生成业绩预告数据
const forecasts = [
{
forecast_type: '预增',
report_date: '2024年年报',
content: `${stockName}预计2024年度归属于上市公司股东的净利润为58亿元至62亿元同比增长10%至17%。`,
reason: '报告期内,公司主营业务收入稳步增长,产品结构持续优化,毛利率提升;同时公司加大研发投入,新产品市场表现良好。',
change_range: {
lower: 10,
upper: 17
},
publish_date: '2024-10-15'
},
{
forecast_type: '略增',
report_date: '2024年三季报',
content: `${stockName}预计2024年1-9月归属于上市公司股东的净利润为42亿元至45亿元同比增长5%至12%。`,
reason: '公司积极拓展市场渠道,销售规模持续扩大,经营效益稳步提升。',
change_range: {
lower: 5,
upper: 12
},
publish_date: '2024-07-12'
},
{
forecast_type: forecastTypes[Math.floor(Math.random() * forecastTypes.length)],
report_date: '2024年中报',
content: `${stockName}预计2024年上半年归属于上市公司股东的净利润为28亿元至30亿元。`,
reason: '受益于行业景气度回升及公司降本增效措施效果显现,经营业绩同比有所改善。',
change_range: {
lower: 3,
upper: 8
},
publish_date: '2024-04-20'
}
];
return HttpResponse.json({
success: true,
data: {
stock_code: stockCode,
stock_name: stockName,
forecasts: forecasts
}
});
}),
// 获取股票报价(批量)
http.post('/api/stock/quotes', async ({ request }) => {
await delay(200);
@@ -414,6 +476,25 @@ export const stockHandlers = [
stockMap[s.code] = s.name;
});
// 行业和指数映射表
const stockIndustryMap = {
'000001': { industry_l1: '金融', industry: '银行', index_tags: ['沪深300', '上证180'] },
'600519': { industry_l1: '消费', industry: '白酒', index_tags: ['沪深300', '上证50'] },
'300750': { industry_l1: '工业', industry: '电池', index_tags: ['创业板50'] },
'601318': { industry_l1: '金融', industry: '保险', index_tags: ['沪深300', '上证50'] },
'600036': { industry_l1: '金融', industry: '银行', index_tags: ['沪深300', '上证50'] },
'000858': { industry_l1: '消费', industry: '白酒', index_tags: ['沪深300'] },
'002594': { industry_l1: '汽车', industry: '乘用车', index_tags: ['沪深300', '创业板指'] },
};
const defaultIndustries = [
{ industry_l1: '科技', industry: '软件' },
{ industry_l1: '医药', industry: '化学制药' },
{ industry_l1: '消费', industry: '食品' },
{ industry_l1: '金融', industry: '证券' },
{ industry_l1: '工业', industry: '机械' },
];
// 为每只股票生成报价数据
const quotesData = {};
codes.forEach(stockCode => {
@@ -426,6 +507,11 @@ export const stockHandlers = [
// 昨收
const prevClose = parseFloat((basePrice - change).toFixed(2));
// 获取行业和指数信息
const codeWithoutSuffix = stockCode.replace(/\.(SH|SZ)$/i, '');
const industryInfo = stockIndustryMap[codeWithoutSuffix] ||
defaultIndustries[Math.floor(Math.random() * defaultIndustries.length)];
quotesData[stockCode] = {
code: stockCode,
name: stockMap[stockCode] || `股票${stockCode}`,
@@ -439,7 +525,23 @@ export const stockHandlers = [
volume: Math.floor(Math.random() * 100000000),
amount: parseFloat((Math.random() * 10000000000).toFixed(2)),
market: stockCode.startsWith('6') ? 'SH' : 'SZ',
update_time: new Date().toISOString()
update_time: new Date().toISOString(),
// 行业和指数标签
industry_l1: industryInfo.industry_l1,
industry: industryInfo.industry,
index_tags: industryInfo.index_tags || [],
// 关键指标
pe: parseFloat((Math.random() * 50 + 5).toFixed(2)),
eps: parseFloat((Math.random() * 5 + 0.1).toFixed(3)),
pb: parseFloat((Math.random() * 8 + 0.5).toFixed(2)),
market_cap: `${(Math.random() * 5000 + 100).toFixed(0)}亿`,
week52_low: parseFloat((basePrice * 0.7).toFixed(2)),
week52_high: parseFloat((basePrice * 1.3).toFixed(2)),
// 主力动态
main_net_inflow: parseFloat((Math.random() * 10 - 5).toFixed(2)),
institution_holding: parseFloat((Math.random() * 50 + 10).toFixed(2)),
buy_ratio: parseFloat((Math.random() * 40 + 30).toFixed(2)),
sell_ratio: parseFloat((100 - (Math.random() * 40 + 30)).toFixed(2))
};
});