Files
zt-closet-wxmini-frontend/.codebuddy/plans/前端同步后端AI穿搭待保存改造_7e01cff1.md
T
2026-09-15 23:04:38 +08:00

15 KiB
Raw Blame History

name, overview, design, todos
name overview design todos
前端同步后端AI穿搭待保存改造 跟进后端本轮改动:穿搭对象新增 status(1正常/2封禁/3待保存)、未保存 AI 穿搭 7 天自动清理、任务快照 15 分钟。前端新增 pages/ai-pending 管理页(待保存/已保存分段,支持保存、删除、重新生成、查看详情),我的穿搭只保留手工创建(source=1)并在顶部加入口,同步统一 status 展示口径与超期/清理兜底文案。
styleKeywords fontSystem colorSystem
零彩色灰阶
杂志排版
发丝线分层
毛玻璃悬浮层
极简克制
fontFamily heading subheading body
Songti-SC, PingFang-SC
size weight
68rpx 400
size weight
34rpx 600
size weight
30rpx 400
primary background text functional
#0A0A0A
#1C1C1E
#6E6E73
#FFFFFF
#F7F7F5
#EFEFED
#0A0A0A
#6E6E73
#AEAEB2
#C9C9CE
#B9B9BE
#D2D2D7
id content status
status-contract 补 OutfitItem.status 类型,新增 utils/outfit-status.ts 与 utils/outfit-cover.ts 收敛状态口径与封面组装 completed
id content status dependencies
my-outfits-entry 我的穿搭改为只取 source=1,改用统一状态胶囊并新增 AI 穿搭入口卡片与待保存角标 completed
status-contract
id content status dependencies
pending-page 新增 pages/ai-pending 页面:待保存/已保存分段、保存/删除/重新生成/详情与 7 天清理提示 completed
status-contract
id content status
ai-recommend-entry AI 推荐页接入 AI 穿搭入口,90402 文案改为引导并补换一套时的未保存提示 completed
id content status dependencies
detail-status 穿搭详情页支持待保存直接保存、封禁态只读并隐藏管理操作 completed
status-contract
id content status dependencies
qa-verify 用 [subagent:code-explorer] 与 [skill:lsp-code-analysis] 核对引用点,用 [skill:playwright-cli] 对照参考稿,跑 tsc 与静态审计并输出真机验收清单 completed
my-outfits-entry
pending-page
ai-recommend-entry
detail-status

产品概述

后端已完成 AI 推荐异步化与穿搭状态体系改造(穿搭对象带 status:正常 / 封禁 / 待保存,且超过 7 天未保存的 AI 推荐由后端自动清理)。前端本轮跟进:把 AI 生成的穿搭从「我的穿搭」中完全独立出来,收进新页面「AI 穿搭」统一管理,让用户可随时找回、保存或清理 AI 生成结果。

核心功能

  • 新增「AI 穿搭」页:分「待保存 / 已保存」两段;待保存项支持 保存到我的穿搭、查看详情、删除、重新生成;已保存项仅查看(删除走详情页既有入口)
  • 待保存说明与超期兜底:页面顶部说明「保存后进入「我的穿搭」;超过 7 天未保存将自动清理」;保存时若已被清理,给出「这套搭配已被清理,请重新生成」的明确提示并移出列表
  • 我的穿搭只留手工创建:列表请求按来源过滤,AI 穿搭不再混入;顶部新增「AI 穿搭」入口卡片,存在待保存项时显示数量角标
  • AI 推荐页打通入口:「场景抽屉」底部可进入「AI 穿搭」;生成结果过期提示里引导用户去「AI 穿搭」查看是否已生成;重新生成前提示上一套未保存的推荐去哪找
  • 穿搭详情页状态化:待保存的 AI 穿搭在详情页可直接保存;已封禁的穿搭只读展示,隐藏全部管理操作
  • 删除二次确认:删除 AI 生成结果前弹玻璃确认层,说明该操作不可恢复

视觉效果

