feat: 添加事件详情面板

This commit is contained in:
zdl
2025-10-31 14:38:43 +08:00
parent c372832f1f
commit 9fd9fcb731
3 changed files with 346 additions and 7 deletions

View File

@@ -817,6 +817,105 @@ export function generatePopularKeywords(limit = 20) {
}));
}
/**
* 生成历史事件对比数据
* @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 }
@@ -855,23 +954,40 @@ export function generateDynamicNewsEvents(timeRange = null, count = 30) {
const relatedMaxChg = (Math.random() * 25).toFixed(2); // 0% 到 25%
const relatedWeekChg = (Math.random() * 30 - 10).toFixed(2); // -10% 到 20%
// 为每个事件随机选择2-5个相关股票
// 为每个事件随机选择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++) {
relatedStocks.push(industryStocks[j % industryStocks.length].stock_code);
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.includes(randomStock.stock_code)) {
relatedStocks.push(randomStock.stock_code);
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]
});
}
}
@@ -896,6 +1012,8 @@ export function generateDynamicNewsEvents(timeRange = null, count = 30) {
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