Files
vf_react/src/views/Company/components/CompanyOverview/DeepAnalysisTab/index.tsx
zdl f6f6ecb465 feat(DeepAnalysis): 实现 Tab 懒加载,按需请求数据
- DeepAnalysis/index.js: 重构为懒加载模式
  - 添加 TAB_API_MAP 映射 Tab 与接口关系
  - 战略分析/业务结构共享 comprehensive-analysis 接口
  - 产业链/发展历程按需加载对应接口
  - 使用 loadedApisRef 缓存已加载状态,避免重复请求
  - 各接口独立 loading 状态管理
  - 添加 stockCode 竞态条件保护

- DeepAnalysisTab/index.tsx: 支持受控模式
  - 新增 activeTab/onTabChange props
  - loading 状态下保持 Tab 导航可切换

- types.ts: 新增 DeepAnalysisTabKey 类型和相关 props

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-12 15:20:37 +08:00

111 lines
3.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 深度分析 Tab 主组件
*
* 使用 SubTabContainer 二级导航组件,分为 4 个子 Tab
* 1. 战略分析 - 核心定位 + 战略分析 + 竞争地位
* 2. 业务结构 - 业务结构树 + 业务板块详情
* 3. 产业链 - 产业链分析(独立,含 Sankey 图)
* 4. 发展历程 - 关键因素 + 时间线
*
* 支持懒加载:通过 activeTab 和 onTabChange 实现按需加载数据
*/
import React, { useMemo } from 'react';
import { Card, CardBody, Center, VStack, Spinner, Text } from '@chakra-ui/react';
import { FaBrain, FaBuilding, FaLink, FaHistory } from 'react-icons/fa';
import SubTabContainer, { type SubTabConfig } from '@components/SubTabContainer';
import { StrategyTab, BusinessTab, ValueChainTab, DevelopmentTab } from './tabs';
import type { DeepAnalysisTabProps, DeepAnalysisTabKey } from './types';
// 主题配置(与 BasicInfoTab 保持一致)
const THEME = {
cardBg: 'gray.900',
border: 'rgba(212, 175, 55, 0.3)',
};
/**
* Tab 配置
*/
const DEEP_ANALYSIS_TABS: SubTabConfig[] = [
{ key: 'strategy', name: '战略分析', icon: FaBrain, component: StrategyTab },
{ key: 'business', name: '业务结构', icon: FaBuilding, component: BusinessTab },
{ key: 'valueChain', name: '产业链', icon: FaLink, component: ValueChainTab },
{ key: 'development', name: '发展历程', icon: FaHistory, component: DevelopmentTab },
];
/**
* Tab key 到 index 的映射
*/
const TAB_KEY_TO_INDEX: Record<DeepAnalysisTabKey, number> = {
strategy: 0,
business: 1,
valueChain: 2,
development: 3,
};
const DeepAnalysisTab: React.FC<DeepAnalysisTabProps> = ({
comprehensiveData,
valueChainData,
keyFactorsData,
loading,
cardBg,
expandedSegments,
onToggleSegment,
activeTab,
onTabChange,
}) => {
// 计算当前 Tab 索引(受控模式)
const currentIndex = useMemo(() => {
if (activeTab) {
return TAB_KEY_TO_INDEX[activeTab] ?? 0;
}
return undefined; // 非受控模式
}, [activeTab]);
// 加载状态
if (loading) {
return (
<Card bg={THEME.cardBg} shadow="md" border="1px solid" borderColor={THEME.border}>
<CardBody p={0}>
<SubTabContainer
tabs={DEEP_ANALYSIS_TABS}
index={currentIndex}
onTabChange={onTabChange}
componentProps={{}}
themePreset="blackGold"
/>
<Center h="200px">
<VStack spacing={4}>
<Spinner size="xl" color="blue.500" />
<Text color="gray.400">...</Text>
</VStack>
</Center>
</CardBody>
</Card>
);
}
return (
<Card bg={THEME.cardBg} shadow="md" border="1px solid" borderColor={THEME.border}>
<CardBody p={0}>
<SubTabContainer
tabs={DEEP_ANALYSIS_TABS}
index={currentIndex}
onTabChange={onTabChange}
componentProps={{
comprehensiveData,
valueChainData,
keyFactorsData,
cardBg,
expandedSegments,
onToggleSegment,
}}
themePreset="blackGold"
/>
</CardBody>
</Card>
);
};
export default DeepAnalysisTab;