延续现有零彩色灰阶杂志风:衬线大标题 + 小字号大写 eyebrow、下划线式文字分段、发丝线分隔、直角卡片配无缝拼图封面、悬浮玻璃操作条与玻璃弹层。新的操作行以「实心黑主按钮 + 无衬线文字按钮」排布,待保存用实心黑胶囊、已封禁以降透明度呈现,保持全站只有白与灰阶。

技术栈

  • 原生微信小程序(TypeScript + WXML + WXSS),无构建脚本,沿用 miniprogram-api-typings
  • 复用现有 v2 设计系统:app.wxss 令牌与通用类、styles/icons.wxss(CSS mask 单色图标)、components/{navigation-bar, empty-state, v2-overlay}
  • 复用现有请求与工具层:utils/request、utils/logger、utils/paged(normalizePaged / mergePaged / hasMorePaged)、utils/nav(navScroll)、utils/tabbar

实现方案

契约对齐(与后端已确认的真实行为)

  • GET /outfit 请求参数为 { page, page_size, is_public?, source? } —— 只支持 source 过滤,没有 status 过滤;DAO 不会过滤 status=3 / status=2
  • OutfitCreateResponse 已带 status(1 正常 / 2 封禁 / 3 待保存),列表、详情、创建响应都有
  • GET /outfit/community 固定 is_public=2 AND audit_status=2 AND status=1,社区天然不含待保存与封禁
  • POST /ai-recommend/save:status=3 → 置 1;已为 1 → 幂等返回 nil;已被清理 → 40000;封禁 → 40003
  • DELETE /outfit/:uuid 可用(事务删明细 + 主表)
  • 待保存 AI 穿搭 7 天后由后端每小时清理一次(软删除,列表与详情立即不可见)

关键决策

  1. 我的穿搭用服务端过滤:请求带 source=1(后端现成参数),分页 total 正确、无需客户端剔除,彻底避免「客户端过滤导致某页全被剔除、列表越翻越空」的分页塌陷问题。
  2. AI 穿搭页用单分页流 + 客户端拆段:一次 source=2 的累积数组,渲染时派生成「待保存(status=3)/ 已保存(status=1)」两段;hasMore 只看原始分页是否满额(hasMorePaged(all, total, pageSize))。保存成功后本地迁移(把该项从待保存段移入已保存段并置本地 status=1),不重新请求,避免闪屏与流量。
  3. 状态口径收敛为单一事实来源:新增 utils/outfit-status.ts,输出胶囊文案 + 类名、以及 isPendingSave / isBanned 判定,供 outfit / ai-pending / outfit-detail 三处共用,杜绝同一条语义在三个文件各写一遍 if-else。
  4. 复用优先、最小改面:新页面结构直接套用已上线验证的 outfit 页模式(.head / .segbar / 骨架 / empty-state / 卡片 / float-duo);把两页共用的无缝拼图封面(.collage 系列样式 + 封面组装函数)上提为共享资产,避免复制粘贴后视觉分叉。
  5. 入口计数不追求全量准确:我的穿搭页 onShow 静默拉一页 source=2&page_size=20 统计 status===3 数量用于角标引导;请求失败或超页则只显示入口不显示数字,避免为角标做 N 次翻页。
  6. 口径提示(需在实现中保持一致):按已确认口径,所有 source=2 穿搭只在「AI 穿搭」页查看,因此「保存到我的穿搭」按钮语义为「保存为正式穿搭(status 3→1)」,保存后该项进入 AI 穿搭页的「已保存」段而不进入「我的穿搭」列表;若后续希望保存后的 AI 穿搭回流,只需把 source=1 过滤改为「source=1 或 (source=2 且 status=1)」,改动集中在一处。

状态流转

flowchart LR
  A[AI 推荐生成] --> B[落库 status=3 待保存]
  B --> C[AI 穿搭页 · 待保存段]
  C -->|POST /ai-recommend/save| D[status=1 已保存]
  D --> E[AI 穿搭页 · 已保存段]
  C -->|DELETE /outfit/:uuid| F[本地移除]
  C -.->|超过 7 天被后端清理后 save| G[40000 提示已被清理]

