// src/views/Company/components/CompanyOverview/NewsEventsTab.js // 新闻动态 Tab - 相关新闻事件列表 + 分页 import React from "react"; import { Box, VStack, HStack, Text, Badge, Icon, Card, CardBody, Button, Input, InputGroup, InputLeftElement, Tag, Center, Spinner, } from "@chakra-ui/react"; import { SearchIcon } from "@chakra-ui/icons"; import { FaNewspaper, FaBullhorn, FaGavel, FaFlask, FaDollarSign, FaShieldAlt, FaFileAlt, FaIndustry, FaEye, FaFire, FaChartLine, FaChevronLeft, FaChevronRight, } from "react-icons/fa"; // 黑金主题配色 const THEME_PRESETS = { blackGold: { bg: "#0A0E17", cardBg: "#1A1F2E", cardHoverBg: "#212633", cardBorder: "rgba(212, 175, 55, 0.2)", cardHoverBorder: "#D4AF37", textPrimary: "#E8E9ED", textSecondary: "#A0A4B8", textMuted: "#6B7280", gold: "#D4AF37", goldLight: "#FFD54F", inputBg: "#151922", inputBorder: "#2D3748", buttonBg: "#D4AF37", buttonText: "#0A0E17", buttonHoverBg: "#FFD54F", badgeS: { bg: "rgba(255, 195, 0, 0.2)", color: "#FFD54F" }, badgeA: { bg: "rgba(249, 115, 22, 0.2)", color: "#FB923C" }, badgeB: { bg: "rgba(59, 130, 246, 0.2)", color: "#60A5FA" }, badgeC: { bg: "rgba(107, 114, 128, 0.2)", color: "#9CA3AF" }, tagBg: "rgba(212, 175, 55, 0.15)", tagColor: "#D4AF37", spinnerColor: "#D4AF37", }, default: { bg: "white", cardBg: "white", cardHoverBg: "gray.50", cardBorder: "gray.200", cardHoverBorder: "blue.300", textPrimary: "gray.800", textSecondary: "gray.600", textMuted: "gray.500", gold: "blue.500", goldLight: "blue.400", inputBg: "white", inputBorder: "gray.200", buttonBg: "blue.500", buttonText: "white", buttonHoverBg: "blue.600", badgeS: { bg: "red.100", color: "red.600" }, badgeA: { bg: "orange.100", color: "orange.600" }, badgeB: { bg: "yellow.100", color: "yellow.600" }, badgeC: { bg: "green.100", color: "green.600" }, tagBg: "cyan.50", tagColor: "cyan.600", spinnerColor: "blue.500", }, }; /** * 新闻动态 Tab 组件 * * Props: * - newsEvents: 新闻事件列表数组 * - newsLoading: 加载状态 * - newsPagination: 分页信息 { page, per_page, total, pages, has_next, has_prev } * - searchQuery: 搜索关键词 * - onSearchChange: 搜索输入回调 (value) => void * - onSearch: 搜索提交回调 () => void * - onPageChange: 分页回调 (page) => void * - cardBg: 卡片背景色 * - themePreset: 主题预设 'blackGold' | 'default' */ const NewsEventsTab = ({ newsEvents = [], newsLoading = false, newsPagination = { page: 1, per_page: 10, total: 0, pages: 0, has_next: false, has_prev: false, }, searchQuery = "", onSearchChange, onSearch, onPageChange, cardBg, themePreset = "default", }) => { // 获取主题配色 const theme = THEME_PRESETS[themePreset] || THEME_PRESETS.default; const isBlackGold = themePreset === "blackGold"; // 事件类型图标映射 const getEventTypeIcon = (eventType) => { const iconMap = { 企业公告: FaBullhorn, 政策: FaGavel, 技术突破: FaFlask, 企业融资: FaDollarSign, 政策监管: FaShieldAlt, 政策动态: FaFileAlt, 行业事件: FaIndustry, }; return iconMap[eventType] || FaNewspaper; }; // 重要性颜色映射 - 根据主题返回不同配色 const getImportanceBadgeStyle = (importance) => { if (isBlackGold) { const styles = { S: theme.badgeS, A: theme.badgeA, B: theme.badgeB, C: theme.badgeC, }; return styles[importance] || { bg: "rgba(107, 114, 128, 0.2)", color: "#9CA3AF" }; } // 默认主题使用 colorScheme const colorMap = { S: "red", A: "orange", B: "yellow", C: "green", }; return { colorScheme: colorMap[importance] || "gray" }; }; // 处理搜索输入 const handleInputChange = (e) => { onSearchChange?.(e.target.value); }; // 处理搜索提交 const handleSearchSubmit = () => { onSearch?.(); }; // 处理键盘事件 const handleKeyPress = (e) => { if (e.key === "Enter") { handleSearchSubmit(); } }; // 处理分页 const handlePageChange = (page) => { onPageChange?.(page); // 滚动到列表顶部 document .getElementById("news-list-top") ?.scrollIntoView({ behavior: "smooth" }); }; // 渲染分页按钮 const renderPaginationButtons = () => { const { page: currentPage, pages: totalPages } = newsPagination; const pageButtons = []; // 显示当前页及前后各2页 let startPage = Math.max(1, currentPage - 2); let endPage = Math.min(totalPages, currentPage + 2); // 如果开始页大于1,显示省略号 if (startPage > 1) { pageButtons.push( ... ); } for (let i = startPage; i <= endPage; i++) { const isActive = i === currentPage; pageButtons.push( ); } // 如果结束页小于总页数,显示省略号 if (endPage < totalPages) { pageButtons.push( ... ); } return pageButtons; }; return ( {/* 搜索框和统计信息 */} {newsPagination.total > 0 && ( 共找到{" "} {newsPagination.total} {" "} 条新闻 )}
{/* 新闻列表 */} {newsLoading ? (
正在加载新闻...
) : newsEvents.length > 0 ? ( <> {newsEvents.map((event, idx) => { const importanceBadgeStyle = getImportanceBadgeStyle( event.importance ); const eventTypeIcon = getEventTypeIcon(event.event_type); return ( {/* 标题栏 */} {event.title} {/* 标签栏 */} {event.importance && ( {event.importance}级 )} {event.event_type && ( {event.event_type} )} {event.invest_score && ( 投资分: {event.invest_score} )} {event.keywords && event.keywords.length > 0 && ( <> {event.keywords .slice(0, 4) .map((keyword, kidx) => ( {typeof keyword === "string" ? keyword : keyword?.concept || keyword?.name || "未知"} ))} )} {/* 右侧信息栏 */} {event.created_at ? new Date( event.created_at ).toLocaleDateString("zh-CN", { year: "numeric", month: "2-digit", day: "2-digit", }) : ""} {event.view_count !== undefined && ( {event.view_count} )} {event.hot_score !== undefined && ( {event.hot_score.toFixed(1)} )} {event.creator && ( @{event.creator.username} )} {/* 描述 */} {event.description && ( {event.description} )} {/* 收益率数据 */} {(event.related_avg_chg !== null || event.related_max_chg !== null || event.related_week_chg !== null) && ( 相关涨跌: {event.related_avg_chg !== null && event.related_avg_chg !== undefined && ( 平均 0 ? "#EF4444" : "#10B981" } > {event.related_avg_chg > 0 ? "+" : ""} {event.related_avg_chg.toFixed(2)}% )} {event.related_max_chg !== null && event.related_max_chg !== undefined && ( 最大 0 ? "#EF4444" : "#10B981" } > {event.related_max_chg > 0 ? "+" : ""} {event.related_max_chg.toFixed(2)}% )} {event.related_week_chg !== null && event.related_week_chg !== undefined && ( 0 ? "#EF4444" : "#10B981" } > {event.related_week_chg > 0 ? "+" : ""} {event.related_week_chg.toFixed(2)}% )} )} ); })} {/* 分页控件 */} {newsPagination.pages > 1 && ( {/* 分页信息 */} 第 {newsPagination.page} / {newsPagination.pages} 页 {/* 分页按钮 */} {/* 页码按钮 */} {renderPaginationButtons()} )} ) : (
暂无相关新闻 {searchQuery ? "尝试修改搜索关键词" : "该公司暂无新闻动态"}
)} ); }; export default NewsEventsTab;