fix: 空评论列表 500,并完善撤回审计与角色说明
空切片 JSON 统一为数组;撤回保留正文供站长阅读,成员侧居中提示与重新编辑;头像支持拖放;角色弹窗补全职责说明并汇入封禁。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -27,6 +27,7 @@ import { isStaff } from "@/lib/roles";
|
||||
import { onUserUpdate, onForceLogout } from "@/lib/userEvents";
|
||||
import { realtime, RT_CHAT_UNREAD } from "@/lib/realtime";
|
||||
import type { RtChatUnreadData } from "@/lib/realtime";
|
||||
import { onDocumentVisible } from "@/lib/visibilityReconcile";
|
||||
import NotificationBell from "./NotificationBell";
|
||||
import Avatar from "./Avatar";
|
||||
|
||||
@@ -112,29 +113,26 @@ export default function Header({
|
||||
return off;
|
||||
}, [user, pathname]);
|
||||
|
||||
// 会话内已读后主动对账(ChatRoomClient 派发)
|
||||
// 会话内已读 / 回前台:合并对账(短时间多次 markRead 只打一次 summary)
|
||||
useEffect(() => {
|
||||
if (!user) return;
|
||||
const onSync = () => {
|
||||
let debounceTimer: ReturnType<typeof setTimeout> | null = null;
|
||||
const pullSummary = () => {
|
||||
apiChatUnreadSummary()
|
||||
.then((res) => setChatUnread(res.total || 0))
|
||||
.catch(() => {});
|
||||
};
|
||||
const onSync = () => {
|
||||
if (debounceTimer) clearTimeout(debounceTimer);
|
||||
debounceTimer = setTimeout(pullSummary, 250);
|
||||
};
|
||||
window.addEventListener("j13-chat-unread-sync", onSync);
|
||||
return () => window.removeEventListener("j13-chat-unread-sync", onSync);
|
||||
}, [user]);
|
||||
|
||||
// 切回标签页时重新对账未读
|
||||
useEffect(() => {
|
||||
if (!user) return;
|
||||
const onVisible = () => {
|
||||
if (document.visibilityState !== "visible") return;
|
||||
apiChatUnreadSummary()
|
||||
.then((res) => setChatUnread(res.total || 0))
|
||||
.catch(() => {});
|
||||
const offVisible = onDocumentVisible(pullSummary);
|
||||
return () => {
|
||||
if (debounceTimer) clearTimeout(debounceTimer);
|
||||
window.removeEventListener("j13-chat-unread-sync", onSync);
|
||||
offVisible();
|
||||
};
|
||||
document.addEventListener("visibilitychange", onVisible);
|
||||
return () => document.removeEventListener("visibilitychange", onVisible);
|
||||
}, [user]);
|
||||
|
||||
const handleSearch = (e: React.FormEvent) => {
|
||||
|
||||
Reference in New Issue
Block a user