事件中心UI优化

This commit is contained in:
2025-11-07 10:31:42 +08:00
parent 663d73609a
commit 2a122b0013
3 changed files with 216 additions and 27 deletions

View File

@@ -0,0 +1,137 @@
// src/views/Community/components/DynamicNewsDetail/CompactStockItem.js
// 精简模式股票卡片组件(浮动卡片样式)
import React from 'react';
import {
Box,
Text,
Tooltip,
useColorModeValue,
} from '@chakra-ui/react';
/**
* 精简模式股票卡片组件
* @param {Object} props
* @param {Object} props.stock - 股票对象
* @param {Object} props.quote - 股票行情数据(可选)
*/
const CompactStockItem = ({ stock, quote = null }) => {
const nameColor = useColorModeValue('gray.700', 'gray.300');
const handleViewDetail = () => {
const stockCode = stock.stock_code.split('.')[0];
window.open(`https://valuefrontier.cn/company?scode=${stockCode}`, '_blank');
};
// 格式化涨跌幅显示
const formatChange = (value) => {
if (value === null || value === undefined || isNaN(value)) return '--';
const prefix = value > 0 ? '+' : '';
return `${prefix}${parseFloat(value).toFixed(2)}%`;
};
// 获取涨跌幅颜色(涨红跌绿)
const getChangeColor = (value) => {
const num = parseFloat(value);
if (isNaN(num) || num === 0) return 'gray.500';
return num > 0 ? 'red.500' : 'green.500';
};
// 获取背景渐变色(涨红跌绿)
const getBackgroundGradient = (value) => {
const num = parseFloat(value);
if (isNaN(num) || num === 0) {
return 'linear(to-br, gray.50, gray.100)';
}
return num > 0
? 'linear(to-br, red.50, red.100)'
: 'linear(to-br, green.50, green.100)';
};
// 获取边框颜色
const getBorderColor = (value) => {
const num = parseFloat(value);
if (isNaN(num) || num === 0) return 'gray.300';
return num > 0 ? 'red.300' : 'green.300';
};
// 获取涨跌幅数据(优先使用 quotefallback 到 stock
const change = quote?.change ?? stock.daily_change ?? null;
return (
<Tooltip
label={`${stock.stock_name} - 点击查看详情`}
placement="top"
hasArrow
bg="gray.700"
color="white"
fontSize="xs"
>
<Box
bgGradient={getBackgroundGradient(change)}
borderWidth="3px"
borderColor={getBorderColor(change)}
borderRadius="2xl"
p={4}
onClick={handleViewDetail}
cursor="pointer"
boxShadow="lg"
position="relative"
overflow="hidden"
_before={{
content: '""',
position: 'absolute',
top: 0,
left: 0,
right: 0,
height: '4px',
bg: getBorderColor(change),
}}
_hover={{
boxShadow: '2xl',
transform: 'translateY(-4px) scale(1.02)',
}}
transition="all 0.3s ease-in-out"
display="inline-block"
minW="150px"
>
{/* 股票代码 */}
<Text
fontSize="md"
fontWeight="bold"
color={getChangeColor(change)}
mb={2}
textAlign="center"
>
{stock.stock_code}
</Text>
{/* 涨跌幅 - 超大号显示 */}
<Text
fontSize="3xl"
fontWeight="black"
color={getChangeColor(change)}
textAlign="center"
lineHeight="1"
textShadow="0 1px 2px rgba(0,0,0,0.1)"
>
{formatChange(change)}
</Text>
{/* 股票名称(小字) */}
<Text
fontSize="xs"
color={nameColor}
mt={2}
textAlign="center"
noOfLines={1}
fontWeight="medium"
>
{stock.stock_name}
</Text>
</Box>
</Tooltip>
);
};
export default CompactStockItem;

View File

