diff --git a/.codebuddy/plans/小程序UI全量改版V2灰阶杂志风_6658869a.md b/.codebuddy/plans/小程序UI全量改版V2灰阶杂志风_6658869a.md new file mode 100644 index 0000000..95a4eda --- /dev/null +++ b/.codebuddy/plans/小程序UI全量改版V2灰阶杂志风_6658869a.md @@ -0,0 +1,297 @@ +--- +name: 小程序UI全量改版V2灰阶杂志风 +overview: 把 miniprogram/ 现有 18 个页面的 UI 从旧 iOS 蓝白风格全量重写为 stitch_ai_ui_v2 的「零彩色灰阶杂志风 + 毛玻璃悬浮层」,保持全部业务逻辑与状态矩阵不变,并补齐上传页处理中三步进度等 v2 稿未覆盖的细节,交付真机可运行的小程序代码。 +design: + styleKeywords: + - 零彩色灰阶 + - 毛玻璃浮层 + - 杂志大留白 + - 衬线大标题 + - 发丝线分隔 + - 悬浮胶囊标签栏 + - 买手店线稿质感 + - 苹果级缓动 + fontSystem: + fontFamily: Songti SC / PingFang SC + heading: + size: 68rpx + weight: 500 + subheading: + size: 34rpx + weight: 600 + body: + size: 30rpx + weight: 400 + colorSystem: + primary: + - "#0A0A0A" + - "#1C1C1E" + - "#2C2C2E" + background: + - "#FFFFFF" + - "#F7F7F5" + - "#EFEFED" + text: + - "#0A0A0A" + - "#6E6E73" + - "#AEAEB2" + functional: + - "#C9C9CE" + - "#B9B9BE" + - "#E5E5E7" + - "#D2D2D7" +todos: + - id: baseline-tokens + content: 用 [subagent:code-explorer] 盘点旧彩色类与原生弹窗引用,重写 app.wxss 令牌与 icons.wxss 图标 + status: completed + - id: shell + content: 重写悬浮玻璃胶囊 tabBar 与「大标题+滚动收缩」导航,新增 utils/nav.ts 阈值 handler + status: completed + dependencies: + - baseline-tokens + - id: overlay + content: 新增 v2-overlay 玻璃弹层组件(Modal/ActionSheet/Toast)并替换原生确认与选择弹窗 + status: completed + dependencies: + - baseline-tokens + - id: tab-pages + content: 重写 5 个 tab 页(衣橱/穿搭/运势/分享/我的)的视觉与信息层级 + status: completed + dependencies: + - shell + - overlay + - id: detail-pages + content: 重写详情与表单页(衣物详情/穿搭详情/穿搭编辑/AI 推荐/通知两页) + status: completed + dependencies: + - shell + - overlay + - id: upload-flow + content: 补全上传处理过程三态,重写登录/分享三页/商城/订单 + status: completed + dependencies: + - shell + - overlay + - id: qa + content: 用 [skill:playwright-cli] 逐屏对照 v2 基准走查,清理零彩色与类名残留并输出真机验收清单 + status: completed + dependencies: + - tab-pages + - detail-pages + - upload-flow +--- + +## 产品概述 + +把正在运行的「纸条 AI 衣橱」微信小程序(`miniprogram/`,当前仍是 iOS 蓝白彩色风)整体升级为 v2 设计语言:零彩色灰阶、毛玻璃浮层、杂志式大留白、衬线大标题。18 个页面全部覆盖,真机可运行,业务逻辑与在途改动保持不变。同时补全 v2 相对现有前端需要强化的部分,重点是衣物上传后的处理过程界面。 + +## 核心功能 + +- 全局设计系统替换:旧 iOS 彩色令牌(#007AFF 蓝等)→ v2 灰阶令牌、衬线/无衬线双字阶、1rpx 发丝线、玻璃层与统一缓动 +- 导航体系重构:进入页面为左对齐衬线大标题 + 大写英文 eyebrow,向下滚动收缩为居中玻璃小标题 +- 底部标签栏改为悬浮玻璃胶囊,未读徽标零彩色化(黑底白字数字胶囊) +- 18 个页面按 v2 重排信息层级与视觉:登录、衣橱、穿搭、运势、分享、我的、上传、衣物详情、穿搭详情、穿搭编辑、AI 推荐、通知列表与详情、分享创建与两个分享详情、额度与会员、订单 +- 衣物处理过程界面补全:选图后显示用户实际图片 + 三段发丝线进度轨(排队中 / AI 抠图 / 智能分类,由 ProcessStatus 轮询驱动 step 0/1/2)+ 失败态与重新上传 / 手动填写 / 额度不足弹窗,并保持衣橱「AI 处理中」角标与衣物详情处理中态一致 +- 弹层视觉统一:居中玻璃卡、底部动作表、深色玻璃胶囊 Toast +- 全状态覆盖:骨架屏 / 空态 / 列表 / 加载更多 / 没有更多了 / 失败 / 失效 / 只读 + +## 视觉要求 + +- 零彩色纪律:所有颜色取自灰阶令牌,唯一彩色例外是运势页幸运色的 8px 色点;旧状态色语义在零彩色下重建(进行中=实心黑胶囊,中性=浅灰胶囊,失效=降透明度或删除线,AI 来源=黑底白字描边胶囊,删除/取消=黑字下划线文字按钮) +- 内容区像杂志内页:纯白纸面、超大留白、发丝线分组、大块内容保持直角,圆角只出现在胶囊/抽屉/小控件 +- 衣物图片是唯一主角;导航、底部标签、弹窗与抽屉毛玻璃悬浮在内容之上 +- 交互保持顺滑:统一缓动、按压缩放反馈、列表递进入场,滚动收缩不做逐帧重绘 + +## 边界与约束 + +- 只改 UI 层(WXML/WXSS + 必要的 TS 触点),不重构请求、轮询、支付、分享、日志等业务逻辑 +- 工作区存在未提交改动(穿搭详情、穿搭页、分享页、衣物详情、AI 推荐、config.ts、models.ts),必须以当前工作区版本为基线保留 +- 不做设计稿 HTML 的新增或修改,`stitch_ai_ui_v2/index.html` 仅作只读视觉基准 + +## 技术栈 + +- 微信小程序原生开发:WXML + WXSS + TypeScript(`strict` 严格模式),`renderer: webview`,无框架、无构建链、无组件库 +- 视觉事实来源:`stitch_ai_ui_v2/index.html`(单文件 375×812 交互原型,只读) +- 单位换算规则:v2 的 px × 2 = rpx(`--pad:20px`→`40rpx`,`.display:34px`→`68rpx`,`.eyebrow:10px`→`20rpx`),0.5px 发丝线 → `1rpx` +- 图标:沿用现有 `styles/icons.wxss` 的 CSS mask + `currentColor` 方案(天然单色,符合零彩色),把内联 SVG 的 `stroke-width` 由 2 调整为 1.5,并补齐 v2 用到的图标(返回 chevron-left、时钟、图片、锁、向上箭头等) +- 字体:系统字体栈(衬线 `"Songti SC","STSong","Noto Serif SC",Georgia,serif`;无衬线 `-apple-system,BlinkMacSystemFont,"PingFang SC"`),禁用 `wx.loadFontFace`(需 https 外链) + +## 实现方案 + +核心策略:**令牌层 → 组件层 → 页面层** 三段式。先把设计系统落到 `app.wxss` 与共享组件,再逐页重排 WXML/WXSS,TS 只做最小触点修改,避免 18 页各写一套视觉。 + +1. **令牌层先行**:重写 `app.wxss`,用 `page` 选择器固化灰阶、双字阶、发丝线、玻璃、圆角、缓动与排版工具类;全量删除旧彩色类(`.tag-blue/.tag-green/.tag-red/.tag-orange/.tag-indigo/.btn-primary` 蓝底/`.fab` 蓝底蓝阴影等,页面侧仅约 35 处引用),**不留兼容别名**,防止零彩色纪律被绕过。 +2. **组件层收敛重复**:重写 `custom-tab-bar`(通栏 → 悬浮玻璃胶囊,选中态实心黑 + 顶部短横线)、`components/navigation-bar`(同标签名原地重写,页面 JSON 不用改,保留胶囊安全区计算与页面栈不足 switchTab 兜底)、`components/clothes-card`、`components/empty-state`;新增 `components/v2-overlay` 承载 Modal / ActionSheet / Toast 三类玻璃弹层。 +3. **页面层只改结构与样式**:18 页 WXML/WXSS 按 v2 稿逐屏重排(下划线式分类条与分段、规格表、数字条、无缝拼图、悬浮玻璃操作条等),TS 仅在必要处改动:状态角标语义字段(如 `_statusType: 'blue'` → 灰阶语义)、弹层调用替换、滚动收缩 handler 接入。 +4. **滚动收缩驱动方式**:15 个页面用 ``(wardrobe 还带 refresher 与上拉分页),3 个页面(login / notification-detail / upload)用页面级滚动。统一新增 `utils/nav.ts` 导出共享 handler,页面侧仅一行接入;scroll-view 页面加 `bindscroll="onNavScroll"`,页面级滚动页面用 `onPageScroll`。 +5. **上传处理过程补全**:processing 态改为 `Processing` eyebrow + 衬线大标题「AI 正在识别你的衣物…」+ 灰字「通常需要 10 秒左右,请稍候」+ 用户实际选中图片(`imagePath`,极小圆角、居中留白)+ 三段发丝线进度轨(实心/空心圆点 + 1px 连线,`step` 由既有 `pollStatus` 驱动);failed 态为「!」+ 衬线标题 + 双按钮;保留「衣物已上传」弹窗、额度不足弹窗与手动填写跳转。 + +关键取舍: + +- **不引入组件库(tdesign 等)**:v2 需要精确控制字距、行高、发丝线与玻璃透明度,组件库反而增加覆盖成本与体积;原生 WXSS 即可满足。 +- **弹层不做全量替换**:`utils/request` 层统一的 `wx.showToast` 错误提示保留原生(非阻塞、改动风险高),仅把用户可见的确认/选择类弹窗(上传来源选择、上传完成、额度不足、删除确认、公开确认、取消分享、AI 生成确认、支付确认)迁移到 `v2-overlay`,回调分支与原逻辑一一对应。 +- **不做逐页独立样式**:所有页面只消费令牌与通用类,避免出现 18 份近似样式,降低后续维护成本。 + +性能与可靠性: + +- 滚动监听只在跨越阈值(约 56px)时翻转布尔值 `setData`,绝不逐帧 setData;避免 `scroll-view` 高频事件造成卡顿 +- `backdrop-filter` 每屏限制 2 层(导航 + tabBar 或浮层),并给出 `rgba` 兜底底色,规避 Android 低版本不支持导致的透明穿帮 +- 保留 `lazy-load`、`wx:key`、`mergePaged` 分页合并、未读轮询 30s 节流与 tabBar 首帧安全 setData 机制 +- 页面切换动画用 CSS `animation` 实现,不重建 DOM,不增加运行时开销 + +## 执行注意 + +- **未提交改动保护**:`outfit-detail.wxml/.ts`、`outfit.wxml/.ts/.wxss`、`closet-share.wxml/.ts`、`closet-share-create.ts`、`clothes-detail.ts`、`ai-recommend.ts`、`outfit-share-detail.ts`、`types/models.ts`、`utils/config.ts` 的在途逻辑必须原样保留,以工作区当前版本为基线改写 WXML,禁止回退或覆盖。 +- **零彩色自查**:改完后用正则扫描 `miniprogram/**/*.wxss`,除幸运色色点与衣物线稿灰阶外,不允许出现任何有彩色 hex / rgba 彩色通道。 +- **类名一致性**:WXML 引用的每个类都要在 WXSS(页面或全局)中有定义,避免残留 `.card/.tag-*` 等已删除类造成样式丢失。 +- **悬浮层避让**:悬浮 tabBar 与悬浮操作条要求内容区 `padding-bottom` 预留(≥200rpx),避免最后一行内容被遮挡;滚动收缩的导航下内容顶部要预留状态栏 + 导航高度。 +- **组件样式隔离**:`clothes-card`/`empty-state` 已是 `apply-shared`,可继续复用全局令牌与通用类;新增组件若需复用全局类,同样在 `.json` 声明 `styleIsolation: apply-shared`。 +- **日志规范**:沿用 `utils/logger`,本次不新增噪声日志;弹层与滚动逻辑异常只走 `logger.warn`。 +- **验收方式**:Linux 环境无法启动微信开发者工具,视觉验收依赖「v2 原型基准截图 + 静态自查 + 用户真机/开发者工具预览」,需在收尾时输出逐页验收清单。 + +## 架构设计 + +```mermaid +graph TD + A["令牌层 app.wxss:灰阶 / 双字阶 / 发丝线 / 玻璃 / 圆角 / 缓动"] --> B["图标层 styles/icons.wxss:1.5px 描边 mask 图标"] + A --> C["壳层:custom-tab-bar 悬浮胶囊 + navigation-bar 大标题收缩 + utils/nav.ts 滚动阈值"] + A --> D["通用组件层:clothes-card / empty-state / v2-overlay(Modal·ActionSheet·Toast)"] + C --> E["页面层:5 个 tab 页 / 详情页 / 表单流程页 / 分享页 / 交易页 / 登录页"] + D --> E + E --> F["业务逻辑层:pages/*/*.ts 保持不变(请求 / 轮询 / 支付 / 分享 / 日志)"] +``` + +## 目录结构 + +``` +/root/zt-closet-wxmini-frontend/miniprogram/ +├── app.wxss # [MODIFY] 全量替换为 v2 令牌与通用类:灰阶墨阶/纸面/发丝线/玻璃/深色块、 +│ # 衬线+无衬线双字阶、.eyebrow/.display/.t-*/.num/.hair/.pad 工具类、 +│ # .btn(ink/ghost/text)/.tag(零彩色变体)/.chip/.skeleton/.seg/.spec/.statbar/.tile/.empty、 +│ # 悬浮层与安全区;删除全部旧彩色类与旧卡片投影 +├── app.json # [MODIFY] window.backgroundColor → #FFFFFF;tabBar color #AEAEB2 / +│ # selectedColor #0A0A0A / backgroundColor #FFFFFF(custom tabBar 的兜底色) +├── styles/icons.wxss # [MODIFY] 26 个 mask 图标描边 2 → 1.5;补齐 chevron-left / clock / image / +│ # lock / arrow-up-right / star-half 等 v2 用到的图标;尺寸档位对齐 v2(21px→42rpx 等) +├── utils/nav.ts # [NEW] 导出 onNavScroll / onPageScrollNav 共享 handler:按阈值(56px)翻转 +│ # navScrolled 布尔值,跨阈值才 setData;供 18 页一行接入 +├── custom-tab-bar/index.wxml # [MODIFY] 通栏 → 悬浮玻璃胶囊结构;选中态实心黑 + 顶部短横线;徽标零彩色 +├── custom-tab-bar/index.wxss # [MODIFY] 左右各 32rpx、圆角 56rpx、距底 24rpx + env(safe-area-inset-bottom)、 +│ # rgba(255,255,255,.72) + backdrop-filter + 1rpx 发丝边;.tab-badge 黑底白字数字胶囊 +├── custom-tab-bar/index.ts # [KEEP] 未读轮询节流、首帧安全 setData、matchRoute 选中态逻辑不动 +├── components/navigation-bar/ # [MODIFY] 原地重写(标签名不变,页面 JSON 无需改) +│ ├── navigation-bar.wxml # 结构:状态栏占位 + 返回按钮 + 右侧操作槽;大标题态在页面内容顶部渲染 +│ ├── navigation-bar.wxss # 非滚动:透明无边框;滚动后:玻璃底 + 居中 30rpx 小标题 + 1rpx 发丝下边 +│ ├── navigation-bar.ts # 保留 getMenuButtonBoundingClientRect 安全区计算与页面栈不足 switchTab 兜底; +│ │ # 新增 large / eyebrow / scrolled / actionText 属性 +│ └── navigation-bar.json # [MODIFY] 如需复用全局 .icon/.eyebrow 则声明 styleIsolation: apply-shared +├── components/clothes-card/ # [MODIFY] 去卡片容器与描边,图下两行(衬线品名 + 灰色属性行); +│ └── (wxml/wxss) # 状态角标改零彩色(进行中=实心黑胶囊,其他=浅灰胶囊);勾选圈改细描边黑圈 +├── components/empty-state/ # [MODIFY] 细描边线稿图标 + 衬线标题 + 灰字描述 + 黑胶囊/描边双按钮 +│ └── (wxml/wxss) +├── components/v2-overlay/ # [NEW] 统一玻璃弹层组件 +│ ├── index.wxml / index.wxss # modal 居中玻璃卡 / actionsheet 底部动作表(含抓手)/ toast 深色玻璃胶囊 +│ ├── index.ts # properties: type/title/content/buttons/visible;methods: open/close; +│ │ # triggerEvent('confirm'|'cancel'|'select'),与原生回调分支一一对应 +│ └── index.json # styleIsolation: apply-shared +└── pages/ # 18 页:WXML/WXSS 重排 + 必要 TS 触点 + ├── login/ # [MODIFY] 全屏纯白 + 居中线稿 Logo + 衬线品牌名 + 灰字 slogan + 底部实心黑胶囊; + │ # 新手礼包改居中玻璃卡 + 发丝线权益列表 + ├── wardrobe/ # [MODIFY] 衬线大标题 + 右侧统计行;分类由横滑胶囊改下划线式分类条(保留 categories + │ # 数据与选中绑定);网格去卡片容器;FAB 改黑底白玻璃圆钮; + │ # ts 仅改 _statusType 语义('blue' → 零彩色变体) + ├── outfit/ # [MODIFY] 分段改下划线式文字分段;「创建穿搭」「AI 推荐」合并为 tabBar 上方 + │ # 悬浮玻璃双按钮条;社区卡改瀑布流编辑排版 + ├── horoscope/ # [MODIFY] 巨大衬线星座名 + 超大衬线数字 + 5 个细描边星;三项评分改横向发丝线刻度尺; + │ # 长文本改衬线引文排版;幸运色/数字两栏发丝线小格(幸运色色点保留) + ├── closet-share/ # [MODIFY] 下划线分段;分享卡改横向条目(左 72×72 灰度拼图 + 右衬线标题/灰字有效期); + │ # 失效项降至 40% 透明度 + 描边角标 + ├── profile/ # [MODIFY] 72px 头像 + 衬线昵称 + 灰字副信息;额度概览改四栏发丝线数字条; + │ # 功能列表改纯发丝线分组列表(行高 104rpx + 灰色值 + 极细箭头) + ├── upload/ # [MODIFY] 三态重写:idle 巨大虚线发丝线方框 + 细描边相机 + 衬线引导语; + │ # processing 显示实际图片 + 三段发丝线进度轨(排队中/AI 抠图/智能分类); + │ # failed 极简「!」+ 衬线标题 + 双按钮;ts 接入 v2-overlay 替换弹窗 + ├── clothes-detail/ # [MODIFY] 属性改规格表(左 13px 灰标签 / 右 15px 黑值 + 发丝线行,分组用中英文 eyebrow); + │ # 量化评分改细描边方点;适用场合改描边胶囊;保留处理中/失败/失效/只读四态 + ├── outfit-detail/ # [MODIFY] 无缝白缝拼图封面 + 衬线大标题 + eyebrow 来源标签 + 发丝线标签行 + + │ # 横滑单品缩略图;底部改悬浮玻璃胶囊操作条;保留属主/访客双角色与在途逻辑 + ├── outfit-edit/ # [MODIFY] 表单视图与选择衣物视图双视图重排;选择态改细描边勾选 + 黑胶囊计数条 + ├── ai-recommend/ # [MODIFY] 生成态改呼吸感细描边圆环 + 衬线文案;结果态改拼图卡 + 横滑单品;ts 替换确认弹窗 + ├── notification/ # [MODIFY] 未读用左侧 2.5px 黑竖条 + 黑字标题,已读降为 ink-3;3 态覆盖 + ├── notification-detail/ # [MODIFY] 衬线标题 + eyebrow 时间 + 发丝线正文排版 + ├── closet-share-create/ # [MODIFY] 配置 / 选择衣物 / 成功预览三视图重排;底部实心黑胶囊按钮 + ├── closet-share-detail/ # [MODIFY] 分享者行 + 无缝拼图 + 只读网格 + 悬浮玻璃「分享给好友」黑胶囊;保留需登录/失效态 + ├── outfit-share-detail/ # [MODIFY] 同上结构,保留双角色与失效态 + ├── mall/ # [MODIFY] 会员卡用全稿唯一深色块(--block);额度改四栏数字条;商品行左线稿图标 / + │ # 中名称描述 / 右 tabular 价格 + 黑胶囊「购买」;ts 替换支付确认弹窗 + └── order/ # [MODIFY] 订单状态改描边胶囊(文案不依赖颜色);待支付倒计时改 tabular 衬线数字;3 态覆盖 +``` + +## 关键代码结构 + +`app.wxss` 的令牌块是全部 18 页与所有组件的共享契约(rpx 已按 px×2 换算,`page` 选择器替代 `:root`): + +```css +page { + /* 墨阶 */ + --ink: #0A0A0A; --ink-2: #6E6E73; --ink-3: #AEAEB2; --ink-4: #C9C9CE; --art: #B9B9BE; + /* 纸面 */ + --paper: #FFFFFF; --paper-2: #F7F7F5; --paper-3: #EFEFED; + /* 发丝线与填充 */ + --hairline: rgba(0,0,0,.08); --hairline-2: rgba(0,0,0,.14); + --fill: rgba(120,120,128,.07); --fill-2: rgba(120,120,128,.13); + /* 深色块(全稿唯一视觉锚点:商城会员卡) */ + --block: #1C1C1E; --block-2: #2C2C2E; + /* 玻璃 */ + --glass: rgba(255,255,255,.72); --glass-2: rgba(255,255,255,.86); --glass-dark: rgba(28,28,30,.82); + /* 字族与缓动 */ + --serif: "Songti SC","STSong","Noto Serif SC",Georgia,serif; + --sans: -apple-system,BlinkMacSystemFont,"PingFang SC","Helvetica Neue",Arial,sans-serif; + --ease: cubic-bezier(.32,.72,0,1); + /* 圆角与度量 */ + --r-img: 8rpx; --r-ctrl: 20rpx; --r-sheet: 40rpx; --r-pill: 999rpx; + --pad: 40rpx; --nav-h: 88rpx; --tab-h: 120rpx; +} +``` + +## 设计风格 + +沿用 v2 稿的「安静的展厅」:把衣橱当成一间高级买手店,内容区是一张纯白纸张,衣物图片是唯一主角,所有 UI 元素退到发丝线级别;导航、底部标签、弹窗做成悬浮在纸面上的毛玻璃层。零彩色,靠字重对比、留白尺度、发丝线与玻璃透明度建立秩序。 + +## 布局与信息架构 + +- 页面左右边距 40rpx;区块垂直间距 64rpx,块内 32rpx;正文行高 1.6~1.75;图文之间永远留白 +- 分组用 1rpx 发丝线而非卡片描边/投影;大块内容保持直角,圆角只出现在胶囊、抽屉与小控件 +- 导航:进入页面为左对齐衬线大标题 + 大写英文 eyebrow,向下滚动收缩为居中玻璃小标题 +- 底部标签:悬浮玻璃胶囊(左右各 32rpx、圆角 56rpx、距底 24rpx + 安全区),选中态实心黑 + 顶部短横线 +- 分类与分段:由横滑胶囊改为下划线式极简条,选中项黑字加粗 + 2rpx 黑色下划线 + +## 页面要点 + +- 五个 tab 页:衣橱为衬线大标题 + 统计行 + 下划线分类条 + 无容器网格;穿搭为下划线分段 + tabBar 上方悬浮玻璃双按钮条;运势为杂志内页(巨大衬线星座名、超大数字、发丝线刻度尺、衬线引文、两栏小格);分享为横向条目卡 + 失效降透明;我的为四栏数字条 + 纯发丝线分组列表 +- 详情页:规格表(左灰标签 / 右黑值)+ 细描边方点评分 + 描边胶囊标签 + 无缝拼图封面 + 悬浮玻璃底部操作条 +- 表单流程页:上传 idle 为巨大虚线方框 + 细描边相机;processing 为实际图片 + 三段发丝线进度轨(实心/空心圆点 + 1px 连线);failed 为极简「!」+ 衬线标题 + 双按钮;穿搭编辑为表单与选择双视图 +- 分享与交易:分享创建三视图 + 两个分享详情只读网格;额度与会员用全稿唯一深色块 + 四栏数字条 + 黑胶囊购买;订单用描边状态胶囊 + tabular 衬线倒计时 +- 登录:全屏纯白 + 居中线稿 Logo + 衬线品牌名 + 灰字 slogan + 底部实心黑胶囊按钮,新手礼包为居中玻璃卡 + +## 交互与动效 + +统一缓动 cubic-bezier(.32,.72,0,1),时长 320~420ms;按压 scale(.97) + 透明度 0.6;列表入场 40ms 递增;页面切换右滑入 + 轻微缩放淡入;弹层自底部滑入带轻微回弹;四类弹层(居中玻璃卡 / 底部抽屉 / 动作表 / 深色玻璃 Toast)统一由 v2-overlay 管理,保证可开关且不遮挡导航与标签栏。 + +## 响应式与适配 + +以 375pt 为基准,全量使用 rpx 自适应;顶部状态栏与微信胶囊由 navigation-bar 组件按 `wx.getMenuButtonBoundingClientRect()` 动态计算;底部安全区用 `env(safe-area-inset-bottom)`;悬浮层下内容预留 padding,避免最后一行被遮挡。 + +## Agent Extensions + +### SubAgent + +- **code-explorer** +- Purpose: 改造前一次性盘点旧彩色类与原生弹窗的全部引用点、18 个页面的区块与状态矩阵基线,形成逐页改造清单,避免漏改导致样式丢失或弹窗语义错位 +- Expected outcome: 一份可逐条勾选的清单:旧彩色类引用位置(约 35 处)、`wx.showModal/showActionSheet` 调用点、每页 WXML 区块与状态分支、各页滚动容器类型 + +### Skill + +- **playwright-cli** +- Purpose: 用无头浏览器打开 `stitch_ai_ui_v2/index.html`,逐屏截图存档为视觉基准,并在收尾阶段对关键屏做尺寸、颜色、字阶的像素级对照走查 +- Expected outcome: 18 屏基准截图 + 与实现值的对照结论(间距、字号、发丝线、玻璃透明度、悬浮层避让),据此修正偏差 \ No newline at end of file diff --git a/.codebuddy/plans/穿搭页补全社区分段_83cc2406.md b/.codebuddy/plans/穿搭页补全社区分段_83cc2406.md new file mode 100644 index 0000000..e2f7f6e --- /dev/null +++ b/.codebuddy/plans/穿搭页补全社区分段_83cc2406.md @@ -0,0 +1,206 @@ +--- +name: 穿搭页补全社区分段 +overview: 在穿搭 tab 新增「社区」分段,浏览所有用户公开的穿搭(作者信息、拼图封面、点赞/收藏数、场景与发布时间),并新增后端社区列表接口支撑。 +design: + styleKeywords: + - iOS HIG + - 清爽克制 + - 发丝分隔线 + - 系统蓝 + - 线性图标 + fontSystem: + fontFamily: PingFang SC + heading: + size: 32rpx + weight: 600 + subheading: + size: 28rpx + weight: 500 + body: + size: 26rpx + weight: 400 + colorSystem: + primary: + - "#007AFF" + - "#5856D6" + background: + - "#F2F2F7" + - "#FFFFFF" + text: + - "#000000" + - "#3C3C43" + - "#8E8E93" + - "#C7C7CC" + functional: + - "#FF2D55" + - "#34C759" + - "#FF9500" + - "#FF3B30" +todos: + - id: backend-community-api + content: 用 [subagent:code-explorer] 确认后端批量查询与计数模式;实现 GET /outfit/community 接口(DTO/DAO/Service/路由)并更新接口文档 + status: completed + - id: frontend-community-data + content: models.ts 新增社区穿搭类型;outfit.ts 实现三态分段、社区取数、相对时间与详情跳转 + status: completed + dependencies: + - backend-community-api + - id: frontend-community-ui + content: outfit.wxml/wxss 实现社区分段、作者行卡片、互动数据与空态样式 + status: completed + dependencies: + - frontend-community-data + - id: verify-community + content: 运行 go build 与 tsc 类型检查,核对前后端字段契约与路由注册 + status: completed + dependencies: + - backend-community-api + - frontend-community-ui +--- + +## 产品概述 + +为「纸条AI衣橱」小程序补全社区功能:在「穿搭」页现有「我的穿搭 / 已收藏」两个分段基础上,新增「社区」分段,让所有用户都能浏览其他用户公开的穿搭,并进入详情点赞、收藏,形成「公开到社区 → 他人浏览互动」的完整闭环。 + +## 核心功能 + +- 穿搭页分段控件扩展为三态:「我的穿搭 / 已收藏 / 社区」,切换即加载对应列表并重置分页 +- 社区分段以卡片流展示其他用户公开的穿搭(仅展示已公开且审核通过、状态正常的穿搭) +- 社区卡片内容:作者头像与昵称(卡片顶部)、拼图式衣物封面与件数、穿搭名称、场景标签、点赞数与收藏数、相对发布时间 +- 点击社区卡片进入他人视角的穿搭详情页,可点赞、收藏(复用现有详情页,不新增页面) +- 社区列表支持下拉刷新、上拉加载更多、骨架屏加载态与空态提示 +- 社区分段隐藏「+ 创建穿搭 / AI 推荐」入口行(浏览场景不展示管理入口) + +## 视觉与交互效果 + +延续现有 iOS HIG 风格:分组灰底、纯白卡片、发丝分隔线、系统蓝强调色。社区卡片在现有穿搭卡片结构上顶部新增作者行(圆形头像 + 昵称 + 右侧相对时间),底部 meta 行新增点赞、收藏两组互动数据,整体与「我的穿搭」卡片流视觉统一、切换分段有平滑过渡。 + +## 技术栈 + +- 前端:微信小程序原生 + TypeScript(沿用现有 webview 渲染与纯 WXSS 手写方案,不引入组件库) +- 后端:Go + Gin + GORM/MySQL(zt-closet-backend,新增接口沿用现有分层:router → handler → service → dao) +- 复用:前端 `request` 封装、`paged` 分页工具、`format.formatRelativeTime`、`logger`、`empty-state` 组件与图标库;后端 `PageRequest/PageResponse`、`normalizePage`、批量查询与批量组装模式 + +## 实现方案 + +### 总体策略 + +后端新增鉴权接口 `GET /outfit/community`:分页返回「其他用户已公开(is_public=2 且 audit_status=2 且 status=1)」的穿搭列表,聚合作者信息与点赞/收藏计数后一次性下发;前端将 `pages/outfit` 页扩展为三态分段,第三段对接新接口渲染社区卡片流,点击进入现有他人视角详情页(owner=0)。全程复用既有模式,不引入新架构、不新增页面、不改动 tabBar。 + +### 关键决策与理由 + +1. **接口路径 `GET /outfit/community`**:与既有 `GET /outfit/:uuid` 在同一 Gin 路由树共存是安全的——项目内已有完全相同形态的先例(`/notification/unread` 与 `/notification/:uuid` 共存且线上运行正常),Gin 1.12 静态路由优先匹配。 +2. **排除本人的公开穿搭**(SQL 加 `user_id != 当前用户`):贴合用户「查看其他用户公开的穿搭」的表述,且避免与「我的穿搭」分段内容重复;后续如需包含自己,仅需去掉一个 WHERE 条件。 +3. **互动数据由后端批量聚合下发**(like_count / collect_count):现有穿搭列表在前端逐条请求 `/like/:uuid`(一页 20 条即 20 次请求),社区列表直接使用后端聚合值,杜绝该 N+1 问题。 +4. **后端批量组装杜绝 N+1**:复用 `buildOutfitListResponses` 的批量模式(一次性批量查明细 + 衣物),作者信息用已有 `UserGetByIDs`,点赞/收藏计数新增 `GROUP BY target_id` 批量方法;单页固定约 7 条 SQL,与页大小无关。 +5. **社区卡片复用现有拼图封面结构**(cover-item 循环)与卡片骨架,仅新增作者行与互动数据块,模板通过 `activeTab === 2` 条件渲染差异部分,避免大段重复。 +6. **仅社区分段隐藏入口按钮行**,「我的穿搭 / 已收藏」保持现状,控制改动面。 + +### 性能与可靠性 + +- 后端:分页 `page/page_size`(上限 50,`normalizePage` 规整),`ORDER BY id DESC` 走主键;批量计数对空列表短路,避免 `IN ()` 查询;错误统一返回现有错误码(19001 等),沿用 slog 日志风格。 +- 前端:`page_size=20`、切换分段重置并丢弃过期响应(沿用现有 reqSeq 序号防乱序机制);辅助字段(相对时间)本地计算零请求;失败不打断主流程,仅记录 code 不打印敏感信息。 +- 契约一致性:`created_at` 秒级时间戳(前端 `formatRelativeTime` 直接消费);`owner_avatar` 由后端 `upload.AvatarURL` 转为可访问 URL;`processed_image` 为完整 URL。 + +### 实施注意事项 + +- 后端仓库位于 `/root/zt-closet-backend`(不在前端工作区),当前存在未提交改动(收藏/通知修复),新代码只做追加、不动无关文件。 +- 后端改动需用户自行部署后,前端指向线上域名(BASE_URL)才能联调。 +- 前端不改 `app.json`、不改 `outfit-detail`、不改 tabBar;`outfit.json` 已引入所需组件,无需调整。 +- 复用 `isOutfitPublicVisible` 的可见性口径(公开 2 + 审核通过 2 + 状态正常 1),保证社区列表与详情页可见性判定一致。 + +## 目录结构 + +后端 `/root/zt-closet-backend/`: + +``` +├── internal/dto/outfit.go # [MODIFY] 新增社区列表 DTO:OutfitCommunityListRequest(内嵌 PageRequest)/ OutfitCommunityListResponse(内嵌 PageResponse)/ OutfitCommunityItem(含 outfit_uuid、outfit_name、outfit_desc、scene、source、created_at、items、owner_name、owner_avatar、like_count、collect_count) +├── internal/mysqldao/outfit.go # [MODIFY] 新增 OutfitListCommunity(ctx, excludeUserID, page, pageSize):查询 is_public=2 AND audit_status=2 AND status=1 AND user_id != 本人,Count + Order("id DESC") 分页,参照 OutfitListByUserID 写法 +├── internal/mysqldao/like.go # [MODIFY] 新增 LikeCountByTargets(ctx, likeType, targetIDs):SELECT target_id, COUNT(*) ... GROUP BY target_id(仅 status=1),空入参短路 +├── internal/mysqldao/collect.go # [MODIFY] 新增 CollectCountByTargets 批量计数(同上模式) +├── internal/service/outfit.go # [MODIFY] 新增 CommunityList:normalizePage → 查列表 → 批量组装(复用 OutfitItemListByOutfitIDs + ClothesGetByIDs + UserGetByIDs + upload.AvatarURL + 批量计数),空列表直接返回空数组 +├── internal/routers/api/v1/outfit.go # [MODIFY] 新增 Community handler(GetUserID → ShouldBindQuery → svc → ToResponse,与现有 List 写法一致) +├── internal/routers/router.go # [MODIFY] 鉴权组注册 auth.GET("/outfit/community", outfitHandler.Community) +└── 接口文档.md # [MODIFY] 新增社区列表接口章节;修正 FAQ「没有社区广场接口」的过时说明 +``` + +前端 `/root/zt-closet-wxmini-frontend/`: + +``` +└── miniprogram/ + ├── types/models.ts # [MODIFY] 新增 CommunityOutfitItem 类型(与后端响应字段一一对应) + └── pages/outfit/ + ├── outfit.ts # [MODIFY] activeTab 扩展 0/1/2;fetchList 按分段选 /outfit、/collect、/outfit/community;社区项装饰(直接取 like_count/collect_count,计算相对时间 _time);onOutfitTap 社区项 owner=0;空态文案分支;日志沿用 logger + ├── outfit.wxml # [MODIFY] 分段控件增加「社区」;entry-row 在社区分段隐藏;卡片新增作者行(社区分段)与收藏数、相对时间;状态标签仅非社区分段展示;空态文案分支 + └── outfit.wxss # [MODIFY] 新增作者行、圆形头像(含 icon-user 占位)、昵称、时间、互动数据样式(延续现有 rpx 与色板) +``` + +## 关键代码结构 + +后端响应契约(新增到 `internal/dto/outfit.go`): + +``` +type OutfitCommunityListResponse struct { + PageResponse + List []OutfitCommunityItem `json:"list"` +} + +type OutfitCommunityItem struct { + OutfitUUID string `json:"outfit_uuid"` + OutfitName string `json:"outfit_name"` + OutfitDesc string `json:"outfit_desc"` + Scene string `json:"scene"` + Source int8 `json:"source"` + CreatedAt int64 `json:"created_at"` + Items []OutfitItemResponse `json:"items"` + OwnerName string `json:"owner_name"` + OwnerAvatar string `json:"owner_avatar"` + LikeCount int64 `json:"like_count"` + CollectCount int64 `json:"collect_count"` +} +``` + +前端类型(新增到 `types/models.ts`): + +```ts +export interface CommunityOutfitItem { + outfit_uuid: string + outfit_name: string + outfit_desc: string + scene: string + source: number + created_at: number + items: { clothes_uuid: string; processed_image: string }[] + owner_name: string + owner_avatar: string + like_count: number + collect_count: number +} +``` + +## 设计风格 + +延续项目既有 iOS HIG 视觉语言:分组灰底 #F2F2F7、纯白卡片(圆角 32rpx)、0.5px 发丝分隔线、系统蓝 #007AFF 强调色、SF Symbols 风格线性图标,清爽克制、以内容为中心,社区分段与现有分段无缝衔接。 + +## 分段控件 + +胶囊分段由两项扩展为三项「我的穿搭 / 已收藏 / 社区」,三项等宽;选中项为白色滑块 + 系统蓝加粗文字,未选中为 #3C3C43;切换带轻量过渡,样式沿用现有 .segment 规格(高 64rpx、圆角 16rpx)。 + +## 社区卡片 + +- 作者行(新增):左侧 56rpx 圆形头像(无头像回退浅灰底 icon-user 占位),昵称 26rpx 深色单行省略,右侧相对时间 22rpx 灰字 +- 封面区:复用现有拼图 cover-item 错落摆放(最多 5 件)+ 右上角件数胶囊 +- 信息区:穿搭名 32rpx 加粗单行省略,描述 26rpx 灰字最多两行 +- 互动区(meta 行):左侧场景标签(tag-gray)与件数,右侧点赞(icon-heart)与收藏(icon-star)计数,图标 36rpx 灰字 22rpx,间距与现有卡片一致 + +## 状态设计 + +加载态复用骨架屏(sk-card 呼吸动画);社区空态复用 empty-state(title「还没有公开的穿搭」,desc「把喜欢的穿搭公开到社区,让大家看到你的搭配」,无按钮);列表底部「没有更多了」提示沿用现有样式;卡片按压态用现有 active 透明度反馈。 + +## Agent Extensions + +### SubAgent + +- **code-explorer** +- Purpose: 后端仓库(117 个 Go 文件)实现社区接口前,跨文件梳理 like/collect 数据模型、批量计数与批量组装模式、DTO/Handler 既有写法,确保新代码完全复用现有模式 +- Expected outcome: 产出可复用的批量计数 SQL 模式与接口实现要点清单(表名、字段、既有工具函数位置),降低返工与不一致风险 \ No newline at end of file diff --git a/.codebuddy/plans/纸条AI衣橱小程序UI全量重构设计稿_61bafb55.md b/.codebuddy/plans/纸条AI衣橱小程序UI全量重构设计稿_61bafb55.md new file mode 100644 index 0000000..bd61770 --- /dev/null +++ b/.codebuddy/plans/纸条AI衣橱小程序UI全量重构设计稿_61bafb55.md @@ -0,0 +1,270 @@ +--- +name: 纸条AI衣橱小程序UI全量重构设计稿 +overview: 为「纸条AI衣橱」微信小程序(18 个页面)重新设计一套「杂志风纯白留白 + 毛玻璃悬浮层、纯黑白灰零彩色」的苹果式简约高级 UI,并以单个自包含 HTML 文件交付可点击跳转、tab 可切换、弹窗可开关的高保真交互原型,完整覆盖现有全部功能与全部状态。 +design: + architecture: + framework: html + styleKeywords: + - 杂志编辑部风 + - 毛玻璃浮层 + - 零彩色灰阶 + - 大留白 + - 发丝线分隔 + - 衬线大标题 + - 悬浮胶囊标签栏 + - 苹果级缓动 + - 买手店线稿质感 + fontSystem: + fontFamily: Songti SC / PingFang SC + heading: + size: 34px + weight: 500 + subheading: + size: 17px + weight: 500 + body: + size: 15px + weight: 400 + colorSystem: + primary: + - "#0A0A0A" + - "#1C1C1E" + - "#2C2C2E" + background: + - "#FFFFFF" + - "#F7F7F5" + - "#EFEFED" + text: + - "#0A0A0A" + - "#6E6E73" + - "#AEAEB2" + functional: + - "#E5E5E7" + - "#D2D2D7" + - "#0A0A0A" + - "#AEAEB2" +todos: + - id: baseline + content: 用 [subagent:code-explorer] 核对 18 页区块、状态矩阵与微文案,产出页面清单基线 + status: completed + - id: design-system + content: 建立零彩色设计令牌、双字阶、设备壳、毛玻璃浮层与 SVG 图标衣物线稿组件库 + status: completed + dependencies: + - baseline + - id: interaction-core + content: 实现栈式路由、标签与分段切换、状态切换器、四类弹层控制器与左侧索引 + status: completed + dependencies: + - design-system + - id: flow-closet + content: 完成登录、衣橱网格、上传三态与衣物详情四态页面 + status: completed + dependencies: + - interaction-core + - id: flow-outfit + content: 完成穿搭三段式、穿搭详情、穿搭编辑双视图与 AI 推荐页 + status: completed + dependencies: + - interaction-core + - id: flow-share + content: 完成运势内页、分享列表、衣柜分享创建三视图与两个分享详情 + status: completed + dependencies: + - interaction-core + - id: flow-profile + content: 完成我的页、通知列表与通知详情、编辑资料底部抽屉 + status: completed + dependencies: + - interaction-core + - id: flow-commerce + content: 完成商城双视图与订单页,含支付确认弹窗与待支付倒计时 + status: completed + dependencies: + - interaction-core + - id: spec-and-qa + content: 补设计规范页,用 [skill:playwright-cli] 逐屏截图走查全链路与状态矩阵 + status: completed + dependencies: + - flow-closet + - flow-outfit + - flow-share + - flow-profile + - flow-commerce + - id: deploy-preview + content: 用 [integration:cloudStudio] 部署原型,产出手机可预览链接 + status: completed + dependencies: + - spec-and-qa +--- + +## 产品概述 + +「纸条 AI 衣橱」是一款智能衣橱与穿搭小程序,覆盖衣物管理、AI 穿搭推荐、每日运势、好友分享、会员额度与订单等完整业务。本次对全部 18 个页面做整体 UI 重构,产出可点击走通全流程的单文件交互原型,整体基调为「苹果简约高级」。 + +## 核心功能 + +- 登录与新手礼包引导 +- 衣橱:分类浏览、拍照上传衣物(含 AI 识别进度)、衣物详情与 15 项属性编辑 +- 穿搭:我的穿搭 / 已收藏 / 社区三段浏览,创建与编辑穿搭,AI 推荐生成与保存 +- 运势:星座今日运势、四项评分、幸运色与幸运数字 +- 分享:衣柜分享与穿搭分享的创建、查看、只读浏览与失效态 +- 我的:资料与额度概览、通知、商城会员与额度包、订单管理 +- 全局:5 个底部标签、骨架屏 / 空态 / 异常态、弹窗与底部抽屉、未读红点 + +## 视觉要求 + +- 采用「浅色为底 + 玻璃浮层」:内容区像杂志内页,纯白纸面、衬线大标题、超大留白、发丝分隔线,衣物图片是唯一主角;导航栏、底部标签、弹窗与抽屉用毛玻璃悬浮在内容之上 +- 零彩色:完全用黑白灰层次表达信息与状态,唯一色彩来自衣物本身与幸运色 +- 页面间可真实点击跳转、标签可切换、弹窗可开关,能像真机一样走完整流程 +- 重构不只是换皮,需按产品设计逻辑重排信息架构、层级与交互反馈 + +## 技术栈 + +- 交付物:单个自包含 HTML 文件,路径 `/root/zt-closet-wxmini-frontend/stitch_ai_ui_v2/index.html`(新建目录,不覆盖旧 `stitch_ai_ui/`) +- 纯原生 HTML5 + CSS3(CSS 自定义属性设计令牌、Grid/Flex、backdrop-filter、clip-path)+ 原生 ES6 JavaScript,无框架、无构建、无包管理 +- 零外部依赖:不使用 Tailwind CDN / FontAwesome / Google Fonts(旧稿的致命问题:离线打开即掉样式),图标全部用内联 `` sprite,字体走系统字体栈 +- 图片占位:内联 SVG 灰度线稿(衬衫 / 裤装 / 连衣裙 / 外套 / 鞋 / 包 / 配饰剪影),既离线可用又天然契合零彩色调性 +- 验证:用 playwright-cli 以 `file://` 打开原型,逐屏截图并点击走查 + +## 实现方案 + +核心策略:**一套设计令牌 + 一个页面容器 + 一个路由栈 + 一个状态机**,让 18 屏共享同一套视觉与交互内核,避免逐页重造。 + +1. **设计系统先行**:用 CSS 变量固化零彩色灰阶、衬线/无衬线双字阶、间距刻度、发丝线、玻璃材质、软阴影与统一缓动曲线。所有页面只消费令牌,禁止硬编码颜色。 +2. **页面容器**:18 屏写成 `
`,默认 `display:none`,由路由控制显隐;5 个 tab 屏共享同一个底部玻璃 tabBar(提到 screen 之外,随 tab 路由显隐),与真实小程序 `custom-tab-bar` 的共享方式一致。 +3. **栈式路由**:`navigate(screen, params)` / `back()`,维护页面栈以支持真实返回;`params` 驱动同一屏的变体(`owner=1|0` 决定穿搭详情是属主态还是访客态、`readonly=true` 决定衣物详情是否隐藏编辑删除、`tab=flow` 决定商城进入额度明细视图)。 +4. **状态机**:每屏内用 `data-state`(`skeleton | empty | list | loading | error`)切换,右侧状态切换器直接改这个属性,一套标记覆盖完整状态矩阵,无需为每个状态写重复结构。 +5. **统一弹层**:四类 —— Modal(居中玻璃卡)、Sheet(底部抽屉带抓手)、ActionSheet(iOS 底部动作表)、Toast(深色玻璃胶囊),全部由同一 overlay 控制器管理,保证「可开关」。 +6. **真实跳转**:所有可点元素声明 `data-nav="clothes-detail"` + `data-params='{"uuid":"c1"}'`,在 `#app` 上做事件委托统一处理,保证能像真机一样点着走。 + +关键取舍: + +- **不引 Tailwind CDN**:离线可用 + 杂志风排版需要精确控制字距、行高、发丝线、玻璃透明度,原子类反而增加噪音。代价是 CSS 体积更大 → 用「令牌 + 语义类」收敛,禁止逐页堆裸样式。 +- **不引字体 CDN**:中文衬线用 `"Songti SC", "STSong", "Noto Serif SC", serif` 回退栈,拉丁回退 `Georgia`,保证任何环境打开都不掉字。 +- **占位图用 SVG 线稿而非图床外链**:后端 `processed_image` 在原型中取不到,外链图会离线失效且引入杂色;灰度线稿的代价是不如实拍图真实,通过大量留白与统一构图补足质感。 +- **单文件而非多文件**:用户明确要「单文件可点击交互原型」。代价是文件较大 → 用分节注释 + 页面名前缀类名组织。 + +性能与可靠性: + +- 单文件无网络请求,首屏即渲染,无加载抖动。`backdrop-filter` 是唯一较重属性 → 限制每屏玻璃层数量(导航栏 + 底部栏/浮层,最多 2 层),避免大面积模糊导致滚动掉帧。 +- 事件委托统一在 `#app` 上,避免 18 屏 × N 元素逐个绑定监听。 +- 页面切换只切 `display`,不重建 DOM,保证跳转瞬时响应。 + +## 架构设计 + +```mermaid +graph TD + A["原型外壳:左索引 + iPhone 设备框 + 右状态切换器"] --> B["路由层:navigate / back / params 页面栈"] + B --> C["页面层:18 个 section.screen + data-state 状态机"] + B --> D["浮层层:tabBar / Modal / Sheet / ActionSheet / Toast"] + C --> E["组件层:按钮 / 分段 / 胶囊 / 列表行 / 规格行 / 卡片 / 骨架 / 空态"] + D --> E + E --> F["令牌层:零彩色灰阶 / 双字阶 / 间距 / 发丝线 / 玻璃 / 阴影 / 缓动"] + C --> G["素材层:内联 SVG symbol 图标 + 衣物线稿占位插画"] +``` + +## 目录结构 + +``` +/root/zt-closet-wxmini-frontend/ +├── stitch_ai_ui_v2/ # [NEW] 新版设计稿目录(旧 stitch_ai_ui/ 原样保留) +│ └── index.html # [NEW] 单文件可点击交互原型,内部按以下分节组织: +│ #
+│ # 左索引面板:分组(登录 / 核心 Tab / 详情 / 表单流程 / 分享 / 交易 / 规范) +│ # 设备框 →
内含 18 个
+│ # 共享浮层容器:tabBar + overlay(Modal / Sheet / ActionSheet / Toast) +│ # 右状态切换器:skeleton / empty / list / error / loading +│ # 底部:色板与字阶规范展示 +│ # + +