fix: 修复导航栏 Max 会员订阅信息显示问题

- 修复 HomeNavbar 中 useEffect 执行顺序导致订阅信息不加载的问题
- 移除 ref 检查逻辑,改为直接根据登录状态加载订阅信息
- 增强订阅相关的调试日志输出(getCurrentUser, API handler, HomeNavbar)
- 优化用户数据获取的日志格式,便于问题排查
This commit is contained in:
zdl
2025-10-30 13:09:41 +08:00
parent 1d5efd88b2
commit 3acc00ac8d
3 changed files with 56 additions and 41 deletions

View File

@@ -788,19 +788,18 @@ export default function HomeNavbar() {
// 加载订阅信息 // 加载订阅信息
React.useEffect(() => { React.useEffect(() => {
const userIdChanged = prevUserIdRef.current !== userId; // ✅ 移除 ref 检查,直接根据登录状态加载
const authChanged = prevIsAuthenticatedRef.current !== isAuthenticated;
if (userIdChanged || authChanged) {
if (isAuthenticated && user) { if (isAuthenticated && user) {
const loadSubscriptionInfo = async () => { const loadSubscriptionInfo = async () => {
try { try {
const base = getApiBase(); const base = getApiBase();
logger.debug('HomeNavbar', '开始加载订阅信息', { user_id: user?.id });
const response = await fetch(base + '/api/subscription/current', { const response = await fetch(base + '/api/subscription/current', {
credentials: 'include', credentials: 'include',
}); });
if (response.ok) { if (response.ok) {
const data = await response.json(); const data = await response.json();
logger.debug('HomeNavbar', 'API 返回订阅数据', data);
if (data.success && data.data) { if (data.success && data.data) {
// 数据标准化处理确保type字段是小写的 'free', 'pro', 或 'max' // 数据标准化处理确保type字段是小写的 'free', 'pro', 或 'max'
const normalizedData = { const normalizedData = {
@@ -810,6 +809,7 @@ export default function HomeNavbar() {
is_active: data.data.is_active !== false, is_active: data.data.is_active !== false,
end_date: data.data.end_date || null end_date: data.data.end_date || null
}; };
logger.info('HomeNavbar', '订阅信息已更新', normalizedData);
setSubscriptionInfo(normalizedData); setSubscriptionInfo(normalizedData);
} }
} }
@@ -820,6 +820,7 @@ export default function HomeNavbar() {
loadSubscriptionInfo(); loadSubscriptionInfo();
} else { } else {
// 用户未登录时,重置为免费版 // 用户未登录时,重置为免费版
logger.debug('HomeNavbar', '用户未登录,重置订阅信息为免费版');
setSubscriptionInfo({ setSubscriptionInfo({
type: 'free', type: 'free',
status: 'active', status: 'active',
@@ -827,8 +828,7 @@ export default function HomeNavbar() {
is_active: true is_active: true
}); });
} }
} }, [isAuthenticated, userId, user]); // ✅ React 会自动去重,不会造成无限循环
}, [isAuthenticated, userId, user]); // ⚡ 使用 userId防重复通过 ref 判断
return ( return (
<> <>

View File

@@ -112,12 +112,20 @@ export function getCurrentUser() {
const stored = localStorage.getItem('mock_current_user'); const stored = localStorage.getItem('mock_current_user');
if (stored) { if (stored) {
const user = JSON.parse(stored); const user = JSON.parse(stored);
console.log('[Mock State] 获取当前登录用户:', user); console.log('[Mock State] 获取当前登录用户:', {
id: user.id,
phone: user.phone,
nickname: user.nickname,
subscription_type: user.subscription_type,
subscription_status: user.subscription_status,
subscription_days_left: user.subscription_days_left
});
return user; return user;
} }
} catch (error) { } catch (error) {
console.error('[Mock State] 解析用户数据失败:', error); console.error('[Mock State] 解析用户数据失败:', error);
} }
console.log('[Mock State] 未找到当前登录用户');
return null; return null;
} }

View File

@@ -594,14 +594,13 @@ export const accountHandlers = [
const currentUser = getCurrentUser(); const currentUser = getCurrentUser();
if (!currentUser) { if (!currentUser) {
console.warn('[Mock API] 获取订阅详情失败: 用户未登录');
return HttpResponse.json( return HttpResponse.json(
{ success: false, error: '未登录' }, { success: false, error: '未登录' },
{ status: 401 } { status: 401 }
); );
} }
console.log('[Mock] 获取当前订阅详情');
// 基于当前用户的订阅类型返回详情 // 基于当前用户的订阅类型返回详情
const userSubscriptionType = (currentUser.subscription_type || 'free').toLowerCase(); const userSubscriptionType = (currentUser.subscription_type || 'free').toLowerCase();
@@ -614,6 +613,14 @@ export const accountHandlers = [
end_date: currentUser.subscription_end_date || null end_date: currentUser.subscription_end_date || null
}; };
console.log('[Mock API] 获取当前订阅详情:', {
user_id: currentUser.id,
phone: currentUser.phone,
subscription_type: userSubscriptionType,
subscription_status: subscriptionDetails.status,
days_left: subscriptionDetails.days_left
});
return HttpResponse.json({ return HttpResponse.json({
success: true, success: true,
data: subscriptionDetails data: subscriptionDetails