update pay ui
This commit is contained in:
@@ -512,7 +512,7 @@ const SectorRelationMap = ({ data }) => {
|
||||
};
|
||||
|
||||
// 数据分析主组件
|
||||
export const DataAnalysis = ({ dailyData, wordCloudData }) => {
|
||||
export const DataAnalysis = ({ dailyData, wordCloudData, totalStocks, dateStr }) => {
|
||||
const cardBg = useColorModeValue('white', 'gray.800');
|
||||
|
||||
const pieData = useMemo(() => {
|
||||
@@ -538,10 +538,30 @@ export const DataAnalysis = ({ dailyData, wordCloudData }) => {
|
||||
return Object.values(dailyData.sector_data).flatMap(sector => sector.stocks || []);
|
||||
}, [dailyData]);
|
||||
|
||||
// 格式化日期显示
|
||||
const formatDate = (str) => {
|
||||
if (!str || str.length !== 8) return '';
|
||||
return `${str.slice(0, 4)}年${parseInt(str.slice(4, 6))}月${parseInt(str.slice(6, 8))}日`;
|
||||
};
|
||||
|
||||
return (
|
||||
<Card bg={cardBg} borderRadius="xl" boxShadow="xl">
|
||||
<CardHeader>
|
||||
<Heading size="md">数据分析</Heading>
|
||||
<HStack justify="space-between" align="center" flexWrap="wrap" gap={2}>
|
||||
<Heading size="md">数据分析</Heading>
|
||||
{totalStocks !== undefined && (
|
||||
<HStack spacing={3}>
|
||||
{dateStr && (
|
||||
<Badge colorScheme="gray" fontSize="sm" px={3} py={1}>
|
||||
{formatDate(dateStr)}
|
||||
</Badge>
|
||||
)}
|
||||
<Badge colorScheme="red" fontSize="lg" px={4} py={2} borderRadius="md">
|
||||
今日涨停: {totalStocks} 只
|
||||
</Badge>
|
||||
</HStack>
|
||||
)}
|
||||
</HStack>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<Tabs variant="soft-rounded" colorScheme="blue" isLazy>
|
||||
|
||||
@@ -1,18 +1,13 @@
|
||||
import React, { useState } from 'react';
|
||||
import {
|
||||
Box,
|
||||
Card,
|
||||
CardBody,
|
||||
VStack,
|
||||
HStack,
|
||||
Text,
|
||||
Button,
|
||||
Input,
|
||||
InputGroup,
|
||||
InputLeftElement,
|
||||
Select,
|
||||
RadioGroup,
|
||||
Radio,
|
||||
Modal,
|
||||
ModalOverlay,
|
||||
ModalContent,
|
||||
@@ -39,14 +34,11 @@ import {
|
||||
AlertIcon,
|
||||
} from '@chakra-ui/react';
|
||||
import { formatTooltipText, getFormattedTextProps } from '../../../utils/textUtils';
|
||||
import { SearchIcon, CalendarIcon, DownloadIcon } from '@chakra-ui/icons';
|
||||
import { SearchIcon, DownloadIcon } from '@chakra-ui/icons';
|
||||
|
||||
// 高级搜索组件
|
||||
// 简化版搜索组件 - 仅支持股票代码/名称精确匹配
|
||||
export const AdvancedSearch = ({ onSearch, loading }) => {
|
||||
const [searchKeyword, setSearchKeyword] = useState('');
|
||||
const [searchMode, setSearchMode] = useState('hybrid');
|
||||
const [searchType, setSearchType] = useState('all');
|
||||
const [dateRange, setDateRange] = useState({ start: '', end: '' });
|
||||
|
||||
const cardBg = useColorModeValue('white', 'gray.800');
|
||||
const toast = useToast();
|
||||
@@ -54,7 +46,7 @@ export const AdvancedSearch = ({ onSearch, loading }) => {
|
||||
const handleSearch = () => {
|
||||
if (!searchKeyword.trim()) {
|
||||
toast({
|
||||
title: '请输入搜索关键词',
|
||||
title: '请输入股票代码或名称',
|
||||
status: 'warning',
|
||||
duration: 2000,
|
||||
});
|
||||
@@ -62,139 +54,54 @@ export const AdvancedSearch = ({ onSearch, loading }) => {
|
||||
}
|
||||
|
||||
const searchParams = {
|
||||
query: searchKeyword,
|
||||
mode: searchMode,
|
||||
type: searchType,
|
||||
query: searchKeyword.trim(),
|
||||
mode: 'exact', // 固定为精确匹配
|
||||
page: 1,
|
||||
page_size: 50,
|
||||
};
|
||||
|
||||
// 添加日期范围
|
||||
if (dateRange.start || dateRange.end) {
|
||||
searchParams.date_range = {};
|
||||
if (dateRange.start) searchParams.date_range.start = dateRange.start.replace(/-/g, '');
|
||||
if (dateRange.end) searchParams.date_range.end = dateRange.end.replace(/-/g, '');
|
||||
}
|
||||
|
||||
onSearch(searchParams);
|
||||
};
|
||||
|
||||
const clearSearch = () => {
|
||||
setSearchKeyword('');
|
||||
setDateRange({ start: '', end: '' });
|
||||
setSearchType('all');
|
||||
setSearchMode('hybrid');
|
||||
};
|
||||
|
||||
return (
|
||||
<Card bg={cardBg} borderRadius="xl" boxShadow="xl" mb={6}>
|
||||
<CardBody>
|
||||
<VStack spacing={4}>
|
||||
<HStack w="full" spacing={3}>
|
||||
<InputGroup size="lg" flex={1}>
|
||||
<InputLeftElement>
|
||||
<SearchIcon color="gray.400" />
|
||||
</InputLeftElement>
|
||||
<Input
|
||||
placeholder="搜索股票名称、代码或涨停原因..."
|
||||
value={searchKeyword}
|
||||
onChange={(e) => setSearchKeyword(e.target.value)}
|
||||
onKeyPress={(e) => e.key === 'Enter' && handleSearch()}
|
||||
fontSize="md"
|
||||
/>
|
||||
</InputGroup>
|
||||
<Button
|
||||
size="lg"
|
||||
colorScheme="blue"
|
||||
onClick={handleSearch}
|
||||
isLoading={loading}
|
||||
px={8}
|
||||
leftIcon={<SearchIcon />}
|
||||
>
|
||||
搜索
|
||||
</Button>
|
||||
<Button
|
||||
size="lg"
|
||||
variant="outline"
|
||||
onClick={clearSearch}
|
||||
px={6}
|
||||
>
|
||||
清空
|
||||
</Button>
|
||||
</HStack>
|
||||
|
||||
<HStack w="full" spacing={4} align="start">
|
||||
<Box flex={1}>
|
||||
<Text fontSize="sm" mb={2} fontWeight="bold">搜索类型</Text>
|
||||
<RadioGroup value={searchType} onChange={setSearchType}>
|
||||
<HStack spacing={4}>
|
||||
<Radio value="all">全部</Radio>
|
||||
<Radio value="stock">股票</Radio>
|
||||
<Radio value="reason">涨停原因</Radio>
|
||||
</HStack>
|
||||
</RadioGroup>
|
||||
</Box>
|
||||
|
||||
<Box flex={1}>
|
||||
<Text fontSize="sm" mb={2} fontWeight="bold">搜索模式</Text>
|
||||
<Select
|
||||
value={searchMode}
|
||||
onChange={(e) => setSearchMode(e.target.value)}
|
||||
bg="white"
|
||||
_dark={{ bg: 'gray.700' }}
|
||||
sx={{
|
||||
'& option': {
|
||||
bg: 'white',
|
||||
color: 'gray.800',
|
||||
_dark: {
|
||||
bg: 'gray.700',
|
||||
color: 'white'
|
||||
}
|
||||
}
|
||||
}}
|
||||
>
|
||||
<option value="hybrid">智能搜索(推荐)</option>
|
||||
<option value="text">精确匹配</option>
|
||||
<option value="vector">语义搜索</option>
|
||||
</Select>
|
||||
</Box>
|
||||
|
||||
<Box flex={2}>
|
||||
<Text fontSize="sm" mb={2} fontWeight="bold">日期范围(可选)</Text>
|
||||
<HStack>
|
||||
<InputGroup size="md">
|
||||
<InputLeftElement>
|
||||
<CalendarIcon color="gray.400" boxSize={4} />
|
||||
</InputLeftElement>
|
||||
<Input
|
||||
type="date"
|
||||
value={dateRange.start}
|
||||
onChange={(e) => setDateRange({...dateRange, start: e.target.value})}
|
||||
/>
|
||||
</InputGroup>
|
||||
<Text>至</Text>
|
||||
<InputGroup size="md">
|
||||
<InputLeftElement>
|
||||
<CalendarIcon color="gray.400" boxSize={4} />
|
||||
</InputLeftElement>
|
||||
<Input
|
||||
type="date"
|
||||
value={dateRange.end}
|
||||
onChange={(e) => setDateRange({...dateRange, end: e.target.value})}
|
||||
/>
|
||||
</InputGroup>
|
||||
</HStack>
|
||||
</Box>
|
||||
</HStack>
|
||||
|
||||
<Alert status="info" borderRadius="md" fontSize="sm">
|
||||
<AlertIcon />
|
||||
<Text>
|
||||
<strong>提示:</strong>搜索结果将在新窗口中显示,不会影响当前页面的数据展示。
|
||||
您可以搜索不同日期范围内的涨停股票进行对比分析。
|
||||
</Text>
|
||||
</Alert>
|
||||
</VStack>
|
||||
<HStack w="full" spacing={3}>
|
||||
<InputGroup size="lg" flex={1}>
|
||||
<InputLeftElement>
|
||||
<SearchIcon color="gray.400" />
|
||||
</InputLeftElement>
|
||||
<Input
|
||||
placeholder="输入股票代码或名称搜索(如 600000 或 浦发银行)"
|
||||
value={searchKeyword}
|
||||
onChange={(e) => setSearchKeyword(e.target.value)}
|
||||
onKeyPress={(e) => e.key === 'Enter' && handleSearch()}
|
||||
fontSize="md"
|
||||
/>
|
||||
</InputGroup>
|
||||
<Button
|
||||
size="lg"
|
||||
colorScheme="blue"
|
||||
onClick={handleSearch}
|
||||
isLoading={loading}
|
||||
px={8}
|
||||
leftIcon={<SearchIcon />}
|
||||
>
|
||||
搜索
|
||||
</Button>
|
||||
<Button
|
||||
size="lg"
|
||||
variant="outline"
|
||||
onClick={clearSearch}
|
||||
px={6}
|
||||
>
|
||||
清空
|
||||
</Button>
|
||||
</HStack>
|
||||
</CardBody>
|
||||
</Card>
|
||||
);
|
||||
|
||||
@@ -16,13 +16,8 @@ import {
|
||||
Tooltip,
|
||||
Card,
|
||||
CardBody,
|
||||
Stat,
|
||||
StatLabel,
|
||||
StatNumber,
|
||||
StatHelpText,
|
||||
StatArrow,
|
||||
Alert,
|
||||
AlertIcon,
|
||||
Alert,
|
||||
AlertIcon,
|
||||
} from '@chakra-ui/react';
|
||||
import {
|
||||
RepeatIcon,
|
||||
@@ -247,61 +242,6 @@ export default function LimitAnalyse() {
|
||||
return result;
|
||||
};
|
||||
|
||||
// 渲染统计卡片
|
||||
const StatsCards = () => (
|
||||
<SimpleGrid columns={{ base: 2, md: 4 }} spacing={4} mb={6}>
|
||||
<Card bg={cardBg} borderRadius="lg" boxShadow="md">
|
||||
<CardBody>
|
||||
<Stat>
|
||||
<StatLabel fontSize="sm">今日涨停</StatLabel>
|
||||
<StatNumber fontSize="2xl" color="red.500">
|
||||
{dailyData?.total_stocks || 0}
|
||||
</StatNumber>
|
||||
<StatHelpText>
|
||||
<StatArrow type="increase" />
|
||||
较昨日 +23%
|
||||
</StatHelpText>
|
||||
</Stat>
|
||||
</CardBody>
|
||||
</Card>
|
||||
|
||||
<Card bg={cardBg} borderRadius="lg" boxShadow="md">
|
||||
<CardBody>
|
||||
<Stat>
|
||||
<StatLabel fontSize="sm">最热板块</StatLabel>
|
||||
<StatNumber fontSize="xl" color={accentColor}>
|
||||
{dailyData?.summary?.top_sector || '-'}
|
||||
</StatNumber>
|
||||
<StatHelpText>{dailyData?.summary?.top_sector_count || 0} 只</StatHelpText>
|
||||
</Stat>
|
||||
</CardBody>
|
||||
</Card>
|
||||
|
||||
<Card bg={cardBg} borderRadius="lg" boxShadow="md">
|
||||
<CardBody>
|
||||
<Stat>
|
||||
<StatLabel fontSize="sm">公告涨停</StatLabel>
|
||||
<StatNumber fontSize="2xl" color="orange.500">
|
||||
{dailyData?.summary?.announcement_stocks || 0}
|
||||
</StatNumber>
|
||||
<StatHelpText>重大利好</StatHelpText>
|
||||
</Stat>
|
||||
</CardBody>
|
||||
</Card>
|
||||
|
||||
<Card bg={cardBg} borderRadius="lg" boxShadow="md">
|
||||
<CardBody>
|
||||
<Stat>
|
||||
<StatLabel fontSize="sm">早盘强势</StatLabel>
|
||||
<StatNumber fontSize="2xl" color="green.500">
|
||||
{dailyData?.summary?.zt_time_distribution?.morning || 0}
|
||||
</StatNumber>
|
||||
<StatHelpText>开盘涨停</StatHelpText>
|
||||
</Stat>
|
||||
</CardBody>
|
||||
</Card>
|
||||
</SimpleGrid>
|
||||
);
|
||||
|
||||
const formatDisplayDate = (date) => {
|
||||
if (!date) return '';
|
||||
@@ -431,21 +371,10 @@ export default function LimitAnalyse() {
|
||||
|
||||
{/* 主内容区 */}
|
||||
<Container maxW="container.xl" py={8}>
|
||||
{/* 统计卡片 */}
|
||||
{loading ? (
|
||||
<SimpleGrid columns={{ base: 2, md: 4 }} spacing={4} mb={6}>
|
||||
{[...Array(4)].map((_, i) => (
|
||||
<Skeleton key={i} height="100px" borderRadius="lg" />
|
||||
))}
|
||||
</SimpleGrid>
|
||||
) : (
|
||||
<StatsCards />
|
||||
)}
|
||||
|
||||
{/* 高级搜索 */}
|
||||
{/* 搜索框 */}
|
||||
<AdvancedSearch onSearch={handleSearch} loading={loading} />
|
||||
|
||||
{/* 数据分析 - 移到板块详情上方 */}
|
||||
{/* 数据分析(含涨停统计) */}
|
||||
{loading ? (
|
||||
<Skeleton height="500px" borderRadius="xl" mb={6} />
|
||||
) : (
|
||||
@@ -453,6 +382,8 @@ export default function LimitAnalyse() {
|
||||
<DataAnalysis
|
||||
dailyData={dailyData}
|
||||
wordCloudData={wordCloudData}
|
||||
totalStocks={dailyData?.total_stocks || 0}
|
||||
dateStr={dateStr}
|
||||
/>
|
||||
</Box>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user