feat(DeepAnalysis): 增强策略Tab功能
- 新增策略相关类型定义 - StrategyTab 功能增强 - 调整组件结构
This commit is contained in:
@@ -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,
|
||||||
|
|||||||
@@ -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>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -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>;
|
||||||
|
|||||||
@@ -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}
|
||||||
|
|||||||
Reference in New Issue
Block a user