// src/hooks/useSubscription.js // 订阅信息自定义 Hook - 使用 Redux 状态管理 import { useEffect } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { useAuth } from '../contexts/AuthContext'; import { logger } from '../utils/logger'; import { fetchSubscriptionInfo, openModal, closeModal, resetToFree, selectSubscriptionInfo, selectSubscriptionLoading, selectSubscriptionLoaded, selectSubscriptionError, selectSubscriptionModalOpen } from '../store/slices/subscriptionSlice'; // 订阅级别映射 const SUBSCRIPTION_LEVELS = { free: 0, pro: 1, max: 2 }; // 功能权限映射 const FEATURE_REQUIREMENTS = { 'related_stocks': 'pro', // 相关标的 'related_concepts': 'pro', // 相关概念 'transmission_chain': 'max', // 事件传导链分析 'historical_events_full': 'pro', // 历史事件对比(完整版) 'concept_html_detail': 'pro', // 概念HTML具体内容 'concept_stats_panel': 'pro', // 概念统计中心 'concept_related_stocks': 'pro', // 概念相关股票 'concept_timeline': 'max', // 概念历史时间轴 'hot_stocks': 'pro' // 热门个股 }; /** * 订阅信息自定义 Hook (Redux 版本) * * 功能: * - 自动根据登录状态加载订阅信息 (从 Redux) * - 提供权限检查方法 * - 提供订阅 Modal 控制方法 * * @returns {{ * subscriptionInfo: Object, * loading: boolean, * error: string|null, * isSubscriptionModalOpen: boolean, * openSubscriptionModal: Function, * closeSubscriptionModal: Function, * refreshSubscription: Function, * hasFeatureAccess: Function, * hasSubscriptionLevel: Function, * getRequiredLevel: Function, * getSubscriptionStatusText: Function, * getUpgradeRecommendation: Function * }} */ export const useSubscription = () => { const dispatch = useDispatch(); const { user, isAuthenticated } = useAuth(); // Redux 状态 const subscriptionInfo = useSelector(selectSubscriptionInfo); const loading = useSelector(selectSubscriptionLoading); const loaded = useSelector(selectSubscriptionLoaded); const error = useSelector(selectSubscriptionError); const isSubscriptionModalOpen = useSelector(selectSubscriptionModalOpen); // 自动加载订阅信息(带防重复逻辑) useEffect(() => { if (isAuthenticated && user) { // 只在未加载且未在加载中时才请求,避免多个组件重复调用 if (!loaded && !loading) { dispatch(fetchSubscriptionInfo()); logger.debug('useSubscription', '加载订阅信息', { userId: user.id }); } } else { // 用户未登录,重置为免费版 dispatch(resetToFree()); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [isAuthenticated, user?.id, dispatch, loaded, loading]); // 获取订阅级别数值 const getSubscriptionLevel = (type = null) => { const subType = (type || subscriptionInfo.type || 'free').toLowerCase(); return SUBSCRIPTION_LEVELS[subType] || 0; }; // 检查是否有指定功能的权限 const hasFeatureAccess = (featureName) => { // Max 用户解锁所有功能 if (user?.subscription_type === 'max' || subscriptionInfo.type === 'max') { return true; } if (!subscriptionInfo.is_active) { return false; } const requiredLevel = FEATURE_REQUIREMENTS[featureName]; if (!requiredLevel) { return true; // 如果功能不需要特定权限,默认允许 } const currentLevel = getSubscriptionLevel(); const requiredLevelNum = getSubscriptionLevel(requiredLevel); return currentLevel >= requiredLevelNum; }; // 检查是否达到指定订阅级别 const hasSubscriptionLevel = (requiredLevel) => { if (!subscriptionInfo.is_active) { return false; } const currentLevel = getSubscriptionLevel(); const requiredLevelNum = getSubscriptionLevel(requiredLevel); return currentLevel >= requiredLevelNum; }; // 获取功能所需的订阅级别 const getRequiredLevel = (featureName) => { return FEATURE_REQUIREMENTS[featureName] || 'free'; }; // 获取订阅状态文本 const getSubscriptionStatusText = () => { const type = subscriptionInfo.type || 'free'; switch (type.toLowerCase()) { case 'free': return '免费版'; case 'pro': return 'Pro版'; case 'max': return 'Max版'; default: return '未知'; } }; // 获取升级建议 const getUpgradeRecommendation = (featureName) => { const requiredLevel = getRequiredLevel(featureName); const currentType = subscriptionInfo.type || 'free'; if (hasFeatureAccess(featureName)) { return null; } return { current: currentType, required: requiredLevel, message: `此功能需要${requiredLevel === 'pro' ? 'Pro版' : 'Max版'}订阅` }; }; return { // 订阅信息 (来自 Redux) subscriptionInfo, loading, error, // Modal 控制 isSubscriptionModalOpen, openSubscriptionModal: () => dispatch(openModal()), closeSubscriptionModal: () => dispatch(closeModal()), // 权限检查方法 hasFeatureAccess, hasSubscriptionLevel, getRequiredLevel, getSubscriptionStatusText, getUpgradeRecommendation, // 手动刷新 refreshSubscription: () => dispatch(fetchSubscriptionInfo()) }; };