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

172 lines
9.2 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
name: 通知与分享入口互换
overview: 将底部 tabBar 的「通知」替换为「分享」,通知入口移入「我的」页面菜单;「分享」tab 页内实现「我的分享 / 分享给我的」两个分段,未读红点迁移到「我的」tab 图标上。
design:
styleKeywords:
- iOS HIG
- 清爽克制
- 胶囊分段
- 系统蓝
- 线性图标
fontSystem:
fontFamily: PingFang SC
heading:
size: 34rpx
weight: 600
subheading:
size: 28rpx
weight: 500
body:
size: 26rpx
weight: 400
colorSystem:
primary:
- "#007AFF"
- "#5856D6"
- "#FF2D55"
background:
- "#F2F2F7"
- "#FFFFFF"
text:
- "#000000"
- "#3C3C43"
- "#8E8E93"
- "#C7C7CC"
functional:
- "#FF3B30"
- "#34C759"
- "#FF9500"
todos:
- id: update-tabbar
content: 调整 tabBar 入口与红点(app.json + custom-tab-bar)
status: completed
- id: upgrade-share-page
content: 升级分享页为 tab 页并实现「我的分享/分享给我的」双分段
status: completed
dependencies:
- update-tabbar
- id: update-profile
content: 修改我的页通知入口并同步未读红点
status: completed
- id: adjust-notification
content: 调整通知页为普通页面(返回按钮、移除 tab 同步)
status: 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
```
## 关键代码结构
补充分享列表项类型,兼容「分享给我的」返回的分享者信息:
```ts
export interface ClosetShareItem {
share_uuid: string
share_type: number
clothes_count: number
expire_time: number
status: number
owner_name?: string // 分享者昵称(分享给我的列表返回)
owner_avatar?: string // 分享者头像(分享给我的列表返回)
}
```
分享页核心状态:
```ts
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+」,无未读时隐藏。