diff --git a/src/hooks/useSubscription.js b/src/hooks/useSubscription.js index e49270ac..e6a6a59b 100644 --- a/src/hooks/useSubscription.js +++ b/src/hooks/useSubscription.js @@ -34,7 +34,9 @@ const FEATURE_REQUIREMENTS = { 'concept_stats_panel': 'pro', // 概念统计中心 'concept_related_stocks': 'pro', // 概念相关股票 'concept_timeline': 'max', // 概念历史时间轴 - 'hot_stocks': 'pro' // 热门个股 + 'hot_stocks': 'pro', // 热门个股 + 'deep_analysis': 'pro', // 个股深度分析 + 'concept_sector': 'pro', // 个股概念板块 }; /** diff --git a/src/views/Company/components/CompanyTabs/index.js b/src/views/Company/components/CompanyTabs/index.js index 5a3b3da2..2b0864a0 100644 --- a/src/views/Company/components/CompanyTabs/index.js +++ b/src/views/Company/components/CompanyTabs/index.js @@ -1,8 +1,11 @@ // src/views/Company/components/CompanyTabs/index.js // Tab 容器组件 - 使用通用 TabContainer 组件 -import React from 'react'; +import React, { useMemo } from 'react'; +import { Box, VStack, Text, Button, Icon } from '@chakra-ui/react'; +import { Lock, Crown } from 'lucide-react'; import TabContainer from '@components/TabContainer'; +import { useSubscription } from '@hooks/useSubscription'; import { COMPANY_TABS, getTabNameByIndex } from '../../constants'; // 子组件导入(Tab 内容组件) @@ -32,15 +35,159 @@ const TAB_COMPONENTS = { overview: BasicInfoTab, }; +/** + * 需要 Pro 权限的 Tab 配置 + * key: Tab 的 key + * value: 对应的功能权限名称 + */ +const PRO_REQUIRED_TABS = { + analysis: 'deep_analysis', + concept: 'concept_sector', +}; + +/** + * 权限锁定遮罩组件 + */ +const ProLockedOverlay = ({ tabName, onUpgrade }) => ( + + {/* 背景装饰 */} + + + + {/* 锁定图标 */} + + + + + {/* 标题 */} + + + {tabName} - Pro 专属功能 + + + 升级到 Pro 版本,解锁完整的{tabName}功能,获取更深入的投资洞察 + + + + {/* 功能亮点 */} + + {tabName === '深度分析' && ( + <> + ✨ AI 智能分析报告 + ✨ 多维度估值模型 + ✨ 行业对比分析 + + )} + {tabName === '概念板块' && ( + <> + ✨ 所属概念板块详情 + ✨ 概念热度分析 + ✨ 板块联动关系 + + )} + + + {/* 升级按钮 */} + + + + 享受更多高级功能和专业分析 + + + +); + +/** + * 创建带权限检查的包装组件 + */ +const createProtectedComponent = (OriginalComponent, featureName, tabName) => { + const ProtectedComponent = (props) => { + const { hasFeatureAccess, openSubscriptionModal } = useSubscription(); + + // 检查是否有权限访问 + if (!hasFeatureAccess(featureName)) { + return ( + + ); + } + + // 有权限,渲染原始组件 + return ; + }; + + ProtectedComponent.displayName = `Protected(${OriginalComponent.displayName || OriginalComponent.name || 'Component'})`; + return ProtectedComponent; +}; + /** * 构建 TabContainer 所需的 tabs 配置 - * 合并 COMPANY_TABS 和对应的组件 + * 合并 COMPANY_TABS 和对应的组件,并为需要权限的 Tab 添加保护 */ const buildTabsConfig = () => { - return COMPANY_TABS.map((tab) => ({ - ...tab, - component: TAB_COMPONENTS[tab.key], - })); + return COMPANY_TABS.map((tab) => { + const originalComponent = TAB_COMPONENTS[tab.key]; + const featureName = PRO_REQUIRED_TABS[tab.key]; + + // 如果是需要 Pro 权限的 Tab,包装组件 + const component = featureName + ? createProtectedComponent(originalComponent, featureName, tab.name) + : originalComponent; + + return { + ...tab, + component, + }; + }); }; // 预构建 tabs 配置(避免每次渲染重新计算) @@ -53,6 +200,7 @@ const TABS_CONFIG = buildTabsConfig(); * - 使用通用 TabContainer 组件 * - 保持黑金主题风格 * - 触发 Tab 变更追踪 + * - 对"深度分析"和"概念板块"添加 Pro 权限控制 * * @param {Object} props * @param {string} props.stockCode - 当前股票代码