Merge branch 'feature_bugfix/251217_stock' of https://git.valuefrontier.cn/vf/vf_react into feature_bugfix/251217_stock
This commit is contained in:
@@ -0,0 +1,81 @@
|
|||||||
|
/**
|
||||||
|
* FeatureCardItem - 功能卡片项组件
|
||||||
|
* 用于展示单个功能入口,包含图标、标题和描述
|
||||||
|
*/
|
||||||
|
import React from 'react';
|
||||||
|
import { Box, Flex, VStack, Text } from '@chakra-ui/react';
|
||||||
|
import type { Feature } from '@/types/home';
|
||||||
|
|
||||||
|
/** 获取图标背景渐变色 */
|
||||||
|
const getIconBgGradient = (color: string): string => {
|
||||||
|
const gradients: Record<string, string> = {
|
||||||
|
yellow: 'linear-gradient(135deg, #F6AD55 0%, #ED8936 100%)',
|
||||||
|
purple: 'linear-gradient(135deg, #B794F4 0%, #805AD5 100%)',
|
||||||
|
blue: 'linear-gradient(135deg, #63B3ED 0%, #3182CE 100%)',
|
||||||
|
green: 'linear-gradient(135deg, #68D391 0%, #38A169 100%)',
|
||||||
|
orange: 'linear-gradient(135deg, #FBD38D 0%, #DD6B20 100%)',
|
||||||
|
teal: 'linear-gradient(135deg, #4FD1C5 0%, #319795 100%)',
|
||||||
|
cyan: 'linear-gradient(135deg, #76E4F7 0%, #00B5D8 100%)',
|
||||||
|
red: 'linear-gradient(135deg, #FC8181 0%, #E53E3E 100%)'
|
||||||
|
};
|
||||||
|
return gradients[color] || gradients.blue;
|
||||||
|
};
|
||||||
|
|
||||||
|
export interface FeatureCardItemProps {
|
||||||
|
feature: Feature;
|
||||||
|
onClick: (feature: Feature) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const FeatureCardItem: React.FC<FeatureCardItemProps> = ({ feature, onClick }) => {
|
||||||
|
return (
|
||||||
|
<Flex
|
||||||
|
bg="whiteAlpha.50"
|
||||||
|
borderRadius="xl"
|
||||||
|
p={4}
|
||||||
|
cursor="pointer"
|
||||||
|
onClick={() => onClick(feature)}
|
||||||
|
_hover={{
|
||||||
|
bg: 'whiteAlpha.100',
|
||||||
|
transform: 'translateY(-2px)',
|
||||||
|
boxShadow: 'lg'
|
||||||
|
}}
|
||||||
|
transition="all 0.2s ease"
|
||||||
|
align="center"
|
||||||
|
gap={3}
|
||||||
|
border="1px solid"
|
||||||
|
borderColor="whiteAlpha.100"
|
||||||
|
>
|
||||||
|
{/* 左侧图标 */}
|
||||||
|
<Box
|
||||||
|
w="48px"
|
||||||
|
h="48px"
|
||||||
|
minW="48px"
|
||||||
|
borderRadius="full"
|
||||||
|
background={getIconBgGradient(feature.color)}
|
||||||
|
display="flex"
|
||||||
|
alignItems="center"
|
||||||
|
justifyContent="center"
|
||||||
|
boxShadow="md"
|
||||||
|
>
|
||||||
|
<Text fontSize="xl">{feature.icon}</Text>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
{/* 右侧文字 */}
|
||||||
|
<VStack align="start" spacing={0.5} flex={1}>
|
||||||
|
<Text fontWeight="bold" color="white" fontSize="sm">
|
||||||
|
{feature.title}
|
||||||
|
</Text>
|
||||||
|
<Text
|
||||||
|
fontSize="xs"
|
||||||
|
color="whiteAlpha.700"
|
||||||
|
noOfLines={2}
|
||||||
|
lineHeight="1.4"
|
||||||
|
>
|
||||||
|
{feature.description}
|
||||||
|
</Text>
|
||||||
|
</VStack>
|
||||||
|
</Flex>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default FeatureCardItem;
|
||||||
73
src/views/Center/components/FeatureEntryPanel/index.tsx
Normal file
73
src/views/Center/components/FeatureEntryPanel/index.tsx
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
/**
|
||||||
|
* FeatureEntryPanel - 功能入口面板
|
||||||
|
* 黑金色主题,展示平台核心功能快捷入口
|
||||||
|
*/
|
||||||
|
import React, { useCallback } from 'react';
|
||||||
|
import { Box, SimpleGrid, HStack, Text, Icon } from '@chakra-ui/react';
|
||||||
|
import { CheckCircleIcon } from '@chakra-ui/icons';
|
||||||
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
import GlassCard from '@components/GlassCard';
|
||||||
|
import { CORE_FEATURES } from '@/constants/homeFeatures';
|
||||||
|
import type { Feature } from '@/types/home';
|
||||||
|
import FeatureCardItem from './FeatureCardItem';
|
||||||
|
|
||||||
|
const FeatureEntryPanel: React.FC = () => {
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
|
const handleFeatureClick = useCallback(
|
||||||
|
(feature: Feature) => {
|
||||||
|
if (feature.url.startsWith('http')) {
|
||||||
|
window.open(feature.url, '_blank');
|
||||||
|
} else {
|
||||||
|
navigate(feature.url);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[navigate]
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<GlassCard
|
||||||
|
variant="transparent"
|
||||||
|
rounded="2xl"
|
||||||
|
padding="md"
|
||||||
|
hoverable={false}
|
||||||
|
cornerDecor
|
||||||
|
>
|
||||||
|
{/* 标题栏 - 参考投资仪表盘样式 */}
|
||||||
|
<HStack mb={4} spacing={2}>
|
||||||
|
<Icon
|
||||||
|
as={CheckCircleIcon}
|
||||||
|
boxSize={5}
|
||||||
|
color="rgba(72, 187, 120, 0.9)"
|
||||||
|
/>
|
||||||
|
<Text
|
||||||
|
fontSize="lg"
|
||||||
|
fontWeight="bold"
|
||||||
|
color="rgba(255, 255, 255, 0.95)"
|
||||||
|
letterSpacing="wide"
|
||||||
|
>
|
||||||
|
核心功能入口
|
||||||
|
</Text>
|
||||||
|
<Box
|
||||||
|
h="1px"
|
||||||
|
flex={1}
|
||||||
|
bgGradient="linear(to-r, rgba(72, 187, 120, 0.4), transparent)"
|
||||||
|
ml={2}
|
||||||
|
/>
|
||||||
|
</HStack>
|
||||||
|
|
||||||
|
{/* 功能卡片网格 */}
|
||||||
|
<SimpleGrid columns={{ base: 1, sm: 2, md: 3, lg: 4 }} spacing={3}>
|
||||||
|
{CORE_FEATURES.map((feature) => (
|
||||||
|
<FeatureCardItem
|
||||||
|
key={feature.id}
|
||||||
|
feature={feature}
|
||||||
|
onClick={handleFeatureClick}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</SimpleGrid>
|
||||||
|
</GlassCard>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default FeatureEntryPanel;
|
||||||
@@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Box } from '@chakra-ui/react';
|
import { Box } from '@chakra-ui/react';
|
||||||
|
import FeatureEntryPanel from './components/FeatureEntryPanel';
|
||||||
import InvestmentPlanningCenter from './components/InvestmentPlanningCenter';
|
import InvestmentPlanningCenter from './components/InvestmentPlanningCenter';
|
||||||
import MarketDashboard from '@views/Profile/components/MarketDashboard';
|
import MarketDashboard from '@views/Profile/components/MarketDashboard';
|
||||||
import ForumCenter from '@views/Profile/components/ForumCenter';
|
import ForumCenter from '@views/Profile/components/ForumCenter';
|
||||||
@@ -33,6 +34,11 @@ const Center: React.FC = () => {
|
|||||||
<ForumCenter />
|
<ForumCenter />
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
|
{/* 功能入口面板 */}
|
||||||
|
<Box mb={4}>
|
||||||
|
<FeatureEntryPanel />
|
||||||
|
</Box>
|
||||||
|
|
||||||
{/* 投资规划中心(整合了日历、计划、复盘,应用 FUI 毛玻璃风格) */}
|
{/* 投资规划中心(整合了日历、计划、复盘,应用 FUI 毛玻璃风格) */}
|
||||||
<Box>
|
<Box>
|
||||||
<InvestmentPlanningCenter />
|
<InvestmentPlanningCenter />
|
||||||
|
|||||||
@@ -267,15 +267,15 @@ export default function AccountOverview({ account, tradingEvents }) {
|
|||||||
</Badge>
|
</Badge>
|
||||||
</HStack>
|
</HStack>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardBody>
|
<CardBody pt={0}>
|
||||||
<AssetAllocationChart
|
<AssetAllocationChart
|
||||||
cashAmount={account?.availableCash || 0}
|
cashAmount={account?.availableCash || 0}
|
||||||
stockAmount={account?.marketValue || 0}
|
stockAmount={account?.marketValue || 0}
|
||||||
height={280}
|
height={200}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{/* 详细配置信息 */}
|
{/* 详细配置信息 */}
|
||||||
<VStack spacing={3} mt={4}>
|
<VStack spacing={2} mt={2}>
|
||||||
<HStack justify="space-between" w="full">
|
<HStack justify="space-between" w="full">
|
||||||
<HStack spacing={2}>
|
<HStack spacing={2}>
|
||||||
<Box w={3} h={3} bg="blue.400" borderRadius="sm" />
|
<Box w={3} h={3} bg="blue.400" borderRadius="sm" />
|
||||||
|
|||||||
@@ -15,12 +15,12 @@ interface AssetAllocationChartProps {
|
|||||||
* 资产配置环形图
|
* 资产配置环形图
|
||||||
* @param cashAmount - 现金资产金额
|
* @param cashAmount - 现金资产金额
|
||||||
* @param stockAmount - 股票资产金额
|
* @param stockAmount - 股票资产金额
|
||||||
* @param height - 图表高度,默认 280px
|
* @param height - 图表高度,默认 200px
|
||||||
*/
|
*/
|
||||||
export const AssetAllocationChart = ({
|
export const AssetAllocationChart = ({
|
||||||
cashAmount,
|
cashAmount,
|
||||||
stockAmount,
|
stockAmount,
|
||||||
height = 280
|
height = 200
|
||||||
}: AssetAllocationChartProps) => {
|
}: AssetAllocationChartProps) => {
|
||||||
const total = cashAmount + stockAmount;
|
const total = cashAmount + stockAmount;
|
||||||
|
|
||||||
@@ -48,7 +48,7 @@ export const AssetAllocationChart = ({
|
|||||||
},
|
},
|
||||||
legend: {
|
legend: {
|
||||||
orient: 'horizontal',
|
orient: 'horizontal',
|
||||||
bottom: 10,
|
bottom: 0,
|
||||||
left: 'center',
|
left: 'center',
|
||||||
textStyle: {
|
textStyle: {
|
||||||
color: '#666',
|
color: '#666',
|
||||||
@@ -62,8 +62,8 @@ export const AssetAllocationChart = ({
|
|||||||
{
|
{
|
||||||
name: '资产配置',
|
name: '资产配置',
|
||||||
type: 'pie',
|
type: 'pie',
|
||||||
radius: ['45%', '70%'],
|
radius: ['40%', '65%'],
|
||||||
center: ['50%', '45%'],
|
center: ['50%', '42%'],
|
||||||
avoidLabelOverlap: true,
|
avoidLabelOverlap: true,
|
||||||
itemStyle: {
|
itemStyle: {
|
||||||
borderRadius: 4,
|
borderRadius: 4,
|
||||||
|
|||||||
Reference in New Issue
Block a user