fix: 会员过期时跳过 API 请求 & 限制 STOMP WebSocket 重连次数

- DynamicNewsDetailPanel: 添加会员过期判断,过期时显示续费提示
  - RelatedConceptsSection: 会员过期时跳过概念 API 请求
  - TransmissionChainAnalysis: 会员过期时跳过传导链 API 请求
  - BytedeskWidget: 限制 STOMP WebSocket 最多重连 3 次,屏蔽相关日志
This commit is contained in:
zdl
2025-12-24 15:24:06 +08:00
parent 6f44b8210e
commit c529626ce2
4 changed files with 120 additions and 18 deletions

View File

@@ -18,6 +18,7 @@ import { getImportanceConfig } from '@constants/importanceLevels';
import { eventService } from '@services/eventService';
import { useEventStocks } from '@components/Charts/Stock';
import { toggleEventFollow, selectEventFollowStatus } from '@store/slices/communityDataSlice';
import { selectSubscriptionInfo } from '@store/slices/subscriptionSlice';
import { useAuth } from '@contexts/AuthContext';
import EventHeaderInfo from './EventHeaderInfo';
import CompactMetaBar from './CompactMetaBar';
@@ -102,6 +103,10 @@ const DynamicNewsDetailPanel = ({ event, showHeader = true }) => {
// 获取用户会员等级(修复:字段名从 subscription_tier 改为 subscription_type
const userTier = user?.subscription_type || 'free';
// 获取订阅信息,用于判断会员是否过期
const subscriptionInfo = useSelector(selectSubscriptionInfo);
const isSubscriptionExpired = subscriptionInfo.type !== 'free' && !subscriptionInfo.is_active;
// 从 Redux 读取关注状态
const eventFollowStatus = useSelector(selectEventFollowStatus);
const isFollowing = event?.id ? (eventFollowStatus[event.id]?.isFollowing || false) : false;
@@ -111,12 +116,16 @@ const DynamicNewsDetailPanel = ({ event, showHeader = true }) => {
const [fullEventDetail, setFullEventDetail] = useState(null);
const [loadingDetail, setLoadingDetail] = useState(false);
// 权限判断函数
// 权限判断函数 - 会员过期时视为无权限
const hasAccess = useCallback((requiredTier) => {
// 会员已过期,视为无权限
if (isSubscriptionExpired) {
return false;
}
const tierLevel = { free: 0, pro: 1, max: 2 };
const result = tierLevel[userTier] >= tierLevel[requiredTier];
return result;
}, [userTier]);
}, [userTier, isSubscriptionExpired]);
// 升级弹窗状态
const [upgradeModal, setUpgradeModal] = useState({
@@ -169,14 +178,14 @@ const DynamicNewsDetailPanel = ({ event, showHeader = true }) => {
// 子区块折叠状态管理 - 使用 useReducer 整合
const [sectionState, dispatchSection] = useReducer(sectionReducer, initialSectionState);
// 锁定点击处理 - 弹出升级弹窗
// 锁定点击处理 - 弹出升级弹窗(会员过期时显示续费提示)
const handleLockedClick = useCallback((featureName, requiredLevel) => {
setUpgradeModal({
isOpen: true,
requiredLevel,
featureName
requiredLevel: isSubscriptionExpired ? subscriptionInfo.type : requiredLevel,
featureName: isSubscriptionExpired ? `${featureName}(会员已过期,请续费)` : featureName
});
}, []);
}, [isSubscriptionExpired, subscriptionInfo.type]);
// 关闭升级弹窗
const handleCloseUpgradeModal = useCallback(() => {

View File

@@ -2,6 +2,7 @@
// 相关概念区组件 - 便当盒网格布局
import React, { useState, useEffect } from 'react';
import { useSelector } from 'react-redux';
import {
Box,
Flex,
@@ -18,6 +19,7 @@ import {
import { useNavigate } from 'react-router-dom';
import { logger } from '@utils/logger';
import { getApiBase } from '@utils/apiConfig';
import { selectSubscriptionInfo } from '@store/slices/subscriptionSlice';
/**
* 单个概念卡片组件(便当盒样式)
@@ -100,6 +102,10 @@ const RelatedConceptsSection = ({
const [error, setError] = useState(null);
const navigate = useNavigate();
// 获取订阅信息,用于判断会员是否过期
const subscriptionInfo = useSelector(selectSubscriptionInfo);
const isSubscriptionExpired = subscriptionInfo.type !== 'free' && !subscriptionInfo.is_active;
// 颜色配置 - 使用深色主题固定颜色
const sectionBg = 'transparent';
const headingColor = '#e2e8f0';
@@ -107,7 +113,7 @@ const RelatedConceptsSection = ({
const countBadgeBg = '#3182ce';
const countBadgeColor = '#ffffff';
// 获取相关概念
// 获取相关概念 - 如果被锁定或会员过期则跳过 API 请求
useEffect(() => {
const fetchConcepts = async () => {
if (!eventId) {
@@ -115,6 +121,13 @@ const RelatedConceptsSection = ({
return;
}
// 如果被锁定或会员已过期,不发起 API 请求
if (isLocked || isSubscriptionExpired) {
setLoading(false);
setConcepts([]);
return;
}
try {
setLoading(true);
setError(null);
@@ -152,7 +165,7 @@ const RelatedConceptsSection = ({
};
fetchConcepts();
}, [eventId]);
}, [eventId, isLocked, isSubscriptionExpired]);
// 跳转到概念中心
const handleNavigate = (concept) => {