15 KiB
name, overview, design, todos
| name | overview | design | todos | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 前端同步后端AI穿搭待保存改造 | 跟进后端本轮改动:穿搭对象新增 status(1正常/2封禁/3待保存)、未保存 AI 穿搭 7 天自动清理、任务快照 15 分钟。前端新增 pages/ai-pending 管理页(待保存/已保存分段,支持保存、删除、重新生成、查看详情),我的穿搭只保留手工创建(source=1)并在顶部加入口,同步统一 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=2OutfitCreateResponse已带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;封禁 →40003DELETE /outfit/:uuid可用(事务删明细 + 主表)- 待保存 AI 穿搭 7 天后由后端每小时清理一次(软删除,列表与详情立即不可见)
关键决策
- 我的穿搭用服务端过滤:请求带
source=1(后端现成参数),分页total正确、无需客户端剔除,彻底避免「客户端过滤导致某页全被剔除、列表越翻越空」的分页塌陷问题。 - AI 穿搭页用单分页流 + 客户端拆段:一次
source=2的累积数组,渲染时派生成「待保存(status=3)/ 已保存(status=1)」两段;hasMore只看原始分页是否满额(hasMorePaged(all, total, pageSize))。保存成功后本地迁移(把该项从待保存段移入已保存段并置本地 status=1),不重新请求,避免闪屏与流量。 - 状态口径收敛为单一事实来源:新增
utils/outfit-status.ts,输出胶囊文案 + 类名、以及isPendingSave / isBanned判定,供 outfit / ai-pending / outfit-detail 三处共用,杜绝同一条语义在三个文件各写一遍 if-else。 - 复用优先、最小改面:新页面结构直接套用已上线验证的 outfit 页模式(
.head / .segbar / 骨架 / empty-state / 卡片 / float-duo);把两页共用的无缝拼图封面(.collage系列样式 + 封面组装函数)上提为共享资产,避免复制粘贴后视觉分叉。 - 入口计数不追求全量准确:我的穿搭页
onShow静默拉一页source=2&page_size=20统计status===3数量用于角标引导;请求失败或超页则只显示入口不显示数字,避免为角标做 N 次翻页。 - 口径提示(需在实现中保持一致):按已确认口径,所有
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 穿搭页,自上而下)
- 顶部导航:透明起点为 34px 左对齐衬线大标题,向下滚动收缩为居中玻璃小标题,右侧无操作项。
- 页头:10px 大写字距 eyebrow「AI Styling」+ 衬线 display「AI 穿搭」,左右 20px 内边距。
- 下划线式文字分段:待保存 / 已保存,选中项黑色加粗 + 2px 实心黑下划线,未选中为中性灰,左右滑动不折行。
- 待保存段:首行 13px 中性灰说明「保存后进入「我的穿搭」;超过 7 天未保存将自动清理」;卡片为直角无缝拼图封面(4/3/2/1 分格,超出显示 +N 角标,件数胶囊叠右下),下方名称(17px/600)+ 场景描边胶囊 + 生成时间;卡片底部操作行:实心黑主按钮「保存到我的穿搭」占满剩余宽度,「重新生成」「删除」为 14px 中性灰文字按钮。
- 已保存段:同款卡片但仅展示与点击进入详情,无内联操作按钮,保持信息密度一致。
- 状态视图:骨架为灰阶占位条 + 图片块;空态用线稿图标 + 标题 + 说明 + 主按钮;触底显示「没有更多了」小字。
- 玻璃弹层:删除使用居中玻璃 modal(标题 + 说明「删除后不可恢复」+ 取消 / 确认删除),点击遮罩取消,主按钮为实心黑。
- 动效与响应:列表项入场 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 视觉零漂移