refactor: Community 目录结构重组 + 修复导入路径 + 添加 Mock 数据
## 目录重构 - DynamicNewsCard/ → DynamicNews/(含 layouts/, hooks/ 子目录) - EventCard 原子组件 → EventCard/atoms/ - EventDetailModal 独立目录化 - HotEvents 独立目录化(含 CSS) - SearchFilters 独立目录化(CompactSearchBox, TradingTimeFilter) ## 导入路径修复 - EventCard/*.js: 统一使用 @constants/, @utils/, @components/ 别名 - atoms/*.js: 修复移动后的相对路径问题 - DynamicNewsCard.js: 更新 contexts, store, constants 导入 - EventHeaderInfo.js, CompactMetaBar.js: 修复 EventFollowButton 导入 ## Mock Handler 添加 - /api/events/:eventId/expectation-score - 事件超预期得分 - /api/index/:indexCode/realtime - 指数实时行情 ## 警告修复 - CitationMark.js: overlayInnerStyle → styles (Antd 5.x) - CitedContent.js: 移除不支持的 jsx 属性 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,190 @@
|
||||
// src/views/Community/components/DynamicNews/layouts/VerticalModeLayout.js
|
||||
// 纵向分栏模式布局组件
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import {
|
||||
Box,
|
||||
VStack,
|
||||
Flex,
|
||||
Center,
|
||||
Text,
|
||||
useBreakpointValue,
|
||||
useDisclosure
|
||||
} from '@chakra-ui/react';
|
||||
import { InfoIcon } from '@chakra-ui/icons';
|
||||
import HorizontalDynamicNewsEventCard from '../../EventCard/HorizontalDynamicNewsEventCard';
|
||||
import EventDetailScrollPanel from '../EventDetailScrollPanel';
|
||||
import EventDetailModal from '../../EventDetailModal';
|
||||
import PaginationControl from '../PaginationControl';
|
||||
|
||||
/**
|
||||
* 纵向分栏模式布局
|
||||
* 固定布局:左侧事件列表 3fr | 右侧详情 7fr
|
||||
*
|
||||
* @param {string} display - CSS display 属性(用于显示/隐藏组件)
|
||||
* @param {Array} events - 当前页的事件列表(分页数据)
|
||||
* @param {Object} selectedEvent - 当前选中的事件
|
||||
* @param {Function} onEventSelect - 事件选择回调
|
||||
* @param {Object} eventFollowStatus - 事件关注状态
|
||||
* @param {Function} onToggleFollow - 关注按钮回调
|
||||
* @param {Function} getTimelineBoxStyle - 时间线样式获取函数
|
||||
* @param {string} borderColor - 边框颜色
|
||||
* @param {number} currentPage - 当前页码
|
||||
* @param {number} totalPages - 总页数
|
||||
* @param {Function} onPageChange - 页码改变回调
|
||||
*/
|
||||
const VerticalModeLayout = React.memo(({
|
||||
display = 'flex',
|
||||
events,
|
||||
selectedEvent,
|
||||
onEventSelect,
|
||||
eventFollowStatus,
|
||||
onToggleFollow,
|
||||
getTimelineBoxStyle,
|
||||
borderColor,
|
||||
currentPage = 1,
|
||||
totalPages = 1,
|
||||
onPageChange,
|
||||
}) => {
|
||||
// 详情面板重置 key(预留,用于未来功能)
|
||||
const [detailPanelKey] = useState(0);
|
||||
|
||||
// 响应式布局
|
||||
const isMobile = useBreakpointValue({ base: true, lg: false });
|
||||
const flexDirection = useBreakpointValue({ base: 'column', lg: 'row' });
|
||||
const gap = useBreakpointValue({ base: 3, lg: 6 });
|
||||
|
||||
// 移动端模态框控制
|
||||
const { isOpen: isMobileModalOpen, onOpen: onMobileModalOpen, onClose: onMobileModalClose } = useDisclosure();
|
||||
const [mobileSelectedEvent, setMobileSelectedEvent] = useState(null);
|
||||
|
||||
// 处理移动端事件点击
|
||||
const handleMobileEventClick = (event) => {
|
||||
if (isMobile) {
|
||||
setMobileSelectedEvent(event);
|
||||
onMobileModalOpen();
|
||||
} else {
|
||||
onEventSelect(event);
|
||||
}
|
||||
};
|
||||
|
||||
// 固定布局比例:左侧(4),右侧(6)- 平衡布局,确保左侧有足够空间显示内容
|
||||
const leftFlex = '4';
|
||||
const rightFlex = '6';
|
||||
|
||||
return (
|
||||
<Flex
|
||||
display={display}
|
||||
direction={flexDirection}
|
||||
gap={gap}
|
||||
position="relative"
|
||||
transition="all 0.3s ease-in-out"
|
||||
h="100%"
|
||||
overflow="hidden"
|
||||
>
|
||||
{/* 左侧:事件列表 - 独立滚动 */}
|
||||
<Box
|
||||
flex={isMobile ? '1' : leftFlex}
|
||||
minWidth={0}
|
||||
w={isMobile ? '100%' : 'auto'}
|
||||
overflowY="auto"
|
||||
h="100%"
|
||||
data-event-list-container="true"
|
||||
css={{
|
||||
overscrollBehavior: 'contain',
|
||||
'&::-webkit-scrollbar': {
|
||||
width: '6px',
|
||||
},
|
||||
'&::-webkit-scrollbar-track': {
|
||||
background: '#f1f1f1',
|
||||
},
|
||||
'&::-webkit-scrollbar-thumb': {
|
||||
background: '#888',
|
||||
borderRadius: '3px',
|
||||
},
|
||||
'&::-webkit-scrollbar-thumb:hover': {
|
||||
background: '#555',
|
||||
},
|
||||
}}
|
||||
>
|
||||
{/* 事件列表 */}
|
||||
{events && events.length > 0 ? (
|
||||
<VStack
|
||||
spacing={2}
|
||||
align="stretch"
|
||||
p={2}
|
||||
>
|
||||
{events.map((event) => (
|
||||
<HorizontalDynamicNewsEventCard
|
||||
key={event.id}
|
||||
event={event}
|
||||
isSelected={selectedEvent?.id === event.id}
|
||||
onEventClick={() => handleMobileEventClick(event)}
|
||||
isFollowing={eventFollowStatus[event.id]?.isFollowing}
|
||||
followerCount={eventFollowStatus[event.id]?.followerCount}
|
||||
onToggleFollow={onToggleFollow}
|
||||
timelineStyle={getTimelineBoxStyle()}
|
||||
borderColor={borderColor}
|
||||
indicatorSize="default"
|
||||
layout="vertical"
|
||||
/>
|
||||
))}
|
||||
</VStack>
|
||||
) : (
|
||||
/* 空状态 */
|
||||
<Center h="100%" minH="400px">
|
||||
<VStack spacing={4}>
|
||||
<InfoIcon w={12} h={12} color="gray.400" />
|
||||
<Text fontSize="lg" color="gray.500" textAlign="center">
|
||||
当前筛选条件下暂无数据
|
||||
</Text>
|
||||
<Text fontSize="sm" color="gray.400" textAlign="center">
|
||||
请尝试调整筛选条件
|
||||
</Text>
|
||||
</VStack>
|
||||
</Center>
|
||||
)}
|
||||
|
||||
{/* 分页控制器 - 放在事件列表下方 */}
|
||||
{totalPages > 1 && onPageChange && (
|
||||
<Box pt={3} pb={1}>
|
||||
<PaginationControl
|
||||
currentPage={currentPage}
|
||||
totalPages={totalPages}
|
||||
onPageChange={onPageChange}
|
||||
/>
|
||||
</Box>
|
||||
)}
|
||||
</Box>
|
||||
|
||||
{/* 右侧:事件详情 - 独立滚动 - 移动端隐藏 */}
|
||||
{!isMobile && (
|
||||
<Box
|
||||
flex={rightFlex}
|
||||
minHeight={0}
|
||||
position="relative"
|
||||
overflow="hidden"
|
||||
h="100%"
|
||||
>
|
||||
{/* 详情面板 */}
|
||||
<EventDetailScrollPanel
|
||||
key={detailPanelKey}
|
||||
detailMode="no-header"
|
||||
selectedEvent={selectedEvent}
|
||||
/>
|
||||
</Box>
|
||||
)}
|
||||
|
||||
{/* 移动端详情弹窗 */}
|
||||
{isMobile && (
|
||||
<EventDetailModal
|
||||
open={isMobileModalOpen}
|
||||
onClose={onMobileModalClose}
|
||||
event={mobileSelectedEvent}
|
||||
/>
|
||||
)}
|
||||
</Flex>
|
||||
);
|
||||
});
|
||||
|
||||
export default VerticalModeLayout;
|
||||
Reference in New Issue
Block a user