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:
zdl
2025-12-09 13:16:43 +08:00
parent aac031f17c
commit 44fcef5eae
47 changed files with 409 additions and 76 deletions

View File

@@ -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;