feat: 添加相关概念组件

This commit is contained in:
zdl
2025-10-31 20:08:53 +08:00
parent 57c4c3c959
commit fc251ede05
5 changed files with 456 additions and 0 deletions

View File

@@ -0,0 +1,122 @@
// src/views/Community/components/DynamicNewsDetail/RelatedConceptsSection/index.js
// 相关概念区组件(主组件)
import React, { useState } from 'react';
import {
Box,
SimpleGrid,
Flex,
Button,
Collapse,
Heading,
useColorModeValue,
} from '@chakra-ui/react';
import { ChevronDownIcon, ChevronUpIcon } from '@chakra-ui/icons';
import { useNavigate } from 'react-router-dom';
import SimpleConceptCard from './SimpleConceptCard';
import DetailedConceptCard from './DetailedConceptCard';
import TradingDateInfo from './TradingDateInfo';
/**
* 相关概念区组件
* @param {Object} props
* @param {Array<Object>} props.keywords - 相关概念数组
* - name: 概念名称
* - stock_count: 相关股票数量
* - relevance: 相关度0-100
* @param {string} props.effectiveTradingDate - 有效交易日期(涨跌幅数据日期)
* @param {string|Object} props.eventTime - 事件发生时间
*/
const RelatedConceptsSection = ({ keywords, effectiveTradingDate, eventTime }) => {
const [isExpanded, setIsExpanded] = useState(false);
const navigate = useNavigate();
// 颜色配置
const sectionBg = useColorModeValue('gray.50', 'gray.750');
const headingColor = useColorModeValue('gray.700', 'gray.200');
// 如果没有关键词,不渲染
if (!keywords || keywords.length === 0) {
return null;
}
/**
* 根据相关度获取颜色(浅色背景 + 深色文字)
* @param {number} relevance - 相关度0-100
* @returns {Object} 包含背景色和文字色
*/
const getRelevanceColor = (relevance) => {
if (relevance >= 90) {
return { bg: 'purple.50', color: 'purple.800' }; // 极高相关
} else if (relevance >= 80) {
return { bg: 'pink.50', color: 'pink.800' }; // 高相关
} else if (relevance >= 70) {
return { bg: 'orange.50', color: 'orange.800' }; // 中等相关
} else {
return { bg: 'gray.100', color: 'gray.700' }; // 低相关
}
};
/**
* 处理概念点击
* @param {Object} concept - 概念对象
*/
const handleConceptClick = (concept) => {
// 跳转到概念详情页
navigate(`/concept/${concept.name}`);
};
return (
<Box bg={sectionBg} p={3} borderRadius="md">
{/* 标题栏 */}
<Flex justify="space-between" align="center" mb={3}>
<Heading size="sm" color={headingColor}>
相关概念
</Heading>
<Button
size="sm"
variant="ghost"
colorScheme="blue"
rightIcon={isExpanded ? <ChevronUpIcon /> : <ChevronDownIcon />}
onClick={() => setIsExpanded(!isExpanded)}
>
{isExpanded ? '收起' : '查看详细描述'}
</Button>
</Flex>
{/* 简单模式:横向卡片列表(总是显示) */}
<Flex gap={2} flexWrap="wrap" mb={isExpanded ? 3 : 0}>
{keywords.map((concept, index) => (
<SimpleConceptCard
key={index}
concept={concept}
onClick={handleConceptClick}
getRelevanceColor={getRelevanceColor}
/>
))}
</Flex>
{/* 详细模式:卡片网格(可折叠) */}
<Collapse in={isExpanded} animateOpacity>
{/* 交易日期信息 */}
<TradingDateInfo
effectiveTradingDate={effectiveTradingDate}
eventTime={eventTime}
/>
{/* 详细概念卡片网格 */}
<SimpleGrid columns={{ base: 1, md: 2 }} spacing={4}>
{keywords.map((concept, index) => (
<DetailedConceptCard
key={index}
concept={concept}
onClick={handleConceptClick}
/>
))}
</SimpleGrid>
</Collapse>
</Box>
);
};
export default RelatedConceptsSection;