import React from 'react';
import { formatDateTime } from '../../utils/formatters';
function renderFreshness(freshness) {
if (!freshness || typeof freshness !== 'object') return null;
const lastFetch = freshness.last_news_fetch || '-';
return `新闻更新到 ${lastFetch}${freshness.refreshed ? ' · 本次已刷新' : ''}`;
}
function categoryLabel(value) {
const normalized = String(value || '').trim().toLowerCase();
const labels = {
market: '市场交易',
policy: '政策监管',
earnings: '业绩财报',
product_tech: '产品技术',
competition: '竞争格局',
management: '管理层动态',
};
return labels[normalized] || value || '';
}
function relevanceLabel(value) {
const normalized = String(value || '').trim().toLowerCase();
const labels = {
high: '高相关',
medium: '中相关',
low: '低相关',
relevant: '高相关',
};
return labels[normalized] || value || '';
}
function analysisSourceLabel(value) {
const normalized = String(value || '').trim().toLowerCase();
if (normalized === 'llm') return 'LLM分析';
if (normalized === 'local') return '规则分析';
return value || '';
}
function sentimentStyle(sentiment) {
const normalized = String(sentiment || '').trim().toLowerCase();
if (normalized === 'positive') {
return { border: '#16a34a', background: '#f0fdf4', color: '#166534', label: '利多' };
}
if (normalized === 'negative') {
return { border: '#dc2626', background: '#fef2f2', color: '#991b1b', label: '利空' };
}
return { border: '#6b7280', background: '#f9fafb', color: '#4b5563', label: '中性' };
}
export default function ExplainNewsSection({
newsSnapshot,
visibleNewsByCategory,
visibleNews,
selectedNewsFreshness,
activeNewsCategory,
onSelectNewsCategory,
activeNewsSentiment,
onSelectNewsSentiment,
newsCategories,
tickerNews,
isOpen,
onToggle,
}) {
return (
新闻面板
{newsSnapshot?.source ? `最近 ${visibleNewsByCategory.length} 条 · ${newsSnapshot.source}` : `最近 ${visibleNewsByCategory.length} 条真实新闻`}
{renderFreshness(selectedNewsFreshness) ? (
{renderFreshness(selectedNewsFreshness)}
) : null}
{!isOpen ? (
新闻面板已收起,需要时再展开查看分类、情绪和新闻卡片。
) : (
<>
{Object.entries(newsCategories)
.filter(([, meta]) => Number(meta?.count || 0) > 0)
.map(([key, meta]) => {
const isActive = activeNewsCategory === key;
const pos = Number(meta?.positive_ids?.length || 0);
const neg = Number(meta?.negative_ids?.length || 0);
return (
);
})}
{[
{ key: 'all', label: '全部情绪' },
{ key: 'positive', label: '利多' },
{ key: 'negative', label: '利空' },
{ key: 'neutral', label: '中性' }
].map((item) => {
const isActive = activeNewsSentiment === item.key;
return (
);
})}
{tickerNews.length === 0 ? (
当前数据源没有返回相关新闻
) : (
{visibleNewsByCategory.map((item) => (
{(() => {
const sentimentMeta = sentimentStyle(item.sentiment);
return (
{sentimentMeta.label}
{item.relevance ? (
{relevanceLabel(item.relevance)}
) : null}
{item.analysisSource ? (
{analysisSourceLabel(item.analysisSource)}
) : null}
{item.analysisModelLabel ? (
{item.analysisModelLabel}
) : null}
{typeof item.retT0 === 'number' ? (
= 0 ? '#15803d' : '#b91c1c', fontWeight: 700 }}>
T0 {item.retT0 >= 0 ? '+' : ''}{(item.retT0 * 100).toFixed(2)}%
) : null}
);
})()}
{item.category ? (
{categoryLabel(item.category)}
) : null}
{item.title}
{formatDateTime(item.date)}
{item.source}
{item.related ? (
关联: {item.related}
) : null}
{item.summary || '该新闻没有可用摘要。'}
{item.keyDiscussion ? (
核心讨论: {item.keyDiscussion}
) : null}
{item.reasonGrowth ? (
利多逻辑: {item.reasonGrowth}
) : null}
{item.reasonDecrease ? (
利空逻辑: {item.reasonDecrease}
) : null}
{item.url ? (
) : null}
))}
)}
>
)}
);
}