Files
vf_react/src/views/Community/components/DynamicNewsDetail/RelatedConceptsSection/ConceptStockItem.js
zdl 39dc6a8a34 feat: 修复相关概念卡片跳转逻辑,支持跳转至概念中心
功能优化:
- 相关概念卡片点击跳转至概念中心(/concepts)并自动搜索该概念
- 概念相关股票支持点击跳转至公司详情页

组件修改:
- RelatedConceptsSection/index.js:
  * 修复 handleConceptClick 函数跳转路径
  * 从错误的 /concept/:name 改为正确的 /concepts?q=:name
  * 使用 encodeURIComponent 确保中文概念名称正确编码

- RelatedConceptsSection/ConceptStockItem.js:
  * 新增 handleStockClick 点击处理函数
  * 点击股票跳转至公司详情页(valuefrontier.cn/company)
  * 添加 hover 效果和过渡动画
  * 使用 stopPropagation 防止事件冒泡到概念卡片

跳转行为:
- 简单概念卡片(横向)→ 点击跳转到概念中心搜索结果页
- 详细概念卡片(展开后)→ 点击跳转到概念中心搜索结果页
- 概念相关股票 → 点击跳转到公司详情页(新标签页)

URL示例:
- 点击"人工智能"概念 → /concepts?q=人工智能
- 点击股票"000001.SZ" → valuefrontier.cn/company?scode=000001

用户体验提升:
- 概念卡片跳转逻辑符合用户预期
- 股票点击可查看公司详情,提供更多信息
- 事件冒泡控制正确,避免误触发

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-03 12:58:21 +08:00

80 lines
2.2 KiB
JavaScript

// src/views/Community/components/DynamicNewsDetail/RelatedConceptsSection/ConceptStockItem.js
// 概念股票列表项组件
import React from 'react';
import {
Box,
HStack,
Text,
Badge,
useColorModeValue,
} from '@chakra-ui/react';
/**
* 概念股票列表项组件
* @param {Object} props
* @param {Object} props.stock - 股票对象
* - stock_name: 股票名称
* - stock_code: 股票代码
* - change_pct: 涨跌幅
* - reason: 关联原因
*/
const ConceptStockItem = ({ stock }) => {
const sectionBg = useColorModeValue('gray.50', 'gray.750');
const conceptNameColor = useColorModeValue('gray.800', 'gray.100');
const stockCountColor = useColorModeValue('gray.500', 'gray.400');
const stockChangePct = parseFloat(stock.change_pct);
const stockChangeColor = stockChangePct > 0 ? 'red' : stockChangePct < 0 ? 'green' : 'gray';
const stockChangeSymbol = stockChangePct > 0 ? '+' : '';
// 处理股票详情跳转
const handleStockClick = (e) => {
e.stopPropagation(); // 阻止事件冒泡到概念卡片
const cleanCode = stock.stock_code.replace(/\.(SZ|SH)$/i, '');
window.open(`https://valuefrontier.cn/company?scode=${cleanCode}`, '_blank');
};
return (
<Box
p={2}
borderRadius="md"
bg={sectionBg}
fontSize="xs"
cursor="pointer"
onClick={handleStockClick}
_hover={{
bg: useColorModeValue('gray.100', 'gray.700'),
transform: 'translateX(4px)',
}}
transition="all 0.2s"
>
<HStack justify="space-between" mb={1}>
<HStack spacing={2}>
<Text fontWeight="semibold" color={conceptNameColor}>
{stock.stock_name}
</Text>
<Badge size="sm" variant="outline">
{stock.stock_code}
</Badge>
</HStack>
{stock.change_pct && (
<Badge
colorScheme={stockChangeColor}
fontSize="xs"
>
{stockChangeSymbol}{stockChangePct.toFixed(2)}%
</Badge>
)}
</HStack>
{stock.reason && (
<Text fontSize="xs" color={stockCountColor} mt={1} noOfLines={2}>
{stock.reason}
</Text>
)}
</Box>
);
};
export default ConceptStockItem;