Files
vf_react/src/mocks/data/events.js
zdl 7e32dda2df feat本次提交包含的优化
 StockChangeIndicators 组件优化

  - 调整 padding 使布局更紧凑
  - 修复窄卡片中的折行问题
  - 自动根据内容调整宽度

   重要性等级视觉优化

  - 统一使用红色系(S→A→B→C:从深红到浅红)
  - 添加 badgeBg 字段支持新的角标样式

   DynamicNewsEventCard 卡片改版

  - 左上角矩形角标显示重要性(镂空边框样式)
  - 悬浮显示所有等级说明
  - 标题限制两行显示

   Mock 数据完整性

  - 添加缺失的 related_week_chg 字段
  - 确保三个涨跌幅指标数据完整
2025-11-03 15:38:30 +08:00

1181 lines
57 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Mock 事件相关数据
// Mock 股票池 - 常见的A股股票
const stockPool = [
{ stock_code: '600000.SH', stock_name: '浦发银行', industry: '银行' },
{ stock_code: '600519.SH', stock_name: '贵州茅台', industry: '白酒' },
{ stock_code: '600036.SH', stock_name: '招商银行', industry: '银行' },
{ stock_code: '601318.SH', stock_name: '中国平安', industry: '保险' },
{ stock_code: '600016.SH', stock_name: '民生银行', industry: '银行' },
{ stock_code: '601398.SH', stock_name: '工商银行', industry: '银行' },
{ stock_code: '601288.SH', stock_name: '农业银行', industry: '银行' },
{ stock_code: '601166.SH', stock_name: '兴业银行', industry: '银行' },
{ stock_code: '000001.SZ', stock_name: '平安银行', industry: '银行' },
{ stock_code: '000002.SZ', stock_name: '万科A', industry: '房地产' },
{ stock_code: '000858.SZ', stock_name: '五粮液', industry: '白酒' },
{ stock_code: '000333.SZ', stock_name: '美的集团', industry: '家电' },
{ stock_code: '002415.SZ', stock_name: '海康威视', industry: '安防' },
{ stock_code: '002594.SZ', stock_name: 'BYD比亚迪', industry: '新能源汽车' },
{ stock_code: '300750.SZ', stock_name: '宁德时代', industry: '新能源' },
{ stock_code: '300059.SZ', stock_name: '东方财富', industry: '证券' },
{ stock_code: '601888.SH', stock_name: '中国中免', industry: '免税' },
{ stock_code: '600276.SH', stock_name: '恒瑞医药', industry: '医药' },
{ stock_code: '600887.SH', stock_name: '伊利股份', industry: '乳制品' },
{ stock_code: '601012.SH', stock_name: '隆基绿能', industry: '光伏' },
{ stock_code: '688981.SH', stock_name: '中芯国际', industry: '半导体' },
{ stock_code: '600309.SH', stock_name: '万华化学', industry: '化工' },
{ stock_code: '603259.SH', stock_name: '药明康德', industry: '医药研发' },
{ stock_code: '002475.SZ', stock_name: '立讯精密', industry: '电子' },
{ stock_code: '000063.SZ', stock_name: '中兴通讯', industry: '通信设备' },
];
// 关联描述模板 - 更详细和专业的描述
const relationDescTemplates = [
'主营业务直接相关,预计受事件影响较大。公司在该领域拥有领先的市场地位,事件催化有望带动业绩增长。',
'产业链上游核心供应商,间接受益明显。随着下游需求提升,公司产品销量和价格有望双升。',
'产业链下游龙头企业,需求端直接受益。事件将推动行业景气度提升,公司订单量预计大幅增长。',
'同行业竞争对手,市场份额有望提升。行业整体向好背景下,公司凭借技术优势可能获得更多市场机会。',
'参股该领域优质企业,投资收益可期。被投企业在事件催化下估值提升,将为公司带来可观的投资回报。',
'业务板块深度布局相关领域,多项产品受益。公司提前布局的战略眼光将在此次事件中得到验证。',
'控股子公司主营相关业务,贡献利润占比较高。子公司业绩改善将直接提升上市公司整体盈利能力。',
'近期公告加大投资布局该领域,潜在受益标的。公司前瞻性布局正逢政策东风,项目落地进度有望加快。',
'行业绝对龙头,市场关注度极高。事件影响下,资金有望持续流入,股价弹性较大。',
'技术储备充足且研发投入领先,有望抢占市场先机。公司多项核心技术处于行业领先地位。',
'已有成熟产品线和完善销售渠道,短期内可实现业绩兑现。公司产能充足,可快速响应市场需求。',
'战略转型方向高度契合事件主题,转型进程有望提速。管理层明确表态将加大相关业务投入力度。',
'拥有稀缺资源或独家技术,竞争壁垒显著。事件催化下,公司核心竞争优势将进一步凸显。',
'区域市场领导者,地方政策支持力度大。公司深耕区域市场多年,具备先发优势和政府资源。',
'新增产能即将释放,业绩拐点临近。事件催化恰逢产能爬坡期,盈利能力有望超预期。',
'与行业巨头建立战略合作,订单保障充足。大客户资源优势明显,业务增长确定性强。',
];
// 模拟作者列表
const authorPool = [
"张明", "李华", "王芳", "陈强", "赵磊", "孙杰", "周磊", "吴洋",
"刘畅", "林芳", "郑华", "钱敏", "张敏", "赵强", "张华", "李明"
];
// 生成随机关联股票数据
export function generateRelatedStocks(eventId, count = 5) {
// 使用事件ID作为随机种子确保相同事件ID返回相同的股票列表
const seed = parseInt(eventId) || 1;
const selectedStocks = [];
// 伪随机选择股票基于事件ID
for (let i = 0; i < Math.min(count, stockPool.length); i++) {
const index = (seed * 17 + i * 13) % stockPool.length;
const stock = stockPool[index];
const descIndex = (seed * 7 + i * 11) % relationDescTemplates.length;
const authorIndex1 = (seed * 3 + i * 5) % authorPool.length;
const authorIndex2 = (seed * 5 + i * 7) % authorPool.length;
// 获取模板文本
const templateText = relationDescTemplates[descIndex];
// 将模板文本分成两部分作为query_part
const sentences = templateText.split('。');
const queryPart1 = sentences[0] || templateText.substring(0, 30);
const queryPart2 = sentences[1] || templateText.substring(30, 60);
// 生成随机日期基于seed
const baseDate = new Date('2025-08-01');
const daysOffset1 = (seed * i * 3) % 30;
const daysOffset2 = (seed * i * 5) % 30;
const date1 = new Date(baseDate);
date1.setDate(date1.getDate() + daysOffset1);
const date2 = new Date(baseDate);
date2.setDate(date2.getDate() + daysOffset2);
selectedStocks.push({
stock_code: stock.stock_code,
stock_name: stock.stock_name,
relation_desc: {
data: [
{
author: authorPool[authorIndex1],
sentences: sentences[0] + '。' + (sentences[1] || ''),
query_part: queryPart1,
match_score: i < 2 ? "优" : "良",
declare_date: date1.toISOString(),
report_title: `${stock.stock_name}:行业分析与投资价值研究-深度报告`
},
{
author: authorPool[authorIndex2],
sentences: sentences.slice(2).join('。') || templateText,
query_part: queryPart2 || '政策催化,市场关注度提升',
match_score: i < 3 ? "优" : "良",
declare_date: date2.toISOString(),
report_title: `${stock.industry}行业:事件驱动下的投资机会分析`
}
]
},
industry: stock.industry,
// 可选字段 - 用于前端显示更多信息
relevance_score: Math.max(60, 100 - i * 8), // 相关性评分,递减
impact_level: i < 2 ? 'high' : i < 4 ? 'medium' : 'low', // 影响程度
});
}
return selectedStocks;
}
// Mock 事件相关股票数据映射
// 这里可以为特定事件ID预设特定的股票列表
export const mockEventStocks = {
// 示例事件ID为1的预设股票消费刺激政策
'1': [
{
stock_code: '600519.SH',
stock_name: '贵州茅台',
relation_desc: {
data: [
{
author: "张明",
sentences: "贵州茅台作为白酒行业绝对龙头品牌溢价能力强提价预期明确。2024年产能持续释放叠加渠道库存处于低位业绩增长确定性高。",
query_part: "白酒行业绝对龙头,高端消费代表性标的",
match_score: "优",
declare_date: "2025-03-15T00:00:00",
report_title: "贵州茅台:高端白酒龙头,消费复苏核心受益标的-深度报告"
},
{
author: "李华",
sentences: "消费刺激政策将直接提振高端白酒需求,茅台作为高端消费代表性品牌,需求弹性大,定价权强。机构持仓集中度高,资金关注度极高。",
query_part: "消费刺激政策直接受益,品牌溢价能力行业领先",
match_score: "优",
declare_date: "2025-03-20T00:00:00",
report_title: "白酒行业:消费政策催化,高端白酒迎来配置良机"
}
]
},
industry: '白酒',
relevance_score: 95,
impact_level: 'high',
},
{
stock_code: '000858.SZ',
stock_name: '五粮液',
relation_desc: {
data: [
{
author: "王芳",
sentences: "五粮液作为白酒行业第二梯队领军企业,产品矩阵完善,中高端产品结构优化进程加快。管理层改革成效显著,渠道改革红利持续释放。",
query_part: "白酒行业第二梯队领军企业,产品矩阵完善",
match_score: "良",
declare_date: "2025-03-18T00:00:00",
report_title: "五粮液:改革红利释放,次高端市场份额稳步提升"
},
{
author: "陈强",
sentences: "消费复苏背景下,五粮液次高端市场份额稳步提升。估值修复空间较大,股价弹性优于行业平均水平。",
query_part: "消费复苏受益明显,估值修复空间大",
match_score: "良",
declare_date: "2025-03-22T00:00:00",
report_title: "白酒行业复盘:次高端品牌估值修复进行时"
}
]
},
industry: '白酒',
relevance_score: 90,
impact_level: 'high',
},
{
stock_code: '600887.SH',
stock_name: '伊利股份',
relation_desc: '乳制品行业龙头,市占率稳居第一。消费品类中必选消费属性强,受政策刺激需求提升明显。公司全国化布局完善,冷链物流体系成熟,新品推出节奏加快。常温、低温双轮驱动,盈利能力持续改善。分红率稳定,股息收益率具有吸引力。',
industry: '乳制品',
relevance_score: 82,
impact_level: 'medium',
},
{
stock_code: '000333.SZ',
stock_name: '美的集团',
relation_desc: '家电行业龙头以旧换新政策核心受益标的。公司产品线覆盖全品类渠道布局线上线下协同优势明显。智能家居战略推进顺利高端化、国际化双线并进。成本控制能力行业领先ROE水平稳定在20%以上。',
industry: '家电',
relevance_score: 78,
impact_level: 'medium',
},
],
// 事件ID为2的预设股票AI人工智能发展政策
'2': [
{
stock_code: '002415.SZ',
stock_name: '海康威视',
relation_desc: {
data: [
{
author: "赵敏",
sentences: "海康威视作为AI+安防龙头企业智能视觉技术全球领先。公司AI芯片、算法、云平台业务增长迅速研发投入占比保持10%以上。",
query_part: "AI+安防龙头企业,智能视觉技术全球领先",
match_score: "优",
declare_date: "2025-04-10T00:00:00",
report_title: "海康威视AI赋能安防技术护城河持续加深-深度报告"
},
{
author: "孙杰",
sentences: "人工智能政策支持下,智慧城市、智能交通等政府项目订单充足。海外市场拓展提速,国际化战略成效显著。",
query_part: "人工智能政策支持,政府项目订单充足",
match_score: "优",
declare_date: "2025-04-12T00:00:00",
report_title: "AI产业链深度政策催化下的投资机遇分析"
}
]
},
industry: '安防',
relevance_score: 92,
impact_level: 'high',
},
{
stock_code: '000063.SZ',
stock_name: '中兴通讯',
relation_desc: {
data: [
{
author: "周磊",
sentences: "中兴通讯作为5G通信设备商是算力网络建设核心受益者。AI大模型训练和推理需要海量算力支撑公司服务器、交换机等产品需求激增。",
query_part: "5G通信设备商算力网络建设核心受益者",
match_score: "优",
declare_date: "2025-04-08T00:00:00",
report_title: "中兴通讯:算力基础设施建设加速,订单饱满-点评报告"
},
{
author: "吴洋",
sentences: "运营商资本开支回暖5G-A、算力网络投资加速。国产替代进程加快中兴通讯市场份额持续提升盈利能力改善明显。",
query_part: "国产替代加速,市场份额持续提升",
match_score: "良",
declare_date: "2025-04-15T00:00:00",
report_title: "通信设备行业:运营商资本开支拐点已现"
},
{
author: "刘畅",
sentences: "AI产业链中算力基础设施投资是重中之重。中兴通讯在数据中心交换机、服务器等领域布局完善技术实力强劲。",
query_part: "AI算力基础设施投资核心标的",
match_score: "优",
declare_date: "2025-04-18T00:00:00",
report_title: "AI算力产业链投资机会深度解析"
}
]
},
industry: '通信设备',
relevance_score: 88,
impact_level: 'high',
},
{
stock_code: '688981.SH',
stock_name: '中芯国际',
relation_desc: '国内半导体制造龙头AI芯片代工核心标的。人工智能发展带动高端芯片需求爆发公司先进制程产能利用率高位运行。政策支持力度空前产业基金持续注资扩产进度超预期。国产替代空间巨大长期成长确定性强。',
industry: '半导体',
relevance_score: 85,
impact_level: 'high',
},
{
stock_code: '002475.SZ',
stock_name: '立讯精密',
relation_desc: '精密制造龙头AI终端设备供应链核心企业。AI眼镜、AI手机等新型终端设备放量公司作为苹果、Meta等巨头供应商直接受益。自动化生产水平行业领先成本优势明显。新业务拓展顺利汽车电子、服务器连接器增长快速。',
industry: '电子',
relevance_score: 80,
impact_level: 'medium',
},
],
// 事件ID为3的预设股票新能源汽车补贴延续
'3': [
{
stock_code: '300750.SZ',
stock_name: '宁德时代',
relation_desc: {
data: [
{
author: "张华",
sentences: "宁德时代作为全球动力电池绝对龙头市占率超35%,技术路线覆盖三元、磷酸铁锂、钠电池等全品类。客户资源优质,特斯拉、比亚迪等头部车企深度绑定。",
query_part: "动力电池绝对龙头全球市占率超35%",
match_score: "优",
declare_date: "2025-05-10T00:00:00",
report_title: "宁德时代:全球动力电池龙头,新能源汽车核心受益标的"
},
{
author: "李明",
sentences: "新能源汽车补贴延续政策出台,将直接刺激终端需求,宁德时代作为产业链核心环节,电池出货量有望大幅提升。储能业务高速增长,打开第二增长曲线。",
query_part: "补贴政策核心受益,储能业务打开第二曲线",
match_score: "优",
declare_date: "2025-05-12T00:00:00",
report_title: "新能源汽车产业链:补贴延续下的投资机遇"
}
]
},
industry: '新能源',
relevance_score: 98,
impact_level: 'high',
},
{
stock_code: '002594.SZ',
stock_name: 'BYD比亚迪',
relation_desc: {
data: [
{
author: "王芳",
sentences: "比亚迪月销量持续突破30万辆市占率稳步提升。王朝、海洋、腾势三大品牌矩阵完善价格带覆盖10-50万元产品竞争力强。",
query_part: "新能源汽车销量冠军月销超30万辆",
match_score: "优",
declare_date: "2025-05-08T00:00:00",
report_title: "比亚迪:新能源汽车销量王者,产业链垂直整合优势显著"
},
{
author: "陈强",
sentences: "电池、电机、电控自主可控,成本优势明显。出海战略推进顺利,欧洲、东南亚市场表现亮眼,国际化进程加速。",
query_part: "垂直整合成本优势,出海战略成效显著",
match_score: "良",
declare_date: "2025-05-15T00:00:00",
report_title: "比亚迪国际化战略深度解析"
}
]
},
industry: '新能源汽车',
relevance_score: 95,
impact_level: 'high',
},
{
stock_code: '601012.SH',
stock_name: '隆基绿能',
relation_desc: {
data: [
{
author: "赵磊",
sentences: "隆基绿能作为光伏组件龙头单晶硅片市占率第一。BC电池技术领先产品溢价能力强一体化产能布局完善。",
query_part: "光伏组件龙头BC电池技术领先",
match_score: "良",
declare_date: "2025-05-05T00:00:00",
report_title: "隆基绿能:光伏技术引领者,一体化优势突出"
},
{
author: "孙杰",
sentences: "新能源汽车补贴延续带动绿色能源需求增长。隆基海外收入占比超50%,全球化布局分散风险,盈利稳定性强。",
query_part: "绿色能源需求增长,全球化布局优势",
match_score: "良",
declare_date: "2025-05-18T00:00:00",
report_title: "光伏行业:新能源政策催化下的配置机会"
}
]
},
industry: '光伏',
relevance_score: 85,
impact_level: 'medium',
},
{
stock_code: '688187.SH',
stock_name: '天齐锂业',
relation_desc: {
data: [
{
author: "刘畅",
sentences: "天齐锂业拥有优质锂矿资源,锂资源自给率高,成本优势显著。澳洲、智利矿山产能稳定,国内锂盐产能持续扩张。",
query_part: "锂资源龙头,优质矿山资源储备充足",
match_score: "优",
declare_date: "2025-05-20T00:00:00",
report_title: "天齐锂业:锂资源龙头,成本优势突出"
},
{
author: "吴洋",
sentences: "新能源汽车、储能需求增长带动锂盐价格中枢上移。锂价回暖周期开启,天齐锂业业绩弹性巨大,是锂价上行核心受益标的。",
query_part: "锂价回暖周期受益,业绩弹性大",
match_score: "优",
declare_date: "2025-05-22T00:00:00",
report_title: "锂行业:供需格局改善,价格拐点已现"
}
]
},
industry: '有色金属',
relevance_score: 82,
impact_level: 'high',
},
],
// 事件ID为4的预设股票医药创新支持政策
'4': [
{
stock_code: '600276.SH',
stock_name: '恒瑞医药',
relation_desc: {
data: [
{
author: "周磊",
sentences: "恒瑞医药作为创新药龙头研发管线最丰富涵盖肿瘤、麻醉、造影等多领域。PD-1、PARP抑制剂等重磅产品进入收获期放量迅速。",
query_part: "创新药龙头,研发管线最丰富",
match_score: "优",
declare_date: "2025-06-10T00:00:00",
report_title: "恒瑞医药:创新药进入收获期,业绩拐点显现"
},
{
author: "钱敏",
sentences: "创新药政策支持力度加大集采影响逐步消化。恒瑞研发投入占比超20%,海外授权合作频繁,国际化进程加速。",
query_part: "政策支持加码,国际化进程加速",
match_score: "优",
declare_date: "2025-06-12T00:00:00",
report_title: "医药创新政策解读:龙头企业核心受益"
}
]
},
industry: '医药',
relevance_score: 93,
impact_level: 'high',
},
{
stock_code: '603259.SH',
stock_name: '药明康德',
relation_desc: {
data: [
{
author: "孙杰",
sentences: "药明康德作为CRO/CDMO龙头全球制药产业链核心服务商。客户覆盖全球TOP20药企粘性强订单饱满。一体化平台优势明显。",
query_part: "CRO/CDMO龙头全球制药核心服务商",
match_score: "优",
declare_date: "2025-06-08T00:00:00",
report_title: "药明康德CRO龙头地位稳固订单饱满"
},
{
author: "林芳",
sentences: "创新药研发投入增加,外包渗透率提升。药明从研发到商业化全流程服务能力强,海外收入占比高,人民币贬值受益。",
query_part: "外包渗透率提升,全流程服务优势",
match_score: "良",
declare_date: "2025-06-15T00:00:00",
report_title: "CRO行业创新药外包需求持续增长"
}
]
},
industry: '医药研发',
relevance_score: 90,
impact_level: 'high',
},
{
stock_code: '300760.SZ',
stock_name: '迈瑞医疗',
relation_desc: {
data: [
{
author: "赵强",
sentences: "迈瑞医疗产品线覆盖生命信息与支持、体外诊断、医学影像三大领域。高端医疗设备国产替代加速,市占率持续提升。",
query_part: "医疗器械龙头,国产替代加速",
match_score: "良",
declare_date: "2025-06-05T00:00:00",
report_title: "迈瑞医疗:医疗器械龙头,国产化进程提速"
},
{
author: "吴洋",
sentences: "海外市场突破进展顺利,进入更多顶级医院。研发能力强,新品推出节奏加快,盈利能力稳定,现金流充沛。",
query_part: "海外突破顺利,研发能力强劲",
match_score: "良",
declare_date: "2025-06-18T00:00:00",
report_title: "医疗器械行业:国产品牌全球化加速"
}
]
},
industry: '医疗器械',
relevance_score: 87,
impact_level: 'medium',
},
],
// 事件ID为5的预设股票数字经济发展规划
'5': [
{
stock_code: '300059.SZ',
stock_name: '东方财富',
relation_desc: {
data: [
{
author: "郑华",
sentences: "东方财富作为互联网金融龙头流量优势显著APP月活超亿。券商、基金代销、数据服务多业务协同形成完整生态闭环。",
query_part: "互联网金融龙头,流量优势显著",
match_score: "优",
declare_date: "2025-07-10T00:00:00",
report_title: "东方财富:互联网金融龙头,生态优势突出"
},
{
author: "刘明",
sentences: "数字经济发展推动线上理财渗透率提升。市场交易活跃度提升佣金收入和利息收入双增长低成本负债优势明显ROE水平行业领先。",
query_part: "数字经济受益,线上理财渗透率提升",
match_score: "优",
declare_date: "2025-07-12T00:00:00",
report_title: "数字经济政策解读:互联网金融核心受益"
}
]
},
industry: '证券',
relevance_score: 88,
impact_level: 'high',
},
{
stock_code: '002410.SZ',
stock_name: '广联达',
relation_desc: {
data: [
{
author: "张敏",
sentences: "广联达作为建筑信息化龙头,工程造价软件市占率第一。云转型进入收获期,订阅模式收入占比提升,现金流改善明显。",
query_part: "建筑信息化龙头,云转型收获期",
match_score: "良",
declare_date: "2025-07-08T00:00:00",
report_title: "广联达:建筑信息化龙头,云转型成效显著"
},
{
author: "李芳",
sentences: "数字化转型加速,建筑行业信息化需求旺盛。施工、设计等新业务拓展顺利,成长空间广阔,政策支持力度大,行业壁垒高。",
query_part: "数字化转型加速,新业务拓展顺利",
match_score: "良",
declare_date: "2025-07-15T00:00:00",
report_title: "建筑信息化:数字经济下的产业升级机遇"
}
]
},
industry: '软件',
relevance_score: 85,
impact_level: 'medium',
},
],
};
// 获取事件相关股票
export function getEventRelatedStocks(eventId) {
// 优先返回预设的股票列表
if (mockEventStocks[eventId]) {
return mockEventStocks[eventId];
}
// 否则生成随机股票列表3-6只股票
const count = 3 + (parseInt(eventId) % 4);
return generateRelatedStocks(eventId, count);
}
// ==================== Mock 事件列表数据 ====================
// 事件类型池
const eventTypes = ['政策发布', '行业动向', '公司公告', '市场研判', '技术突破', '财报发布', '投融资', '高管变动'];
// 行业池
const industries = ['半导体', '新能源', '人工智能', '医药', '消费', '金融', '房地产', '通信', '互联网', '军工', '化工', '机械'];
// 事件标题模板
const eventTitleTemplates = [
'{industry}行业迎来重大政策利好',
'{company}发布{quarter}财报,业绩超预期',
'{industry}板块集体大涨,{company}涨停',
'央行宣布{policy},影响{industry}行业',
'{company}与{partner}达成战略合作',
'{industry}技术取得重大突破',
'{company}拟投资{amount}亿元布局{industry}',
'国家发改委:支持{industry}产业发展',
'{industry}龙头{company}涨价{percent}%',
'{company}回购股份,彰显信心',
];
// 生成随机公司名
function generateCompanyName(industry) {
const prefixes = ['华为', '中兴', '阿里', '腾讯', '比亚迪', '宁德时代', '隆基', '恒瑞', '茅台', '五粮液', '海康', '中芯'];
const suffixes = ['科技', '集团', '股份', '控股', '实业', ''];
const prefix = prefixes[Math.floor(Math.random() * prefixes.length)];
const suffix = suffixes[Math.floor(Math.random() * suffixes.length)];
return `${prefix}${suffix}`;
}
// 生成事件标题
function generateEventTitle(industry, seed) {
const template = eventTitleTemplates[seed % eventTitleTemplates.length];
return template
.replace('{industry}', industry)
.replace('{company}', generateCompanyName(industry))
.replace('{partner}', generateCompanyName(industry))
.replace('{quarter}', ['一季度', '半年度', '三季度', '年度'][seed % 4])
.replace('{policy}', ['降准0.5%', '降息25BP', 'MLF下调', '提高赤字率'][seed % 4])
.replace('{amount}', [50, 100, 200, 500][seed % 4])
.replace('{percent}', [5, 10, 15, 20][seed % 4]);
}
// 生成事件描述
function generateEventDescription(industry, importance, seed) {
const impacts = {
S: '重大利好预计将对行业格局产生深远影响相关概念股有望持续受益。机构预计该事件将带动行业整体估值提升15-20%,龙头企业市值增长空间广阔。',
A: '重要利好,市场情绪积极,短期内资金流入明显。分析师普遍认为该事件将推动行业景气度上行,相关公司业绩有望超预期增长。',
B: '中性偏好,对部分细分领域有一定促进作用。虽然不是行业性机会,但优质标的仍有结构性行情,建议关注业绩确定性强的公司。',
C: '影响有限,市场反应平淡,但长期来看仍有积极意义。事件对行业发展方向有指引作用,关注后续政策跟进和落地情况。',
};
const details = [
`根据最新消息,${industry}领域将获得新一轮政策支持,产业链相关企业订单饱满。`,
`${industry}板块近期表现活跃,多只个股创出年内新高,资金持续流入。`,
`行业专家指出,${industry}产业正处于高速发展期,市场空间广阔,龙头企业优势明显。`,
`券商研报显示,${industry}行业估值处于历史低位,当前具备较高配置价值。`,
];
return impacts[importance] + details[seed % details.length];
}
// 生成关键词(对象数组格式,包含完整信息)
function generateKeywords(industry, seed) {
const commonKeywords = ['政策', '利好', '业绩', '涨停', '龙头', '突破', '合作', '投资'];
const industryKeywords = {
'半导体': ['芯片', '晶圆', '封测', 'AI芯片', '国产替代'],
'新能源': ['电池', '光伏', '储能', '新能源车', '锂电'],
'人工智能': ['大模型', 'AI应用', '算力', '数据', '机器学习'],
'医药': ['创新药', 'CRO', '医疗器械', '生物制药', '仿制药'],
'消费': ['白酒', '食品', '家电', '零售', '免税'],
};
// 概念描述模板
const descriptionTemplates = {
'政策': '政策性利好消息对相关行业和板块产生积极影响,带动市场情绪和资金流向。',
'利好': '市场积极因素推动相关板块上涨,投资者情绪乐观,资金持续流入。',
'业绩': '公司业绩超预期增长,盈利能力提升,市场给予更高估值预期。',
'涨停': '强势涨停板显示市场热度,短期资金追捧,板块效应明显。',
'龙头': '行业龙头企业具备竞争优势,市场地位稳固,带动板块走势。',
'突破': '技术面或基本面出现重大突破,打开上涨空间,吸引资金关注。',
'合作': '战略合作为公司带来新的增长点,业务协同效应显著。',
'投资': '重大投资项目落地,长期发展空间广阔,市场预期良好。',
'芯片': '国产芯片替代加速,自主可控需求强烈,政策和资金支持力度大。',
'晶圆': '晶圆产能紧张,供需关系改善,相关企业盈利能力提升。',
'封测': '封测环节景气度上行,订单饱满,产能利用率提高。',
'AI芯片': '人工智能快速发展带动AI芯片需求爆发市场空间巨大。',
'国产替代': '国产替代进程加速,政策扶持力度大,进口依赖度降低。',
'电池': '新能源汽车渗透率提升,动力电池需求旺盛,技术迭代加快。',
'光伏': '光伏装机量快速增长,成本持续下降,行业景气度维持高位。',
'储能': '储能市场爆发式增长,政策支持力度大,应用场景不断拓展。',
'新能源车': '新能源汽车销量高增长,渗透率持续提升,产业链受益明显。',
'锂电': '锂电池技术进步,成本优势扩大,下游应用领域持续扩张。',
'大模型': '大语言模型技术突破,商业化进程加速,应用场景广阔。',
'AI应用': '人工智能应用落地加速,垂直领域渗透率提升,市场空间巨大。',
'算力': '算力需求持续增长,数据中心建设加速,相关产业链受益。',
'数据': '数据要素市场化改革推进,数据价值释放,相关企业盈利模式清晰。',
'机器学习': '机器学习技术成熟,应用场景丰富,商业价值逐步显现。',
'创新药': '创新药研发管线丰富,商业化进程顺利,市场给予高估值。',
'CRO': 'CRO行业高景气订单充足盈利能力稳定增长。',
'医疗器械': '医疗器械国产化率提升,技术创新加快,市场份额扩大。',
'生物制药': '生物制药技术突破,产品管线丰富,商业化前景广阔。',
'仿制药': '仿制药集采常态化,质量优势企业市场份额提升。',
'白酒': '白酒消费升级,高端产品量价齐升,龙头企业护城河深厚。',
'食品': '食品饮料需求稳定,品牌力强的企业市场份额持续提升。',
'家电': '家电消费需求回暖,智能化升级带动产品结构优化。',
'零售': '零售行业数字化转型,线上线下融合,运营效率提升。',
'免税': '免税政策优化,消费回流加速,行业景气度上行。'
};
const keywordNames = [
...commonKeywords.slice(seed % 3, seed % 3 + 3),
...(industryKeywords[industry] || []).slice(0, 2)
].slice(0, 5);
const matchTypes = ['hybrid_knn', 'keyword', 'semantic'];
// 生成历史触发时间3-5个历史日期
const generateHappenedTimes = (baseSeed) => {
const times = [];
const count = 3 + (baseSeed % 3); // 3-5个时间点
for (let i = 0; i < count; i++) {
const daysAgo = 30 + (baseSeed * 7 + i * 11) % 330; // 30-360天前
const date = new Date();
date.setDate(date.getDate() - daysAgo);
times.push(date.toISOString().split('T')[0]);
}
return times.sort().reverse(); // 降序排列
};
// 生成核心相关股票4-6只
const generateRelatedStocks = (conceptName, baseSeed) => {
const stockCount = 4 + (baseSeed % 3); // 4-6只股票
const selectedStocks = [];
for (let i = 0; i < stockCount && i < stockPool.length; i++) {
const stockIndex = (baseSeed + i * 7) % stockPool.length;
const stock = stockPool[stockIndex];
selectedStocks.push({
stock_name: stock.stock_name,
stock_code: stock.stock_code,
reason: relationDescTemplates[(baseSeed + i) % relationDescTemplates.length],
change_pct: (Math.random() * 15 - 5).toFixed(2) // -5% ~ +10%
});
}
return selectedStocks;
};
// 将字符串数组转换为对象数组匹配真实API数据结构
return keywordNames.map((name, index) => {
const score = (70 + Math.floor((seed * 7 + index * 11) % 30)) / 100; // 0.70-0.99的分数
const avgChangePct = (Math.random() * 15 - 5).toFixed(2); // -5% ~ +10% 的涨跌幅
return {
concept: name, // 使用 concept 字段而不是 name
stock_count: 10 + Math.floor((seed + index) % 30), // 10-39个相关股票
score: parseFloat(score.toFixed(2)), // 0-1之间的分数而不是0-100
description: descriptionTemplates[name] || `${name}相关概念,市场关注度较高,具有一定的投资价值。`,
price_info: { // 将 avg_change_pct 嵌套在 price_info 对象中
avg_change_pct: parseFloat(avgChangePct)
},
match_type: matchTypes[(seed + index) % 3], // 随机匹配类型
happened_times: generateHappenedTimes(seed + index), // 历史触发时间
stocks: generateRelatedStocks(name, seed + index) // 核心相关股票
};
});
}
/**
* 生成 Mock 事件列表
* @param {Object} params - 查询参数
* @returns {Object} - {events: [], pagination: {}}
*/
export function generateMockEvents(params = {}) {
const {
page = 1,
per_page = 10,
sort = 'new',
importance = 'all',
date_range = '',
q = '',
industry_code = '',
stock_code = '',
} = params;
// 生成200个事件用于测试足够测试分页功能
const totalEvents = 200;
const allEvents = [];
const importanceLevels = ['S', 'A', 'B', 'C'];
const baseDate = new Date(); // 使用当前日期作为基准
for (let i = 0; i < totalEvents; i++) {
const industry = industries[i % industries.length];
const imp = importanceLevels[i % importanceLevels.length];
const eventType = eventTypes[i % eventTypes.length];
// 生成随机日期最近30天内
const createdAt = new Date(baseDate);
createdAt.setDate(createdAt.getDate() - (i % 30));
// 生成随机热度和收益率
const hotScore = Math.max(50, 100 - i);
const relatedAvgChg = (Math.random() * 20 - 5).toFixed(2); // -5% 到 15%
const relatedMaxChg = (Math.random() * 30).toFixed(2); // 0% 到 30%
const relatedWeekChg = (Math.random() * 30 - 10).toFixed(2); // -10% 到 20%
// 生成价格走势数据(前一天、当天、后一天)
const generatePriceTrend = (seed) => {
const basePrice = 10 + (seed % 90); // 基础价格 10-100
const trend = [];
// 前一天5个数据点
let price = basePrice;
for (let i = 0; i < 5; i++) {
price = price + (Math.random() - 0.5) * 0.5;
trend.push(parseFloat(price.toFixed(2)));
}
// 当天5个数据点
for (let i = 0; i < 5; i++) {
price = price + (Math.random() - 0.4) * 0.8; // 轻微上涨趋势
trend.push(parseFloat(price.toFixed(2)));
}
// 后一天5个数据点
for (let i = 0; i < 5; i++) {
price = price + (Math.random() - 0.45) * 1.0;
trend.push(parseFloat(price.toFixed(2)));
}
return trend;
};
// 为每个事件随机选择2-5个相关股票
const relatedStockCount = 2 + (i % 4); // 2-5个股票
const relatedStocks = [];
const industryStocks = stockPool.filter(s => s.industry === industry);
const addedStockCodes = new Set(); // 用于去重
// 优先选择同行业股票
if (industryStocks.length > 0) {
for (let j = 0; j < Math.min(relatedStockCount, industryStocks.length); j++) {
const stock = industryStocks[j % industryStocks.length];
if (!addedStockCodes.has(stock.stock_code)) {
const dailyChange = (Math.random() * 6 - 2).toFixed(2); // -2% ~ +4%
const weekChange = (Math.random() * 10 - 3).toFixed(2); // -3% ~ +7%
relatedStocks.push({
stock_name: stock.stock_name,
stock_code: stock.stock_code,
relation_desc: relationDescTemplates[(i + j) % relationDescTemplates.length],
daily_change: dailyChange,
week_change: weekChange,
price_trend: generatePriceTrend(i * 100 + j)
});
addedStockCodes.add(stock.stock_code);
}
}
}
// 如果同行业股票不够,从整个 stockPool 中补充
let poolIndex = 0;
while (relatedStocks.length < relatedStockCount && poolIndex < stockPool.length) {
const randomStock = stockPool[poolIndex % stockPool.length];
if (!addedStockCodes.has(randomStock.stock_code)) {
const dailyChange = (Math.random() * 6 - 2).toFixed(2); // -2% ~ +4%
const weekChange = (Math.random() * 10 - 3).toFixed(2); // -3% ~ +7%
relatedStocks.push({
stock_name: randomStock.stock_name,
stock_code: randomStock.stock_code,
relation_desc: relationDescTemplates[(i + poolIndex) % relationDescTemplates.length],
daily_change: dailyChange,
week_change: weekChange,
price_trend: generatePriceTrend(i * 100 + poolIndex)
});
addedStockCodes.add(randomStock.stock_code);
}
poolIndex++;
}
// 计算交易日期模拟下一交易日这里简单地加1天
const tradingDate = new Date(createdAt);
tradingDate.setDate(tradingDate.getDate() + 1);
allEvents.push({
id: i + 1,
title: generateEventTitle(industry, i),
description: generateEventDescription(industry, imp, i),
content: generateEventDescription(industry, imp, i),
event_type: eventType,
importance: imp,
status: 'published',
created_at: createdAt.toISOString(),
updated_at: createdAt.toISOString(),
trading_date: tradingDate.toISOString().split('T')[0], // YYYY-MM-DD 格式
hot_score: hotScore,
view_count: Math.floor(Math.random() * 10000),
related_avg_chg: parseFloat(relatedAvgChg),
related_max_chg: parseFloat(relatedMaxChg),
related_week_chg: parseFloat(relatedWeekChg),
keywords: generateKeywords(industry, i),
is_ai_generated: i % 4 === 0, // 25% 的事件是AI生成
industry: industry,
related_stocks: relatedStocks, // 添加相关股票列表
historical_events: generateHistoricalEvents(industry, i), // 添加历史事件
transmission_chain: generateTransmissionChain(industry, i), // 添加传导链数据
});
}
// 筛选
let filteredEvents = allEvents;
// 重要性筛选
if (importance && importance !== 'all') {
filteredEvents = filteredEvents.filter(e => e.importance === importance);
}
// 关键词搜索
if (q) {
const query = q.toLowerCase();
filteredEvents = filteredEvents.filter(e =>
e.title.toLowerCase().includes(query) ||
e.description.toLowerCase().includes(query) ||
e.keywords.some(k => k.toLowerCase().includes(query))
);
}
// 行业筛选
if (industry_code) {
filteredEvents = filteredEvents.filter(e =>
e.industry.includes(industry_code) || e.keywords.includes(industry_code)
);
}
// 股票代码筛选
if (stock_code) {
// 移除可能的后缀 (.SH, .SZ)
const cleanStockCode = stock_code.replace(/\.(SH|SZ)$/, '');
filteredEvents = filteredEvents.filter(e => {
if (!e.related_stocks || e.related_stocks.length === 0) {
return false;
}
// 检查事件的 related_stocks 中是否包含该股票代码
return e.related_stocks.some(code => {
const cleanCode = code.replace(/\.(SH|SZ)$/, '');
return cleanCode === cleanStockCode || code === stock_code;
});
});
}
// 日期范围筛选
if (date_range) {
const [startStr, endStr] = date_range.split(' 至 ');
if (startStr && endStr) {
const start = new Date(startStr);
const end = new Date(endStr);
filteredEvents = filteredEvents.filter(e => {
const eventDate = new Date(e.created_at);
return eventDate >= start && eventDate <= end;
});
}
}
// 排序
if (sort === 'hot') {
filteredEvents.sort((a, b) => b.hot_score - a.hot_score);
} else if (sort === 'returns') {
filteredEvents.sort((a, b) => b.related_avg_chg - a.related_avg_chg);
} else {
// 默认按时间排序 (new)
filteredEvents.sort((a, b) => new Date(b.created_at) - new Date(a.created_at));
}
// 分页
const start = (page - 1) * per_page;
const end = start + per_page;
const paginatedEvents = filteredEvents.slice(start, end);
return {
events: paginatedEvents,
pagination: {
page: page,
per_page: per_page,
total: filteredEvents.length,
total_pages: Math.ceil(filteredEvents.length / per_page),
},
};
}
/**
* 生成热点事件
* @param {number} limit - 返回数量
* @returns {Array} - 热点事件列表
*/
export function generateHotEvents(limit = 5) {
const { events } = generateMockEvents({ sort: 'hot', per_page: limit });
return events;
}
/**
* 生成热门关键词
* @param {number} limit - 返回数量
* @returns {Array} - 热门关键词列表
*/
export function generatePopularKeywords(limit = 20) {
const allKeywords = [
'人工智能', '芯片', '新能源', '锂电池', '光伏', '储能',
'消费', '白酒', '医药', 'CRO', '半导体', '国产替代',
'军工', '航空', '5G', '通信', '互联网', '云计算',
'大数据', '区块链', '元宇宙', '新基建', '数字经济',
];
return allKeywords.slice(0, limit).map((keyword, index) => ({
keyword,
count: Math.max(10, 100 - index * 3),
trend: index % 3 === 0 ? 'up' : index % 3 === 1 ? 'down' : 'stable',
}));
}
/**
* 生成历史事件对比数据
* @param {string} industry - 行业
* @param {number} index - 索引
* @returns {Array} - 历史事件列表
*/
function generateHistoricalEvents(industry, index) {
const historicalCount = 3 + (index % 3); // 3-5个历史事件
const historical = [];
const baseDate = new Date();
for (let i = 0; i < historicalCount; i++) {
// 生成过去1-6个月的随机时间
const monthsAgo = 1 + Math.floor(Math.random() * 6);
const eventDate = new Date(baseDate);
eventDate.setMonth(eventDate.getMonth() - monthsAgo);
const similarityScore = 0.6 + Math.random() * 0.35; // 60%-95%相似度
historical.push({
id: `hist_${industry}_${index}_${i}`,
title: generateEventTitle(industry, i + index * 10),
created_at: eventDate.toISOString(),
related_avg_chg: parseFloat((Math.random() * 15 - 3).toFixed(2)),
related_max_chg: parseFloat((Math.random() * 25).toFixed(2)),
similarity_score: parseFloat(similarityScore.toFixed(2)),
view_count: Math.floor(Math.random() * 3000) + 500,
});
}
// 按相似度排序
historical.sort((a, b) => b.similarity_score - a.similarity_score);
return historical;
}
/**
* 生成传导链数据
* @param {string} industry - 行业
* @param {number} index - 索引
* @returns {Object} - 传导链数据 { nodes, edges }
*/
function generateTransmissionChain(industry, index) {
const nodeTypes = ['event', 'industry', 'company', 'policy', 'technology', 'market'];
const impactTypes = ['positive', 'negative', 'neutral', 'mixed'];
const strengthLevels = ['strong', 'medium', 'weak'];
const nodes = [];
const edges = [];
// 主事件节点
nodes.push({
id: 1,
name: '主事件',
type: 'event',
extra: { is_main_event: true, description: `${industry}重要事件` }
});
// 生成5-8个相关节点
const nodeCount = 5 + (index % 4);
for (let i = 2; i <= nodeCount; i++) {
const nodeType = nodeTypes[i % nodeTypes.length];
const industryStock = stockPool.find(s => s.industry === industry);
let nodeName;
if (nodeType === 'company' && industryStock) {
nodeName = industryStock.name;
} else if (nodeType === 'industry') {
nodeName = `${industry}产业`;
} else if (nodeType === 'policy') {
nodeName = '相关政策';
} else if (nodeType === 'technology') {
nodeName = '技术创新';
} else if (nodeType === 'market') {
nodeName = '市场需求';
} else {
nodeName = `节点${i}`;
}
nodes.push({
id: i,
name: nodeName,
type: nodeType,
extra: { description: `${nodeName}相关信息` }
});
// 创建与主事件或其他节点的连接
const targetId = i === 2 ? 1 : Math.max(1, Math.floor(Math.random() * (i - 1)) + 1);
edges.push({
source: targetId,
target: i,
impact: impactTypes[i % impactTypes.length],
strength: strengthLevels[i % strengthLevels.length],
description: `传导路径${i}`
});
}
return { nodes, edges };
}
/**
* 生成动态新闻事件(实时要闻·动态追踪专用)
* @param {Object} timeRange - 时间范围 { startTime, endTime }
* @param {number} count - 生成事件数量默认30条
* @returns {Array} - 事件列表
*/
export function generateDynamicNewsEvents(timeRange = null, count = 30) {
const events = [];
const importanceLevels = ['S', 'A', 'B', 'C'];
// 如果没有提供时间范围默认生成最近24小时的事件
let startTime, endTime;
if (timeRange) {
startTime = new Date(timeRange.startTime);
endTime = new Date(timeRange.endTime);
} else {
endTime = new Date();
startTime = new Date(endTime.getTime() - 24 * 60 * 60 * 1000); // 24小时前
}
// 计算时间跨度(毫秒)
const timeSpan = endTime.getTime() - startTime.getTime();
for (let i = 0; i < count; i++) {
const industry = industries[i % industries.length];
const imp = importanceLevels[i % importanceLevels.length];
const eventType = eventTypes[i % eventTypes.length];
// 在时间范围内随机生成事件时间
const randomOffset = Math.random() * timeSpan;
const createdAt = new Date(startTime.getTime() + randomOffset);
// 生成随机热度和收益率
const hotScore = Math.max(60, 100 - i * 1.2); // 动态新闻热度更高
const relatedAvgChg = (Math.random() * 15 - 3).toFixed(2); // -3% 到 12%
const relatedMaxChg = (Math.random() * 25).toFixed(2); // 0% 到 25%
const relatedWeekChg = (Math.random() * 30 - 10).toFixed(2); // -10% 到 20%
// 为每个事件随机选择2-5个相关股票完整对象
const relatedStockCount = 2 + (i % 4);
const relatedStocks = [];
const industryStocks = stockPool.filter(s => s.industry === industry);
const relationDescriptions = [
'直接受益标的',
'产业链上游企业',
'产业链下游企业',
'行业龙头企业',
'潜在受益标的',
'概念相关个股'
];
// 优先选择同行业股票
if (industryStocks.length > 0) {
for (let j = 0; j < Math.min(relatedStockCount, industryStocks.length); j++) {
const stock = industryStocks[j % industryStocks.length];
relatedStocks.push({
stock_code: stock.stock_code,
stock_name: stock.name,
relation_desc: relationDescriptions[j % relationDescriptions.length]
});
}
}
// 如果同行业股票不够,从整个 stockPool 中补充
while (relatedStocks.length < relatedStockCount && relatedStocks.length < stockPool.length) {
const randomStock = stockPool[relatedStocks.length % stockPool.length];
if (!relatedStocks.some(s => s.stock_code === randomStock.stock_code)) {
relatedStocks.push({
stock_code: randomStock.stock_code,
stock_name: randomStock.name,
relation_desc: relationDescriptions[relatedStocks.length % relationDescriptions.length]
});
}
}
events.push({
id: `dynamic_${i + 1}`,
title: generateEventTitle(industry, i),
description: generateEventDescription(industry, imp, i),
content: generateEventDescription(industry, imp, i),
event_type: eventType,
importance: imp,
status: 'published',
created_at: createdAt.toISOString(),
updated_at: createdAt.toISOString(),
hot_score: hotScore,
view_count: Math.floor(Math.random() * 5000) + 1000, // 1000-6000 浏览量
follower_count: Math.floor(Math.random() * 500) + 50, // 50-550 关注数
post_count: Math.floor(Math.random() * 100) + 10, // 10-110 帖子数
related_avg_chg: parseFloat(relatedAvgChg),
related_max_chg: parseFloat(relatedMaxChg),
related_week_chg: parseFloat(relatedWeekChg),
keywords: generateKeywords(industry, i),
is_ai_generated: i % 3 === 0, // 33% 的事件是AI生成
industry: industry,
related_stocks: relatedStocks,
historical_events: generateHistoricalEvents(industry, i),
transmission_chain: generateTransmissionChain(industry, i),
creator: {
username: authorPool[i % authorPool.length],
avatar_url: null
}
});
}
// 按时间倒序排序(最新的在前)
events.sort((a, b) => new Date(b.created_at) - new Date(a.created_at));
return events;
}