first commit

This commit is contained in:
2026-09-11 01:45:04 +08:00
commit 0a8d60d87f
145 changed files with 40978 additions and 0 deletions
@@ -0,0 +1,172 @@
---
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+」,无未读时隐藏。