feat: 添加事件详情面板
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user