Files
zt-closet-wxmini-frontend/.codebuddy/plans/通知与分享入口互换_0674a6ce.md
T
2026-09-11 01:45:04 +08:00

9.2 KiB
Raw Blame History

name, overview, design, todos
name overview design todos
通知与分享入口互换 将底部 tabBar 的「通知」替换为「分享」,通知入口移入「我的」页面菜单;「分享」tab 页内实现「我的分享 / 分享给我的」两个分段,未读红点迁移到「我的」tab 图标上。
styleKeywords fontSystem colorSystem
iOS HIG
清爽克制
胶囊分段
系统蓝
线性图标
fontFamily heading subheading body
PingFang SC
size weight
34rpx 600
size weight
28rpx 500
size weight
26rpx 400
primary background text functional
#007AFF
#5856D6
#FF2D55
#F2F2F7
#FFFFFF
#000000
#3C3C43
#8E8E93
#C7C7CC
#FF3B30
#34C759
#FF9500
id content status
update-tabbar 调整 tabBar 入口与红点(app.json + custom-tab-bar) completed
id content status dependencies
upgrade-share-page 升级分享页为 tab 页并实现「我的分享/分享给我的」双分段 completed
update-tabbar
id content status
update-profile 修改我的页通知入口并同步未读红点 completed
id content status
adjust-notification 调整通知页为普通页面(返回按钮、移除 tab 同步) completed

产品概述

对微信小程序「纸条AI衣橱」的底部导航与入口布局进行调整:将底部导航栏第 4 个入口由「通知」改为「分享」,原「我的」页面内的「我的分享」入口改为「通知」;分享页新增「我的分享 / 分享给我的」两个分段展示;未读通知红点由通知 tab 移至底部「我的」tab 图标右上角。

核心功能

  • 底部导航栏第 4 个入口显示「分享」(分享图标),点击进入分享页。
  • 「我的」页面功能列表中新增「通知」入口(铃铛图标),点击进入通知列表页。
  • 分享页顶部提供「我的分享 / 分享给我的」分段切换:
  • 「我的分享」展示当前用户发起的衣柜分享,保留「新建分享」入口。
  • 「分享给我的」展示他人分享给当前用户的衣柜分享,卡片展示分享者头像与昵称。
  • 底部「我的」tab 图标右上角显示未读通知数红点,超过 99 显示「99+」。
  • 通知页由 tab 页改为普通二级页,支持返回上一页。

技术栈

  • 平台:微信小程序原生 + TypeScript(沿用现有 skyline + glass-easel 架构)
  • 网络层:复用现有 miniprogram/utils/request.ts 的 request<T> 封装
  • UI:纯 WXSS 手写,复用现有 navigation-bar、empty-state、custom-tab-bar 组件与 styles/icons.wxss 图标库

实现方案

整体策略

在现有「5 个 tabBar 页 + 二级页」架构上做入口互换与页面能力升级,不引入新页面、新组件、新依赖。分享页从二级页升级为 tabBar 页并新增分段切换;通知页从 tabBar 页降级为二级页。红点数据源由原通知页单向写缓存,扩展为 tabBar 组件主动拉取 /notification/unread。

关键决策

  • 分享页分段采用「单一当前列表 + 切换重置」模式:用 activeTab(0=我的分享,1=分享给我的)控制当前展示,切换分段时清空 list 并重置分页状态,再调用对应接口。避免维护两套分页状态,符合 KISS/YAGNI,切换后重新拉取的开销可接受。
  • 两个列表接口复用同一响应结构:GET /closet-share 与 GET /closet-share/received 均返回 PagedResult<ClosetShareItem>;后者额外返回 owner_name/owner_avatar,前端 ClosetShareItem 补字段即可,decorate() 对两接口通用。
  • 红点刷新采用「缓存先行 + 异步刷新」:tabBar 组件 attached 时先读 zt_closet_unread 立即渲染,再请求 /notification/unread 更新缓存与视图;通知页 fetchUnread 保持写缓存并调 tabBar.refreshUnread(),形成闭环。
  • 入口切换避免 tab 页跳转错误:profile 中删除原 onTapShare 的 navigateTo('/pages/closet-share/closet-share')(tab 页不能用 navigateTo),改为 navigateTo('/pages/notification/notification')。