性能与可靠性

  • 列表渲染只对累积数组做一次 filter,复杂度 O(n),n 为已加载条数(每页 20),无额外遍历
  • 待保存计数为单次静默请求(失败降级不打扰用户),不阻塞首屏
  • 保存/删除均加 loading 防抖,避免重复提交;定时器与请求回调统一由 reqSeq 防串页
  • 所有错误路径必须有可见出口:40000(已被清理)、40002(删除失败)、网络异常,均弹层或 toast 明示,禁止静默

目录结构(仅列受影响文件)

miniprogram/
├── app.json                                      # [MODIFY] pages 数组末尾注册 pages/ai-pending/ai-pending
├── app.wxss                                      # [MODIFY] 上移共用「无缝拼图封面」样式(.collage/.cg/.pic/.ph/.cg-more/.cg-badge),供穿搭页与 AI 穿搭页共用
├── types/models.ts                               # [MODIFY] OutfitItem 补 status: number(1 正常 2 封禁 3 待保存),与后端 OutfitCreateResponse 对齐
├── utils/outfit-status.ts                        # [NEW] 状态口径单一事实来源:胶囊文案+类名、isPendingSave/isBanned
├── utils/outfit-cover.ts                         # [NEW] 拼图封面组装:由 items 取前 4 件图片、生成 4/3/2/1 分格类名与 +N 角标、空数据补线稿格
├── pages/ai-pending/ai-pending.json              # [NEW] usingComponents 声明 navigation-bar / empty-state / v2-overlay(相对路径 ../../components/...)
├── pages/ai-pending/ai-pending.wxml              # [NEW] 页头 + 下划线分段(待保存/已保存)+ 说明行 + 卡片列表(封面/名称/场景胶囊/件数/时间)+ 操作行 + 骨架 + 空态 + 删除确认弹层
├── pages/ai-pending/ai-pending.wxss              # [NEW] 页面级样式:入口说明行、卡片操作行(ink 主按钮 + 文字按钮)、角标;拼图卡与全局类一律复用 app.wxss
├── pages/ai-pending/ai-pending.ts                # [NEW] 分页拉取 source=2 + 按 status 拆段 + 保存/删除/重新生成/详情 + 下拉刷新与触底加载
├── pages/outfit/outfit.ts                        # [MODIFY] 我的穿搭请求带 source=1;getStatusText 收敛到共享口径;新增待保存计数与跳转 AI 穿搭页
├── pages/outfit/outfit.wxml                      # [MODIFY] 我的穿搭分段下新增「AI 穿搭」入口卡片(含待保存角标)
├── pages/outfit/outfit.wxss                      # [MODIFY] 入口卡片样式;删除已上移到 app.wxss 的拼图封面重复定义
├── pages/ai-recommend/ai-recommend.ts            # [MODIFY] 新增进入 AI 穿搭页;90402 文案引导 + 弹层加「去看看」;换一套确认文案补未保存提示
├── pages/ai-recommend/ai-recommend.wxml          # [MODIFY] 场景抽屉底部新增「查看我的 AI 穿搭」文字入口
├── pages/outfit-detail/outfit-detail.ts          # [MODIFY] 待保存态保存逻辑(含防抖与 40000 兜底)
└── pages/outfit-detail/outfit-detail.wxml        # [MODIFY] 待保存显示「保存到我的穿搭」并隐藏公开;封禁态只读、隐藏更多入口与状态提示行

关键结构(供三个模块共用的状态口径)

export type OutfitStatusPill = { text: string; cls: string }
export type OutfitStatusLike = { status?: number; source?: number; is_public?: number }

// 待保存(3) 优先于来源判定;封禁(2) 降透明度;AI 已保存(1 且 source=2) 用实心黑胶囊
export function outfitStatusPill(o: OutfitStatusLike): OutfitStatusPill
export function isPendingSave(o: OutfitStatusLike): boolean
export function isBanned(o: OutfitStatusLike): boolean