@@ -1,11 +1,18 @@
// src/views/Community/components/DynamicNewsDetail/RelatedStocksSection.js
// 相关股票列表区组件(纯内容,不含标题)
import React from 'react';
import React, { useState } from 'react';
import {
VStack,
Flex,
Button,
ButtonGroup,
Wrap,
WrapItem,
} from '@chakra-ui/react';
import { ViewIcon, ViewOffIcon } from '@chakra-ui/icons';
import StockListItem from './StockListItem';
import CompactStockItem from './CompactStockItem';
/**
* 相关股票列表区组件(纯内容部分)
@@ -23,12 +30,40 @@ const RelatedStocksSection = ({
watchlistSet = new Set(),
onWatchlistToggle
}) => {
// 显示模式:'detail' 详情模式, 'compact' 精简模式
const [viewMode, setViewMode] = useState('detail');
// 如果没有股票数据,不渲染
if (!stocks || stocks.length === 0) {
return null;
}
return (
<VStack align="stretch" spacing={4}>
{/* 模式切换按钮 */}
<Flex justify="flex-end">
<ButtonGroup size="sm" isAttached variant="outline">
<Button
leftIcon={<ViewIcon />}
colorScheme={viewMode === 'detail' ? 'blue' : 'gray'}
variant={viewMode === 'detail' ? 'solid' : 'outline'}
onClick={() => setViewMode('detail')}
>
详情模式
</Button>
<Button
leftIcon={<ViewOffIcon />}
colorScheme={viewMode === 'compact' ? 'blue' : 'gray'}
variant={viewMode === 'compact' ? 'solid' : 'outline'}
onClick={() => setViewMode('compact')}
>
精简模式
</Button>
</ButtonGroup>
</Flex>
{/* 详情模式 */}
{viewMode === 'detail' && (
<VStack align="stretch" spacing={3}>
{stocks.map((stock, index) => (
<StockListItem
@@ -41,6 +76,22 @@ const RelatedStocksSection = ({
/>
))}
</VStack>
)}
{/* 精简模式 */}
{viewMode === 'compact' && (
<Wrap spacing={4}>
{stocks.map((stock, index) => (
<WrapItem key={index}>
<CompactStockItem
stock={stock}
quote={quotes[stock.stock_code]}
/>
</WrapItem>
))}
</Wrap>
)}
</VStack>
);
};

View File

@@ -126,13 +126,14 @@ const StockListItem = ({
>
{/* 单行紧凑布局:名称+涨跌幅 | 分时图 | K线图 | 关联描述 */}
<HStack spacing={3} align="stretch">
{/* 左侧:股票名称 + 涨跌幅(垂直排列) */}
{/* 左侧:股票名称 + 涨跌幅(垂直排列) - 收窄 */}
<VStack
align="stretch"
spacing={1}
minW="140px"
maxW="160px"
minW="100px"
maxW="120px"
justify="center"
flexShrink={0}
>
<Tooltip
label="点击查看股票详情"
@@ -143,7 +144,7 @@ const StockListItem = ({
fontSize="xs"
>
<Text
fontSize="md"
fontSize="sm"
fontWeight="bold"
color={codeColor}
noOfLines={1}
@@ -154,9 +155,9 @@ const StockListItem = ({
{stock.stock_name}
</Text>
</Tooltip>
<HStack spacing={2} align="center">
<HStack spacing={1} align="center">
<Text
fontSize="xl"
fontSize="lg"
fontWeight="bold"
color={getChangeColor(change)}
>
@@ -176,9 +177,9 @@ const StockListItem = ({
</HStack>
</VStack>
{/* 分时图 */}
{/* 分时图 - 固定宽度 */}
<Box
w="180px"
w="160px"
borderWidth="1px"
borderColor={useColorModeValue('blue.100', 'blue.700')}
borderRadius="md"
@@ -189,6 +190,7 @@ const StockListItem = ({
setIsModalOpen(true);
}}
cursor="pointer"
flexShrink={0}
_hover={{
borderColor: useColorModeValue('blue.300', 'blue.500'),
boxShadow: 'sm'
@@ -209,9 +211,9 @@ const StockListItem = ({
/>
</Box>
{/* K线图 */}
{/* K线图 - 固定宽度 */}
<Box
w="180px"
w="160px"
borderWidth="1px"
borderColor={useColorModeValue('purple.100', 'purple.700')}
borderRadius="md"
@@ -222,6 +224,7 @@ const StockListItem = ({
setIsModalOpen(true);
}}
cursor="pointer"
flexShrink={0}
_hover={{
borderColor: useColorModeValue('purple.300', 'purple.500'),
boxShadow: 'sm'
@@ -242,7 +245,7 @@ const StockListItem = ({
/>
</Box>
{/* 关联描述(单行显示,点击展开) */}
{/* 关联描述(单行显示,点击展开)- 占据更多空间 */}
{relationText && relationText !== '--' && (
<Tooltip
label={isDescExpanded ? "点击收起" : "点击展开完整描述"}
@@ -269,10 +272,8 @@ const StockListItem = ({
}}
transition="background 0.2s"
>
<Text fontSize="xs" color={descColor} fontWeight="semibold" mb={1}>
关联描述
</Text>
<Collapse in={isDescExpanded} startingHeight={20}>
{/* 去掉"关联描述"标题 */}
<Collapse in={isDescExpanded} startingHeight={40}>
<Text
fontSize="sm"
color={nameColor}