diff --git a/src/views/Community/components/EventCard/HorizontalDynamicNewsEventCard.js b/src/views/Community/components/EventCard/HorizontalDynamicNewsEventCard.js index c182a738..b8afacfd 100644 --- a/src/views/Community/components/EventCard/HorizontalDynamicNewsEventCard.js +++ b/src/views/Community/components/EventCard/HorizontalDynamicNewsEventCard.js @@ -252,17 +252,17 @@ const HorizontalDynamicNewsEventCard = React.memo(({ - {/* 第二行:涨跌幅数据 + 互动指标 */} - - + {/* 第二行:涨跌幅数据 */} + - {/* 互动指标:浏览量、关注数、看多/看空 */} - {showEngagement && ( + {/* 第三行:互动指标 - 独立一行更醒目 */} + {showEngagement && ( + - )} - + + )} diff --git a/src/views/Community/components/EventCard/atoms/EventEngagement.js b/src/views/Community/components/EventCard/atoms/EventEngagement.js index 80fefb5d..b2c3fcaf 100644 --- a/src/views/Community/components/EventCard/atoms/EventEngagement.js +++ b/src/views/Community/components/EventCard/atoms/EventEngagement.js @@ -4,12 +4,12 @@ import React, { useState, useCallback } from 'react'; import { HStack, + VStack, Box, Text, Tooltip, - IconButton, - Badge, useToast, + Flex, } from '@chakra-ui/react'; import { ViewIcon, StarIcon } from '@chakra-ui/icons'; import { TbArrowBigUp, TbArrowBigDown, TbArrowBigUpFilled, TbArrowBigDownFilled } from 'react-icons/tb'; @@ -18,8 +18,6 @@ import { useAuth } from '@contexts/AuthContext'; /** * 格式化数字(大于1000显示为 1k, 1.2k 等) - * @param {number} num - 原始数字 - * @returns {string} 格式化后的字符串 */ const formatCount = (num) => { if (num == null || isNaN(num)) return '0'; @@ -29,17 +27,7 @@ const formatCount = (num) => { }; /** - * 事件互动组件 - * @param {Object} props - * @param {number} props.eventId - 事件ID - * @param {number} props.viewCount - 浏览量 - * @param {number} props.followerCount - 关注数 - * @param {number} props.bullishCount - 看多数 - * @param {number} props.bearishCount - 看空数 - * @param {string} props.userVote - 用户当前投票状态 ('bullish' | 'bearish' | null) - * @param {string} props.size - 尺寸 ('xs' | 'sm' | 'md') - * @param {boolean} props.showVoting - 是否显示投票功能 - * @param {Function} props.onVoteChange - 投票变化回调 + * 事件互动组件 - 精美设计版 */ const EventEngagement = ({ eventId, @@ -55,7 +43,6 @@ const EventEngagement = ({ const toast = useToast(); const { isLoggedIn } = useAuth(); - // 本地状态管理(乐观更新) const [localVote, setLocalVote] = useState(userVote); const [localBullish, setLocalBullish] = useState(bullishCount); const [localBearish, setLocalBearish] = useState(bearishCount); @@ -63,16 +50,12 @@ const EventEngagement = ({ // 尺寸配置 const sizeConfig = { - xs: { fontSize: '10px', iconSize: '12px', spacing: 1, btnSize: 'xs' }, - sm: { fontSize: 'xs', iconSize: '14px', spacing: 1.5, btnSize: 'xs' }, - md: { fontSize: 'sm', iconSize: '16px', spacing: 2, btnSize: 'sm' }, + xs: { fontSize: '10px', iconSize: 12, spacing: 1.5, pillPx: 2, pillPy: 0.5 }, + sm: { fontSize: '11px', iconSize: 14, spacing: 2, pillPx: 2.5, pillPy: 1 }, + md: { fontSize: '12px', iconSize: 16, spacing: 2.5, pillPx: 3, pillPy: 1.5 }, }; const config = sizeConfig[size] || sizeConfig.sm; - /** - * 处理投票 - * @param {string} voteType - 'bullish' | 'bearish' - */ const handleVote = useCallback(async (voteType) => { if (!isLoggedIn) { toast({ @@ -88,22 +71,16 @@ const EventEngagement = ({ if (isVoting) return; setIsVoting(true); - // 计算新的投票状态 const newVote = localVote === voteType ? null : voteType; const oldVote = localVote; - // 乐观更新本地状态 setLocalVote(newVote); - // 更新计数 let newBullish = localBullish; let newBearish = localBearish; - // 取消之前的投票 if (oldVote === 'bullish') newBullish--; if (oldVote === 'bearish') newBearish--; - - // 添加新投票 if (newVote === 'bullish') newBullish++; if (newVote === 'bearish') newBearish++; @@ -124,14 +101,12 @@ const EventEngagement = ({ throw new Error(data.error || '投票失败'); } - // 使用服务器返回的准确数据 if (data.data) { setLocalBullish(data.data.bullish_count ?? newBullish); setLocalBearish(data.data.bearish_count ?? newBearish); setLocalVote(data.data.user_vote); } - // 触发回调 onVoteChange?.({ eventId, userVote: data.data?.user_vote, @@ -141,7 +116,6 @@ const EventEngagement = ({ } catch (error) { console.error('投票失败:', error); - // 回滚状态 setLocalVote(oldVote); setLocalBullish(bullishCount); setLocalBearish(bearishCount); @@ -158,92 +132,158 @@ const EventEngagement = ({ } }, [eventId, isLoggedIn, isVoting, localVote, localBullish, localBearish, bullishCount, bearishCount, toast, onVoteChange]); - // 计算看多比例(用于显示) const totalVotes = localBullish + localBearish; const bullishRatio = totalVotes > 0 ? Math.round((localBullish / totalVotes) * 100) : 50; return ( e.stopPropagation()}> - {/* 浏览量 */} + {/* 浏览量 - 精美胶囊样式 */} - - - {formatCount(viewCount)} + + + + {formatCount(viewCount)} + - {/* 关注数 */} + {/* 关注数 - 带星星图标 */} - - - {formatCount(followerCount)} + + + + {formatCount(followerCount)} + - {/* 看多/看空投票 */} + {/* 看多/看空投票区 - 精美设计 */} {showVoting && ( - + {/* 看多按钮 */} - handleVote('bullish')} + disabled={isVoting} + borderRightWidth="1px" + borderColor="whiteAlpha.200" + > + {localVote === 'bullish' ? : } - onClick={() => handleVote('bullish')} - isLoading={isVoting} - aria-label="看多" - minW="auto" - h="auto" - p={0.5} - color={localVote === 'bullish' ? 'red.400' : 'gray.400'} - _hover={{ color: 'red.400', bg: 'rgba(239, 68, 68, 0.1)' }} - /> + + {formatCount(localBullish)} + + - {/* 投票比例显示 */} + {/* 比例指示条 - 中间显示 */} {totalVotes > 0 && ( - = 50 ? 'rgba(239, 68, 68, 0.15)' : 'rgba(16, 185, 129, 0.15)'} - color={bullishRatio >= 50 ? 'red.400' : 'green.400'} - fontWeight="medium" + - {bullishRatio}% - + {/* 背景进度条 */} + = 50 ? 'rgba(239, 68, 68, 0.2)' : 'rgba(16, 185, 129, 0.2)'} + transition="width 0.3s ease" + /> + = 50 ? 'red.400' : 'green.400'} + position="relative" + zIndex={1} + > + {bullishRatio}% + + )} {/* 看空按钮 */} - handleVote('bearish')} + disabled={isVoting} + borderLeftWidth={totalVotes > 0 ? '1px' : 0} + borderColor="whiteAlpha.200" + > + {localVote === 'bearish' ? : } - onClick={() => handleVote('bearish')} - isLoading={isVoting} - aria-label="看空" - minW="auto" - h="auto" - p={0.5} - color={localVote === 'bearish' ? 'green.400' : 'gray.400'} - _hover={{ color: 'green.400', bg: 'rgba(16, 185, 129, 0.1)' }} - /> + + {formatCount(localBearish)} + + )}