186 lines
7.0 KiB
JavaScript
186 lines
7.0 KiB
JavaScript
// src/views/Community/components/PopularKeywords.js
|
||
import React, { useState, useEffect } from 'react';
|
||
import { Card, Tag, Space, Spin, Empty, Button } from 'antd';
|
||
import { FireOutlined, RightOutlined } from '@ant-design/icons';
|
||
|
||
const API_BASE_URL = process.env.NODE_ENV === 'production'
|
||
? '/concept-api'
|
||
: 'http://192.168.1.58:6801';
|
||
|
||
// 获取域名前缀
|
||
const DOMAIN_PREFIX = process.env.NODE_ENV === 'production'
|
||
? ''
|
||
: 'https://valuefrontier.cn';
|
||
|
||
const PopularKeywords = ({ onKeywordClick }) => {
|
||
const [keywords, setKeywords] = useState([]);
|
||
const [loading, setLoading] = useState(false);
|
||
|
||
// 加载热门概念(涨幅前20)
|
||
const loadPopularConcepts = async () => {
|
||
setLoading(true);
|
||
try {
|
||
const response = await fetch(`${API_BASE_URL}/search`, {
|
||
method: 'POST',
|
||
headers: {
|
||
'Content-Type': 'application/json',
|
||
},
|
||
body: JSON.stringify({
|
||
query: '', // 空查询获取所有概念
|
||
size: 20, // 获取前20个
|
||
page: 1,
|
||
sort_by: 'change_pct' // 按涨跌幅排序
|
||
})
|
||
});
|
||
|
||
const data = await response.json();
|
||
|
||
if (data.results) {
|
||
// 转换数据格式
|
||
const formattedData = data.results.map(item => ({
|
||
keyword: item.concept,
|
||
count: item.stock_count,
|
||
change_pct: item.price_info?.avg_change_pct || 0,
|
||
concept_id: item.concept_id
|
||
}));
|
||
setKeywords(formattedData);
|
||
}
|
||
} catch (error) {
|
||
console.error('Failed to load popular concepts:', error);
|
||
setKeywords([]);
|
||
} finally {
|
||
setLoading(false);
|
||
}
|
||
};
|
||
|
||
// 组件挂载时加载数据
|
||
useEffect(() => {
|
||
loadPopularConcepts();
|
||
}, []);
|
||
|
||
// 根据涨跌幅获取标签颜色
|
||
const getTagColor = (changePct) => {
|
||
if (changePct > 5) return 'red';
|
||
if (changePct > 3) return 'volcano';
|
||
if (changePct > 1) return 'orange';
|
||
if (changePct > 0) return 'gold';
|
||
if (changePct === 0) return 'default';
|
||
if (changePct > -1) return 'lime';
|
||
if (changePct > -3) return 'green';
|
||
if (changePct > -5) return 'cyan';
|
||
return 'blue';
|
||
};
|
||
|
||
// 格式化涨跌幅显示
|
||
const formatChangePct = (pct) => {
|
||
if (pct === null || pct === undefined) return '';
|
||
const formatted = pct.toFixed(2);
|
||
if (pct > 0) return `+${formatted}%`;
|
||
return `${formatted}%`;
|
||
};
|
||
|
||
// 处理概念标签点击 - 跳转到对应概念页面
|
||
const handleConceptClick = (concept) => {
|
||
// 如果原有的 onKeywordClick 存在,可以选择是否还要调用
|
||
// onKeywordClick && onKeywordClick(concept.keyword);
|
||
|
||
// 跳转到对应概念的页面
|
||
const url = `${DOMAIN_PREFIX}/htmls/${encodeURIComponent(concept.keyword)}.html`;
|
||
window.open(url, '_blank');
|
||
};
|
||
|
||
// 查看更多概念
|
||
const handleViewMore = () => {
|
||
const url = `${DOMAIN_PREFIX}/concepts`;
|
||
window.open(url, '_blank');
|
||
};
|
||
|
||
return (
|
||
<Card
|
||
title={
|
||
<span>
|
||
<FireOutlined style={{ marginRight: 8, color: '#ff4d4f' }} />
|
||
热门概念
|
||
</span>
|
||
}
|
||
className="popular-keywords"
|
||
style={{ marginBottom: 16 }}
|
||
extra={
|
||
<span style={{ fontSize: 12, color: '#999' }}>
|
||
涨幅TOP20
|
||
</span>
|
||
}
|
||
>
|
||
<Spin spinning={loading}>
|
||
{keywords && keywords.length > 0 ? (
|
||
<>
|
||
<Space size={[8, 8]} wrap style={{ marginBottom: 16 }}>
|
||
{keywords.map((item) => (
|
||
<Tag
|
||
key={item.concept_id}
|
||
color={getTagColor(item.change_pct)}
|
||
style={{
|
||
cursor: 'pointer',
|
||
marginBottom: 8,
|
||
padding: '2px 8px',
|
||
transition: 'all 0.3s'
|
||
}}
|
||
onClick={() => handleConceptClick(item)}
|
||
onMouseEnter={(e) => {
|
||
e.currentTarget.style.transform = 'scale(1.05)';
|
||
e.currentTarget.style.boxShadow = '0 2px 8px rgba(0,0,0,0.15)';
|
||
}}
|
||
onMouseLeave={(e) => {
|
||
e.currentTarget.style.transform = 'scale(1)';
|
||
e.currentTarget.style.boxShadow = 'none';
|
||
}}
|
||
>
|
||
<span>{item.keyword}</span>
|
||
<span style={{
|
||
marginLeft: 6,
|
||
fontWeight: 'bold'
|
||
}}>
|
||
{formatChangePct(item.change_pct)}
|
||
</span>
|
||
<span style={{
|
||
marginLeft: 4,
|
||
fontSize: 11,
|
||
opacity: 0.8
|
||
}}>
|
||
({item.count}股)
|
||
</span>
|
||
</Tag>
|
||
))}
|
||
</Space>
|
||
|
||
{/* 查看更多按钮 */}
|
||
<div style={{
|
||
borderTop: '1px solid #f0f0f0',
|
||
paddingTop: 12,
|
||
textAlign: 'center'
|
||
}}>
|
||
<Button
|
||
type="link"
|
||
onClick={handleViewMore}
|
||
style={{
|
||
color: '#1890ff',
|
||
fontWeight: 500
|
||
}}
|
||
>
|
||
查看更多概念
|
||
<RightOutlined style={{ fontSize: 12, marginLeft: 4 }} />
|
||
</Button>
|
||
</div>
|
||
</>
|
||
) : (
|
||
<Empty
|
||
description="暂无热门概念"
|
||
image={Empty.PRESENTED_IMAGE_SIMPLE}
|
||
/>
|
||
)}
|
||
</Spin>
|
||
</Card>
|
||
);
|
||
};
|
||
|
||
export default PopularKeywords; |