feat: Phase 2e-1 统一通知中心 + 我的 TabBar 聚合未读红点
后端(notify 模块) - 新增 notify 模块:DAO/Service/Pusher 接口/Controller/Router/CleanupTask - 数据库 DDL:notify_notifications 表 + 3 索引(user+created/user+is_read/user+category) - 11 种 type 枚举(好友/群聊 9 种 + meeting_* 2 种预留)+ 4 种 category - 跨模块集成:contact 3 处 Pusher(friend_request/accepted/rejected) - 跨模块集成:group 6 处 Pusher(invite/join_request/approved/rejected/kicked/role_changed) - WS handler 断线补偿:连接建立即推送 notify.unread.total - 5 REST API(4 用户 + 1 管理员广播)+ 2 WS 事件(notify.new / notify.unread.total) - 30 天已读通知定时清理(未读永久保留) - Provider/Wire 依赖注入(NotifyPusher、NotifyConnectHook、UserInfoResolver 接口) 前端 - 新增 notify 模块:API/Pinia Store(5 分类分页缓存 + 未读数 + WS 事件)/NotifyItem/通知中心主页 - profile 入口:铃铛 badge + 菜单项 badge + 数字显示 - App.vue/login 初始化 notifyStore WS 监听;logout 调用 notifyStore.reset() 清缓存 - 清理 contact.js/group.js 中散落 toast 与冗余 notify.friend.request/group.join.request 处理 - CustomTabBar 新增 hasDot() 聚合指示器:我的 Tab 显示纯红点(无数字), 当前聚合 notifyStore.unreadTotal,未来可扩展「资料待完善/安全提醒/新版本」等 文档 - 新增 Phase 2e 整体路线图 docs/plans/2026-04-20-phase2e-design.md - 新增 Phase 2e-1 专用设计 docs/plans/2026-04-20-phase2e-1-design.md(§6.4 TabBar 聚合红点) - 新增 Phase 2e-1 实施计划 docs/plans/2026-04-20-phase2e-1-implementation.plan.md - 新增 E2E 验证报告 test-report-phase2e-1-notification.md(含 Playwright MCP 2 个现场 Bug 修复记录) - 更新 docs/progress/CURRENT_STATUS.md、docs/api/README.md、docs/api/frontend/notify.md - 更新 .cursor/rules/project-context.mdc、docs/plans/2026-02-27-echochat-system-design.md 其他 - .gitignore 排除 .playwright-mcp/ MCP 临时快照 架构决策 - 单端 WS 连接:沿用现有 ws.Hub,多端已读同步推迟到 Phase 2f/二期 - 跨模块依赖:contact/group → notify 严格单向(接口注入模式) - 降级策略:Pusher 先入库后推送;WS 失败不回滚入库;入库失败仅 Warn 不影响业务 Playwright MCP 回归(4 类场景全通) - 实时推送(admin 广播 → 1s 内前端自动插入 + 角标 +1) - Deep-link 跳转(好友申请通知 → contact/request 页) - 批量清零(全部已读按钮) - TabBar 聚合红点(有未读亮/全部已读灭)与 notifyStore.unreadTotal 三层同步 Made-with: Cursor
This commit is contained in:
@@ -22,13 +22,26 @@ alwaysApply: true
|
||||
- 分支:`feature/phase2c-group-read-receipt`
|
||||
- **Phase 2d(消息类型扩展)**:✅ 全部完成(14 个 Task + 代码审查修复 2 项 + 富媒体 Bug 修复 4 项 + UX 优化 1 项),设计文档 `docs/plans/2026-03-04-phase2d-design.md`
|
||||
- **⚠️ 分支说明**:Phase 2d 的实际开发工作误用了 `feature/phase2c-group-read-receipt` 分支,`feature/phase2d-message-types` 分支未承载 2d 代码。此次偏差不做回溯修复;**Phase 2e 起必须为每个阶段新建独立分支**(`feature/phase2e-xxx`)。
|
||||
- **Phase 2e(会议与通知系统)**:🚧 规划完成,拆分为三子阶段,设计文档 `docs/plans/2026-04-20-phase2e-design.md`
|
||||
- 2e-1 通知系统(3-4 天)✅ **已完成**:统一通知中心 + 11 种类型 + Pusher 接口注入 + 30 天清理 + 管理员广播 + 前端 5 分类 Tab
|
||||
* 单端 WS 连接架构(沿用),不做多端已读同步(设计文档 §3.1/§3.5/§九 已修订,多端改造推迟到 Phase 2f/二期)
|
||||
* 专用设计:`docs/plans/2026-04-20-phase2e-1-design.md`;实施计划:`docs/plans/2026-04-20-phase2e-1-implementation.plan.md`;验证报告:`test-report-phase2e-1-notification.md`
|
||||
* API 文档:`docs/api/frontend/notify.md`
|
||||
- 2e-2 会议 MVP(10-14 天)📋 待开发:mediasoup Node.js 独立服务 + 即时会议(≤8 人)+ 音视频控制
|
||||
- 2e-3 会议增强(7-10 天)📋 待开发:预约会议 + 定时提醒 + 会议邀请(复用 2e-1)
|
||||
- 分支:`feature/phase2e-meeting-notification`(基于 `origin/feature/phase2c-group-read-receipt`)
|
||||
- **关键技术锁定**:维持 mediasoup SFU 架构(非 Mesh),前端用 mediasoup-client,信令复用现有 WS Hub
|
||||
- **显式推迟清单**(必须留档,见设计文档 §九):
|
||||
* → Phase 2f:WS Hub 多端连接改造、会议管理后台、通知广播发布 UI、管理端仪表板、操作日志页、系统配置管理、通知分类开关
|
||||
* → 第二期:屏幕共享、会议录制、虚拟背景、微信登录、互动直播、视频消息、表情包、消息转发/引用
|
||||
* → 第三期:微服务拆分、K8s、跨服 Worker 集群、AI 语音转文字
|
||||
- **开发者运维脚本(2026-04-20)**:新增 `scripts/{start,stop,status}.sh` 三件套,`scripts/dev-setup.sh` 补齐 MinIO 健康检查;遵循 setup/start 职责分离(Rails/Django 社区模式)
|
||||
- **聊天页 UX 优化(2026-04-20)**:单聊/群聊引入「新消息悬浮提示 + 按需已读」机制(贴底自动滚+已读,远离底部显示"N 条新消息"悬浮按钮),消除"视图未见但对方已读"的 UX 错位;**后续修复**:watch 误将"加载更多历史消息"计入 newMsgCount → 改为对比「末尾消息标识(tail id/client_msg_id)」而非 `messages.length`,真实双账号(duanlingyun ↔ bojinyuan)端到端验证通过
|
||||
- **语音消息 H5 兼容(2026-04-20)**:修复 PC Chrome 无法按住"按住说话"的问题,链路涉及 4 层(事件 + 录音 API + 上传 + 后端校验):VoiceRecorder 并行监听 touch/mouse 事件;新增 `H5Recorder` 类(基于 `MediaRecorder + getUserMedia`)作为 uni 录音接口在 H5 端的回退;`uploadVoice` 增加 blob 分支走 `fetch+FormData` 精确控制 filename;后端 `allowedVoiceExts` 扩展 `.webm/.ogg`。Playwright 端到端验证:录音计时正常(3s→5s 跳动)、Blob 上传成功、数据库 `im_messages` type=3 记录写入
|
||||
- **语音未听红点(2026-04-20,仿微信)**:语音需"听"才算真消费,仅通用已读不能准确反映 → 为「对方发来的」语音叠加独立状态。`chat store` 新增 `voicePlayedMap` + 4 API(`markVoicePlayed/isVoicePlayed/loadVoicePlayedState/resetVoicePlayedState`),localStorage 按 userId 隔离(`echo:voice-played:{userId}`),不同步后端(私人视图态);`MsgVoice.vue` 自主消费 store(单聊/群聊同构),模板加 `.unplayed-dot`(10rpx 红圆),`onTogglePlay` 点击即标记清除;`user.logout()` 补 `resetVoicePlayedState()` 防串用户。Playwright 验证:duanlingyun(13) ↔ bojinyuan(7) 会话 6,初始 5 个红点(对方 5 条语音) → 点击 2 条 → 红点减至 3 → 页面刷新仍为 3(持久化生效)
|
||||
- **已读状态刷新持久化(2026-04-20)**:修复"刷新后所有已读标签变未读 / 群聊 N人已读消失"的体验倒退 bug,根因是前端 `readStatusMap`/`groupReadCountMap` 仅由 WS 事件填充、刷新后无 API 补回。扩展 `HistoryMessageResponse` 新增 `peer_last_read_msg_id`(单聊)+ `read_count_map`(群聊仅含自己发送消息);`GetHistoryMessages` 按会话类型分支填充(`GetPeerUserID`+`GetMember` 或 `readRecorder.GetReadCountBatch`);前端 `loadHistoryMessages` 仅在首次加载时回填(避免加载更多时覆盖 WS 增量)。Playwright 双端验证:单聊会话 6(peer_last_read=202)首屏 20 已读+1 未读、群聊 8 刷新后 13 条自己消息全部显示"N人已读"(11×1人 + 2×2人);不新增 API,不增加请求次数,向前兼容
|
||||
- 范围:图片/语音/文件消息完整流程 + 管理端消息管理(列表+统计+撤回+删除)+ ECharts 仪表板
|
||||
- **跨模块通信模式**:接口注入标准(ws.FriendIDsGetter / im.FriendChecker / im.UserInfoGetter → contact.FriendshipDAO,im.OfflineMessagePusher → ws.Handler,contact.OnlineChecker → ws.OnlineService,im.GroupInfoGetter → group.GroupDAO,im.MessageReadRecorder → group.MessageReadDAO,group.UserInfoProvider → auth.UserDAO,group.MessageWriter → im.MessageDAO,admin.MessageManageService → im.ConversationDAO + ws.PubSub)
|
||||
- **跨模块通信模式**:接口注入标准(ws.FriendIDsGetter / im.FriendChecker / im.UserInfoGetter / notify.UserInfoResolver → contact.FriendshipDAO,im.OfflineMessagePusher → ws.Handler,contact.OnlineChecker → ws.OnlineService,im.GroupInfoGetter → group.GroupDAO,im.MessageReadRecorder → group.MessageReadDAO,group.UserInfoProvider → auth.UserDAO,group.MessageWriter → im.MessageDAO,admin.MessageManageService → im.ConversationDAO + ws.PubSub,**contact.NotifyPusher / group.NotifyPusher → notify.NotifyService**,**ws.NotifyConnectHook → notify.NotifyService**)
|
||||
|
||||
## 项目概述
|
||||
|
||||
|
||||
Reference in New Issue
Block a user