- echarts.ts: 将 EChartsOption 改为 EChartsCoreOption 的类型别名 - FuiCorners: 移除 extends BoxProps,position 重命名为 corner - KLineChartModal/TimelineChartModal/ConcentrationCard: 使用导入的 EChartsOption - LoadingState: 新增骨架屏 variant 支持 - FinancialPanorama: 使用骨架屏加载状态 - useFinancialData/financialService: 优化数据获取逻辑 - Company/index: 简化组件结构 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
115 lines
2.8 KiB
TypeScript
115 lines
2.8 KiB
TypeScript
// src/views/Company/components/LoadingState.tsx
|
|
// 统一的加载状态组件 - 黑金主题
|
|
|
|
import React, { memo } from "react";
|
|
import { Center, VStack, Spinner, Text, Box, Skeleton, SimpleGrid } from "@chakra-ui/react";
|
|
|
|
// 黑金主题配置
|
|
const THEME = {
|
|
gold: "#D4AF37",
|
|
goldLight: "rgba(212, 175, 55, 0.3)",
|
|
bgInset: "rgba(26, 32, 44, 0.6)",
|
|
borderGlass: "rgba(212, 175, 55, 0.2)",
|
|
textSecondary: "gray.400",
|
|
radiusSM: "md",
|
|
radiusMD: "lg",
|
|
};
|
|
|
|
interface LoadingStateProps {
|
|
message?: string;
|
|
height?: string;
|
|
/** 使用骨架屏模式(更好的视觉体验) */
|
|
variant?: "spinner" | "skeleton";
|
|
/** 骨架屏行数 */
|
|
skeletonRows?: number;
|
|
}
|
|
|
|
/**
|
|
* 骨架屏组件(黑金主题)
|
|
*/
|
|
const SkeletonContent: React.FC<{ rows: number }> = memo(({ rows }) => (
|
|
<VStack align="stretch" spacing={4} w="100%">
|
|
{/* 头部骨架 */}
|
|
<Box display="flex" justifyContent="space-between" alignItems="center">
|
|
<Skeleton
|
|
height="28px"
|
|
width="180px"
|
|
startColor={THEME.bgInset}
|
|
endColor={THEME.borderGlass}
|
|
borderRadius={THEME.radiusSM}
|
|
/>
|
|
<Skeleton
|
|
height="24px"
|
|
width="100px"
|
|
startColor={THEME.bgInset}
|
|
endColor={THEME.borderGlass}
|
|
borderRadius={THEME.radiusSM}
|
|
/>
|
|
</Box>
|
|
|
|
{/* 内容骨架行 */}
|
|
<SimpleGrid columns={{ base: 2, md: 4 }} spacing={4}>
|
|
{Array.from({ length: Math.min(rows, 8) }).map((_, i) => (
|
|
<Skeleton
|
|
key={i}
|
|
height="60px"
|
|
startColor={THEME.bgInset}
|
|
endColor={THEME.borderGlass}
|
|
borderRadius={THEME.radiusMD}
|
|
/>
|
|
))}
|
|
</SimpleGrid>
|
|
|
|
{/* 图表区域骨架 */}
|
|
<Skeleton
|
|
height="200px"
|
|
startColor={THEME.bgInset}
|
|
endColor={THEME.borderGlass}
|
|
borderRadius={THEME.radiusMD}
|
|
/>
|
|
</VStack>
|
|
));
|
|
|
|
SkeletonContent.displayName = "SkeletonContent";
|
|
|
|
/**
|
|
* 统一的加载状态组件(黑金主题)
|
|
*
|
|
* 用于所有一级 Tab 的 loading 状态展示
|
|
* @param variant - "spinner"(默认)或 "skeleton"(骨架屏)
|
|
*/
|
|
const LoadingState: React.FC<LoadingStateProps> = memo(({
|
|
message = "加载中...",
|
|
height = "300px",
|
|
variant = "spinner",
|
|
skeletonRows = 4,
|
|
}) => {
|
|
if (variant === "skeleton") {
|
|
return (
|
|
<Box h={height} p={4}>
|
|
<SkeletonContent rows={skeletonRows} />
|
|
</Box>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<Center h={height}>
|
|
<VStack spacing={4}>
|
|
<Spinner
|
|
size="xl"
|
|
color={THEME.gold}
|
|
thickness="4px"
|
|
speed="0.65s"
|
|
/>
|
|
<Text fontSize="sm" color={THEME.textSecondary}>
|
|
{message}
|
|
</Text>
|
|
</VStack>
|
|
</Center>
|
|
);
|
|
});
|
|
|
|
LoadingState.displayName = "LoadingState";
|
|
|
|
export default LoadingState;
|