feat(DeepAnalysis): 增强策略Tab功能

- 新增策略相关类型定义
 - StrategyTab 功能增强
 - 调整组件结构
This commit is contained in:
zdl
2025-12-16 16:22:39 +08:00
parent 24720dbba0
commit 3f1f438440
4 changed files with 66 additions and 3 deletions

View File

@@ -47,6 +47,7 @@ const DeepAnalysisTab: React.FC<DeepAnalysisTabProps> = ({
comprehensiveData, comprehensiveData,
valueChainData, valueChainData,
keyFactorsData, keyFactorsData,
industryRankData,
loading, loading,
cardBg, cardBg,
expandedSegments, expandedSegments,
@@ -96,6 +97,7 @@ const DeepAnalysisTab: React.FC<DeepAnalysisTabProps> = ({
comprehensiveData, comprehensiveData,
valueChainData, valueChainData,
keyFactorsData, keyFactorsData,
industryRankData,
cardBg, cardBg,
expandedSegments, expandedSegments,
onToggleSegment, onToggleSegment,

View File

@@ -1,7 +1,7 @@
/** /**
* 战略分析 Tab * 战略分析 Tab
* *
* 包含:核心定位 + 战略分析 + 竞争地位分析 * 包含:核心定位 + 战略分析 + 竞争地位分析 + 行业排名
*/ */
import React, { memo } from 'react'; import React, { memo } from 'react';
@@ -11,15 +11,18 @@ import {
StrategyAnalysisCard, StrategyAnalysisCard,
CompetitiveAnalysisCard, CompetitiveAnalysisCard,
} from '../components'; } from '../components';
import type { ComprehensiveData } from '../types'; import { IndustryRankingView } from '../../../FinancialPanorama/components';
import type { ComprehensiveData, IndustryRankData } from '../types';
export interface StrategyTabProps { export interface StrategyTabProps {
comprehensiveData?: ComprehensiveData; comprehensiveData?: ComprehensiveData;
industryRankData?: IndustryRankData[];
cardBg?: string; cardBg?: string;
} }
const StrategyTab: React.FC<StrategyTabProps> = memo(({ const StrategyTab: React.FC<StrategyTabProps> = memo(({
comprehensiveData, comprehensiveData,
industryRankData,
cardBg, cardBg,
}) => { }) => {
return ( return (
@@ -44,6 +47,15 @@ const StrategyTab: React.FC<StrategyTabProps> = memo(({
{comprehensiveData?.competitive_position && ( {comprehensiveData?.competitive_position && (
<CompetitiveAnalysisCard comprehensiveData={comprehensiveData} /> <CompetitiveAnalysisCard comprehensiveData={comprehensiveData} />
)} )}
{/* 行业排名 */}
{industryRankData && industryRankData.length > 0 && (
<IndustryRankingView
industryRank={industryRankData}
bgColor="white"
borderColor="gray.200"
/>
)}
</TabPanelContainer> </TabPanelContainer>
); );
}); });

View File

@@ -265,6 +265,35 @@ export interface KeyFactorsData {
development_timeline?: DevelopmentTimeline; development_timeline?: DevelopmentTimeline;
} }
// ==================== 行业排名类型 ====================
/** 行业排名指标 */
export interface RankingMetric {
value?: number;
rank?: number;
industry_avg?: number;
}
/** 行业排名数据 */
export interface IndustryRankData {
period: string;
report_type: string;
rankings?: {
industry_name: string;
level_description: string;
metrics?: {
eps?: RankingMetric;
bvps?: RankingMetric;
roe?: RankingMetric;
revenue_growth?: RankingMetric;
profit_growth?: RankingMetric;
operating_margin?: RankingMetric;
debt_ratio?: RankingMetric;
receivable_turnover?: RankingMetric;
};
}[];
}
// ==================== 主组件 Props 类型 ==================== // ==================== 主组件 Props 类型 ====================
/** Tab 类型 */ /** Tab 类型 */
@@ -274,6 +303,7 @@ export interface DeepAnalysisTabProps {
comprehensiveData?: ComprehensiveData; comprehensiveData?: ComprehensiveData;
valueChainData?: ValueChainData; valueChainData?: ValueChainData;
keyFactorsData?: KeyFactorsData; keyFactorsData?: KeyFactorsData;
industryRankData?: IndustryRankData[];
loading?: boolean; loading?: boolean;
cardBg?: string; cardBg?: string;
expandedSegments: Record<number, boolean>; expandedSegments: Record<number, boolean>;

View File

@@ -40,17 +40,20 @@ const DeepAnalysis = ({ stockCode }) => {
const [comprehensiveData, setComprehensiveData] = useState(null); const [comprehensiveData, setComprehensiveData] = useState(null);
const [valueChainData, setValueChainData] = useState(null); const [valueChainData, setValueChainData] = useState(null);
const [keyFactorsData, setKeyFactorsData] = useState(null); const [keyFactorsData, setKeyFactorsData] = useState(null);
const [industryRankData, setIndustryRankData] = useState(null);
// 各接口独立的 loading 状态 // 各接口独立的 loading 状态
const [comprehensiveLoading, setComprehensiveLoading] = useState(false); const [comprehensiveLoading, setComprehensiveLoading] = useState(false);
const [valueChainLoading, setValueChainLoading] = useState(false); const [valueChainLoading, setValueChainLoading] = useState(false);
const [keyFactorsLoading, setKeyFactorsLoading] = useState(false); const [keyFactorsLoading, setKeyFactorsLoading] = useState(false);
const [industryRankLoading, setIndustryRankLoading] = useState(false);
// 已加载的接口记录(用于缓存判断) // 已加载的接口记录(用于缓存判断)
const loadedApisRef = useRef({ const loadedApisRef = useRef({
comprehensive: false, comprehensive: false,
valueChain: false, valueChain: false,
keyFactors: false, keyFactors: false,
industryRank: false,
}); });
// 业务板块展开状态 // 业务板块展开状态
@@ -114,6 +117,17 @@ const DeepAnalysis = ({ stockCode }) => {
} }
break; break;
case "industryRank":
setIndustryRankLoading(true);
const industryRankRes = await fetch(
`${API_BASE_URL}/api/financial/industry-rank/${stockCode}`
).then((r) => r.json());
if (currentStockCodeRef.current === stockCode) {
if (industryRankRes.success) setIndustryRankData(industryRankRes.data);
loadedApisRef.current.industryRank = true;
}
break;
default: default:
break; break;
} }
@@ -126,6 +140,7 @@ const DeepAnalysis = ({ stockCode }) => {
if (apiKey === "comprehensive") setComprehensiveLoading(false); if (apiKey === "comprehensive") setComprehensiveLoading(false);
if (apiKey === "valueChain") setValueChainLoading(false); if (apiKey === "valueChain") setValueChainLoading(false);
if (apiKey === "keyFactors") setKeyFactorsLoading(false); if (apiKey === "keyFactors") setKeyFactorsLoading(false);
if (apiKey === "industryRank") setIndustryRankLoading(false);
} }
}, },
[stockCode] [stockCode]
@@ -165,17 +180,20 @@ const DeepAnalysis = ({ stockCode }) => {
setComprehensiveData(null); setComprehensiveData(null);
setValueChainData(null); setValueChainData(null);
setKeyFactorsData(null); setKeyFactorsData(null);
setIndustryRankData(null);
setExpandedSegments({}); setExpandedSegments({});
loadedApisRef.current = { loadedApisRef.current = {
comprehensive: false, comprehensive: false,
valueChain: false, valueChain: false,
keyFactors: false, keyFactors: false,
industryRank: false,
}; };
// 重置为默认 Tab 并加载数据 // 重置为默认 Tab 并加载数据
setActiveTab("strategy"); setActiveTab("strategy");
// 加载默认 Tab 的数据 // 加载默认 Tab 的数据(战略分析需要 comprehensive 和 industryRank
loadApiData("comprehensive"); loadApiData("comprehensive");
loadApiData("industryRank");
} }
}, [stockCode, loadApiData]); }, [stockCode, loadApiData]);
@@ -199,6 +217,7 @@ const DeepAnalysis = ({ stockCode }) => {
comprehensiveData={comprehensiveData} comprehensiveData={comprehensiveData}
valueChainData={valueChainData} valueChainData={valueChainData}
keyFactorsData={keyFactorsData} keyFactorsData={keyFactorsData}
industryRankData={industryRankData}
loading={getCurrentLoading()} loading={getCurrentLoading()}
cardBg="white" cardBg="white"
expandedSegments={expandedSegments} expandedSegments={expandedSegments}