refactor(LimitAnalyse): 重构主页面布局与数据服务
- 整合市场全景、板块异动、高位股统计模块
- 状态提升实现板块点击联动(selectedSector)
- 更新 ztStaticService 静态数据服务:
- 添加缓存机制(dates 5分钟、daily 30分钟)
- 转换 stock_codes 为完整 stocks 对象
- 支持 sector_relations 板块关联数据
- 更新 Mock handlers:
- 完善 dates.json / daily/{date}.json 静态路径
- 添加 sector_relations 网络图数据生成
- 支持 chart_data 饼图数据结构
This commit is contained in:
@@ -2,45 +2,35 @@ import React, { useState, useEffect } from 'react';
|
||||
import {
|
||||
Box,
|
||||
VStack,
|
||||
HStack,
|
||||
Heading,
|
||||
Text,
|
||||
Badge,
|
||||
useToast,
|
||||
Skeleton,
|
||||
IconButton,
|
||||
Flex,
|
||||
useColorModeValue,
|
||||
SimpleGrid,
|
||||
Tooltip,
|
||||
Card,
|
||||
CardBody,
|
||||
Alert,
|
||||
AlertIcon,
|
||||
} from '@chakra-ui/react';
|
||||
import { RefreshCw, ChevronUp } from 'lucide-react';
|
||||
|
||||
// 导入拆分的组件
|
||||
// 注意:在实际使用中,这些组件应该被拆分到独立的文件中
|
||||
// 这里为了演示,我们假设它们已经被正确导出
|
||||
import { GLASS_BLUR } from '@/constants/glassConfig';
|
||||
|
||||
// 使用静态数据服务(从 /data/zt/ 读取 JSON 文件)
|
||||
import ztStaticService from '../../services/ztStaticService';
|
||||
|
||||
// 导入的组件(实际使用时应该从独立文件导入)
|
||||
// 恢复使用本页自带的轻量日历
|
||||
import EnhancedCalendar from './components/EnhancedCalendar';
|
||||
import SectorDetails from './components/SectorDetails';
|
||||
import { DataAnalysis } from './components/DataVisualizationComponents';
|
||||
import { AdvancedSearch, SearchResultsModal } from './components/SearchComponents';
|
||||
// 导入的组件
|
||||
import LimitUpEmotionCycle from './components/LimitUpEmotionCycle';
|
||||
import { SearchResultsModal } from './components/SearchComponents';
|
||||
|
||||
// 导航栏已由 MainLayout 提供,无需在此导入
|
||||
|
||||
// 导入高位股统计组件
|
||||
import HighPositionStocks from './components/HighPositionStocks';
|
||||
// 导入市场全景模块
|
||||
import MarketPanorama from './components/MarketPanorama';
|
||||
import { logger } from '../../utils/logger';
|
||||
import { useLimitAnalyseEvents } from './hooks/useLimitAnalyseEvents';
|
||||
import { GLASS_BLUR } from '@/constants/glassConfig';
|
||||
|
||||
// 玻璃拟态样式(保留供将来使用)
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const glassStyle = {
|
||||
bg: 'rgba(15, 15, 22, 0.9)',
|
||||
backdropFilter: `${GLASS_BLUR.lg} saturate(180%)`,
|
||||
border: '1px solid rgba(212, 175, 55, 0.15)',
|
||||
borderRadius: '20px',
|
||||
};
|
||||
|
||||
// 主组件
|
||||
export default function LimitAnalyse() {
|
||||
@@ -52,9 +42,15 @@ export default function LimitAnalyse() {
|
||||
const [wordCloudData, setWordCloudData] = useState([]);
|
||||
const [searchResults, setSearchResults] = useState(null);
|
||||
const [isSearchOpen, setIsSearchOpen] = useState(false);
|
||||
const [selectedSector, setSelectedSector] = useState(null);
|
||||
|
||||
const toast = useToast();
|
||||
|
||||
// 处理板块点击(从热力图联动到板块异动明细)
|
||||
const handleSectorSelect = (sectorName) => {
|
||||
setSelectedSector(sectorName);
|
||||
};
|
||||
|
||||
// 🎯 PostHog 事件追踪
|
||||
const {
|
||||
trackDateSelected,
|
||||
@@ -166,6 +162,9 @@ export default function LimitAnalyse() {
|
||||
const dateString = formatDateStr(date);
|
||||
setDateStr(dateString);
|
||||
|
||||
// 日期切换时清空板块选择
|
||||
setSelectedSector(null);
|
||||
|
||||
// 🎯 追踪日期选择
|
||||
trackDateSelected(dateString, previousDateStr);
|
||||
|
||||
@@ -239,164 +238,37 @@ export default function LimitAnalyse() {
|
||||
return result;
|
||||
};
|
||||
|
||||
|
||||
const formatDisplayDate = (date) => {
|
||||
if (!date) return '';
|
||||
const year = date.getFullYear();
|
||||
const month = date.getMonth() + 1;
|
||||
const day = date.getDate();
|
||||
return `${year}年${month}月${day}日`;
|
||||
};
|
||||
|
||||
const getSelectedDateCount = () => {
|
||||
if (!selectedDate || !availableDates?.length) return null;
|
||||
const date = formatDateStr(selectedDate);
|
||||
const found = availableDates.find(d => d.date === date);
|
||||
return found ? found.count : null;
|
||||
};
|
||||
|
||||
return (
|
||||
<Box minH="100vh" bg={bgColor}>
|
||||
{/* 导航栏已由 MainLayout 提供 */}
|
||||
|
||||
{/* 顶部Header */}
|
||||
<Box bgGradient="linear(to-br, blue.500, purple.600)" color="white" py={8} px={6} borderRadius="xl">
|
||||
<SimpleGrid columns={{ base: 1, lg: 2 }} spacing={6} alignItems="stretch">
|
||||
{/* 左侧:标题置顶,注释与图例贴底 */}
|
||||
<Flex direction="column" minH="420px" justify="space-between">
|
||||
<VStack align="start" spacing={4}>
|
||||
<HStack>
|
||||
<Badge colorScheme="whiteAlpha" fontSize="sm" px={2}>
|
||||
AI驱动
|
||||
</Badge>
|
||||
<Badge colorScheme="yellow" fontSize="sm" px={2}>
|
||||
实时更新
|
||||
</Badge>
|
||||
</HStack>
|
||||
<Heading
|
||||
size="3xl"
|
||||
fontWeight="extrabold"
|
||||
letterSpacing="-0.5px"
|
||||
lineHeight="shorter"
|
||||
textShadow="0 6px 24px rgba(0,0,0,0.25)"
|
||||
>
|
||||
涨停板块分析平台
|
||||
</Heading>
|
||||
<Text fontSize="xl" opacity={0.98} fontWeight="semibold" textShadow="0 4px 16px rgba(0,0,0,0.2)">
|
||||
以大模型辅助整理海量信息,结合领域知识图谱与分析师复核,呈现涨停板块关键线索
|
||||
</Text>
|
||||
</VStack>
|
||||
|
||||
<VStack align="stretch" spacing={3}>
|
||||
<Alert
|
||||
status="info"
|
||||
borderRadius="xl"
|
||||
bg="whiteAlpha.200"
|
||||
color="whiteAlpha.900"
|
||||
borderWidth="1px"
|
||||
borderColor="whiteAlpha.300"
|
||||
backdropFilter={`saturate(180%) ${GLASS_BLUR.sm}`}
|
||||
boxShadow="0 8px 32px rgba(0,0,0,0.2)"
|
||||
>
|
||||
<AlertIcon />
|
||||
<Text fontSize="md" fontWeight="medium">
|
||||
{selectedDate ? `当前选择:${formatDisplayDate(selectedDate)}` : '当前选择:--'}
|
||||
{getSelectedDateCount() != null ? ` - ${getSelectedDateCount()}只涨停` : ''}
|
||||
</Text>
|
||||
</Alert>
|
||||
|
||||
<Card
|
||||
bg="whiteAlpha.200"
|
||||
color="whiteAlpha.900"
|
||||
borderRadius="xl"
|
||||
boxShadow="0 8px 32px rgba(0,0,0,0.2)"
|
||||
borderWidth="1px"
|
||||
borderColor="whiteAlpha.300"
|
||||
backdropFilter={`saturate(180%) ${GLASS_BLUR.sm}`}
|
||||
w="full"
|
||||
>
|
||||
<CardBody>
|
||||
<VStack align="stretch" spacing={2}>
|
||||
<Heading size="sm" color="whiteAlpha.900">涨停数量图例</Heading>
|
||||
<VStack align="stretch" spacing={2}>
|
||||
<HStack>
|
||||
<Box w={5} h={5} bg="green.200" borderRadius="md" border="1px solid" borderColor="whiteAlpha.400" />
|
||||
<Text fontSize="sm">少量 (≤50只)</Text>
|
||||
</HStack>
|
||||
<HStack>
|
||||
<Box w={5} h={5} bg="yellow.200" borderRadius="md" border="1px solid" borderColor="whiteAlpha.400" />
|
||||
<Text fontSize="sm">中等 (51-80只)</Text>
|
||||
</HStack>
|
||||
<HStack>
|
||||
<Box w={5} h={5} bg="red.200" borderRadius="md" border="1px solid" borderColor="whiteAlpha.400" />
|
||||
<Text fontSize="sm">大量 (>80只)</Text>
|
||||
</HStack>
|
||||
</VStack>
|
||||
</VStack>
|
||||
</CardBody>
|
||||
</Card>
|
||||
</VStack>
|
||||
</Flex>
|
||||
|
||||
{/* 右侧:半屏日历 */}
|
||||
<Card
|
||||
bg="whiteAlpha.200"
|
||||
borderRadius="xl"
|
||||
boxShadow="0 8px 32px rgba(0,0,0,0.2)"
|
||||
borderWidth="1px"
|
||||
borderColor="whiteAlpha.300"
|
||||
backdropFilter={`saturate(180%) ${GLASS_BLUR.sm}`}
|
||||
w="full"
|
||||
>
|
||||
<CardBody p={4}>
|
||||
<EnhancedCalendar
|
||||
selectedDate={selectedDate}
|
||||
onDateChange={handleDateChange}
|
||||
availableDates={availableDates}
|
||||
compact
|
||||
hideSelectionInfo
|
||||
hideLegend
|
||||
width="100%"
|
||||
cellHeight={16}
|
||||
/>
|
||||
</CardBody>
|
||||
</Card>
|
||||
</SimpleGrid>
|
||||
{/* ==================== 第一部分:宏观情绪定调 ==================== */}
|
||||
{/* 涨停情绪周期 - 置顶,判断市场处于周期的什么阶段 */}
|
||||
<Box mb={6}>
|
||||
<LimitUpEmotionCycle
|
||||
selectedDate={selectedDate}
|
||||
onDateChange={handleDateChange}
|
||||
availableDates={availableDates}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
{/* 主内容区 - padding 由 MainLayout 统一设置 */}
|
||||
<Box py={8}>
|
||||
{/* 搜索框 */}
|
||||
<AdvancedSearch onSearch={handleSearch} loading={loading} />
|
||||
|
||||
{/* 数据分析(含涨停统计) */}
|
||||
{/* 主内容区 */}
|
||||
<Box>
|
||||
{/* 市场全景与板块分析模块 */}
|
||||
{loading ? (
|
||||
<Skeleton height="500px" borderRadius="xl" mb={6} />
|
||||
) : (
|
||||
<Box mb={6}>
|
||||
<DataAnalysis
|
||||
dailyData={dailyData}
|
||||
wordCloudData={wordCloudData}
|
||||
totalStocks={dailyData?.total_stocks || 0}
|
||||
dateStr={dateStr}
|
||||
/>
|
||||
</Box>
|
||||
<MarketPanorama
|
||||
dailyData={dailyData}
|
||||
wordCloudData={wordCloudData}
|
||||
totalStocks={dailyData?.total_stocks || 0}
|
||||
selectedSector={selectedSector}
|
||||
onSectorSelect={handleSectorSelect}
|
||||
sortedSectors={getSortedSectorData()}
|
||||
dateStr={dateStr}
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* 板块详情 - 核心内容 */}
|
||||
{loading ? (
|
||||
<Skeleton height="600px" borderRadius="xl" mb={6} />
|
||||
) : (
|
||||
<Box mb={6}>
|
||||
<SectorDetails
|
||||
sortedSectors={getSortedSectorData()}
|
||||
totalStocks={dailyData?.total_stocks || 0}
|
||||
/>
|
||||
</Box>
|
||||
)}
|
||||
|
||||
{/* 高位股统计 */}
|
||||
<HighPositionStocks dateStr={dateStr} />
|
||||
</Box>
|
||||
|
||||
{/* 弹窗 */}
|
||||
|
||||
Reference in New Issue
Block a user