✅ StockChangeIndicators 组件优化 - 调整 padding 使布局更紧凑 - 修复窄卡片中的折行问题 - 自动根据内容调整宽度 ✅ 重要性等级视觉优化 - 统一使用红色系(S→A→B→C:从深红到浅红) - 添加 badgeBg 字段支持新的角标样式 ✅ DynamicNewsEventCard 卡片改版 - 左上角矩形角标显示重要性(镂空边框样式) - 悬浮显示所有等级说明 - 标题限制两行显示 ✅ Mock 数据完整性 - 添加缺失的 related_week_chg 字段 - 确保三个涨跌幅指标数据完整
1181 lines
57 KiB
JavaScript
1181 lines
57 KiB
JavaScript
// 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;
|
||
}
|