事件中心UI优化
This commit is contained in:
@@ -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';
|
||||||
|
};
|
||||||
|
|
||||||
|
// 获取涨跌幅数据(优先使用 quote,fallback 到 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;
|
||||||
@@ -1,11 +1,18 @@
|
|||||||
// src/views/Community/components/DynamicNewsDetail/RelatedStocksSection.js
|
// src/views/Community/components/DynamicNewsDetail/RelatedStocksSection.js
|
||||||
// 相关股票列表区组件(纯内容,不含标题)
|
// 相关股票列表区组件(纯内容,不含标题)
|
||||||
|
|
||||||
import React from 'react';
|
import React, { useState } from 'react';
|
||||||
import {
|
import {
|
||||||
VStack,
|
VStack,
|
||||||
|
Flex,
|
||||||
|
Button,
|
||||||
|
ButtonGroup,
|
||||||
|
Wrap,
|
||||||
|
WrapItem,
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
|
import { ViewIcon, ViewOffIcon } from '@chakra-ui/icons';
|
||||||
import StockListItem from './StockListItem';
|
import StockListItem from './StockListItem';
|
||||||
|
import CompactStockItem from './CompactStockItem';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 相关股票列表区组件(纯内容部分)
|
* 相关股票列表区组件(纯内容部分)
|
||||||
@@ -23,23 +30,67 @@ const RelatedStocksSection = ({
|
|||||||
watchlistSet = new Set(),
|
watchlistSet = new Set(),
|
||||||
onWatchlistToggle
|
onWatchlistToggle
|
||||||
}) => {
|
}) => {
|
||||||
|
// 显示模式:'detail' 详情模式, 'compact' 精简模式
|
||||||
|
const [viewMode, setViewMode] = useState('detail');
|
||||||
|
|
||||||
// 如果没有股票数据,不渲染
|
// 如果没有股票数据,不渲染
|
||||||
if (!stocks || stocks.length === 0) {
|
if (!stocks || stocks.length === 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<VStack align="stretch" spacing={3}>
|
<VStack align="stretch" spacing={4}>
|
||||||
{stocks.map((stock, index) => (
|
{/* 模式切换按钮 */}
|
||||||
<StockListItem
|
<Flex justify="flex-end">
|
||||||
key={index}
|
<ButtonGroup size="sm" isAttached variant="outline">
|
||||||
stock={stock}
|
<Button
|
||||||
quote={quotes[stock.stock_code]}
|
leftIcon={<ViewIcon />}
|
||||||
eventTime={eventTime}
|
colorScheme={viewMode === 'detail' ? 'blue' : 'gray'}
|
||||||
isInWatchlist={watchlistSet.has(stock.stock_code)}
|
variant={viewMode === 'detail' ? 'solid' : 'outline'}
|
||||||
onWatchlistToggle={onWatchlistToggle}
|
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
|
||||||
|
key={index}
|
||||||
|
stock={stock}
|
||||||
|
quote={quotes[stock.stock_code]}
|
||||||
|
eventTime={eventTime}
|
||||||
|
isInWatchlist={watchlistSet.has(stock.stock_code)}
|
||||||
|
onWatchlistToggle={onWatchlistToggle}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</VStack>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* 精简模式 */}
|
||||||
|
{viewMode === 'compact' && (
|
||||||
|
<Wrap spacing={4}>
|
||||||
|
{stocks.map((stock, index) => (
|
||||||
|
<WrapItem key={index}>
|
||||||
|
<CompactStockItem
|
||||||
|
stock={stock}
|
||||||
|
quote={quotes[stock.stock_code]}
|
||||||
|
/>
|
||||||
|
</WrapItem>
|
||||||
|
))}
|
||||||
|
</Wrap>
|
||||||
|
)}
|
||||||
</VStack>
|
</VStack>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -126,13 +126,14 @@ const StockListItem = ({
|
|||||||
>
|
>
|
||||||
{/* 单行紧凑布局:名称+涨跌幅 | 分时图 | K线图 | 关联描述 */}
|
{/* 单行紧凑布局:名称+涨跌幅 | 分时图 | K线图 | 关联描述 */}
|
||||||
<HStack spacing={3} align="stretch">
|
<HStack spacing={3} align="stretch">
|
||||||
{/* 左侧:股票名称 + 涨跌幅(垂直排列) */}
|
{/* 左侧:股票名称 + 涨跌幅(垂直排列) - 收窄 */}
|
||||||
<VStack
|
<VStack
|
||||||
align="stretch"
|
align="stretch"
|
||||||
spacing={1}
|
spacing={1}
|
||||||
minW="140px"
|
minW="100px"
|
||||||
maxW="160px"
|
maxW="120px"
|
||||||
justify="center"
|
justify="center"
|
||||||
|
flexShrink={0}
|
||||||
>
|
>
|
||||||
<Tooltip
|
<Tooltip
|
||||||
label="点击查看股票详情"
|
label="点击查看股票详情"
|
||||||
@@ -143,7 +144,7 @@ const StockListItem = ({
|
|||||||
fontSize="xs"
|
fontSize="xs"
|
||||||
>
|
>
|
||||||
<Text
|
<Text
|
||||||
fontSize="md"
|
fontSize="sm"
|
||||||
fontWeight="bold"
|
fontWeight="bold"
|
||||||
color={codeColor}
|
color={codeColor}
|
||||||
noOfLines={1}
|
noOfLines={1}
|
||||||
@@ -154,9 +155,9 @@ const StockListItem = ({
|
|||||||
{stock.stock_name}
|
{stock.stock_name}
|
||||||
</Text>
|
</Text>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<HStack spacing={2} align="center">
|
<HStack spacing={1} align="center">
|
||||||
<Text
|
<Text
|
||||||
fontSize="xl"
|
fontSize="lg"
|
||||||
fontWeight="bold"
|
fontWeight="bold"
|
||||||
color={getChangeColor(change)}
|
color={getChangeColor(change)}
|
||||||
>
|
>
|
||||||
@@ -176,9 +177,9 @@ const StockListItem = ({
|
|||||||
</HStack>
|
</HStack>
|
||||||
</VStack>
|
</VStack>
|
||||||
|
|
||||||
{/* 分时图 */}
|
{/* 分时图 - 固定宽度 */}
|
||||||
<Box
|
<Box
|
||||||
w="180px"
|
w="160px"
|
||||||
borderWidth="1px"
|
borderWidth="1px"
|
||||||
borderColor={useColorModeValue('blue.100', 'blue.700')}
|
borderColor={useColorModeValue('blue.100', 'blue.700')}
|
||||||
borderRadius="md"
|
borderRadius="md"
|
||||||
@@ -189,6 +190,7 @@ const StockListItem = ({
|
|||||||
setIsModalOpen(true);
|
setIsModalOpen(true);
|
||||||
}}
|
}}
|
||||||
cursor="pointer"
|
cursor="pointer"
|
||||||
|
flexShrink={0}
|
||||||
_hover={{
|
_hover={{
|
||||||
borderColor: useColorModeValue('blue.300', 'blue.500'),
|
borderColor: useColorModeValue('blue.300', 'blue.500'),
|
||||||
boxShadow: 'sm'
|
boxShadow: 'sm'
|
||||||
@@ -209,9 +211,9 @@ const StockListItem = ({
|
|||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
{/* K线图 */}
|
{/* K线图 - 固定宽度 */}
|
||||||
<Box
|
<Box
|
||||||
w="180px"
|
w="160px"
|
||||||
borderWidth="1px"
|
borderWidth="1px"
|
||||||
borderColor={useColorModeValue('purple.100', 'purple.700')}
|
borderColor={useColorModeValue('purple.100', 'purple.700')}
|
||||||
borderRadius="md"
|
borderRadius="md"
|
||||||
@@ -222,6 +224,7 @@ const StockListItem = ({
|
|||||||
setIsModalOpen(true);
|
setIsModalOpen(true);
|
||||||
}}
|
}}
|
||||||
cursor="pointer"
|
cursor="pointer"
|
||||||
|
flexShrink={0}
|
||||||
_hover={{
|
_hover={{
|
||||||
borderColor: useColorModeValue('purple.300', 'purple.500'),
|
borderColor: useColorModeValue('purple.300', 'purple.500'),
|
||||||
boxShadow: 'sm'
|
boxShadow: 'sm'
|
||||||
@@ -242,7 +245,7 @@ const StockListItem = ({
|
|||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
{/* 关联描述(单行显示,点击展开) */}
|
{/* 关联描述(单行显示,点击展开)- 占据更多空间 */}
|
||||||
{relationText && relationText !== '--' && (
|
{relationText && relationText !== '--' && (
|
||||||
<Tooltip
|
<Tooltip
|
||||||
label={isDescExpanded ? "点击收起" : "点击展开完整描述"}
|
label={isDescExpanded ? "点击收起" : "点击展开完整描述"}
|
||||||
@@ -269,10 +272,8 @@ const StockListItem = ({
|
|||||||
}}
|
}}
|
||||||
transition="background 0.2s"
|
transition="background 0.2s"
|
||||||
>
|
>
|
||||||
<Text fontSize="xs" color={descColor} fontWeight="semibold" mb={1}>
|
{/* 去掉"关联描述"标题 */}
|
||||||
关联描述
|
<Collapse in={isDescExpanded} startingHeight={40}>
|
||||||
</Text>
|
|
||||||
<Collapse in={isDescExpanded} startingHeight={20}>
|
|
||||||
<Text
|
<Text
|
||||||
fontSize="sm"
|
fontSize="sm"
|
||||||
color={nameColor}
|
color={nameColor}
|
||||||
|
|||||||
Reference in New Issue
Block a user