修复短剧推荐序列化问题

This commit is contained in:
mtvpls
2025-12-18 23:48:12 +08:00
parent c60e25ded6
commit c6e8f70109
3 changed files with 46 additions and 8 deletions

View File

@@ -18,7 +18,7 @@ import {
X,
} from 'lucide-react';
import { useRouter } from 'next/navigation';
import { useEffect, useState } from 'react';
import { useEffect, useRef, useState } from 'react';
import { createPortal } from 'react-dom';
import { getAuthInfoFromBrowserCookie } from '@/lib/auth';
@@ -139,21 +139,55 @@ export const UserMenu: React.FC = () => {
const response = await fetch('/api/notifications');
if (response.ok) {
const data = await response.json();
setUnreadCount(data.unreadCount || 0);
const count = data.unreadCount || 0;
setUnreadCount(count);
// 同步到全局,让其他 UserMenu 实例也能获取
if (typeof window !== 'undefined') {
(window as any).__unreadNotificationCount = count;
}
}
} catch (error) {
console.error('加载未读通知数量失败:', error);
}
};
// 首次加载时检查未读通知数量
// 首次加载时检查未读通知数量(使用全局标记避免多个实例重复请求)
useEffect(() => {
loadUnreadCount();
if (typeof window === 'undefined') return;
// 检查是否已经有其他实例在加载
const globalWindow = window as any;
if (globalWindow.__loadingNotifications) {
// 如果正在加载,等待加载完成后获取结果
const checkInterval = setInterval(() => {
if (!globalWindow.__loadingNotifications && globalWindow.__unreadNotificationCount !== undefined) {
setUnreadCount(globalWindow.__unreadNotificationCount);
clearInterval(checkInterval);
}
}, 100);
return () => clearInterval(checkInterval);
}
// 检查是否已经加载过
if (globalWindow.__unreadNotificationCount !== undefined) {
setUnreadCount(globalWindow.__unreadNotificationCount);
return;
}
// 标记正在加载
globalWindow.__loadingNotifications = true;
loadUnreadCount().finally(() => {
globalWindow.__loadingNotifications = false;
});
}, []);
// 监听通知更新事件
useEffect(() => {
const handleNotificationsUpdated = () => {
// 清除缓存,强制重新加载
if (typeof window !== 'undefined') {
delete (window as any).__unreadNotificationCount;
}
loadUnreadCount();
};
@@ -1455,7 +1489,7 @@ export const UserMenu: React.FC = () => {
isOpen={isNotificationPanelOpen}
onClose={() => {
setIsNotificationPanelOpen(false);
loadUnreadCount(); // 关闭时刷新未读数量
// 不需要在这里刷新NotificationPanel 内部会触发事件
}}
/>,
document.body

View File

@@ -25,7 +25,7 @@ export async function getDuanjuSources(): Promise<DuanjuSource[]> {
const cachedData = await db.getGlobalValue('duanju');
if (cachedData !== null) {
// 有缓存,直接返回
// 有缓存,直接返回getGlobalValue 已经处理了序列化问题)
return cachedData ? JSON.parse(cachedData) : [];
}

View File

@@ -403,12 +403,16 @@ export class UpstashRedisStorage implements IStorage {
const val = await withRetry(() =>
this.client.get(this.globalValueKey(key))
);
return val ? ensureString(val) : null;
// Upstash 会自动反序列化 JSON如果值是对象需要重新序列化为字符串
if (val === null) return null;
if (typeof val === 'string') return val;
// 如果是对象Upstash 自动反序列化的结果),重新序列化
return JSON.stringify(val);
}
async setGlobalValue(key: string, value: string): Promise<void> {
await withRetry(() =>
this.client.set(this.globalValueKey(key), ensureString(value))
this.client.set(this.globalValueKey(key), value)
);
}