实现注意事项

  • closet-share 成为 tab 页后,onShow 需 syncTabBar() 设置 selected: 3(对应第 4 项),与现有 wardrobe/outfit/horoscope/profile 页的 selected 同步模式一致。
  • closet-share.wxml 中 navigation-bar 增加 back="{{false}}"(tab 页不显示返回键),标题由「衣柜分享」调整为「分享」;closet-share-create、closet-share-detail 仍为二级页,用 navigateTo 跳转不受影响。
  • notification.wxml 去掉 back="{{false}}" 以恢复默认返回按钮;notification.ts 删除 syncTabBar()(避免误将 tabBar 高亮切到已不存在的第 4 项),但保留 fetchUnread() 以刷新「我的」tab 红点。
  • 分享给我的卡片头像使用 image 渲染 owner_avatar,为空时回退 icon-user 占位,与 profile 页头像处理方式一致。

架构设计

数据流保持「页面/组件 → request → 后端 API」的单向依赖:

  • tabBar 组件 attached → 读本地缓存 zt_closet_unread 立即显示 → 请求 GET /notification/unread → 写缓存并更新红点。
  • 分享页 onShow → 同步 tabBar 高亮 → 按 activeTab 请求 GET /closet-share 或 GET /closet-share/received → 渲染列表。
  • 我的页 onShow → 同步 tabBar 高亮 → 拉取用户/额度信息,并调用 tabBar.refreshUnread() 刷新红点。

目录结构

本次仅修改现有文件,不新增文件:

miniprogram/
├── app.json                            # [MODIFY] tabBar.list 第4项由 notification 改为 closet-share,text 由「通知」改为「分享」
├── custom-tab-bar/
│   ├── index.ts                        # [MODIFY] 列表第4项改为分享/icon-share;refreshUnread 增加主动请求 /notification/unread
│   └── index.wxml                       # [MODIFY] 红点条件由 icon-bell 改为 icon-user(我的 tab)
├── pages/
│   ├── closet-share/
│   │   ├── closet-share.ts             # [MODIFY] 增加 activeTab 双分段、双接口取数、分页重置、syncTabBar(selected=3)
│   │   ├── closet-share.wxml           # [MODIFY] 增加分段控件;分享给我的卡片展示 owner 信息;新建入口仅我的分享展示;back=false
│   │   └── closet-share.wxss           # [MODIFY] 增加分段样式、分享者头像昵称样式
│   ├── profile/
│   │   ├── profile.ts                  # [MODIFY] onTapShare 改为 onTapNotification(navigateTo notification);onShow 刷新 tabBar 红点
│   │   └── profile.wxml                # [MODIFY] 「我的分享」菜单行改为「通知」(icon-bell,bindtap=onTapNotification)
│   └── notification/
│       ├── notification.ts             # [MODIFY] 删除 syncTabBar;保留 fetchUnread 刷新 tabBar 红点
│       └── notification.wxml           # [MODIFY] navigation-bar 去掉 back="{{false}}",恢复返回按钮
└── types/
    └── models.ts                       # [MODIFY] ClosetShareItem 补充 owner_name、owner_avatar

关键代码结构

补充分享列表项类型,兼容「分享给我的」返回的分享者信息:

export interface ClosetShareItem {
  share_uuid: string
  share_type: number
  clothes_count: number
  expire_time: number
  status: number
  owner_name?: string   // 分享者昵称(分享给我的列表返回)
  owner_avatar?: string // 分享者头像(分享给我的列表返回)
}

分享页核心状态:

data: {
  activeTab: 0 | 1, // 0=我的分享 1=分享给我的
  list: ClosetShareItem[],
  loading: boolean,
  page: number,
  pageSize: number,
  hasMore: boolean,
}

设计风格

延续现有 iOS HIG 视觉语言:清爽克制、系统分组灰底 #F2F2F7 + 纯白卡片 + 发丝分隔线,强调色系统蓝 #007AFF,线性 SF Symbols 风格图标。

分享页分段设计

  • 顶部在导航栏下方放置胶囊式分段控件(Segmented Control):两个等宽胶囊「我的分享」「分享给我的」,选中项为系统蓝底白字,未选中项为灰底深字,切换有轻量过渡;样式与通知页筛选胶囊保持一致,保证全站视觉统一。
  • 「我的分享」列表顶部保留「+ 新建分享」描边按钮,卡片沿用现有四宫格衣物缩略图 + 件数 + 类型 + 有效期布局。
  • 「分享给我的」列表卡片在左侧缩略图基础上,右侧信息区顶部新增分享者行(小圆头像 + 昵称),帮助用户快速识别来源;无头像时回退系统灰色人形占位。
  • 两个分段的空态复用 empty-state 组件,文案分别区分「还没有分享」与「还没有收到分享」。

底部导航设计

  • 第 4 个 tab 由铃铛图标替换为分享图标(三圆点连线),文字由「通知」改为「分享」。
  • 未读通知红点从分享 tab 移至「我的」tab 图标右上角,沿用现有红色胶囊数字样式,超过 99 显示「99+」,无未读时隐藏。