Files
zt-closet-wxmini-frontend/.codebuddy/plans/我的页面通知栏显示未读数量红点_5d52a12d.md
T
2026-09-13 02:44:41 +08:00

6.1 KiB
Raw Blame History

name, overview, todos
name overview todos
我的页面通知栏显示未读数量红点 在「我的」页面「通知」栏右侧显示未读消息数量红点,让用户知道 tabBar 上的红点来自通知,并与 tabBar 红点数量保持一致。
id content status
tabbar-set-unread 在 utils/tabbar.ts 新增 setTabBarUnread,用已知数量直接更新 tabBar 红点 completed
id content status dependencies
profile-fetch-unread profile.ts 新增 unread 与 fetchUnread,onShow 中刷新并同步 tabBar completed
tabbar-set-unread
id content status dependencies
profile-badge-ui profile.wxml 通知行加数量徽标,profile.wxss 新增 menu-badge 样式 completed
profile-fetch-unread
id content status dependencies
verify-badge-flow 用 [skill:lsp-code-analysis] 校验未读红点数据流与引用完整性 completed
profile-badge-ui

产品概述

「我的」页底部 tabBar 的红色数字徽标当前只出现在 tab 图标上,用户看到红点却不知道来自哪个功能。本次在「我的」页面内对应的功能行(「通知」)上同步展示相同数量红点,让红点来源一目了然。

核心功能

  • 「我的」页面「通知」一行右侧展示与 tabBar 一致的未读数量红点(超过 99 显示「99+」)
  • 红点数量与 tabBar 完全同源(通知未读数),保证两处数字始终一致
  • 进入或切回「我的」页时自动刷新未读数:在通知页读完消息返回后,行内红点与 tabBar 红点同步消失
  • 未读数为 0 时该红点不渲染;接口失败时静默降级,不报错、不阻塞页面其他内容
  • 其余功能行(我的额度、我的订单、我的收藏、额度明细)无独立未读数据源,保持原样

视觉与交互

  • 「通知」行内、右侧箭头左侧新增红色胶囊数字徽标,样式与 tabBar 徽标统一(红底白字、圆角胶囊)
  • 页面其余布局与交互不变

技术栈

  • 微信小程序原生框架(TypeScript + WXML + WXSS),沿用现有 utils/request.ts、utils/logger.ts、utils/config.ts、utils/tabbar.ts 等工具模块,无新增依赖

实现方案

  • 数据源唯一:未读数来自 GET /notification/unread 的 unread_count,与 custom-tab-bar/index.ts 的 syncUnread() 使用同一接口,缓存 key 复用 STORAGE_KEYS.UNREAD,避免出现两个红点数量不一致
  • 页面侧新增 fetchUnread():在 profile.ts 的 onShow 中调用(tab 页每次切回都会触发,天然满足「从通知页返回后刷新」的诉求),成功后 setData({ unread }) 并写回 STORAGE_KEYS.UNREAD 缓存
  • 复用既有同步模式:参考 pages/notification/notification.ts 的 fetchUnread()——拿到最新数量后直接更新 tabBar 实例(不发第二次请求)。当前 utils/tabbar.ts 只导出会触发请求的 syncTabBarUnread(),因此新增一个「用已知数量直接更新」的导出函数 setTabBarUnread(count),与既有 getTabBarInstance() / setTabBarSelected() 风格保持一致,不改变 tabBar 组件本身
  • 首帧安全:项目多处注释指出首帧渲染未结束就 setData 会触发「Expected updated data but get first rendering data」导致渲染失败。请求回调中的 setData 天然异步、安全;若要用缓存值立即渲染以减少红点出现延迟,必须放在 wx.nextTick 内(与 pages/outfit/outfit.ts 首次 onShow 的处理方式一致)
  • 性能:单次网络请求(与 tabBar 自身的 30s 节流请求并行、互不干扰),无额外遍历或渲染开销;失败时静默降级,不重试、不阻塞

实现注意

  • 只在已登录分支执行(profile.onShow 中 auth.isLoggedIn() 校验之后),未登录直接早返回,不会产生必然 401 的请求
  • 不改动 custom-tab-bar 组件逻辑、STORAGE_KEYS 既有 key、以及页面其他功能行
  • 日志沿用 logger.debug/warn,模块名保持 const LOG = 'profile'
  • 徽标样式对齐 custom-tab-bar/index.wxss 的 .tab-badge(#FF3B30 底、白字、胶囊圆角),保持全局视觉统一

架构与数据流

简单链路补充,无需架构图。数据流: profile.onShow → fetchUnread() → GET /notification/unread → setData({ unread })(渲染行内红点)+ 写缓存 STORAGE_KEYS.UNREAD + setTabBarUnread(unread)(tabBar 红点不发新请求即同步)

目录结构

本次改动共涉及 4 个文件,均在现有架构内按既有模式修改:

miniprogram/
├── utils/
│   └── tabbar.ts                 # [MODIFY] 新增导出 setTabBarUnread(count: number):取 tabBar 实例并调用其 setUnread(已知数量),不发请求;取不到实例时静默跳过,风格对齐现有 syncTabBarUnread / setTabBarSelected
└── pages/
    └── profile/
        ├── profile.ts            # [MODIFY] data 新增 unread: 0;新增 fetchUnread()(请求 /notification/unread,成功 setData + 写 STORAGE_KEYS.UNREAD 缓存 + setTabBarUnread 同步,失败 logger.warn 静默降级);onShow 登录校验后调用;首帧用缓存值渲染时须包在 wx.nextTick 内;补充 setTabBarUnread 导入
        ├── profile.wxml          # [MODIFY] 「通知」行在 menu-arrow 前插入 wx:if="{{unread > 0}}" 的数量徽标,文案 {{unread > 99 ? '99+' : unread}}
        └── profile.wxss          # [MODIFY] 新增 .menu-badge 样式:红色 #FF3B30 胶囊、白字、font-size 20rpx、line-height/min-width/height 对齐 tabBar 的 .tab-badge,margin-left: 12rpx、flex-shrink: 0,与 .menu-arrow 间距协调

Agent Extensions

Skill

  • lsp-code-analysis
  • Purpose: 校验未读红点数据流的调用链完整性——确认 fetchUnread、setTabBarUnread、setUnread 的引用关系正确,且「我的」页「通知」行绑定与 tabBar 红点数据源唯一,无遗漏或重复渲染路径
  • Expected outcome: 输出 setTabBarUnread / fetchUnread / onTapNotification / unread 的引用清单,确认改动覆盖完整、无其他页面存在同类「红点来源不明」的遗留入口