zdl
|
163c55f819
|
refactor: 重构 NotificationContext.js 日志系统,替换所有 console 调用为 logger
## 主要改动
- 将 47 处 console.log/warn/error 全部替换为 logger 方法
- 删除 6 处装饰性分隔线(%c════════)
- 合并冗余日志,优化日志结构
- 减少代码行数:1021 → 1003(-18 行)
## 日志分类
- logger.info (43 处):重要操作(连接、订阅、通知发送)
- logger.debug (17 处):详细调试信息(数据内容、中间状态)
- logger.warn (5 处):警告信息(权限问题、重复事件、断开连接)
- logger.error (9 处):错误信息(失败、异常、Ref 未初始化)
## 优化效果
- ✅ 生产环境可通过 REACT_APP_ENABLE_DEBUG 控制日志输出
- ✅ 日志更规范,带时间戳和统一格式
- ✅ console.log 调用:47 → 0(100% 清理完成)
- ✅ 代码更清洁,无装饰性代码
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
|
2025-11-17 15:10:41 +08:00 |
|
zdl
|
a9f0c5ced2
|
pref: 删除测试 API(优先)通知
|
2025-11-17 14:47:24 +08:00 |
|
zdl
|
ddd6b2d4af
|
feat: 实现 Socket 触发的智能列表自动刷新功能(带防抖)
核心改动:
- 扩展 NotificationContext,添加事件更新回调注册机制
- VirtualizedFourRowGrid 添加 forwardRef 暴露 getScrollPosition 方法
- DynamicNewsCard 实现智能刷新逻辑(根据模式和滚动位置判断是否刷新)
- Community 页面注册 Socket 回调自动触发刷新
- 创建 TypeScript 通用防抖工具函数(debounce.ts)
- 集成防抖机制(2秒延迟),避免短时间内频繁请求
智能刷新策略:
- 纵向模式 + 第1页:自动刷新列表
- 纵向模式 + 其他页:不刷新(避免打断用户)
- 平铺模式 + 滚动在顶部:自动刷新列表
- 平铺模式 + 滚动不在顶部:仅显示 Toast 提示
防抖效果:
- 短时间内收到多个新事件,只执行最后一次刷新
- 减少服务器压力,提升用户体验
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
|
2025-11-14 19:04:00 +08:00 |
|
zdl
|
6b96744b2c
|
fix(notification): 修复 Socket 重连后通知功能失效问题(方案2)
采用完全重构的方式解决 Socket 重连后事件监听器丢失和闭包陷阱问题。
## 核心问题
1. Socket 重连后,事件监听器被重复注册,导致监听器累积或丢失
2. 闭包陷阱:监听器捕获了过期的 addNotification 函数引用
3. 依赖循环:registerSocketEvents 依赖 addNotification,导致频繁重新创建
## 解决方案(方案2:完全重构)
### 1. 使用 Ref 存储最新函数引用
```javascript
const addNotificationRef = useRef(null);
const adaptEventToNotificationRef = useRef(null);
const isFirstConnect = useRef(true);
```
### 2. 同步最新函数到 Ref
通过 useEffect 确保 ref.current 始终指向最新的函数:
```javascript
useEffect(() => {
addNotificationRef.current = addNotification;
}, [addNotification]);
```
### 3. 监听器只注册一次
- useEffect 依赖数组改为 `[]`(空数组)
- socket.on('new_event') 只在组件挂载时注册一次
- 监听器内部使用 `ref.current` 访问最新函数
### 4. 重连时只重新订阅
- Socket 重连后只调用 `subscribeToEvents()`
- 不再重新注册监听器(避免累积)
## 关键代码变更
### NotificationContext.js
- **新增 Ref 定义**(第 62-65 行):存储最新的回调函数引用
- **新增同步 useEffect**(第 607-615 行):保持 ref 与函数同步
- **删除 registerSocketEvents 函数**:不再需要提取事件注册逻辑
- **重构 Socket useEffect**(第 618-824 行):
- 依赖数组: `[registerSocketEvents, toast]` → `[]`
- 监听器注册: 只在初始化时执行一次
- 重连处理: 只调用 `subscribeToEvents()`,不重新注册监听器
- 防御性检查: 确保 ref 已初始化再使用
## 技术优势
### 彻底解决重复注册
- ✅ 监听器生命周期与组件绑定,只注册一次
- ✅ Socket 重连不会触发监听器重新注册
### 避免闭包陷阱
- ✅ `ref.current` 始终指向最新的函数
- ✅ 监听器不受 useEffect 依赖变化影响
### 简化依赖管理
- ✅ useEffect 无依赖,不会因状态变化而重新运行
- ✅ 性能优化:减少不必要的函数创建和监听器操作
### 提升代码质量
- ✅ 逻辑更清晰:所有监听器集中在一个 useEffect
- ✅ 易于维护:依赖关系简单明了
- ✅ 详细日志:便于调试和追踪问题
## 验证测试
### 测试场景
1. ✅ 首次连接 + 接收事件 → 正常显示通知
2. ✅ 断开重连 + 接收事件 → 重连后正常接收通知
3. ✅ 多次重连 → 每次重连后通知功能正常
4. ✅ 控制台无重复注册警告
### 预期效果
- 首次连接: 显示 "✅ 首次连接成功"
- 重连成功: 显示 "🔄 重连成功!" (不显示 "registerSocketEvents() 被调用")
- 收到事件: 根据页面可见性显示网页通知或浏览器通知
## 影响范围
- 修改文件: `src/contexts/NotificationContext.js`
- 影响功能: Socket 连接管理、事件监听、通知分发
- 兼容性: 完全向后兼容,无破坏性变更
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
|
2025-11-11 13:35:08 +08:00 |
|
zdl
|
463bdbf09c
|
feat: 添加调试 API
- 我修改 NotificationContext.js,暴露 addNotification 到 window
- 或者在调试工具 (devtools/notificationDebugger.js) 中添加测试方法
- 重新构建并部署
- 可以手动触发网页通知
|
2025-11-11 11:45:19 +08:00 |
|
zdl
|
643c3db03e
|
feat: 通知调试能力
|
2025-11-10 20:05:53 +08:00 |
|
|
|
7f2a4dd36a
|
事件中心不提示通知修复
|
2025-11-10 14:20:42 +08:00 |
|
|
|
45ff13f4d0
|
事件中心不提示通知修复
|
2025-11-10 13:46:34 +08:00 |
|
|
|
a00b8bb73d
|
事件中心ui
|
2025-11-10 12:45:34 +08:00 |
|
zdl
|
a9dc1191bf
|
feat:. mockSocketService 添加 connecting 状态
- 新增 connecting 标志防止重复连接
- 在 connect() 方法中检查 connected 和 connecting 状态
- 连接成功或失败后清除 connecting 标志\
2. NotificationContext 调整监听器注册顺序
- 在 useEffect 中重新排序初始化步骤
- 第一步:注册所有事件监听器(connect, disconnect, new_event 等)
- 第二步:获取最大重连次数
- 第三步:调用 socket.connect()
- 使用空依赖数组 [] 防止 React 严格模式重复执行\
3. logger 添加日志限流
- 实现 shouldLog() 函数,1秒内相同日志只输出一次
- 使用 Map 缓存最近日志,带最大缓存限制(100条)
- 应用到所有 logger 方法:info, warn, debug, api.request, api.response
- 错误日志(error, api.error)不做限流,始终输出\
修复 emit 时机确保事件被接收
- 在 mockSocketService 的 connect() 方法中
- 使用 setTimeout(0) 延迟 emit(connect) 调用
- 确保监听器注册完毕后再触发事件\
|
2025-10-27 13:13:56 +08:00 |
|
zdl
|
1ba8b8fd2f
|
feat: 消息通知能力测试
|
2025-10-23 15:25:36 +08:00 |
|
zdl
|
a9fee411ea
|
feat: 权限引导能力测试
|
2025-10-22 15:23:36 +08:00 |
|
zdl
|
23188d5690
|
feat: 修改文件 │
│ │
│ 1. src/services/socketService.js - 指数退避 + 无限重试 │
│ 2. src/components/ConnectionStatusBar/index.js - UI 优化 + 自动消失 │
│ 3. src/App.js - handleClose 实现 + dismissed 状态管理 │
│ 4. src/contexts/NotificationContext.js - 添加成功状态检测 │
│ 5. NOTIFICATION_SYSTEM.md - v2.11.0 文档更新
|
2025-10-21 18:34:38 +08:00 |
|
zdl
|
09c9273190
|
feat: sockt 弹窗功能添加
|
2025-10-21 17:50:21 +08:00 |
|
zdl
|
38499ce650
|
feat: 添加消息推送能力
|
2025-10-21 15:48:38 +08:00 |
|
zdl
|
5a3a3ad42b
|
feat: 添加消息推送能力,添加新闻催化分析页的合规提示
|
2025-10-21 10:59:52 +08:00 |
|