- 新增 currentStockInfo/compareStockInfo 状态管理 - 新增 handleCompare 处理对比数据加载 - StockQuoteCard 传入对比相关 props
173 lines
5.3 KiB
JavaScript
173 lines
5.3 KiB
JavaScript
// src/views/Company/index.js
|
||
// 公司详情页面入口 - 纯组合层
|
||
|
||
import React, { useEffect, useRef, useState, useCallback } from 'react';
|
||
import { Container, VStack, useToast } from '@chakra-ui/react';
|
||
import { useDispatch } from 'react-redux';
|
||
import { loadAllStocks } from '@store/slices/stockSlice';
|
||
import { financialService } from '@services/financialService';
|
||
import { logger } from '@utils/logger';
|
||
|
||
// 自定义 Hooks
|
||
import { useCompanyStock } from './hooks/useCompanyStock';
|
||
import { useCompanyWatchlist } from './hooks/useCompanyWatchlist';
|
||
import { useCompanyEvents } from './hooks/useCompanyEvents';
|
||
import { useStockQuote } from './hooks/useStockQuote';
|
||
import { useBasicInfo } from './components/CompanyOverview/hooks/useBasicInfo';
|
||
|
||
// 页面组件
|
||
import CompanyHeader from './components/CompanyHeader';
|
||
import StockQuoteCard from './components/StockQuoteCard';
|
||
import CompanyTabs from './components/CompanyTabs';
|
||
|
||
/**
|
||
* 公司详情页面
|
||
*
|
||
* 功能:
|
||
* - 股票搜索与代码管理
|
||
* - 自选股添加/移除
|
||
* - 多维度数据展示(概览、行情、财务、预测)
|
||
* - PostHog 事件追踪
|
||
*/
|
||
const CompanyIndex = () => {
|
||
const dispatch = useDispatch();
|
||
const toast = useToast();
|
||
|
||
// 1. 先获取股票代码(不带追踪回调)
|
||
const {
|
||
stockCode,
|
||
inputCode,
|
||
setInputCode,
|
||
handleSearch,
|
||
handleKeyDown,
|
||
} = useCompanyStock();
|
||
|
||
// 加载全部股票列表(用于模糊搜索)
|
||
useEffect(() => {
|
||
dispatch(loadAllStocks());
|
||
}, [dispatch]);
|
||
|
||
// 2. 获取股票行情数据
|
||
const { data: quoteData, isLoading: isQuoteLoading } = useStockQuote(stockCode);
|
||
|
||
// 2.1 获取公司基本信息
|
||
const { basicInfo } = useBasicInfo(stockCode);
|
||
|
||
// 5. 股票对比状态管理
|
||
const [currentStockInfo, setCurrentStockInfo] = useState(null);
|
||
const [compareStockInfo, setCompareStockInfo] = useState(null);
|
||
const [isCompareLoading, setIsCompareLoading] = useState(false);
|
||
|
||
// 加载当前股票财务信息(用于对比)
|
||
useEffect(() => {
|
||
const loadCurrentStockInfo = async () => {
|
||
if (!stockCode) return;
|
||
try {
|
||
const res = await financialService.getStockInfo(stockCode);
|
||
setCurrentStockInfo(res.data);
|
||
} catch (error) {
|
||
logger.error('CompanyIndex', 'loadCurrentStockInfo', error, { stockCode });
|
||
}
|
||
};
|
||
loadCurrentStockInfo();
|
||
// 清除对比数据
|
||
setCompareStockInfo(null);
|
||
}, [stockCode]);
|
||
|
||
// 处理股票对比
|
||
const handleCompare = useCallback(async (compareCode) => {
|
||
if (!compareCode) return;
|
||
|
||
logger.debug('CompanyIndex', '开始加载对比数据', { stockCode, compareCode });
|
||
setIsCompareLoading(true);
|
||
|
||
try {
|
||
const res = await financialService.getStockInfo(compareCode);
|
||
setCompareStockInfo(res.data);
|
||
logger.info('CompanyIndex', '对比数据加载成功', { stockCode, compareCode });
|
||
} catch (error) {
|
||
logger.error('CompanyIndex', 'handleCompare', error, { stockCode, compareCode });
|
||
toast({
|
||
title: '加载对比数据失败',
|
||
description: '请检查股票代码是否正确',
|
||
status: 'error',
|
||
duration: 3000,
|
||
});
|
||
} finally {
|
||
setIsCompareLoading(false);
|
||
}
|
||
}, [stockCode, toast]);
|
||
|
||
// 关闭对比弹窗
|
||
const handleCloseCompare = useCallback(() => {
|
||
// 可选:清除对比数据
|
||
// setCompareStockInfo(null);
|
||
}, []);
|
||
|
||
// 3. 再初始化事件追踪(传入 stockCode)
|
||
const {
|
||
trackStockSearched,
|
||
trackTabChanged,
|
||
trackWatchlistAdded,
|
||
trackWatchlistRemoved,
|
||
} = useCompanyEvents({ stockCode });
|
||
|
||
// 3. 自选股管理
|
||
const {
|
||
isInWatchlist,
|
||
isLoading: isWatchlistLoading,
|
||
toggle: handleWatchlistToggle,
|
||
} = useCompanyWatchlist({
|
||
stockCode,
|
||
tracking: {
|
||
onAdd: trackWatchlistAdded,
|
||
onRemove: trackWatchlistRemoved,
|
||
},
|
||
});
|
||
|
||
// 4. 监听 stockCode 变化,触发搜索追踪
|
||
const prevStockCodeRef = useRef(stockCode);
|
||
useEffect(() => {
|
||
if (stockCode !== prevStockCodeRef.current) {
|
||
trackStockSearched(stockCode, prevStockCodeRef.current);
|
||
prevStockCodeRef.current = stockCode;
|
||
}
|
||
}, [stockCode, trackStockSearched]);
|
||
|
||
return (
|
||
<Container maxW="container.xl" py={0} bg='#1A202C'>
|
||
<VStack align="stretch" spacing={0}>
|
||
{/* 页面头部:标题、搜索 */}
|
||
<CompanyHeader
|
||
inputCode={inputCode}
|
||
onInputChange={setInputCode}
|
||
onSearch={handleSearch}
|
||
onKeyDown={handleKeyDown}
|
||
bgColor="#1A202C"
|
||
/>
|
||
|
||
{/* 股票行情卡片:价格、关键指标、主力动态、公司信息、股票对比 */}
|
||
<StockQuoteCard
|
||
data={quoteData}
|
||
isLoading={isQuoteLoading}
|
||
isInWatchlist={isInWatchlist}
|
||
isWatchlistLoading={isWatchlistLoading}
|
||
onWatchlistToggle={handleWatchlistToggle}
|
||
basicInfo={basicInfo}
|
||
// 股票对比相关
|
||
currentStockInfo={currentStockInfo}
|
||
compareStockInfo={compareStockInfo}
|
||
isCompareLoading={isCompareLoading}
|
||
onCompare={handleCompare}
|
||
onCloseCompare={handleCloseCompare}
|
||
/>
|
||
|
||
{/* Tab 切换区域:概览、行情、财务、预测 */}
|
||
<CompanyTabs stockCode={stockCode} onTabChange={trackTabChanged} bgColor="#1A202C"/>
|
||
</VStack>
|
||
</Container>
|
||
);
|
||
};
|
||
|
||
export default CompanyIndex;
|