实现要点(执行注意)

  • 单位统一 rpx(v2 的 px×2);只允许使用 app.wxss 令牌与既有通用类,禁止新增色值(零彩色审计会拦截)
  • empty-state / v2-overlay 等组件为 styleIsolation: apply-shared,页面样式不要反向覆盖组件内部类
  • 日志统一 logger + 模块名常量(新页 LOG = 'ai-pending'),失败一律 warn 级并带 code,不打日志敏感信息
  • 工作区已有未提交改动(outfit / ai-recommend / outfit-detail / clothes-detail 等),本轮改动必须叠加在其之上,不回溯、不重构无关逻辑
  • 本环境无法启动微信开发者工具,视觉只做静态核对,最终以真机预览为准

设计说明

新增页面严格沿用既有 v2 零彩色灰阶杂志风设计系统,不引入任何新风格要素:颜色只取灰阶令牌,衬线字体用于大标题与数字,无衬线用于正文与按钮,0.5px 发丝线替代边框,仅胶囊/抽屉/小控件使用圆角,统一 cubic-bezier(.32,.72,0,1) 动效与 scale(.97) 按压反馈。

页面区块设计(AI 穿搭页,自上而下)

  1. 顶部导航:透明起点为 34px 左对齐衬线大标题,向下滚动收缩为居中玻璃小标题,右侧无操作项。
  2. 页头:10px 大写字距 eyebrow「AI Styling」+ 衬线 display「AI 穿搭」,左右 20px 内边距。
  3. 下划线式文字分段:待保存 / 已保存,选中项黑色加粗 + 2px 实心黑下划线,未选中为中性灰,左右滑动不折行。
  4. 待保存段:首行 13px 中性灰说明「保存后进入「我的穿搭」;超过 7 天未保存将自动清理」;卡片为直角无缝拼图封面(4/3/2/1 分格,超出显示 +N 角标,件数胶囊叠右下),下方名称(17px/600)+ 场景描边胶囊 + 生成时间;卡片底部操作行:实心黑主按钮「保存到我的穿搭」占满剩余宽度,「重新生成」「删除」为 14px 中性灰文字按钮。
  5. 已保存段:同款卡片但仅展示与点击进入详情,无内联操作按钮,保持信息密度一致。
  6. 状态视图:骨架为灰阶占位条 + 图片块;空态用线稿图标 + 标题 + 说明 + 主按钮;触底显示「没有更多了」小字。
  7. 玻璃弹层:删除使用居中玻璃 modal(标题 + 说明「删除后不可恢复」+ 取消 / 确认删除),点击遮罩取消,主按钮为实心黑。
  8. 动效与响应:列表项入场 40ms 递进淡入上移,分段切换 320ms 交叉淡入,按钮按压 scale(.97) 并降至 60% 透明度;375px 基准宽度自适应,底部预留安全区与 64px 触底间距。

Agent Extensions

SubAgent

  • code-explorer
  • Purpose: 跨文件盘点状态口径相关的全部引用点(OutfitItem / getStatusText / source 判定 / outfit-status 使用处)与旧口径残留,确保「我的穿搭只显示手工创建」与状态胶囊改造无遗漏、无死代码
  • Expected outcome: 给出引用点清单与残留清单,作为状态口径收敛与最终走查的核对依据

Skill

  • lsp-code-analysis

  • Purpose: 用语义分析确认 OutfitItem、OutfitSource、新增 utils/outfit-status 的定义与全部引用关系(含类型错误定位),避免仅靠文本搜索漏掉动态引用与类型不匹配

  • Expected outcome: 得到准确的引用/定义清单与类型诊断,确认 status 字段补齐后无类型错误、无未使用符号

  • playwright-cli

  • Purpose: 打开 stitch_ai_ui_v2/index.html 的穿搭相关参考屏(outfit / outfit-detail / spec 规范页),抓取分段条、卡片、胶囊、发丝线、间距与字号的真实样式值,与新页面 WXSS 逐项核对

  • Expected outcome: 输出一份「参考稿样式值 vs 新页面实现值」的逐项对照结论,修正偏差项,保证新页面与既有 v2 视觉零漂移