fix(DeepAnalysis): 修复行业排名数据未加载导致无法点击弹窗问题

- TAB_API_MAP 改为数组形式,支持一个 Tab 加载多个 API
- strategy Tab 现在同时加载 comprehensive 和 industryRank 数据
- loadTabData 更新为遍历加载所有映射的 API
- currentLoading 计算改为检查任一相关 API 的 loading 状态
- 初始加载逻辑更新为加载 strategy Tab 的所有数据

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
zdl
2025-12-26 15:09:42 +08:00
parent 8d609d5fbf
commit b7ad35ba12
3 changed files with 53 additions and 39 deletions

View File

@@ -7,23 +7,23 @@
* - 竞态条件处理 * - 竞态条件处理
*/ */
import { useState, useCallback, useRef, useEffect } from 'react'; import { useState, useCallback, useRef, useEffect } from "react";
import axios from '@utils/axiosConfig'; import axios from "@utils/axiosConfig";
import { logger } from '@utils/logger'; import { logger } from "@utils/logger";
import type { import type {
ApiKey, ApiKey,
ApiLoadingState, ApiLoadingState,
DataState, DataState,
UseDeepAnalysisDataReturn, UseDeepAnalysisDataReturn,
} from '../types'; } from "../types";
import { TAB_API_MAP } from '../types'; import { TAB_API_MAP } from "../types";
/** API 端点映射 */ /** API 端点映射 */
const API_ENDPOINTS: Record<ApiKey, string> = { const API_ENDPOINTS: Record<ApiKey, string> = {
comprehensive: '/api/company/comprehensive-analysis', comprehensive: "/api/company/comprehensive-analysis",
valueChain: '/api/company/value-chain-analysis', valueChain: "/api/company/value-chain-analysis",
keyFactors: '/api/company/key-factors-timeline', keyFactors: "/api/company/key-factors-timeline",
industryRank: '/api/financial/industry-rank', industryRank: "/api/financial/industry-rank",
}; };
/** 初始数据状态 */ /** 初始数据状态 */
@@ -48,7 +48,9 @@ const initialLoadingState: ApiLoadingState = {
* @param stockCode 股票代码 * @param stockCode 股票代码
* @returns 数据、loading 状态、加载函数 * @returns 数据、loading 状态、加载函数
*/ */
export const useDeepAnalysisData = (stockCode: string): UseDeepAnalysisDataReturn => { export const useDeepAnalysisData = (
stockCode: string
): UseDeepAnalysisDataReturn => {
// 数据状态 // 数据状态
const [data, setData] = useState<DataState>(initialDataState); const [data, setData] = useState<DataState>(initialDataState);
@@ -91,7 +93,9 @@ export const useDeepAnalysisData = (stockCode: string): UseDeepAnalysisDataRetur
loadedApisRef.current[apiKey] = true; loadedApisRef.current[apiKey] = true;
} }
} catch (err) { } catch (err) {
logger.error('DeepAnalysis', `loadApiData:${apiKey}`, err, { stockCode }); logger.error("DeepAnalysis", `loadApiData:${apiKey}`, err, {
stockCode,
});
} finally { } finally {
// 清除 loading再次检查 stockCode // 清除 loading再次检查 stockCode
if (currentStockCodeRef.current === stockCode) { if (currentStockCodeRef.current === stockCode) {
@@ -103,13 +107,13 @@ export const useDeepAnalysisData = (stockCode: string): UseDeepAnalysisDataRetur
); );
/** /**
* 根据 Tab 加载对应数据 * 根据 Tab 加载对应数据(支持一个 Tab 对应多个 API
*/ */
const loadTabData = useCallback( const loadTabData = useCallback(
(tabKey: string) => { (tabKey: string) => {
const apiKey = TAB_API_MAP[tabKey]; const apiKeys = TAB_API_MAP[tabKey];
if (apiKey) { if (apiKeys && apiKeys.length > 0) {
loadApiData(apiKey); apiKeys.forEach((apiKey) => loadApiData(apiKey));
} }
}, },
[loadApiData] [loadApiData]
@@ -134,8 +138,11 @@ export const useDeepAnalysisData = (stockCode: string): UseDeepAnalysisDataRetur
if (stockCode) { if (stockCode) {
currentStockCodeRef.current = stockCode; currentStockCodeRef.current = stockCode;
resetData(); resetData();
// 加载默认 Tabcomprehensive // 加载默认 Tab (strategy) 所需的所有数据
loadApiData('comprehensive'); const defaultTabApis = TAB_API_MAP["strategy"];
if (defaultTabApis) {
defaultTabApis.forEach((apiKey) => loadApiData(apiKey));
}
} }
}, [stockCode, loadApiData, resetData]); }, [stockCode, loadApiData, resetData]);

View File

