diff --git a/src/views/Company/components/CompanyOverview/DeepAnalysisTab.js b/src/views/Company/components/CompanyOverview/DeepAnalysisTab.js
deleted file mode 100644
index d686af03..00000000
--- a/src/views/Company/components/CompanyOverview/DeepAnalysisTab.js
+++ /dev/null
@@ -1,1795 +0,0 @@
-import React, { useState } from "react";
-import {
- Box,
- VStack,
- HStack,
- Text,
- Badge,
- Card,
- CardBody,
- CardHeader,
- Heading,
- SimpleGrid,
- Divider,
- Center,
- Alert,
- AlertIcon,
- Tabs,
- TabList,
- TabPanels,
- Tab,
- TabPanel,
- Button,
- Tag,
- TagLabel,
- Icon,
- Tooltip,
- Grid,
- GridItem,
- useToast,
- IconButton,
- Progress,
- Stat,
- StatLabel,
- StatNumber,
- StatHelpText,
- Accordion,
- AccordionItem,
- AccordionButton,
- AccordionPanel,
- AccordionIcon,
- Fade,
- ScaleFade,
- useDisclosure,
- Modal,
- ModalOverlay,
- ModalContent,
- ModalHeader,
- ModalFooter,
- ModalBody,
- ModalCloseButton,
- Circle,
- Spinner,
-} from "@chakra-ui/react";
-
-import {
- FaBuilding,
- FaChartLine,
- FaLightbulb,
- FaRocket,
- FaNetworkWired,
- FaCog,
- FaTrophy,
- FaShieldAlt,
- FaChartPie,
- FaHistory,
- FaCheckCircle,
- FaExclamationCircle,
- FaArrowUp,
- FaArrowDown,
- FaArrowRight,
- FaArrowLeft,
- FaStar,
- FaUserTie,
- FaIndustry,
- FaDollarSign,
- FaBalanceScale,
- FaFlask,
- FaHandshake,
- FaUsers,
- FaCalendarAlt,
- FaExpandAlt,
- FaCompressAlt,
-} from "react-icons/fa";
-
-import { ExternalLinkIcon } from "@chakra-ui/icons";
-import ReactECharts from "echarts-for-react";
-import { logger } from "@utils/logger";
-import { getApiBase } from "@utils/apiConfig";
-
-const API_BASE_URL = getApiBase();
-
-// 格式化工具
-const formatUtils = {
- formatCurrency: (value) => {
- if (!value && value !== 0) return "-";
- const absValue = Math.abs(value);
- if (absValue >= 100000000) {
- return (value / 100000000).toFixed(2) + "亿元";
- } else if (absValue >= 10000) {
- return (value / 10000).toFixed(2) + "万元";
- }
- return value.toFixed(2) + "元";
- },
- formatBusinessRevenue: (value, unit) => {
- if (!value && value !== 0) return "-";
- if (unit) {
- if (unit === "元") {
- const absValue = Math.abs(value);
- if (absValue >= 100000000) {
- return (value / 100000000).toFixed(2) + "亿元";
- } else if (absValue >= 10000) {
- return (value / 10000).toFixed(2) + "万元";
- }
- return value.toFixed(0) + "元";
- } else if (unit === "万元") {
- const absValue = Math.abs(value);
- if (absValue >= 10000) {
- return (value / 10000).toFixed(2) + "亿元";
- }
- return value.toFixed(2) + "万元";
- } else if (unit === "亿元") {
- return value.toFixed(2) + "亿元";
- } else {
- return value.toFixed(2) + unit;
- }
- }
- const absValue = Math.abs(value);
- if (absValue >= 100000000) {
- return (value / 100000000).toFixed(2) + "亿元";
- } else if (absValue >= 10000) {
- return (value / 10000).toFixed(2) + "万元";
- }
- return value.toFixed(2) + "元";
- },
- formatPercentage: (value) => {
- if (!value && value !== 0) return "-";
- return value.toFixed(2) + "%";
- },
-};
-
-// 免责声明组件
-const DisclaimerBox = () => {
- return (
-
-
-
-
- 免责声明
-
-
- 本内容由AI模型基于新闻、公告、研报等公开信息自动分析和生成,未经许可严禁转载。
- 所有内容仅供参考,不构成任何投资建议,请投资者注意风险,独立审慎决策。
-
-
-
- );
-};
-
-// 评分进度条组件
-const ScoreBar = ({ label, score, icon }) => {
- const percentage = (score / 100) * 100;
- const getColorScheme = () => {
- if (percentage >= 80) return "purple";
- if (percentage >= 60) return "blue";
- if (percentage >= 40) return "yellow";
- return "orange";
- };
-
- return (
-
-
-
- {icon && (
-
- )}
-
- {label}
-
-
- {score || 0}
-
-
-
- );
-};
-
-// 业务结构树形图组件
-const BusinessTreeItem = ({ business, depth = 0 }) => {
- const bgColor = "gray.50";
-
- return (
- 0 ? `4px solid` : "none"}
- borderLeftColor="blue.400"
- borderRadius="md"
- mb={2}
- _hover={{ shadow: "md" }}
- transition="all 0.2s"
- >
-
-
-
-
- {business.business_name}
-
- {business.financial_metrics?.revenue_ratio > 30 && (
-
- 核心业务
-
- )}
-
-
-
- 营收占比:{" "}
- {formatUtils.formatPercentage(
- business.financial_metrics?.revenue_ratio
- )}
-
-
- 毛利率:{" "}
- {formatUtils.formatPercentage(
- business.financial_metrics?.gross_margin
- )}
-
- {business.growth_metrics?.revenue_growth && (
- 0 ? "red" : "green"
- }
- >
-
- 增长: {business.growth_metrics.revenue_growth > 0 ? "+" : ""}
- {formatUtils.formatPercentage(
- business.growth_metrics.revenue_growth
- )}
-
-
- )}
-
-
-
-
- {(() => {
- const revenue =
- business.revenue || business.financial_metrics?.revenue;
- const unit = business.revenue_unit;
- if (revenue || revenue === 0) {
- return formatUtils.formatBusinessRevenue(revenue, unit);
- }
- return "-";
- })()}
-
-
- 营业收入
-
-
-
-
- );
-};
-
-// 产业链节点卡片
-const ValueChainNodeCard = ({ node, isCompany = false, level = 0 }) => {
- const { isOpen, onOpen, onClose } = useDisclosure();
- const [relatedCompanies, setRelatedCompanies] = useState([]);
- const [loadingRelated, setLoadingRelated] = useState(false);
- const toast = useToast();
-
- const getColorScheme = () => {
- if (isCompany) return "blue";
- if (level < 0) return "orange";
- if (level > 0) return "green";
- return "gray";
- };
-
- const colorScheme = getColorScheme();
- const bgColor = `${colorScheme}.50`;
- const borderColor = `${colorScheme}.200`;
-
- const getNodeTypeIcon = (type) => {
- const icons = {
- company: FaBuilding,
- supplier: FaHandshake,
- customer: FaUserTie,
- product: FaIndustry,
- service: FaCog,
- channel: FaNetworkWired,
- raw_material: FaFlask,
- };
- return icons[type] || FaBuilding;
- };
-
- const getImportanceColor = (score) => {
- if (score >= 80) return "red";
- if (score >= 60) return "orange";
- if (score >= 40) return "yellow";
- return "green";
- };
-
- const fetchRelatedCompanies = async () => {
- setLoadingRelated(true);
- try {
- const response = await fetch(
- `${API_BASE_URL}/api/company/value-chain/related-companies?node_name=${encodeURIComponent(
- node.node_name
- )}`
- );
- const data = await response.json();
- if (data.success) {
- setRelatedCompanies(data.data || []);
- } else {
- toast({
- title: "获取相关公司失败",
- description: data.message,
- status: "error",
- duration: 3000,
- isClosable: true,
- });
- }
- } catch (error) {
- logger.error("ValueChainNodeCard", "fetchRelatedCompanies", error, {
- node_name: node.node_name,
- });
- toast({
- title: "获取相关公司失败",
- description: error.message,
- status: "error",
- duration: 3000,
- isClosable: true,
- });
- } finally {
- setLoadingRelated(false);
- }
- };
-
- const handleCardClick = () => {
- onOpen();
- if (relatedCompanies.length === 0) {
- fetchRelatedCompanies();
- }
- };
-
- return (
- <>
-
-
-
-
-
-
-
- {isCompany && (
-
- 核心企业
-
- )}
-
- {node.importance_score >= 70 && (
-
-
-
- )}
-
-
-
- {node.node_name}
-
-
- {node.node_description && (
-
- {node.node_description}
-
- )}
-
-
-
- {node.node_type}
-
- {node.market_share && (
-
- 份额 {node.market_share}%
-
- )}
-
-
- {(node.importance_score || node.importance_score === 0) && (
-
-
-
- 重要度
-
-
- {node.importance_score}
-
-
-
-
- )}
-
-
-
-
-
-
-
-
-
-
-
-
- {node.node_name}
-
- {node.node_type}
- {isCompany && (
-
- 核心企业
-
- )}
-
-
-
-
-
-
-
- {node.node_description && (
-
-
- 节点描述
-
-
- {node.node_description}
-
-
- )}
-
-
-
- 重要度评分
-
- {node.importance_score || 0}
-
-
-
-
-
-
- {node.market_share && (
-
- 市场份额
- {node.market_share}%
-
- )}
-
- {node.dependency_degree && (
-
- 依赖程度
-
- {node.dependency_degree}%
-
-
-
-
- )}
-
-
-
-
-
-
-
- 相关公司
-
- {loadingRelated && }
-
- {loadingRelated ? (
-
-
-
- ) : relatedCompanies.length > 0 ? (
-
- {relatedCompanies.map((company, idx) => {
- const getLevelLabel = (level) => {
- if (level < 0) return { text: "上游", color: "orange" };
- if (level === 0) return { text: "核心", color: "blue" };
- if (level > 0) return { text: "下游", color: "green" };
- return { text: "未知", color: "gray" };
- };
- const levelInfo = getLevelLabel(
- company.node_info?.node_level
- );
-
- return (
-
-
-
-
-
-
-
- {company.stock_name}
-
-
- {company.stock_code}
-
-
- {levelInfo.text}
-
-
- {company.company_name && (
-
- {company.company_name}
-
- )}
-
- }
- variant="ghost"
- colorScheme="blue"
- onClick={() => {
- window.location.href = `/company?stock_code=${company.stock_code}`;
- }}
- aria-label="查看公司详情"
- />
-
-
- {company.node_info?.node_description && (
-
- {company.node_info.node_description}
-
- )}
-
- {company.relationships &&
- company.relationships.length > 0 && (
-
-
- 产业链关系:
-
-
- {company.relationships.map(
- (rel, ridx) => (
-
-
-
- {rel.role === "source"
- ? "流向"
- : "来自"}
-
- {rel.connected_node}
-
-
-
- )
- )}
-
-
- )}
-
-
-
- );
- })}
-
- ) : (
-
-
-
-
- 暂无相关公司
-
-
-
- )}
-
-
-
-
-
-
-
-
- >
- );
-};
-
-// 关键因素卡片
-const KeyFactorCard = ({ factor }) => {
- const impactColor =
- {
- positive: "red",
- negative: "green",
- neutral: "gray",
- mixed: "yellow",
- }[factor.impact_direction] || "gray";
-
- const bgColor = "white";
- const borderColor = "gray.200";
-
- return (
-
-
-
-
-
- {factor.factor_name}
-
-
- {factor.impact_direction === "positive"
- ? "正面"
- : factor.impact_direction === "negative"
- ? "负面"
- : factor.impact_direction === "mixed"
- ? "混合"
- : "中性"}
-
-
-
-
-
- {factor.factor_value}
- {factor.factor_unit && ` ${factor.factor_unit}`}
-
- {factor.year_on_year && (
- 0 ? "red" : "green"}
- >
- 0 ? FaArrowUp : FaArrowDown}
- mr={1}
- boxSize={3}
- />
- {Math.abs(factor.year_on_year)}%
-
- )}
-
-
- {factor.factor_desc && (
-
- {factor.factor_desc}
-
- )}
-
-
-
- 影响权重: {factor.impact_weight}
-
- {factor.report_period && (
-
- {factor.report_period}
-
- )}
-
-
-
-
- );
-};
-
-// 时间线组件
-const TimelineComponent = ({ events }) => {
- const [selectedEvent, setSelectedEvent] = useState(null);
- const { isOpen, onOpen, onClose } = useDisclosure();
-
- // 背景颜色
- const positiveBgColor = "red.50";
- const negativeBgColor = "green.50";
-
- const handleEventClick = (event) => {
- setSelectedEvent(event);
- onOpen();
- };
-
- return (
- <>
-
-
-
-
- {events.map((event, idx) => {
- const isPositive = event.impact_metrics?.is_positive;
- const iconColor = isPositive ? "red.500" : "green.500";
- const bgColor = isPositive ? positiveBgColor : negativeBgColor;
-
- return (
-
-
-
-
-
-
-
-
- handleEventClick(event)}
- _hover={{ shadow: "lg", transform: "translateX(4px)" }}
- transition="all 0.3s ease"
- >
-
-
-
-
-
- {event.event_title}
-
-
-
-
- {event.event_date}
-
-
-
-
- {event.event_type}
-
-
-
-
- {event.event_desc}
-
-
-
-
- 影响度:
-
-
-
-
-
-
-
- );
- })}
-
-
-
- {selectedEvent && (
-
-
-
-
-
-
-
- {selectedEvent.event_title}
-
-
- {selectedEvent.event_type}
-
-
- {selectedEvent.event_date}
-
-
-
-
-
-
-
-
-
-
- 事件详情
-
-
- {selectedEvent.event_desc}
-
-
-
- {selectedEvent.related_info?.financial_impact && (
-
-
- 财务影响
-
-
- {selectedEvent.related_info.financial_impact}
-
-
- )}
-
-
-
- 影响评估
-
-
-
-
- 影响度
-
-
-
-
- {selectedEvent.impact_metrics?.is_positive
- ? "正面影响"
- : "负面影响"}
-
-
-
-
-
-
-
-
-
-
-
- )}
- >
- );
-};
-
-// 生成雷达图配置
-const getRadarChartOption = (comprehensiveData) => {
- if (!comprehensiveData?.competitive_position?.scores) return null;
-
- const scores = comprehensiveData.competitive_position.scores;
- const indicators = [
- { name: "市场地位", max: 100 },
- { name: "技术实力", max: 100 },
- { name: "品牌价值", max: 100 },
- { name: "运营效率", max: 100 },
- { name: "财务健康", max: 100 },
- { name: "创新能力", max: 100 },
- { name: "风险控制", max: 100 },
- { name: "成长潜力", max: 100 },
- ];
-
- const data = [
- scores.market_position || 0,
- scores.technology || 0,
- scores.brand || 0,
- scores.operation || 0,
- scores.finance || 0,
- scores.innovation || 0,
- scores.risk || 0,
- scores.growth || 0,
- ];
-
- return {
- tooltip: { trigger: "item" },
- radar: {
- indicator: indicators,
- shape: "polygon",
- splitNumber: 4,
- name: { textStyle: { color: "#666", fontSize: 12 } },
- splitLine: {
- lineStyle: { color: ["#e8e8e8", "#e0e0e0", "#d0d0d0", "#c0c0c0"] },
- },
- splitArea: {
- show: true,
- areaStyle: {
- color: ["rgba(250,250,250,0.3)", "rgba(200,200,200,0.3)"],
- },
- },
- axisLine: { lineStyle: { color: "#ddd" } },
- },
- series: [
- {
- name: "竞争力评分",
- type: "radar",
- data: [
- {
- value: data,
- name: "当前评分",
- symbol: "circle",
- symbolSize: 5,
- lineStyle: { width: 2, color: "#3182ce" },
- areaStyle: { color: "rgba(49, 130, 206, 0.3)" },
- label: {
- show: true,
- formatter: (params) => params.value,
- color: "#3182ce",
- fontSize: 10,
- },
- },
- ],
- },
- ],
- };
-};
-
-// 生成桑基图配置
-const getSankeyChartOption = (valueChainData) => {
- if (
- !valueChainData?.value_chain_flows ||
- valueChainData.value_chain_flows.length === 0
- )
- return null;
-
- const nodes = new Set();
- const links = [];
-
- valueChainData.value_chain_flows.forEach((flow) => {
- if (!flow?.source?.node_name || !flow?.target?.node_name) return;
- nodes.add(flow.source.node_name);
- nodes.add(flow.target.node_name);
- links.push({
- source: flow.source.node_name,
- target: flow.target.node_name,
- value: parseFloat(flow.flow_metrics?.flow_ratio) || 1,
- lineStyle: { color: "source", opacity: 0.6 },
- });
- });
-
- return {
- tooltip: { trigger: "item", triggerOn: "mousemove" },
- series: [
- {
- type: "sankey",
- layout: "none",
- emphasis: { focus: "adjacency" },
- data: Array.from(nodes).map((name) => ({ name })),
- links: links,
- lineStyle: { color: "gradient", curveness: 0.5 },
- label: { color: "#333", fontSize: 10 },
- },
- ],
- };
-};
-
-// 深度分析 Tab 主组件
-const DeepAnalysisTab = ({
- comprehensiveData,
- valueChainData,
- keyFactorsData,
- loading,
- cardBg,
- expandedSegments,
- onToggleSegment,
-}) => {
- const blueBg = "blue.50";
- const greenBg = "green.50";
- const purpleBg = "purple.50";
- const orangeBg = "orange.50";
-
- if (loading) {
- return (
-
-
-
- 加载深度分析数据...
-
-
- );
- }
-
- return (
-
- {/* 核心定位卡片 */}
- {comprehensiveData?.qualitative_analysis && (
-
-
-
-
- 核心定位
-
-
-
-
-
- {comprehensiveData.qualitative_analysis.core_positioning
- ?.one_line_intro && (
-
-
-
- {
- comprehensiveData.qualitative_analysis.core_positioning
- .one_line_intro
- }
-
-
- )}
-
-
-
-
-
- 投资亮点
-
-
-
- {comprehensiveData.qualitative_analysis.core_positioning
- ?.investment_highlights || "暂无数据"}
-
-
-
-
-
-
-
-
- 商业模式
-
-
-
- {comprehensiveData.qualitative_analysis.core_positioning
- ?.business_model_desc || "暂无数据"}
-
-
-
-
-
-
-
-
- )}
-
- {/* 竞争地位分析 */}
- {comprehensiveData?.competitive_position && (
-
-
-
-
- 竞争地位分析
- {comprehensiveData.competitive_position.ranking && (
-
- 行业排名{" "}
- {comprehensiveData.competitive_position.ranking.industry_rank}
- /
- {
- comprehensiveData.competitive_position.ranking
- .total_companies
- }
-
- )}
-
-
-
-
- {comprehensiveData.competitive_position.analysis
- ?.main_competitors && (
-
-
- 主要竞争对手
-
-
- {comprehensiveData.competitive_position.analysis.main_competitors
- .split(",")
- .map((competitor, idx) => (
-
-
- {competitor.trim()}
-
- ))}
-
-
- )}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {getRadarChartOption(comprehensiveData) && (
-
- )}
-
-
-
-
-
-
-
-
- 竞争优势
-
-
- {comprehensiveData.competitive_position.analysis
- ?.competitive_advantages || "暂无数据"}
-
-
-
-
- 竞争劣势
-
-
- {comprehensiveData.competitive_position.analysis
- ?.competitive_disadvantages || "暂无数据"}
-
-
-
-
-
- )}
-
- {/* 业务结构分析 */}
- {comprehensiveData?.business_structure &&
- comprehensiveData.business_structure.length > 0 && (
-
-
-
-
- 业务结构分析
-
- {comprehensiveData.business_structure[0]?.report_period}
-
-
-
-
-
-
- {comprehensiveData.business_structure.map((business, idx) => (
-
- ))}
-
-
-
- )}
-
- {/* 产业链分析 */}
- {valueChainData && (
-
-
-
-
- 产业链分析
-
-
- 上游 {valueChainData.analysis_summary?.upstream_nodes || 0}
-
-
- 核心 {valueChainData.analysis_summary?.company_nodes || 0}
-
-
- 下游 {valueChainData.analysis_summary?.downstream_nodes || 0}
-
-
-
-
-
-
-
-
- 层级视图
- 流向关系
-
-
-
-
-
- {(valueChainData.value_chain_structure?.nodes_by_level?.[
- "level_-2"
- ] ||
- valueChainData.value_chain_structure?.nodes_by_level?.[
- "level_-1"
- ]) && (
-
-
-
- 上游供应链
-
-
- 原材料与供应商
-
-
-
- {[
- ...(valueChainData.value_chain_structure
- ?.nodes_by_level?.["level_-2"] || []),
- ...(valueChainData.value_chain_structure
- ?.nodes_by_level?.["level_-1"] || []),
- ].map((node, idx) => (
-
- ))}
-
-
- )}
-
- {valueChainData.value_chain_structure?.nodes_by_level?.[
- "level_0"
- ] && (
-
-
-
- 核心企业
-
-
- 公司主体与产品
-
-
-
- {valueChainData.value_chain_structure.nodes_by_level[
- "level_0"
- ].map((node, idx) => (
-
- ))}
-
-
- )}
-
- {(valueChainData.value_chain_structure?.nodes_by_level?.[
- "level_1"
- ] ||
- valueChainData.value_chain_structure?.nodes_by_level?.[
- "level_2"
- ]) && (
-
-
-
- 下游客户
-
-
- 客户与终端市场
-
-
-
- {[
- ...(valueChainData.value_chain_structure
- ?.nodes_by_level?.["level_1"] || []),
- ...(valueChainData.value_chain_structure
- ?.nodes_by_level?.["level_2"] || []),
- ].map((node, idx) => (
-
- ))}
-
-
- )}
-
-
-
-
- {getSankeyChartOption(valueChainData) ? (
-
- ) : (
-
- 暂无流向数据
-
- )}
-
-
-
-
-
- )}
-
- {/* 关键因素与发展时间线 */}
-
-
- {keyFactorsData?.key_factors && (
-
-
-
-
- 关键因素
- {keyFactorsData.key_factors.total_factors} 项
-
-
-
-
-
- {keyFactorsData.key_factors.categories.map(
- (category, idx) => (
-
-
-
-
-
- {category.category_name}
-
-
- {category.factors.length}
-
-
-
-
-
-
-
- {category.factors.map((factor, fidx) => (
-
- ))}
-
-
-
- )
- )}
-
-
-
- )}
-
-
-
- {keyFactorsData?.development_timeline && (
-
-
-
-
- 发展时间线
-
-
- 正面{" "}
- {keyFactorsData.development_timeline.statistics
- ?.positive_events || 0}
-
-
- 负面{" "}
- {keyFactorsData.development_timeline.statistics
- ?.negative_events || 0}
-
-
-
-
-
-
-
-
-
-
-
- )}
-
-
-
- {/* 业务板块详情 */}
- {comprehensiveData?.business_segments &&
- comprehensiveData.business_segments.length > 0 && (
-
-
-
-
- 业务板块详情
-
- {comprehensiveData.business_segments.length} 个板块
-
-
-
-
-
-
- {comprehensiveData.business_segments.map((segment, idx) => {
- const isExpanded = expandedSegments[idx];
-
- return (
-
-
-
-
-
- {segment.segment_name}
-
-
- }
- onClick={() => onToggleSegment(idx)}
- colorScheme="blue"
- >
- {isExpanded ? "折叠" : "展开"}
-
-
-
-
-
- 业务描述
-
-
- {segment.segment_description || "暂无描述"}
-
-
-
-
-
- 竞争地位
-
-
- {segment.competitive_position || "暂无数据"}
-
-
-
-
-
- 未来潜力
-
-
- {segment.future_potential || "暂无数据"}
-
-
-
- {isExpanded && segment.key_products && (
-
-
- 主要产品
-
-
- {segment.key_products}
-
-
- )}
-
- {isExpanded && segment.market_share && (
-
-
- 市场份额
-
-
- {segment.market_share}%
-
-
- )}
-
- {isExpanded && segment.revenue_contribution && (
-
-
- 营收贡献
-
-
- {segment.revenue_contribution}%
-
-
- )}
-
-
-
- );
- })}
-
-
-
- )}
-
- {/* 战略分析 */}
- {comprehensiveData?.qualitative_analysis?.strategy && (
-
-
-
-
- 战略分析
-
-
-
-
-
-
-
-
- 战略方向
-
-
-
- {comprehensiveData.qualitative_analysis.strategy
- .strategy_description || "暂无数据"}
-
-
-
-
-
-
-
-
- 战略举措
-
-
-
- {comprehensiveData.qualitative_analysis.strategy
- .strategic_initiatives || "暂无数据"}
-
-
-
-
-
-
-
- )}
-
- );
-};
-
-export default DeepAnalysisTab;
diff --git a/src/views/Company/components/CompanyOverview/DeepAnalysisTab/atoms/BusinessTreeItem.tsx b/src/views/Company/components/CompanyOverview/DeepAnalysisTab/atoms/BusinessTreeItem.tsx
new file mode 100644
index 00000000..1533f27d
--- /dev/null
+++ b/src/views/Company/components/CompanyOverview/DeepAnalysisTab/atoms/BusinessTreeItem.tsx
@@ -0,0 +1,86 @@
+/**
+ * 业务结构树形项组件
+ *
+ * 递归显示业务结构层级
+ * 使用位置:业务结构分析卡片
+ */
+
+import React from 'react';
+import { Box, HStack, VStack, Text, Badge, Tag, TagLabel } from '@chakra-ui/react';
+import { formatPercentage, formatBusinessRevenue } from '@utils/priceFormatters';
+import type { BusinessTreeItemProps } from '../types';
+
+const BusinessTreeItem: React.FC = ({ business, depth = 0 }) => {
+ const bgColor = 'gray.50';
+
+ // 获取营收显示
+ const getRevenueDisplay = (): string => {
+ const revenue = business.revenue || business.financial_metrics?.revenue;
+ const unit = business.revenue_unit;
+ if (revenue !== undefined && revenue !== null) {
+ return formatBusinessRevenue(revenue, unit);
+ }
+ return '-';
+ };
+
+ return (
+ 0 ? '4px solid' : 'none'}
+ borderLeftColor="blue.400"
+ borderRadius="md"
+ mb={2}
+ _hover={{ shadow: 'md' }}
+ transition="all 0.2s"
+ >
+
+
+
+
+ {business.business_name}
+
+ {business.financial_metrics?.revenue_ratio &&
+ business.financial_metrics.revenue_ratio > 30 && (
+
+ 核心业务
+
+ )}
+
+
+
+ 营收占比: {formatPercentage(business.financial_metrics?.revenue_ratio)}
+
+
+ 毛利率: {formatPercentage(business.financial_metrics?.gross_margin)}
+
+ {business.growth_metrics?.revenue_growth !== undefined && (
+ 0 ? 'red' : 'green'
+ }
+ >
+
+ 增长: {business.growth_metrics.revenue_growth > 0 ? '+' : ''}
+ {formatPercentage(business.growth_metrics.revenue_growth)}
+
+
+ )}
+
+
+
+
+ {getRevenueDisplay()}
+
+
+ 营业收入
+
+
+
+
+ );
+};
+
+export default BusinessTreeItem;
diff --git a/src/views/Company/components/CompanyOverview/DeepAnalysisTab/atoms/DisclaimerBox.tsx b/src/views/Company/components/CompanyOverview/DeepAnalysisTab/atoms/DisclaimerBox.tsx
new file mode 100644
index 00000000..91612f48
--- /dev/null
+++ b/src/views/Company/components/CompanyOverview/DeepAnalysisTab/atoms/DisclaimerBox.tsx
@@ -0,0 +1,28 @@
+/**
+ * 免责声明组件
+ *
+ * 显示 AI 分析内容的免责声明警告框
+ * 使用位置:深度分析各 Card 底部(共 6 处)
+ */
+
+import React from 'react';
+import { Alert, AlertIcon, Box, Text } from '@chakra-ui/react';
+
+const DisclaimerBox: React.FC = () => {
+ return (
+
+
+
+
+ 免责声明
+
+
+ 本内容由AI模型基于新闻、公告、研报等公开信息自动分析和生成,未经许可严禁转载。
+ 所有内容仅供参考,不构成任何投资建议,请投资者注意风险,独立审慎决策。
+
+
+
+ );
+};
+
+export default DisclaimerBox;
diff --git a/src/views/Company/components/CompanyOverview/DeepAnalysisTab/atoms/KeyFactorCard.tsx b/src/views/Company/components/CompanyOverview/DeepAnalysisTab/atoms/KeyFactorCard.tsx
new file mode 100644
index 00000000..fb15fc75
--- /dev/null
+++ b/src/views/Company/components/CompanyOverview/DeepAnalysisTab/atoms/KeyFactorCard.tsx
@@ -0,0 +1,108 @@
+/**
+ * 关键因素卡片组件
+ *
+ * 显示单个关键因素的详细信息
+ * 使用位置:关键因素 Accordion 内
+ */
+
+import React from 'react';
+import {
+ Card,
+ CardBody,
+ VStack,
+ HStack,
+ Text,
+ Badge,
+ Tag,
+ Icon,
+} from '@chakra-ui/react';
+import { FaArrowUp, FaArrowDown } from 'react-icons/fa';
+import type { KeyFactorCardProps, ImpactDirection } from '../types';
+
+/**
+ * 获取影响方向对应的颜色
+ */
+const getImpactColor = (direction?: ImpactDirection): string => {
+ const colorMap: Record = {
+ positive: 'red',
+ negative: 'green',
+ neutral: 'gray',
+ mixed: 'yellow',
+ };
+ return colorMap[direction || 'neutral'] || 'gray';
+};
+
+/**
+ * 获取影响方向的中文标签
+ */
+const getImpactLabel = (direction?: ImpactDirection): string => {
+ const labelMap: Record = {
+ positive: '正面',
+ negative: '负面',
+ neutral: '中性',
+ mixed: '混合',
+ };
+ return labelMap[direction || 'neutral'] || '中性';
+};
+
+const KeyFactorCard: React.FC = ({ factor }) => {
+ const impactColor = getImpactColor(factor.impact_direction);
+ const bgColor = 'white';
+ const borderColor = 'gray.200';
+
+ return (
+
+
+
+
+
+ {factor.factor_name}
+
+
+ {getImpactLabel(factor.impact_direction)}
+
+
+
+
+
+ {factor.factor_value}
+ {factor.factor_unit && ` ${factor.factor_unit}`}
+
+ {factor.year_on_year !== undefined && (
+ 0 ? 'red' : 'green'}
+ >
+ 0 ? FaArrowUp : FaArrowDown}
+ mr={1}
+ boxSize={3}
+ />
+ {Math.abs(factor.year_on_year)}%
+
+ )}
+
+
+ {factor.factor_desc && (
+
+ {factor.factor_desc}
+
+ )}
+
+
+
+ 影响权重: {factor.impact_weight}
+
+ {factor.report_period && (
+
+ {factor.report_period}
+
+ )}
+
+
+
+
+ );
+};
+
+export default KeyFactorCard;
diff --git a/src/views/Company/components/CompanyOverview/DeepAnalysisTab/atoms/ScoreBar.tsx b/src/views/Company/components/CompanyOverview/DeepAnalysisTab/atoms/ScoreBar.tsx
new file mode 100644
index 00000000..338d57f2
--- /dev/null
+++ b/src/views/Company/components/CompanyOverview/DeepAnalysisTab/atoms/ScoreBar.tsx
@@ -0,0 +1,51 @@
+/**
+ * 评分进度条组件
+ *
+ * 显示带图标的评分进度条
+ * 使用位置:竞争力分析区域(共 8 处)
+ */
+
+import React from 'react';
+import { Box, HStack, Text, Badge, Progress, Icon } from '@chakra-ui/react';
+import type { ScoreBarProps } from '../types';
+
+/**
+ * 根据分数百分比获取颜色方案
+ */
+const getColorScheme = (percentage: number): string => {
+ if (percentage >= 80) return 'purple';
+ if (percentage >= 60) return 'blue';
+ if (percentage >= 40) return 'yellow';
+ return 'orange';
+};
+
+const ScoreBar: React.FC = ({ label, score, icon }) => {
+ const percentage = ((score || 0) / 100) * 100;
+ const colorScheme = getColorScheme(percentage);
+
+ return (
+
+
+
+ {icon && (
+
+ )}
+
+ {label}
+
+
+ {score || 0}
+
+
+
+ );
+};
+
+export default ScoreBar;
diff --git a/src/views/Company/components/CompanyOverview/DeepAnalysisTab/atoms/index.ts b/src/views/Company/components/CompanyOverview/DeepAnalysisTab/atoms/index.ts
new file mode 100644
index 00000000..11267f56
--- /dev/null
+++ b/src/views/Company/components/CompanyOverview/DeepAnalysisTab/atoms/index.ts
@@ -0,0 +1,10 @@
+/**
+ * 原子组件导出
+ *
+ * DeepAnalysisTab 内部使用的基础 UI 组件
+ */
+
+export { default as DisclaimerBox } from './DisclaimerBox';
+export { default as ScoreBar } from './ScoreBar';
+export { default as BusinessTreeItem } from './BusinessTreeItem';
+export { default as KeyFactorCard } from './KeyFactorCard';
diff --git a/src/views/Company/components/CompanyOverview/DeepAnalysisTab/components/BusinessSegmentsCard.tsx b/src/views/Company/components/CompanyOverview/DeepAnalysisTab/components/BusinessSegmentsCard.tsx
new file mode 100644
index 00000000..c7e63282
--- /dev/null
+++ b/src/views/Company/components/CompanyOverview/DeepAnalysisTab/components/BusinessSegmentsCard.tsx
@@ -0,0 +1,157 @@
+/**
+ * 业务板块详情卡片
+ *
+ * 显示公司各业务板块的详细信息
+ */
+
+import React from 'react';
+import {
+ Card,
+ CardBody,
+ CardHeader,
+ VStack,
+ HStack,
+ Text,
+ Heading,
+ Badge,
+ Box,
+ Icon,
+ SimpleGrid,
+ Button,
+} from '@chakra-ui/react';
+import { FaIndustry, FaExpandAlt, FaCompressAlt } from 'react-icons/fa';
+import { DisclaimerBox } from '../atoms';
+import type { BusinessSegment } from '../types';
+
+interface BusinessSegmentsCardProps {
+ businessSegments: BusinessSegment[];
+ expandedSegments: Record;
+ onToggleSegment: (index: number) => void;
+ cardBg?: string;
+}
+
+const BusinessSegmentsCard: React.FC = ({
+ businessSegments,
+ expandedSegments,
+ onToggleSegment,
+ cardBg,
+}) => {
+ if (!businessSegments || businessSegments.length === 0) return null;
+
+ return (
+
+
+
+
+ 业务板块详情
+ {businessSegments.length} 个板块
+
+
+
+
+
+ {businessSegments.map((segment, idx) => {
+ const isExpanded = expandedSegments[idx];
+
+ return (
+
+
+
+
+
+ {segment.segment_name}
+
+
+ }
+ onClick={() => onToggleSegment(idx)}
+ colorScheme="blue"
+ >
+ {isExpanded ? '折叠' : '展开'}
+
+
+
+
+
+ 业务描述
+
+
+ {segment.segment_description || '暂无描述'}
+
+
+
+
+
+ 竞争地位
+
+
+ {segment.competitive_position || '暂无数据'}
+
+
+
+
+
+ 未来潜力
+
+
+ {segment.future_potential || '暂无数据'}
+
+
+
+ {isExpanded && segment.key_products && (
+
+
+ 主要产品
+
+
+ {segment.key_products}
+
+
+ )}
+
+ {isExpanded && segment.market_share !== undefined && (
+
+
+ 市场份额
+
+
+ {segment.market_share}%
+
+
+ )}
+
+ {isExpanded && segment.revenue_contribution !== undefined && (
+
+
+ 营收贡献
+
+
+ {segment.revenue_contribution}%
+
+
+ )}
+
+
+
+ );
+ })}
+
+
+
+ );
+};
+
+export default BusinessSegmentsCard;
diff --git a/src/views/Company/components/CompanyOverview/DeepAnalysisTab/components/BusinessStructureCard.tsx b/src/views/Company/components/CompanyOverview/DeepAnalysisTab/components/BusinessStructureCard.tsx
new file mode 100644
index 00000000..9d51726b
--- /dev/null
+++ b/src/views/Company/components/CompanyOverview/DeepAnalysisTab/components/BusinessStructureCard.tsx
@@ -0,0 +1,58 @@
+/**
+ * 业务结构分析卡片
+ *
+ * 显示公司业务结构树形图
+ */
+
+import React from 'react';
+import {
+ Card,
+ CardBody,
+ CardHeader,
+ VStack,
+ HStack,
+ Heading,
+ Badge,
+ Icon,
+} from '@chakra-ui/react';
+import { FaChartPie } from 'react-icons/fa';
+import { DisclaimerBox, BusinessTreeItem } from '../atoms';
+import type { BusinessStructure } from '../types';
+
+interface BusinessStructureCardProps {
+ businessStructure: BusinessStructure[];
+ cardBg?: string;
+}
+
+const BusinessStructureCard: React.FC = ({
+ businessStructure,
+ cardBg,
+}) => {
+ if (!businessStructure || businessStructure.length === 0) return null;
+
+ return (
+
+
+
+
+ 业务结构分析
+ {businessStructure[0]?.report_period}
+
+
+
+
+
+ {businessStructure.map((business, idx) => (
+
+ ))}
+
+
+
+ );
+};
+
+export default BusinessStructureCard;
diff --git a/src/views/Company/components/CompanyOverview/DeepAnalysisTab/components/CompetitiveAnalysisCard.tsx b/src/views/Company/components/CompanyOverview/DeepAnalysisTab/components/CompetitiveAnalysisCard.tsx
new file mode 100644
index 00000000..480c03e4
--- /dev/null
+++ b/src/views/Company/components/CompanyOverview/DeepAnalysisTab/components/CompetitiveAnalysisCard.tsx
@@ -0,0 +1,182 @@
+/**
+ * 竞争地位分析卡片
+ *
+ * 显示竞争力评分、雷达图和竞争分析
+ */
+
+import React from 'react';
+import {
+ Card,
+ CardBody,
+ CardHeader,
+ VStack,
+ HStack,
+ Text,
+ Heading,
+ Badge,
+ Tag,
+ TagLabel,
+ Grid,
+ GridItem,
+ Box,
+ Icon,
+ Divider,
+ SimpleGrid,
+} from '@chakra-ui/react';
+import {
+ FaTrophy,
+ FaCog,
+ FaStar,
+ FaChartLine,
+ FaDollarSign,
+ FaFlask,
+ FaShieldAlt,
+ FaRocket,
+ FaUsers,
+} from 'react-icons/fa';
+import ReactECharts from 'echarts-for-react';
+import { DisclaimerBox, ScoreBar } from '../atoms';
+import { getRadarChartOption } from '../utils/chartOptions';
+import type { ComprehensiveData } from '../types';
+
+interface CompetitiveAnalysisCardProps {
+ comprehensiveData: ComprehensiveData;
+ cardBg?: string;
+}
+
+const CompetitiveAnalysisCard: React.FC = ({
+ comprehensiveData,
+ cardBg,
+}) => {
+ const competitivePosition = comprehensiveData.competitive_position;
+ if (!competitivePosition) return null;
+
+ const radarOption = getRadarChartOption(comprehensiveData);
+
+ return (
+
+
+
+
+ 竞争地位分析
+ {competitivePosition.ranking && (
+
+ 行业排名 {competitivePosition.ranking.industry_rank}/
+ {competitivePosition.ranking.total_companies}
+
+ )}
+
+
+
+
+
+ {/* 主要竞争对手 */}
+ {competitivePosition.analysis?.main_competitors && (
+
+
+ 主要竞争对手
+
+
+ {competitivePosition.analysis.main_competitors
+ .split(',')
+ .map((competitor, idx) => (
+
+
+ {competitor.trim()}
+
+ ))}
+
+
+ )}
+
+ {/* 评分和雷达图 */}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {radarOption && (
+
+ )}
+
+
+
+
+
+ {/* 竞争优势和劣势 */}
+
+
+
+ 竞争优势
+
+
+ {competitivePosition.analysis?.competitive_advantages || '暂无数据'}
+
+
+
+
+ 竞争劣势
+
+
+ {competitivePosition.analysis?.competitive_disadvantages || '暂无数据'}
+
+
+
+
+
+ );
+};
+
+export default CompetitiveAnalysisCard;
diff --git a/src/views/Company/components/CompanyOverview/DeepAnalysisTab/components/CorePositioningCard.tsx b/src/views/Company/components/CompanyOverview/DeepAnalysisTab/components/CorePositioningCard.tsx
new file mode 100644
index 00000000..7138179c
--- /dev/null
+++ b/src/views/Company/components/CompanyOverview/DeepAnalysisTab/components/CorePositioningCard.tsx
@@ -0,0 +1,94 @@
+/**
+ * 核心定位卡片
+ *
+ * 显示公司的核心定位、投资亮点和商业模式
+ */
+
+import React from 'react';
+import {
+ Card,
+ CardBody,
+ CardHeader,
+ VStack,
+ HStack,
+ Text,
+ Heading,
+ Alert,
+ AlertIcon,
+ Grid,
+ GridItem,
+ Box,
+ Icon,
+} from '@chakra-ui/react';
+import { FaLightbulb } from 'react-icons/fa';
+import { DisclaimerBox } from '../atoms';
+import type { QualitativeAnalysis } from '../types';
+
+interface CorePositioningCardProps {
+ qualitativeAnalysis: QualitativeAnalysis;
+ cardBg?: string;
+}
+
+const CorePositioningCard: React.FC = ({
+ qualitativeAnalysis,
+ cardBg,
+}) => {
+ const blueBg = 'blue.50';
+ const greenBg = 'green.50';
+
+ return (
+
+
+
+
+ 核心定位
+
+
+
+
+
+ {qualitativeAnalysis.core_positioning?.one_line_intro && (
+
+
+
+ {qualitativeAnalysis.core_positioning.one_line_intro}
+
+
+ )}
+
+
+
+
+
+ 投资亮点
+
+
+
+ {qualitativeAnalysis.core_positioning?.investment_highlights ||
+ '暂无数据'}
+
+
+
+
+
+
+
+
+ 商业模式
+
+
+
+ {qualitativeAnalysis.core_positioning?.business_model_desc ||
+ '暂无数据'}
+
+
+
+
+
+
+
+
+ );
+};
+
+export default CorePositioningCard;
diff --git a/src/views/Company/components/CompanyOverview/DeepAnalysisTab/components/KeyFactorsCard.tsx b/src/views/Company/components/CompanyOverview/DeepAnalysisTab/components/KeyFactorsCard.tsx
new file mode 100644
index 00000000..3c653449
--- /dev/null
+++ b/src/views/Company/components/CompanyOverview/DeepAnalysisTab/components/KeyFactorsCard.tsx
@@ -0,0 +1,78 @@
+/**
+ * 关键因素卡片
+ *
+ * 显示影响公司的关键因素列表
+ */
+
+import React from 'react';
+import {
+ Card,
+ CardBody,
+ CardHeader,
+ VStack,
+ HStack,
+ Text,
+ Heading,
+ Badge,
+ Box,
+ Icon,
+ Accordion,
+ AccordionItem,
+ AccordionButton,
+ AccordionPanel,
+ AccordionIcon,
+} from '@chakra-ui/react';
+import { FaBalanceScale } from 'react-icons/fa';
+import { DisclaimerBox, KeyFactorCard } from '../atoms';
+import type { KeyFactors } from '../types';
+
+interface KeyFactorsCardProps {
+ keyFactors: KeyFactors;
+ cardBg?: string;
+}
+
+const KeyFactorsCard: React.FC = ({
+ keyFactors,
+ cardBg,
+}) => {
+ return (
+
+
+
+
+ 关键因素
+ {keyFactors.total_factors} 项
+
+
+
+
+
+ {keyFactors.categories.map((category, idx) => (
+
+
+
+
+ {category.category_name}
+
+ {category.factors.length}
+
+
+
+
+
+
+
+ {category.factors.map((factor, fidx) => (
+
+ ))}
+
+
+
+ ))}
+
+
+
+ );
+};
+
+export default KeyFactorsCard;
diff --git a/src/views/Company/components/CompanyOverview/DeepAnalysisTab/components/StrategyAnalysisCard.tsx b/src/views/Company/components/CompanyOverview/DeepAnalysisTab/components/StrategyAnalysisCard.tsx
new file mode 100644
index 00000000..fe411b5f
--- /dev/null
+++ b/src/views/Company/components/CompanyOverview/DeepAnalysisTab/components/StrategyAnalysisCard.tsx
@@ -0,0 +1,79 @@
+/**
+ * 战略分析卡片
+ *
+ * 显示公司战略方向和战略举措
+ */
+
+import React from 'react';
+import {
+ Card,
+ CardBody,
+ CardHeader,
+ VStack,
+ HStack,
+ Text,
+ Heading,
+ Box,
+ Icon,
+ Grid,
+ GridItem,
+} from '@chakra-ui/react';
+import { FaRocket } from 'react-icons/fa';
+import { DisclaimerBox } from '../atoms';
+import type { Strategy } from '../types';
+
+interface StrategyAnalysisCardProps {
+ strategy: Strategy;
+ cardBg?: string;
+}
+
+const StrategyAnalysisCard: React.FC = ({
+ strategy,
+ cardBg,
+}) => {
+ const purpleBg = 'purple.50';
+ const orangeBg = 'orange.50';
+
+ return (
+
+
+
+
+ 战略分析
+
+
+
+
+
+
+
+
+ 战略方向
+
+
+
+ {strategy.strategy_description || '暂无数据'}
+
+
+
+
+
+
+
+
+ 战略举措
+
+
+
+ {strategy.strategic_initiatives || '暂无数据'}
+
+
+
+
+
+
+
+ );
+};
+
+export default StrategyAnalysisCard;
diff --git a/src/views/Company/components/CompanyOverview/DeepAnalysisTab/components/TimelineCard.tsx b/src/views/Company/components/CompanyOverview/DeepAnalysisTab/components/TimelineCard.tsx
new file mode 100644
index 00000000..51c05026
--- /dev/null
+++ b/src/views/Company/components/CompanyOverview/DeepAnalysisTab/components/TimelineCard.tsx
@@ -0,0 +1,58 @@
+/**
+ * 发展时间线卡片
+ *
+ * 显示公司发展历程时间线
+ */
+
+import React from 'react';
+import {
+ Card,
+ CardBody,
+ CardHeader,
+ HStack,
+ Heading,
+ Badge,
+ Box,
+ Icon,
+} from '@chakra-ui/react';
+import { FaHistory } from 'react-icons/fa';
+import { DisclaimerBox } from '../atoms';
+import TimelineComponent from '../organisms/TimelineComponent';
+import type { DevelopmentTimeline } from '../types';
+
+interface TimelineCardProps {
+ developmentTimeline: DevelopmentTimeline;
+ cardBg?: string;
+}
+
+const TimelineCard: React.FC = ({
+ developmentTimeline,
+ cardBg,
+}) => {
+ return (
+
+
+
+
+ 发展时间线
+
+
+ 正面 {developmentTimeline.statistics?.positive_events || 0}
+
+
+ 负面 {developmentTimeline.statistics?.negative_events || 0}
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+export default TimelineCard;
diff --git a/src/views/Company/components/CompanyOverview/DeepAnalysisTab/components/ValueChainCard.tsx b/src/views/Company/components/CompanyOverview/DeepAnalysisTab/components/ValueChainCard.tsx
new file mode 100644
index 00000000..217aa9bb
--- /dev/null
+++ b/src/views/Company/components/CompanyOverview/DeepAnalysisTab/components/ValueChainCard.tsx
@@ -0,0 +1,185 @@
+/**
+ * 产业链分析卡片
+ *
+ * 显示产业链层级视图和流向关系
+ */
+
+import React from 'react';
+import {
+ Card,
+ CardBody,
+ CardHeader,
+ VStack,
+ HStack,
+ Text,
+ Heading,
+ Badge,
+ Box,
+ Icon,
+ SimpleGrid,
+ Tabs,
+ TabList,
+ TabPanels,
+ Tab,
+ TabPanel,
+ Center,
+} from '@chakra-ui/react';
+import { FaNetworkWired } from 'react-icons/fa';
+import ReactECharts from 'echarts-for-react';
+import { DisclaimerBox } from '../atoms';
+import ValueChainNodeCard from '../organisms/ValueChainNodeCard';
+import { getSankeyChartOption } from '../utils/chartOptions';
+import type { ValueChainData } from '../types';
+
+interface ValueChainCardProps {
+ valueChainData: ValueChainData;
+ cardBg?: string;
+}
+
+const ValueChainCard: React.FC = ({
+ valueChainData,
+ cardBg,
+}) => {
+ const sankeyOption = getSankeyChartOption(valueChainData);
+ const nodesByLevel = valueChainData.value_chain_structure?.nodes_by_level;
+
+ // 获取上游节点
+ const upstreamNodes = [
+ ...(nodesByLevel?.['level_-2'] || []),
+ ...(nodesByLevel?.['level_-1'] || []),
+ ];
+
+ // 获取核心节点
+ const coreNodes = nodesByLevel?.['level_0'] || [];
+
+ // 获取下游节点
+ const downstreamNodes = [
+ ...(nodesByLevel?.['level_1'] || []),
+ ...(nodesByLevel?.['level_2'] || []),
+ ];
+
+ return (
+
+
+
+
+ 产业链分析
+
+
+ 上游 {valueChainData.analysis_summary?.upstream_nodes || 0}
+
+
+ 核心 {valueChainData.analysis_summary?.company_nodes || 0}
+
+
+ 下游 {valueChainData.analysis_summary?.downstream_nodes || 0}
+
+
+
+
+
+
+
+
+ 层级视图
+ 流向关系
+
+
+
+ {/* 层级视图 */}
+
+
+ {/* 上游供应链 */}
+ {upstreamNodes.length > 0 && (
+
+
+
+ 上游供应链
+
+
+ 原材料与供应商
+
+
+
+ {upstreamNodes.map((node, idx) => (
+
+ ))}
+
+
+ )}
+
+ {/* 核心企业 */}
+ {coreNodes.length > 0 && (
+
+
+
+ 核心企业
+
+
+ 公司主体与产品
+
+
+
+ {coreNodes.map((node, idx) => (
+
+ ))}
+
+
+ )}
+
+ {/* 下游客户 */}
+ {downstreamNodes.length > 0 && (
+
+
+
+ 下游客户
+
+
+ 客户与终端市场
+
+
+
+ {downstreamNodes.map((node, idx) => (
+
+ ))}
+
+
+ )}
+
+
+
+ {/* 流向关系 */}
+
+ {sankeyOption ? (
+
+ ) : (
+
+ 暂无流向数据
+
+ )}
+
+
+
+
+
+ );
+};
+
+export default ValueChainCard;
diff --git a/src/views/Company/components/CompanyOverview/DeepAnalysisTab/components/index.ts b/src/views/Company/components/CompanyOverview/DeepAnalysisTab/components/index.ts
new file mode 100644
index 00000000..f3e4d8b7
--- /dev/null
+++ b/src/views/Company/components/CompanyOverview/DeepAnalysisTab/components/index.ts
@@ -0,0 +1,14 @@
+/**
+ * Card 子组件导出
+ *
+ * DeepAnalysisTab 的各个区块组件
+ */
+
+export { default as CorePositioningCard } from './CorePositioningCard';
+export { default as CompetitiveAnalysisCard } from './CompetitiveAnalysisCard';
+export { default as BusinessStructureCard } from './BusinessStructureCard';
+export { default as ValueChainCard } from './ValueChainCard';
+export { default as KeyFactorsCard } from './KeyFactorsCard';
+export { default as TimelineCard } from './TimelineCard';
+export { default as BusinessSegmentsCard } from './BusinessSegmentsCard';
+export { default as StrategyAnalysisCard } from './StrategyAnalysisCard';
diff --git a/src/views/Company/components/CompanyOverview/DeepAnalysisTab/index.tsx b/src/views/Company/components/CompanyOverview/DeepAnalysisTab/index.tsx
new file mode 100644
index 00000000..5f600040
--- /dev/null
+++ b/src/views/Company/components/CompanyOverview/DeepAnalysisTab/index.tsx
@@ -0,0 +1,117 @@
+/**
+ * 深度分析 Tab 主组件
+ *
+ * 组合所有子组件,显示公司深度分析内容
+ */
+
+import React from 'react';
+import { VStack, Center, Text, Spinner, Grid, GridItem } from '@chakra-ui/react';
+import {
+ CorePositioningCard,
+ CompetitiveAnalysisCard,
+ BusinessStructureCard,
+ ValueChainCard,
+ KeyFactorsCard,
+ TimelineCard,
+ BusinessSegmentsCard,
+ StrategyAnalysisCard,
+} from './components';
+import type { DeepAnalysisTabProps } from './types';
+
+const DeepAnalysisTab: React.FC = ({
+ comprehensiveData,
+ valueChainData,
+ keyFactorsData,
+ loading,
+ cardBg,
+ expandedSegments,
+ onToggleSegment,
+}) => {
+ // 加载状态
+ if (loading) {
+ return (
+
+
+
+ 加载深度分析数据...
+
+
+ );
+ }
+
+ return (
+
+ {/* 核心定位卡片 */}
+ {comprehensiveData?.qualitative_analysis && (
+
+ )}
+
+ {/* 竞争地位分析 */}
+ {comprehensiveData?.competitive_position && (
+
+ )}
+
+ {/* 业务结构分析 */}
+ {comprehensiveData?.business_structure &&
+ comprehensiveData.business_structure.length > 0 && (
+
+ )}
+
+ {/* 产业链分析 */}
+ {valueChainData && (
+
+ )}
+
+ {/* 关键因素与发展时间线 */}
+
+
+ {keyFactorsData?.key_factors && (
+
+ )}
+
+
+
+ {keyFactorsData?.development_timeline && (
+
+ )}
+
+
+
+ {/* 业务板块详情 */}
+ {comprehensiveData?.business_segments &&
+ comprehensiveData.business_segments.length > 0 && (
+
+ )}
+
+ {/* 战略分析 */}
+ {comprehensiveData?.qualitative_analysis?.strategy && (
+
+ )}
+
+ );
+};
+
+export default DeepAnalysisTab;
diff --git a/src/views/Company/components/CompanyOverview/DeepAnalysisTab/organisms/TimelineComponent/EventDetailModal.tsx b/src/views/Company/components/CompanyOverview/DeepAnalysisTab/organisms/TimelineComponent/EventDetailModal.tsx
new file mode 100644
index 00000000..040c47f3
--- /dev/null
+++ b/src/views/Company/components/CompanyOverview/DeepAnalysisTab/organisms/TimelineComponent/EventDetailModal.tsx
@@ -0,0 +1,136 @@
+/**
+ * 事件详情模态框组件
+ *
+ * 显示时间线事件的详细信息
+ */
+
+import React from 'react';
+import {
+ Modal,
+ ModalOverlay,
+ ModalContent,
+ ModalHeader,
+ ModalFooter,
+ ModalBody,
+ ModalCloseButton,
+ VStack,
+ HStack,
+ Text,
+ Badge,
+ Box,
+ Progress,
+ Icon,
+ Button,
+} from '@chakra-ui/react';
+import { FaCheckCircle, FaExclamationCircle } from 'react-icons/fa';
+import type { TimelineEvent } from '../../types';
+
+interface EventDetailModalProps {
+ isOpen: boolean;
+ onClose: () => void;
+ event: TimelineEvent | null;
+}
+
+const EventDetailModal: React.FC = ({
+ isOpen,
+ onClose,
+ event,
+}) => {
+ if (!event) return null;
+
+ const isPositive = event.impact_metrics?.is_positive;
+ const impactScore = event.impact_metrics?.impact_score || 0;
+
+ return (
+
+
+
+
+
+
+
+ {event.event_title}
+
+
+ {event.event_type}
+
+
+ {event.event_date}
+
+
+
+
+
+
+
+
+
+
+ 事件详情
+
+
+ {event.event_desc}
+
+
+
+ {event.related_info?.financial_impact && (
+
+
+ 财务影响
+
+
+ {event.related_info.financial_impact}
+
+
+ )}
+
+
+
+ 影响评估
+
+
+
+
+ 影响度
+
+
+
+
+ {isPositive ? '正面影响' : '负面影响'}
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+export default EventDetailModal;
diff --git a/src/views/Company/components/CompanyOverview/DeepAnalysisTab/organisms/TimelineComponent/index.tsx b/src/views/Company/components/CompanyOverview/DeepAnalysisTab/organisms/TimelineComponent/index.tsx
new file mode 100644
index 00000000..b5a746f2
--- /dev/null
+++ b/src/views/Company/components/CompanyOverview/DeepAnalysisTab/organisms/TimelineComponent/index.tsx
@@ -0,0 +1,178 @@
+/**
+ * 时间线组件
+ *
+ * 显示公司发展事件时间线
+ */
+
+import React, { useState } from 'react';
+import {
+ Box,
+ VStack,
+ HStack,
+ Text,
+ Badge,
+ Card,
+ CardBody,
+ Icon,
+ Progress,
+ Circle,
+ Fade,
+ useDisclosure,
+} from '@chakra-ui/react';
+import {
+ FaCalendarAlt,
+ FaArrowUp,
+ FaArrowDown,
+} from 'react-icons/fa';
+import EventDetailModal from './EventDetailModal';
+import type { TimelineComponentProps, TimelineEvent } from '../../types';
+
+const TimelineComponent: React.FC = ({ events }) => {
+ const [selectedEvent, setSelectedEvent] = useState(null);
+ const { isOpen, onOpen, onClose } = useDisclosure();
+
+ // 背景颜色
+ const positiveBgColor = 'red.50';
+ const negativeBgColor = 'green.50';
+
+ const handleEventClick = (event: TimelineEvent) => {
+ setSelectedEvent(event);
+ onOpen();
+ };
+
+ return (
+ <>
+
+ {/* 时间线轴 */}
+
+
+
+ {events.map((event, idx) => {
+ const isPositive = event.impact_metrics?.is_positive;
+ const iconColor = isPositive ? 'red.500' : 'green.500';
+ const bgColor = isPositive ? positiveBgColor : negativeBgColor;
+
+ return (
+
+
+ {/* 时间点圆圈 */}
+
+
+
+
+ {/* 连接线 */}
+
+
+ {/* 事件卡片 */}
+ handleEventClick(event)}
+ _hover={{ shadow: 'lg', transform: 'translateX(4px)' }}
+ transition="all 0.3s ease"
+ >
+
+
+
+
+
+ {event.event_title}
+
+
+
+
+ {event.event_date}
+
+
+
+
+ {event.event_type}
+
+
+
+
+ {event.event_desc}
+
+
+
+
+ 影响度:
+
+
+
+
+
+
+
+ );
+ })}
+
+
+
+
+ >
+ );
+};
+
+export default TimelineComponent;
diff --git a/src/views/Company/components/CompanyOverview/DeepAnalysisTab/organisms/ValueChainNodeCard/RelatedCompaniesModal.tsx b/src/views/Company/components/CompanyOverview/DeepAnalysisTab/organisms/ValueChainNodeCard/RelatedCompaniesModal.tsx
new file mode 100644
index 00000000..bf900b61
--- /dev/null
+++ b/src/views/Company/components/CompanyOverview/DeepAnalysisTab/organisms/ValueChainNodeCard/RelatedCompaniesModal.tsx
@@ -0,0 +1,346 @@
+/**
+ * 相关公司模态框组件
+ *
+ * 显示产业链节点的相关上市公司列表
+ */
+
+import React from 'react';
+import {
+ Modal,
+ ModalOverlay,
+ ModalContent,
+ ModalHeader,
+ ModalFooter,
+ ModalBody,
+ ModalCloseButton,
+ VStack,
+ HStack,
+ Text,
+ Badge,
+ Card,
+ CardBody,
+ Icon,
+ IconButton,
+ Center,
+ Spinner,
+ Divider,
+ SimpleGrid,
+ Box,
+ Stat,
+ StatLabel,
+ StatNumber,
+ StatHelpText,
+ Progress,
+ Tooltip,
+ Button,
+} from '@chakra-ui/react';
+import { ExternalLinkIcon } from '@chakra-ui/icons';
+import {
+ FaBuilding,
+ FaHandshake,
+ FaUserTie,
+ FaIndustry,
+ FaCog,
+ FaNetworkWired,
+ FaFlask,
+ FaStar,
+ FaArrowRight,
+ FaArrowLeft,
+} from 'react-icons/fa';
+import type { ValueChainNode, RelatedCompany } from '../../types';
+
+interface RelatedCompaniesModalProps {
+ isOpen: boolean;
+ onClose: () => void;
+ node: ValueChainNode;
+ isCompany: boolean;
+ colorScheme: string;
+ relatedCompanies: RelatedCompany[];
+ loadingRelated: boolean;
+}
+
+/**
+ * 获取节点类型对应的图标
+ */
+const getNodeTypeIcon = (type: string) => {
+ const icons: Record = {
+ company: FaBuilding,
+ supplier: FaHandshake,
+ customer: FaUserTie,
+ product: FaIndustry,
+ service: FaCog,
+ channel: FaNetworkWired,
+ raw_material: FaFlask,
+ };
+ return icons[type] || FaBuilding;
+};
+
+/**
+ * 获取重要度对应的颜色
+ */
+const getImportanceColor = (score?: number): string => {
+ if (!score) return 'green';
+ if (score >= 80) return 'red';
+ if (score >= 60) return 'orange';
+ if (score >= 40) return 'yellow';
+ return 'green';
+};
+
+/**
+ * 获取层级标签
+ */
+const getLevelLabel = (level?: number): { text: string; color: string } => {
+ if (level === undefined) return { text: '未知', color: 'gray' };
+ if (level < 0) return { text: '上游', color: 'orange' };
+ if (level === 0) return { text: '核心', color: 'blue' };
+ return { text: '下游', color: 'green' };
+};
+
+const RelatedCompaniesModal: React.FC = ({
+ isOpen,
+ onClose,
+ node,
+ isCompany,
+ colorScheme,
+ relatedCompanies,
+ loadingRelated,
+}) => {
+ return (
+
+
+
+
+
+
+
+ {node.node_name}
+
+ {node.node_type}
+ {isCompany && (
+
+ 核心企业
+
+ )}
+
+
+
+
+
+
+
+ {node.node_description && (
+
+
+ 节点描述
+
+
+ {node.node_description}
+
+
+ )}
+
+
+
+ 重要度评分
+
+ {node.importance_score || 0}
+
+
+
+
+
+
+ {node.market_share !== undefined && (
+
+ 市场份额
+ {node.market_share}%
+
+ )}
+
+ {node.dependency_degree !== undefined && (
+
+ 依赖程度
+
+ {node.dependency_degree}%
+
+
+
+
+ )}
+
+
+
+
+
+
+
+ 相关公司
+
+ {loadingRelated && }
+
+ {loadingRelated ? (
+
+
+
+ ) : relatedCompanies.length > 0 ? (
+
+ {relatedCompanies.map((company, idx) => {
+ const levelInfo = getLevelLabel(company.node_info?.node_level);
+
+ return (
+
+
+
+
+
+
+
+ {company.stock_name}
+
+
+ {company.stock_code}
+
+
+ {levelInfo.text}
+
+
+ {company.company_name && (
+
+ {company.company_name}
+
+ )}
+
+ }
+ variant="ghost"
+ colorScheme="blue"
+ onClick={() => {
+ window.location.href = `/company?stock_code=${company.stock_code}`;
+ }}
+ aria-label="查看公司详情"
+ />
+
+
+ {company.node_info?.node_description && (
+
+ {company.node_info.node_description}
+
+ )}
+
+ {company.relationships &&
+ company.relationships.length > 0 && (
+
+
+ 产业链关系:
+
+
+ {company.relationships.map((rel, ridx) => (
+
+
+
+ {rel.role === 'source'
+ ? '流向'
+ : '来自'}
+
+ {rel.connected_node}
+
+
+
+ ))}
+
+
+ )}
+
+
+
+ );
+ })}
+
+ ) : (
+
+
+
+
+ 暂无相关公司
+
+
+
+ )}
+
+
+
+
+
+
+
+
+ );
+};
+
+export default RelatedCompaniesModal;
diff --git a/src/views/Company/components/CompanyOverview/DeepAnalysisTab/organisms/ValueChainNodeCard/index.tsx b/src/views/Company/components/CompanyOverview/DeepAnalysisTab/organisms/ValueChainNodeCard/index.tsx
new file mode 100644
index 00000000..5a29c0df
--- /dev/null
+++ b/src/views/Company/components/CompanyOverview/DeepAnalysisTab/organisms/ValueChainNodeCard/index.tsx
@@ -0,0 +1,234 @@
+/**
+ * 产业链节点卡片组件
+ *
+ * 显示产业链中的单个节点,点击可展开查看相关公司
+ */
+
+import React, { useState } from 'react';
+import {
+ Card,
+ CardBody,
+ VStack,
+ HStack,
+ Text,
+ Badge,
+ Icon,
+ Progress,
+ Box,
+ Tooltip,
+ useDisclosure,
+ useToast,
+ ScaleFade,
+} from '@chakra-ui/react';
+import {
+ FaBuilding,
+ FaHandshake,
+ FaUserTie,
+ FaIndustry,
+ FaCog,
+ FaNetworkWired,
+ FaFlask,
+ FaStar,
+} from 'react-icons/fa';
+import { logger } from '@utils/logger';
+import { getApiBase } from '@utils/apiConfig';
+import RelatedCompaniesModal from './RelatedCompaniesModal';
+import type { ValueChainNodeCardProps, RelatedCompany } from '../../types';
+
+const API_BASE_URL = getApiBase();
+
+/**
+ * 获取节点类型对应的图标
+ */
+const getNodeTypeIcon = (type: string) => {
+ const icons: Record = {
+ company: FaBuilding,
+ supplier: FaHandshake,
+ customer: FaUserTie,
+ product: FaIndustry,
+ service: FaCog,
+ channel: FaNetworkWired,
+ raw_material: FaFlask,
+ };
+ return icons[type] || FaBuilding;
+};
+
+/**
+ * 获取重要度对应的颜色
+ */
+const getImportanceColor = (score?: number): string => {
+ if (!score) return 'green';
+ if (score >= 80) return 'red';
+ if (score >= 60) return 'orange';
+ if (score >= 40) return 'yellow';
+ return 'green';
+};
+
+const ValueChainNodeCard: React.FC = ({
+ node,
+ isCompany = false,
+ level = 0,
+}) => {
+ const { isOpen, onOpen, onClose } = useDisclosure();
+ const [relatedCompanies, setRelatedCompanies] = useState([]);
+ const [loadingRelated, setLoadingRelated] = useState(false);
+ const toast = useToast();
+
+ // 根据层级和是否为核心企业确定颜色方案
+ const getColorScheme = (): string => {
+ if (isCompany) return 'blue';
+ if (level < 0) return 'orange';
+ if (level > 0) return 'green';
+ return 'gray';
+ };
+
+ const colorScheme = getColorScheme();
+ const bgColor = `${colorScheme}.50`;
+ const borderColor = `${colorScheme}.200`;
+
+ // 获取相关公司数据
+ const fetchRelatedCompanies = async () => {
+ setLoadingRelated(true);
+ try {
+ const response = await fetch(
+ `${API_BASE_URL}/api/company/value-chain/related-companies?node_name=${encodeURIComponent(
+ node.node_name
+ )}`
+ );
+ const data = await response.json();
+ if (data.success) {
+ setRelatedCompanies(data.data || []);
+ } else {
+ toast({
+ title: '获取相关公司失败',
+ description: data.message,
+ status: 'error',
+ duration: 3000,
+ isClosable: true,
+ });
+ }
+ } catch (error) {
+ logger.error('ValueChainNodeCard', 'fetchRelatedCompanies', error, {
+ node_name: node.node_name,
+ });
+ toast({
+ title: '获取相关公司失败',
+ description: error instanceof Error ? error.message : '未知错误',
+ status: 'error',
+ duration: 3000,
+ isClosable: true,
+ });
+ } finally {
+ setLoadingRelated(false);
+ }
+ };
+
+ // 点击卡片打开模态框
+ const handleCardClick = () => {
+ onOpen();
+ if (relatedCompanies.length === 0) {
+ fetchRelatedCompanies();
+ }
+ };
+
+ return (
+ <>
+
+
+
+
+
+
+
+ {isCompany && (
+
+ 核心企业
+
+ )}
+
+ {node.importance_score !== undefined &&
+ node.importance_score >= 70 && (
+
+
+
+
+
+ )}
+
+
+
+ {node.node_name}
+
+
+ {node.node_description && (
+
+ {node.node_description}
+
+ )}
+
+
+
+ {node.node_type}
+
+ {node.market_share !== undefined && (
+
+ 份额 {node.market_share}%
+
+ )}
+
+
+ {node.importance_score !== undefined && (
+
+
+
+ 重要度
+
+
+ {node.importance_score}
+
+
+
+
+ )}
+
+
+
+
+
+
+ >
+ );
+};
+
+export default ValueChainNodeCard;
diff --git a/src/views/Company/components/CompanyOverview/DeepAnalysisTab/types.ts b/src/views/Company/components/CompanyOverview/DeepAnalysisTab/types.ts
new file mode 100644
index 00000000..54c988ae
--- /dev/null
+++ b/src/views/Company/components/CompanyOverview/DeepAnalysisTab/types.ts
@@ -0,0 +1,326 @@
+/**
+ * DeepAnalysisTab 组件类型定义
+ *
+ * 深度分析 Tab 所需的所有数据接口类型
+ */
+
+// ==================== 格式化工具类型 ====================
+
+export interface FormatUtils {
+ formatCurrency: (value: number | null | undefined) => string;
+ formatBusinessRevenue: (value: number | null | undefined, unit?: string) => string;
+ formatPercentage: (value: number | null | undefined) => string;
+}
+
+// ==================== 竞争力评分类型 ====================
+
+export interface CompetitiveScores {
+ market_position?: number;
+ technology?: number;
+ brand?: number;
+ operation?: number;
+ finance?: number;
+ innovation?: number;
+ risk?: number;
+ growth?: number;
+}
+
+export interface CompetitiveRanking {
+ industry_rank: number;
+ total_companies: number;
+}
+
+export interface CompetitiveAnalysis {
+ main_competitors?: string;
+ competitive_advantages?: string;
+ competitive_disadvantages?: string;
+}
+
+export interface CompetitivePosition {
+ scores?: CompetitiveScores;
+ ranking?: CompetitiveRanking;
+ analysis?: CompetitiveAnalysis;
+}
+
+// ==================== 核心定位类型 ====================
+
+export interface CorePositioning {
+ one_line_intro?: string;
+ investment_highlights?: string;
+ business_model_desc?: string;
+}
+
+export interface Strategy {
+ strategy_description?: string;
+ strategic_initiatives?: string;
+}
+
+export interface QualitativeAnalysis {
+ core_positioning?: CorePositioning;
+ strategy?: Strategy;
+}
+
+// ==================== 业务结构类型 ====================
+
+export interface FinancialMetrics {
+ revenue?: number;
+ revenue_ratio?: number;
+ gross_margin?: number;
+}
+
+export interface GrowthMetrics {
+ revenue_growth?: number;
+}
+
+export interface BusinessStructure {
+ business_name: string;
+ business_level: number;
+ revenue?: number;
+ revenue_unit?: string;
+ financial_metrics?: FinancialMetrics;
+ growth_metrics?: GrowthMetrics;
+ report_period?: string;
+}
+
+// ==================== 业务板块类型 ====================
+
+export interface BusinessSegment {
+ segment_name: string;
+ segment_description?: string;
+ competitive_position?: string;
+ future_potential?: string;
+ key_products?: string;
+ market_share?: number;
+ revenue_contribution?: number;
+}
+
+// ==================== 综合数据类型 ====================
+
+export interface ComprehensiveData {
+ qualitative_analysis?: QualitativeAnalysis;
+ competitive_position?: CompetitivePosition;
+ business_structure?: BusinessStructure[];
+ business_segments?: BusinessSegment[];
+}
+
+// ==================== 产业链类型 ====================
+
+export interface ValueChainNode {
+ node_name: string;
+ node_type: string;
+ node_description?: string;
+ node_level?: number;
+ importance_score?: number;
+ market_share?: number;
+ dependency_degree?: number;
+}
+
+export interface ValueChainFlow {
+ source?: { node_name: string };
+ target?: { node_name: string };
+ flow_metrics?: {
+ flow_ratio?: string;
+ };
+}
+
+export interface NodesByLevel {
+ [key: string]: ValueChainNode[];
+}
+
+export interface ValueChainStructure {
+ nodes_by_level?: NodesByLevel;
+}
+
+export interface AnalysisSummary {
+ upstream_nodes?: number;
+ company_nodes?: number;
+ downstream_nodes?: number;
+}
+
+export interface ValueChainData {
+ value_chain_flows?: ValueChainFlow[];
+ value_chain_structure?: ValueChainStructure;
+ analysis_summary?: AnalysisSummary;
+}
+
+// ==================== 相关公司类型 ====================
+
+export interface RelatedCompanyRelationship {
+ role: 'source' | 'target';
+ connected_node: string;
+}
+
+export interface RelatedCompanyNodeInfo {
+ node_level?: number;
+ node_description?: string;
+}
+
+export interface RelatedCompany {
+ stock_code: string;
+ stock_name: string;
+ company_name?: string;
+ node_info?: RelatedCompanyNodeInfo;
+ relationships?: RelatedCompanyRelationship[];
+}
+
+// ==================== 关键因素类型 ====================
+
+export type ImpactDirection = 'positive' | 'negative' | 'neutral' | 'mixed';
+
+export interface KeyFactor {
+ factor_name: string;
+ factor_value: string | number;
+ factor_unit?: string;
+ factor_desc?: string;
+ impact_direction?: ImpactDirection;
+ impact_weight?: number;
+ year_on_year?: number;
+ report_period?: string;
+}
+
+export interface FactorCategory {
+ category_name: string;
+ factors: KeyFactor[];
+}
+
+export interface KeyFactors {
+ total_factors?: number;
+ categories: FactorCategory[];
+}
+
+// ==================== 时间线事件类型 ====================
+
+export interface ImpactMetrics {
+ is_positive?: boolean;
+ impact_score?: number;
+}
+
+export interface RelatedInfo {
+ financial_impact?: string;
+}
+
+export interface TimelineEvent {
+ event_title: string;
+ event_date: string;
+ event_type: string;
+ event_desc: string;
+ impact_metrics?: ImpactMetrics;
+ related_info?: RelatedInfo;
+}
+
+export interface TimelineStatistics {
+ positive_events?: number;
+ negative_events?: number;
+}
+
+export interface DevelopmentTimeline {
+ events: TimelineEvent[];
+ statistics?: TimelineStatistics;
+}
+
+// ==================== 关键因素数据类型 ====================
+
+export interface KeyFactorsData {
+ key_factors?: KeyFactors;
+ development_timeline?: DevelopmentTimeline;
+}
+
+// ==================== 主组件 Props 类型 ====================
+
+export interface DeepAnalysisTabProps {
+ comprehensiveData?: ComprehensiveData;
+ valueChainData?: ValueChainData;
+ keyFactorsData?: KeyFactorsData;
+ loading?: boolean;
+ cardBg?: string;
+ expandedSegments: Record;
+ onToggleSegment: (index: number) => void;
+}
+
+// ==================== 子组件 Props 类型 ====================
+
+export interface DisclaimerBoxProps {
+ // 无需 props
+}
+
+export interface ScoreBarProps {
+ label: string;
+ score?: number;
+ icon?: React.ComponentType;
+}
+
+export interface BusinessTreeItemProps {
+ business: BusinessStructure;
+ depth?: number;
+}
+
+export interface KeyFactorCardProps {
+ factor: KeyFactor;
+}
+
+export interface ValueChainNodeCardProps {
+ node: ValueChainNode;
+ isCompany?: boolean;
+ level?: number;
+}
+
+export interface TimelineComponentProps {
+ events: TimelineEvent[];
+}
+
+// ==================== 图表配置类型 ====================
+
+export interface RadarIndicator {
+ name: string;
+ max: number;
+}
+
+export interface RadarChartOption {
+ tooltip: { trigger: string };
+ radar: {
+ indicator: RadarIndicator[];
+ shape: string;
+ splitNumber: number;
+ name: { textStyle: { color: string; fontSize: number } };
+ splitLine: { lineStyle: { color: string[] } };
+ splitArea: { show: boolean; areaStyle: { color: string[] } };
+ axisLine: { lineStyle: { color: string } };
+ };
+ series: Array<{
+ name: string;
+ type: string;
+ data: Array<{
+ value: number[];
+ name: string;
+ symbol: string;
+ symbolSize: number;
+ lineStyle: { width: number; color: string };
+ areaStyle: { color: string };
+ label: { show: boolean; formatter: (params: { value: number }) => number; color: string; fontSize: number };
+ }>;
+ }>;
+}
+
+export interface SankeyNode {
+ name: string;
+}
+
+export interface SankeyLink {
+ source: string;
+ target: string;
+ value: number;
+ lineStyle: { color: string; opacity: number };
+}
+
+export interface SankeyChartOption {
+ tooltip: { trigger: string; triggerOn: string };
+ series: Array<{
+ type: string;
+ layout: string;
+ emphasis: { focus: string };
+ data: SankeyNode[];
+ links: SankeyLink[];
+ lineStyle: { color: string; curveness: number };
+ label: { color: string; fontSize: number };
+ }>;
+}
diff --git a/src/views/Company/components/CompanyOverview/DeepAnalysisTab/utils/chartOptions.ts b/src/views/Company/components/CompanyOverview/DeepAnalysisTab/utils/chartOptions.ts
new file mode 100644
index 00000000..7164cc30
--- /dev/null
+++ b/src/views/Company/components/CompanyOverview/DeepAnalysisTab/utils/chartOptions.ts
@@ -0,0 +1,139 @@
+/**
+ * DeepAnalysisTab 图表配置工具
+ *
+ * 生成雷达图和桑基图的 ECharts 配置
+ */
+
+import type {
+ ComprehensiveData,
+ ValueChainData,
+ RadarChartOption,
+ SankeyChartOption,
+} from '../types';
+
+/**
+ * 生成竞争力雷达图配置
+ * @param comprehensiveData - 综合分析数据
+ * @returns ECharts 雷达图配置,或 null(数据不足时)
+ */
+export const getRadarChartOption = (
+ comprehensiveData?: ComprehensiveData
+): RadarChartOption | null => {
+ if (!comprehensiveData?.competitive_position?.scores) return null;
+
+ const scores = comprehensiveData.competitive_position.scores;
+ const indicators = [
+ { name: '市场地位', max: 100 },
+ { name: '技术实力', max: 100 },
+ { name: '品牌价值', max: 100 },
+ { name: '运营效率', max: 100 },
+ { name: '财务健康', max: 100 },
+ { name: '创新能力', max: 100 },
+ { name: '风险控制', max: 100 },
+ { name: '成长潜力', max: 100 },
+ ];
+
+ const data = [
+ scores.market_position || 0,
+ scores.technology || 0,
+ scores.brand || 0,
+ scores.operation || 0,
+ scores.finance || 0,
+ scores.innovation || 0,
+ scores.risk || 0,
+ scores.growth || 0,
+ ];
+
+ return {
+ tooltip: { trigger: 'item' },
+ radar: {
+ indicator: indicators,
+ shape: 'polygon',
+ splitNumber: 4,
+ name: { textStyle: { color: '#666', fontSize: 12 } },
+ splitLine: {
+ lineStyle: { color: ['#e8e8e8', '#e0e0e0', '#d0d0d0', '#c0c0c0'] },
+ },
+ splitArea: {
+ show: true,
+ areaStyle: {
+ color: ['rgba(250,250,250,0.3)', 'rgba(200,200,200,0.3)'],
+ },
+ },
+ axisLine: { lineStyle: { color: '#ddd' } },
+ },
+ series: [
+ {
+ name: '竞争力评分',
+ type: 'radar',
+ data: [
+ {
+ value: data,
+ name: '当前评分',
+ symbol: 'circle',
+ symbolSize: 5,
+ lineStyle: { width: 2, color: '#3182ce' },
+ areaStyle: { color: 'rgba(49, 130, 206, 0.3)' },
+ label: {
+ show: true,
+ formatter: (params: { value: number }) => params.value,
+ color: '#3182ce',
+ fontSize: 10,
+ },
+ },
+ ],
+ },
+ ],
+ };
+};
+
+/**
+ * 生成产业链桑基图配置
+ * @param valueChainData - 产业链数据
+ * @returns ECharts 桑基图配置,或 null(数据不足时)
+ */
+export const getSankeyChartOption = (
+ valueChainData?: ValueChainData
+): SankeyChartOption | null => {
+ if (
+ !valueChainData?.value_chain_flows ||
+ valueChainData.value_chain_flows.length === 0
+ ) {
+ return null;
+ }
+
+ const nodes = new Set();
+ const links: Array<{
+ source: string;
+ target: string;
+ value: number;
+ lineStyle: { color: string; opacity: number };
+ }> = [];
+
+ valueChainData.value_chain_flows.forEach((flow) => {
+ if (!flow?.source?.node_name || !flow?.target?.node_name) return;
+ nodes.add(flow.source.node_name);
+ nodes.add(flow.target.node_name);
+ links.push({
+ source: flow.source.node_name,
+ target: flow.target.node_name,
+ value: parseFloat(flow.flow_metrics?.flow_ratio || '1') || 1,
+ lineStyle: { color: 'source', opacity: 0.6 },
+ });
+ });
+
+ return {
+ tooltip: { trigger: 'item', triggerOn: 'mousemove' },
+ series: [
+ {
+ type: 'sankey',
+ layout: 'none',
+ emphasis: { focus: 'adjacency' },
+ data: Array.from(nodes).map((name) => ({ name })),
+ links: links,
+ lineStyle: { color: 'gradient', curveness: 0.5 },
+ label: { color: '#333', fontSize: 10 },
+ },
+ ],
+ };
+};