feat(DeepAnalysis): 增强策略Tab功能
- 新增策略相关类型定义 - StrategyTab 功能增强 - 调整组件结构
This commit is contained in:
@@ -47,6 +47,7 @@ const DeepAnalysisTab: React.FC<DeepAnalysisTabProps> = ({
|
||||
comprehensiveData,
|
||||
valueChainData,
|
||||
keyFactorsData,
|
||||
industryRankData,
|
||||
loading,
|
||||
cardBg,
|
||||
expandedSegments,
|
||||
@@ -96,6 +97,7 @@ const DeepAnalysisTab: React.FC<DeepAnalysisTabProps> = ({
|
||||
comprehensiveData,
|
||||
valueChainData,
|
||||
keyFactorsData,
|
||||
industryRankData,
|
||||
cardBg,
|
||||
expandedSegments,
|
||||
onToggleSegment,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* 战略分析 Tab
|
||||
*
|
||||
* 包含:核心定位 + 战略分析 + 竞争地位分析
|
||||
* 包含:核心定位 + 战略分析 + 竞争地位分析 + 行业排名
|
||||
*/
|
||||
|
||||
import React, { memo } from 'react';
|
||||
@@ -11,15 +11,18 @@ import {
|
||||
StrategyAnalysisCard,
|
||||
CompetitiveAnalysisCard,
|
||||
} from '../components';
|
||||
import type { ComprehensiveData } from '../types';
|
||||
import { IndustryRankingView } from '../../../FinancialPanorama/components';
|
||||
import type { ComprehensiveData, IndustryRankData } from '../types';
|
||||
|
||||
export interface StrategyTabProps {
|
||||
comprehensiveData?: ComprehensiveData;
|
||||
industryRankData?: IndustryRankData[];
|
||||
cardBg?: string;
|
||||
}
|
||||
|
||||
const StrategyTab: React.FC<StrategyTabProps> = memo(({
|
||||
comprehensiveData,
|
||||
industryRankData,
|
||||
cardBg,
|
||||
}) => {
|
||||
return (
|
||||
@@ -44,6 +47,15 @@ const StrategyTab: React.FC<StrategyTabProps> = memo(({
|
||||
{comprehensiveData?.competitive_position && (
|
||||
<CompetitiveAnalysisCard comprehensiveData={comprehensiveData} />
|
||||
)}
|
||||
|
||||
{/* 行业排名 */}
|
||||
{industryRankData && industryRankData.length > 0 && (
|
||||
<IndustryRankingView
|
||||
industryRank={industryRankData}
|
||||
bgColor="white"
|
||||
borderColor="gray.200"
|
||||
/>
|
||||
)}
|
||||
</TabPanelContainer>
|
||||
);
|
||||
});
|
||||
|
||||
@@ -265,6 +265,35 @@ export interface KeyFactorsData {
|
||||
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 类型 ====================
|
||||
|
||||
/** Tab 类型 */
|
||||
@@ -274,6 +303,7 @@ export interface DeepAnalysisTabProps {
|
||||
comprehensiveData?: ComprehensiveData;
|
||||
valueChainData?: ValueChainData;
|
||||
keyFactorsData?: KeyFactorsData;
|
||||
industryRankData?: IndustryRankData[];
|
||||
loading?: boolean;
|
||||
cardBg?: string;
|
||||
expandedSegments: Record<number, boolean>;
|
||||
|
||||
@@ -40,17 +40,20 @@ const DeepAnalysis = ({ stockCode }) => {
|
||||
const [comprehensiveData, setComprehensiveData] = useState(null);
|
||||
const [valueChainData, setValueChainData] = useState(null);
|
||||
const [keyFactorsData, setKeyFactorsData] = useState(null);
|
||||
const [industryRankData, setIndustryRankData] = useState(null);
|
||||
|
||||
// 各接口独立的 loading 状态
|
||||
const [comprehensiveLoading, setComprehensiveLoading] = useState(false);
|
||||
const [valueChainLoading, setValueChainLoading] = useState(false);
|
||||
const [keyFactorsLoading, setKeyFactorsLoading] = useState(false);
|
||||
const [industryRankLoading, setIndustryRankLoading] = useState(false);
|
||||
|
||||
// 已加载的接口记录(用于缓存判断)
|
||||
const loadedApisRef = useRef({
|
||||
comprehensive: false,
|
||||
valueChain: false,
|
||||
keyFactors: false,
|
||||
industryRank: false,
|
||||
});
|
||||
|
||||
// 业务板块展开状态
|
||||
@@ -114,6 +117,17 @@ const DeepAnalysis = ({ stockCode }) => {
|
||||
}
|
||||
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:
|
||||
break;
|
||||
}
|
||||
@@ -126,6 +140,7 @@ const DeepAnalysis = ({ stockCode }) => {
|
||||
if (apiKey === "comprehensive") setComprehensiveLoading(false);
|
||||
if (apiKey === "valueChain") setValueChainLoading(false);
|
||||
if (apiKey === "keyFactors") setKeyFactorsLoading(false);
|
||||
if (apiKey === "industryRank") setIndustryRankLoading(false);
|
||||
}
|
||||
},
|
||||
[stockCode]
|
||||
@@ -165,17 +180,20 @@ const DeepAnalysis = ({ stockCode }) => {
|
||||
setComprehensiveData(null);
|
||||
setValueChainData(null);
|
||||
setKeyFactorsData(null);
|
||||
setIndustryRankData(null);
|
||||
setExpandedSegments({});
|
||||
loadedApisRef.current = {
|
||||
comprehensive: false,
|
||||
valueChain: false,
|
||||
keyFactors: false,
|
||||
industryRank: false,
|
||||
};
|
||||
|
||||
// 重置为默认 Tab 并加载数据
|
||||
setActiveTab("strategy");
|
||||
// 加载默认 Tab 的数据
|
||||
// 加载默认 Tab 的数据(战略分析需要 comprehensive 和 industryRank)
|
||||
loadApiData("comprehensive");
|
||||
loadApiData("industryRank");
|
||||
}
|
||||
}, [stockCode, loadApiData]);
|
||||
|
||||
@@ -199,6 +217,7 @@ const DeepAnalysis = ({ stockCode }) => {
|
||||
comprehensiveData={comprehensiveData}
|
||||
valueChainData={valueChainData}
|
||||
keyFactorsData={keyFactorsData}
|
||||
industryRankData={industryRankData}
|
||||
loading={getCurrentLoading()}
|
||||
cardBg="white"
|
||||
expandedSegments={expandedSegments}
|
||||
|
||||
Reference in New Issue
Block a user