@@ -7,12 +7,12 @@
* - 业务板块展开状态管理 * - 业务板块展开状态管理
*/ */
import React, { useState, useCallback, useEffect, memo } from 'react'; import React, { useState, useCallback, useEffect, memo } from "react";
import DeepAnalysisTab from '../CompanyOverview/DeepAnalysisTab'; import DeepAnalysisTab from "../CompanyOverview/DeepAnalysisTab";
import type { DeepAnalysisTabKey } from '../CompanyOverview/DeepAnalysisTab/types'; import type { DeepAnalysisTabKey } from "../CompanyOverview/DeepAnalysisTab/types";
import { useDeepAnalysisData } from './hooks'; import { useDeepAnalysisData } from "./hooks";
import { TAB_API_MAP } from './types'; import { TAB_API_MAP } from "./types";
import type { DeepAnalysisProps } from './types'; import type { DeepAnalysisProps } from "./types";
/** /**
* 深度分析组件 * 深度分析组件
@@ -21,10 +21,12 @@ import type { DeepAnalysisProps } from './types';
*/ */
const DeepAnalysis: React.FC<DeepAnalysisProps> = memo(({ stockCode }) => { const DeepAnalysis: React.FC<DeepAnalysisProps> = memo(({ stockCode }) => {
// 当前 Tab // 当前 Tab
const [activeTab, setActiveTab] = useState<DeepAnalysisTabKey>('strategy'); const [activeTab, setActiveTab] = useState<DeepAnalysisTabKey>("strategy");
// 业务板块展开状态 // 业务板块展开状态
const [expandedSegments, setExpandedSegments] = useState<Record<number, boolean>>({}); const [expandedSegments, setExpandedSegments] = useState<
Record<number, boolean>
>({});
// 数据获取 Hook // 数据获取 Hook
const { data, loading, loadTabData } = useDeepAnalysisData(stockCode); const { data, loading, loadTabData } = useDeepAnalysisData(stockCode);
@@ -32,7 +34,7 @@ const DeepAnalysis: React.FC<DeepAnalysisProps> = memo(({ stockCode }) => {
// stockCode 变更时重置 UI 状态 // stockCode 变更时重置 UI 状态
useEffect(() => { useEffect(() => {
if (stockCode) { if (stockCode) {
setActiveTab('strategy'); setActiveTab("strategy");
setExpandedSegments({}); setExpandedSegments({});
} }
}, [stockCode]); }, [stockCode]);
@@ -54,10 +56,11 @@ const DeepAnalysis: React.FC<DeepAnalysisProps> = memo(({ stockCode }) => {
[loadTabData] [loadTabData]
); );
// 获取当前 Tab 的 loading 状态 // 获取当前 Tab 的 loading 状态(任一相关 API loading 则显示 loading
const currentLoading = (() => { const currentLoading = (() => {
const apiKey = TAB_API_MAP[activeTab]; const apiKeys = TAB_API_MAP[activeTab];
return apiKey ? loading[apiKey] : false; if (!apiKeys || apiKeys.length === 0) return false;
return apiKeys.some((apiKey) => loading[apiKey]);
})(); })();
return ( return (
@@ -76,6 +79,6 @@ const DeepAnalysis: React.FC<DeepAnalysisProps> = memo(({ stockCode }) => {
); );
}); });
DeepAnalysis.displayName = 'DeepAnalysis'; DeepAnalysis.displayName = "DeepAnalysis";
export default DeepAnalysis; export default DeepAnalysis;

View File

@@ -9,17 +9,21 @@ export type {
KeyFactorsData, KeyFactorsData,
IndustryRankData, IndustryRankData,
DeepAnalysisTabKey, DeepAnalysisTabKey,
} from '../CompanyOverview/DeepAnalysisTab/types'; } from "../CompanyOverview/DeepAnalysisTab/types";
/** API 接口类型 */ /** API 接口类型 */
export type ApiKey = 'comprehensive' | 'valueChain' | 'keyFactors' | 'industryRank'; export type ApiKey =
| "comprehensive"
| "valueChain"
| "keyFactors"
| "industryRank";
/** Tab 与 API 映射 */ /** Tab 与 API 映射(支持一个 Tab 对应多个 API */
export const TAB_API_MAP: Record<string, ApiKey> = { export const TAB_API_MAP: Record<string, ApiKey[]> = {
strategy: 'comprehensive', strategy: ["comprehensive", "industryRank"], // 战略分析需要综合分析 + 行业排名
business: 'comprehensive', business: ["comprehensive"],
valueChain: 'valueChain', valueChain: ["valueChain"],
development: 'keyFactors', development: ["keyFactors"],
} as const; } as const;
/** API 加载状态 */ /** API 加载状态 */
@@ -69,4 +73,4 @@ import type {
ValueChainData, ValueChainData,
KeyFactorsData, KeyFactorsData,
IndustryRankData, IndustryRankData,
} from '../CompanyOverview/DeepAnalysisTab/types'; } from "../CompanyOverview/DeepAnalysisTab/types";