feat: 将 StockQuoteCard 提升到 Tab 容器上方 + 修复 TS 警告

功能变更:
- 将 StockQuoteCard 从 CompanyOverview 移至 Company/index.tsx
- 股票行情卡片现在在切换 Tab 时始终可见

TypeScript 警告修复:
- SubTabContainer: WebkitBackdropFilter 改用 sx 属性
- DetailTable: 重新定义 TableRowData 类型,支持 boolean 索引
- SubscriptionContentNew: 添加类型安全的 AGREEMENT_URLS 索引访问

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
zdl
2025-12-18 17:25:21 +08:00
parent f36e210fe8
commit 4b3588e8de
5 changed files with 42 additions and 16 deletions

View File

@@ -198,7 +198,7 @@ const SubTabContainer: React.FC<SubTabContainerProps> = memo(({
<TabList <TabList
bg={theme.bg} bg={theme.bg}
backdropFilter="blur(20px)" backdropFilter="blur(20px)"
WebkitBackdropFilter="blur(20px)" sx={{ WebkitBackdropFilter: 'blur(20px)' }}
borderBottom="1px solid" borderBottom="1px solid"
borderColor={theme.borderColor} borderColor={theme.borderColor}
borderRadius={DEEP_SPACE.radiusLG} borderRadius={DEEP_SPACE.radiusLG}

View File

@@ -1632,14 +1632,17 @@ export default function SubscriptionContentNew() {
<Text fontSize="sm" color="rgba(255, 255, 255, 0.7)"> <Text fontSize="sm" color="rgba(255, 255, 255, 0.7)">
<ChakraLink <ChakraLink
href={AGREEMENT_URLS[(selectedPlan as any)?.name?.toLowerCase()] || AGREEMENT_URLS.pro} href={(() => {
const planName = (selectedPlan as { name?: string } | null)?.name?.toLowerCase();
return planName === 'pro' || planName === 'max' ? AGREEMENT_URLS[planName] : AGREEMENT_URLS.pro;
})()}
isExternal isExternal
color="#3182CE" color="#3182CE"
textDecoration="underline" textDecoration="underline"
mx={1} mx={1}
onClick={(e) => e.stopPropagation()} onClick={(e) => e.stopPropagation()}
> >
{(selectedPlan as any)?.name?.toLowerCase() === 'max' ? 'MAX' : 'PRO'} {(selectedPlan as { name?: string } | null)?.name?.toLowerCase() === 'max' ? 'MAX' : 'PRO'}
</ChakraLink> </ChakraLink>
</Text> </Text>
</Checkbox> </Checkbox>

View File

@@ -1,35 +1,31 @@
// src/views/Company/components/CompanyOverview/index.tsx // src/views/Company/components/CompanyOverview/index.tsx
// 公司档案 - 主组件(组合层) // 公司档案 - 主组件(组合层)
// 注StockQuoteCard 已移至 Company/index.tsx放在 Tab 容器上方,切换 Tab 时始终可见
import React from "react"; import React from "react";
import { VStack } from "@chakra-ui/react";
import type { CompanyOverviewProps } from "./types"; import type { CompanyOverviewProps } from "./types";
// 子组件 // 子组件
import StockQuoteCard from "../StockQuoteCard";
import BasicInfoTab from "./BasicInfoTab"; import BasicInfoTab from "./BasicInfoTab";
/** /**
* 公司档案组件 * 公司档案组件
* *
* 功能: * 功能:
* - 显示股票行情卡片(个股详情)
* - 显示基本信息 Tab内部懒加载各子 Tab 数据) * - 显示基本信息 Tab内部懒加载各子 Tab 数据)
* *
* 注意:
* - StockQuoteCard 已提升到 Company/index.tsx 中渲染
* - 确保切换 Tab 时股票行情卡片始终可见
*
* 懒加载策略: * 懒加载策略:
* - BasicInfoTab 内部根据 Tab 切换懒加载数据 * - BasicInfoTab 内部根据 Tab 切换懒加载数据
* - 各 Panel 组件自行获取所需数据(如 BusinessInfoPanel 调用 useBasicInfo * - 各 Panel 组件自行获取所需数据(如 BusinessInfoPanel 调用 useBasicInfo
*/ */
const CompanyOverview: React.FC<CompanyOverviewProps> = ({ stockCode }) => { const CompanyOverview: React.FC<CompanyOverviewProps> = ({ stockCode }) => {
return ( return (
<VStack spacing={6} align="stretch"> <BasicInfoTab stockCode={stockCode} />
{/* 股票行情卡片 - 个股详情 */}
<StockQuoteCard stockCode={stockCode} />
{/* 基本信息内容 - 传入 stockCode内部懒加载各 Tab 数据 */}
<BasicInfoTab stockCode={stockCode} />
</VStack>
); );
}; };

View File

@@ -114,10 +114,13 @@ const tableStyles = `
} }
`; `;
interface TableRowData extends DetailTableRow { // 表格行数据类型 - 扩展索引签名以支持 boolean
type TableRowData = {
key: string; key: string;
isImportant?: boolean; isImportant?: boolean;
} 指标: string;
[year: string]: string | number | boolean | null | undefined;
};
const DetailTable: React.FC<DetailTableProps> = ({ data }) => { const DetailTable: React.FC<DetailTableProps> = ({ data }) => {
const { years, rows } = data; const { years, rows } = data;

View File

@@ -19,6 +19,7 @@ import SubTabContainer from '@components/SubTabContainer';
import { useCompanyEvents } from './hooks/useCompanyEvents'; import { useCompanyEvents } from './hooks/useCompanyEvents';
import { useCompanyData } from './hooks/useCompanyData'; import { useCompanyData } from './hooks/useCompanyData';
import CompanyHeader from './components/CompanyHeader'; import CompanyHeader from './components/CompanyHeader';
import StockQuoteCard from './components/StockQuoteCard';
import { THEME, TAB_CONFIG } from './config'; import { THEME, TAB_CONFIG } from './config';
// ============================================ // ============================================
@@ -39,11 +40,31 @@ TabLoadingFallback.displayName = 'TabLoadingFallback';
interface CompanyContentProps { interface CompanyContentProps {
stockCode: string; stockCode: string;
isInWatchlist: boolean;
watchlistLoading: boolean;
onWatchlistToggle: () => void;
onTabChange: (index: number, tabKey: string) => void; onTabChange: (index: number, tabKey: string) => void;
} }
const CompanyContent = memo<CompanyContentProps>(({ stockCode, onTabChange }) => ( const CompanyContent = memo<CompanyContentProps>(({
stockCode,
isInWatchlist,
watchlistLoading,
onWatchlistToggle,
onTabChange,
}) => (
<Box maxW="container.xl" mx="auto" px={4} py={6}> <Box maxW="container.xl" mx="auto" px={4} py={6}>
{/* 股票行情卡片 - 放在 Tab 切换器上方,始终可见 */}
<Box mb={6}>
<StockQuoteCard
stockCode={stockCode}
isInWatchlist={isInWatchlist}
isWatchlistLoading={watchlistLoading}
onWatchlistToggle={onWatchlistToggle}
/>
</Box>
{/* Tab 内容区 */}
<Box <Box
position="relative" position="relative"
bg={`linear-gradient(145deg, rgba(26, 26, 46, 0.95) 0%, rgba(15, 15, 26, 0.98) 100%)`} bg={`linear-gradient(145deg, rgba(26, 26, 46, 0.95) 0%, rgba(15, 15, 26, 0.98) 100%)`}
@@ -245,6 +266,9 @@ const CompanyIndex: React.FC = () => {
<Box position="relative" zIndex={1}> <Box position="relative" zIndex={1}>
<CompanyContent <CompanyContent
stockCode={stockCode} stockCode={stockCode}
isInWatchlist={isInWatchlist}
watchlistLoading={watchlistLoading}
onWatchlistToggle={handleWatchlistToggle}
onTabChange={handleTabChange} onTabChange={handleTabChange}
/> />
</Box> </Box>