style(DynamicTracking): 应用黑金主题
- NewsEventsTab: 添加黑金主题配色系统 - ForecastPanel: 业绩预告面板黑金样式 - NewsPanel: 切换 blackGold 主题 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,23 +1,49 @@
|
||||
// src/views/Company/components/DynamicTracking/components/ForecastPanel.js
|
||||
// 业绩预告面板
|
||||
// 业绩预告面板 - 黑金主题
|
||||
|
||||
import React, { useState, useEffect, useCallback } from 'react';
|
||||
import {
|
||||
VStack,
|
||||
Card,
|
||||
CardBody,
|
||||
HStack,
|
||||
Badge,
|
||||
Box,
|
||||
Flex,
|
||||
Text,
|
||||
Spinner,
|
||||
Center,
|
||||
} from '@chakra-ui/react';
|
||||
import { Tag } from 'antd';
|
||||
import { logger } from '@utils/logger';
|
||||
import { getApiBase } from '@utils/apiConfig';
|
||||
import { THEME } from '../../CompanyOverview/BasicInfoTab/config';
|
||||
|
||||
const API_BASE_URL = getApiBase();
|
||||
|
||||
// 黑金主题
|
||||
const THEME = {
|
||||
gold: '#D4AF37',
|
||||
goldLight: 'rgba(212, 175, 55, 0.15)',
|
||||
goldBorder: 'rgba(212, 175, 55, 0.3)',
|
||||
bgDark: '#1A202C',
|
||||
cardBg: 'rgba(26, 32, 44, 0.6)',
|
||||
text: '#E2E8F0',
|
||||
textSecondary: '#A0AEC0',
|
||||
positive: '#E53E3E',
|
||||
negative: '#48BB78',
|
||||
};
|
||||
|
||||
// 预告类型配色
|
||||
const getForecastTypeStyle = (type) => {
|
||||
const styles = {
|
||||
'预增': { color: '#E53E3E', bg: 'rgba(229, 62, 62, 0.15)', border: 'rgba(229, 62, 62, 0.3)' },
|
||||
'预减': { color: '#48BB78', bg: 'rgba(72, 187, 120, 0.15)', border: 'rgba(72, 187, 120, 0.3)' },
|
||||
'扭亏': { color: '#D4AF37', bg: 'rgba(212, 175, 55, 0.15)', border: 'rgba(212, 175, 55, 0.3)' },
|
||||
'首亏': { color: '#48BB78', bg: 'rgba(72, 187, 120, 0.15)', border: 'rgba(72, 187, 120, 0.3)' },
|
||||
'续亏': { color: '#718096', bg: 'rgba(113, 128, 150, 0.15)', border: 'rgba(113, 128, 150, 0.3)' },
|
||||
'续盈': { color: '#E53E3E', bg: 'rgba(229, 62, 62, 0.15)', border: 'rgba(229, 62, 62, 0.3)' },
|
||||
'略增': { color: '#ED8936', bg: 'rgba(237, 137, 54, 0.15)', border: 'rgba(237, 137, 54, 0.3)' },
|
||||
'略减': { color: '#38B2AC', bg: 'rgba(56, 178, 172, 0.15)', border: 'rgba(56, 178, 172, 0.3)' },
|
||||
};
|
||||
return styles[type] || { color: THEME.gold, bg: THEME.goldLight, border: THEME.goldBorder };
|
||||
};
|
||||
|
||||
const ForecastPanel = ({ stockCode }) => {
|
||||
const [forecast, setForecast] = useState(null);
|
||||
const [loading, setLoading] = useState(false);
|
||||
@@ -63,33 +89,69 @@ const ForecastPanel = ({ stockCode }) => {
|
||||
}
|
||||
|
||||
return (
|
||||
<VStack spacing={4} align="stretch">
|
||||
{forecast.forecasts.map((item, idx) => (
|
||||
<Card key={idx} bg={THEME.cardBg} borderColor={THEME.border} borderWidth="1px">
|
||||
<CardBody>
|
||||
<HStack justify="space-between" mb={2}>
|
||||
<Badge colorScheme="blue">{item.forecast_type}</Badge>
|
||||
<VStack spacing={3} align="stretch">
|
||||
{forecast.forecasts.map((item, idx) => {
|
||||
const typeStyle = getForecastTypeStyle(item.forecast_type);
|
||||
|
||||
return (
|
||||
<Box
|
||||
key={idx}
|
||||
bg={THEME.cardBg}
|
||||
border="1px solid"
|
||||
borderColor={THEME.goldBorder}
|
||||
borderRadius="md"
|
||||
p={4}
|
||||
>
|
||||
{/* 头部:类型标签 + 报告期 */}
|
||||
<Flex justify="space-between" align="center" mb={3}>
|
||||
<Tag
|
||||
style={{
|
||||
color: typeStyle.color,
|
||||
background: typeStyle.bg,
|
||||
border: `1px solid ${typeStyle.border}`,
|
||||
fontWeight: 500,
|
||||
}}
|
||||
>
|
||||
{item.forecast_type}
|
||||
</Tag>
|
||||
<Text fontSize="sm" color={THEME.textSecondary}>
|
||||
报告期: {item.report_date}
|
||||
</Text>
|
||||
</HStack>
|
||||
<Text mb={2} color={THEME.text}>{item.content}</Text>
|
||||
</Flex>
|
||||
|
||||
{/* 内容 */}
|
||||
<Text color={THEME.text} fontSize="sm" lineHeight="1.6" mb={3}>
|
||||
{item.content}
|
||||
</Text>
|
||||
|
||||
{/* 原因(如有) */}
|
||||
{item.reason && (
|
||||
<Text fontSize="sm" color={THEME.textSecondary}>
|
||||
<Text fontSize="xs" color={THEME.textSecondary} mb={3}>
|
||||
{item.reason}
|
||||
</Text>
|
||||
)}
|
||||
{item.change_range?.lower && (
|
||||
<HStack mt={2}>
|
||||
<Text fontSize="sm" color={THEME.textSecondary}>预计变动范围:</Text>
|
||||
<Badge colorScheme="green">
|
||||
|
||||
{/* 变动范围 */}
|
||||
{item.change_range?.lower !== undefined && (
|
||||
<Flex align="center" gap={2}>
|
||||
<Text fontSize="sm" color={THEME.textSecondary}>
|
||||
预计变动范围:
|
||||
</Text>
|
||||
<Tag
|
||||
style={{
|
||||
color: THEME.gold,
|
||||
background: THEME.goldLight,
|
||||
border: `1px solid ${THEME.goldBorder}`,
|
||||
fontWeight: 600,
|
||||
}}
|
||||
>
|
||||
{item.change_range.lower}% ~ {item.change_range.upper}%
|
||||
</Badge>
|
||||
</HStack>
|
||||
</Tag>
|
||||
</Flex>
|
||||
)}
|
||||
</CardBody>
|
||||
</Card>
|
||||
))}
|
||||
</Box>
|
||||
);
|
||||
})}
|
||||
</VStack>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -107,7 +107,7 @@ const NewsPanel = ({ stockCode }) => {
|
||||
onSearchChange={handleSearchChange}
|
||||
onSearch={handleSearch}
|
||||
onPageChange={handlePageChange}
|
||||
cardBg="white"
|
||||
themePreset="blackGold"
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user