update pay ui
This commit is contained in:
150
src/views/Company/index.tsx
Normal file
150
src/views/Company/index.tsx
Normal file
@@ -0,0 +1,150 @@
|
||||
/**
|
||||
* 公司详情页面
|
||||
*
|
||||
* 特性:
|
||||
* - 黑金主题设计
|
||||
* - 懒加载 Tab 内容
|
||||
* - memo 性能优化
|
||||
* - axios 数据请求
|
||||
*/
|
||||
|
||||
import React, { memo, useCallback, useRef, useEffect, Suspense } from 'react';
|
||||
import { useSearchParams } from 'react-router-dom';
|
||||
import { Box, Spinner, Center } from '@chakra-ui/react';
|
||||
import SubTabContainer from '@components/SubTabContainer';
|
||||
import { useCompanyEvents } from './hooks/useCompanyEvents';
|
||||
import { useCompanyData } from './hooks/useCompanyData';
|
||||
import CompanyHeader from './components/CompanyHeader';
|
||||
import { THEME, TAB_CONFIG } from './config';
|
||||
|
||||
// ============================================
|
||||
// 加载状态组件
|
||||
// ============================================
|
||||
|
||||
const TabLoadingFallback = memo(() => (
|
||||
<Center py={20}>
|
||||
<Spinner size="xl" color={THEME.gold} thickness="3px" />
|
||||
</Center>
|
||||
));
|
||||
|
||||
TabLoadingFallback.displayName = 'TabLoadingFallback';
|
||||
|
||||
// ============================================
|
||||
// 主内容区组件
|
||||
// ============================================
|
||||
|
||||
interface CompanyContentProps {
|
||||
stockCode: string;
|
||||
onTabChange: (index: number, tabKey: string) => void;
|
||||
}
|
||||
|
||||
const CompanyContent = memo<CompanyContentProps>(({ stockCode, onTabChange }) => (
|
||||
<Box maxW="container.xl" mx="auto" px={4} py={6}>
|
||||
<Box
|
||||
bg={THEME.cardBg}
|
||||
borderRadius="xl"
|
||||
border="1px solid"
|
||||
borderColor={THEME.border}
|
||||
overflow="hidden"
|
||||
>
|
||||
<Suspense fallback={<TabLoadingFallback />}>
|
||||
<SubTabContainer
|
||||
tabs={TAB_CONFIG}
|
||||
componentProps={{ stockCode }}
|
||||
onTabChange={onTabChange}
|
||||
themePreset="blackGold"
|
||||
contentPadding={6}
|
||||
isLazy={true}
|
||||
/>
|
||||
</Suspense>
|
||||
</Box>
|
||||
</Box>
|
||||
));
|
||||
|
||||
CompanyContent.displayName = 'CompanyContent';
|
||||
|
||||
// ============================================
|
||||
// 主页面组件
|
||||
// ============================================
|
||||
|
||||
const CompanyIndex: React.FC = () => {
|
||||
// URL 参数管理
|
||||
const [searchParams, setSearchParams] = useSearchParams();
|
||||
const stockCode = searchParams.get('scode') || '000001';
|
||||
const prevStockCodeRef = useRef(stockCode);
|
||||
|
||||
// 数据加载 Hook
|
||||
const {
|
||||
stockInfo,
|
||||
stockInfoLoading,
|
||||
isInWatchlist,
|
||||
watchlistLoading,
|
||||
toggleWatchlist,
|
||||
} = useCompanyData({ stockCode });
|
||||
|
||||
// 事件追踪 Hook
|
||||
const {
|
||||
trackStockSearched,
|
||||
trackTabChanged,
|
||||
trackWatchlistAdded,
|
||||
trackWatchlistRemoved,
|
||||
} = useCompanyEvents({ stockCode });
|
||||
|
||||
// 股票代码变化追踪
|
||||
useEffect(() => {
|
||||
if (stockCode !== prevStockCodeRef.current) {
|
||||
trackStockSearched(stockCode, prevStockCodeRef.current);
|
||||
prevStockCodeRef.current = stockCode;
|
||||
}
|
||||
}, [stockCode, trackStockSearched]);
|
||||
|
||||
// 处理股票切换
|
||||
const handleStockChange = useCallback((newCode: string) => {
|
||||
if (newCode && newCode !== stockCode) {
|
||||
trackStockSearched(newCode, stockCode);
|
||||
setSearchParams({ scode: newCode });
|
||||
}
|
||||
}, [stockCode, setSearchParams, trackStockSearched]);
|
||||
|
||||
// 处理自选股切换(带追踪)
|
||||
const handleWatchlistToggle = useCallback(async () => {
|
||||
const wasInWatchlist = isInWatchlist;
|
||||
await toggleWatchlist();
|
||||
|
||||
// 追踪事件(根据操作前的状态判断)
|
||||
if (wasInWatchlist) {
|
||||
trackWatchlistRemoved(stockCode);
|
||||
} else {
|
||||
trackWatchlistAdded(stockCode);
|
||||
}
|
||||
}, [stockCode, isInWatchlist, toggleWatchlist, trackWatchlistAdded, trackWatchlistRemoved]);
|
||||
|
||||
// 处理 Tab 切换
|
||||
const handleTabChange = useCallback((index: number, tabKey: string) => {
|
||||
const tabName = TAB_CONFIG[index]?.name || tabKey;
|
||||
trackTabChanged(index, tabName, index);
|
||||
}, [trackTabChanged]);
|
||||
|
||||
return (
|
||||
<Box bg={THEME.bg} minH="calc(100vh - 60px)">
|
||||
{/* 顶部搜索栏 */}
|
||||
<CompanyHeader
|
||||
stockCode={stockCode}
|
||||
stockInfo={stockInfo}
|
||||
stockInfoLoading={stockInfoLoading}
|
||||
isInWatchlist={isInWatchlist}
|
||||
watchlistLoading={watchlistLoading}
|
||||
onStockChange={handleStockChange}
|
||||
onWatchlistToggle={handleWatchlistToggle}
|
||||
/>
|
||||
|
||||
{/* 主内容区 */}
|
||||
<CompanyContent
|
||||
stockCode={stockCode}
|
||||
onTabChange={handleTabChange}
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default memo(CompanyIndex);
|
||||
Reference in New Issue
Block a user