update pay ui

This commit is contained in:
2025-12-17 17:29:08 +08:00
parent 8def7f355b
commit 697c366e88
7 changed files with 850 additions and 473 deletions

150
src/views/Company/index.tsx Normal file
View 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);