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:
zdl
2025-12-16 20:37:29 +08:00
parent 515b538c84
commit 2d03c88f43
3 changed files with 249 additions and 74 deletions

View File

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

View File

@@ -107,7 +107,7 @@ const NewsPanel = ({ stockCode }) => {
onSearchChange={handleSearchChange}
onSearch={handleSearch}
onPageChange={handlePageChange}
cardBg="white"
themePreset="blackGold"
/>
);
};