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:
@@ -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();
|
||||||
// 只加载默认 Tab(comprehensive)
|
// 加载默认 Tab (strategy) 所需的所有数据
|
||||||
loadApiData('comprehensive');
|
const defaultTabApis = TAB_API_MAP["strategy"];
|
||||||
|
if (defaultTabApis) {
|
||||||
|
defaultTabApis.forEach((apiKey) => loadApiData(apiKey));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}, [stockCode, loadApiData, resetData]);
|
}, [stockCode, loadApiData, resetData]);
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|||||||
Reference in New Issue
Block a user