Files
workspace/code/app/CLOTHING_OUTFIT_DESIGN.md
T
2026-06-29 15:48:39 +08:00

19 KiB

衣服搭配子模块设计文档

1. 背景

在现有家庭 App 中新增「衣服搭配」子模块,用于管理家庭共享的衣物资产,并基于衣物设计、保存、复用搭配方案。

本模块先按 App 内工具设计,不做营销页。界面重点应是图片可浏览、筛选顺手、保存动作明确。

2. 目标

  • 录入衣服,形成可管理的衣橱。
  • 给衣服维护标签/分类,分类支持自定义。
  • 设计搭配,选择多件衣服组合成一个搭配方案。
  • 保存搭配,搭配也支持标签/分类。
  • 后续可基于分类、标签等维度检索衣服和搭配。

3. 非目标

第一期暂不做:

  • AI 自动搭配。
  • 社区分享、公开穿搭广场。
  • 电商购买链接。
  • 复杂身材数据、尺码推荐。
  • 日历穿搭计划。
  • 洗护/库存/折旧管理。
  • 多成员私有衣橱隔离。

这些能力可以作为后续扩展,不进入第一版主流程。

4. 核心用户故事

衣服管理

  • 作为用户,我可以新增一件衣服,上传图片,填写名称、分类、标签等信息。
  • 作为用户,我可以按分类、标签筛选衣服。
  • 作为用户,我可以编辑或删除已录入的衣服。
  • 作为用户,我可以停用/隐藏不常穿的衣服,而不是必须删除。
  • 作为用户,删除被搭配引用的衣服时,我可以选择是否同时删除相关搭配。

搭配管理

  • 作为用户,我可以从衣橱中选择多件衣服组成一套搭配。
  • 作为用户,我可以保存搭配,填写搭配名称、分类、标签等信息。
  • 作为用户,我可以查看搭配详情,看到包含的所有衣服。
  • 作为用户,我可以编辑搭配中的衣服列表和基础信息。
  • 作为用户,我可以删除搭配,删除搭配不会删除搭配中引用的衣服。

分类/标签管理

  • 作为用户,我可以维护衣服分类,例如上衣、裤子、外套、鞋、包、配饰。
  • 作为用户,我可以维护搭配分类,例如通勤、约会、运动、旅行、居家。
  • 作为用户,我可以维护标签组,例如尺寸、季节、风格、材质、颜色。
  • 作为用户,我可以给衣服和搭配添加多个标签,例如春秋、黑色、正式、宽松、显瘦。
  • 衣服标签和搭配标签需要区分,避免两个场景下的标签互相干扰。

5. 信息架构

建议一级入口叫「穿搭」或「衣橱」。

模块内建议 3 个主视图:

  • 衣橱:衣服列表、筛选、录入入口。
  • 搭配:搭配列表、筛选、创建入口。
  • 分类:衣服分类、搭配分类、标签维护。

第一期保留独立「分类」页,放在衣服搭配模块的底部 Tab 中;新增/编辑流程里也可以保留快速新建入口,减少录入中断。

5.1 已确认规则

  • 子模块永远是家庭共享,不做个人私有衣橱。
  • 衣服图片必须上传,不允许无图衣服。
  • 分类和标签不做默认初始化,由用户自行创建。
  • 分类保持单层,不做父子结构。
  • 尺寸、季节、风格、颜色等父子结构使用“标签组 -> 标签”表达。
  • 衣服标签和搭配标签区分管理。
  • 不做颜色结构化字段,颜色这类信息由用户通过标签处理。
  • 标签使用表情做视觉识别,不单独配置标签颜色。
  • 不做季节、场景固定枚举,季节/场景由用户通过标签或分类自行处理。
  • 数据保存优先使用现有公共接口,例如 data/loadData、data/saveData。
  • 尽量都走通用接口;只有通用接口明显无法保证体验或一致性时,再补特殊接口。
  • 能在前端完成的能力优先放前端,减少后端特殊接口。
  • 删除搭配时,只删除搭配和搭配明细,不删除衣服。
  • 删除衣服时,如果衣服没有被搭配引用,直接删除或软删除该衣服。
  • 删除衣服时,如果衣服已被搭配引用,需要提示用户是否同时删除相关搭配:
    • 用户确认:删除该衣服,同时删除所有引用该衣服的搭配及其明细。
    • 用户取消:衣服和搭配都不删除。

5.2 搭配编辑模式

第一版采用「自由拖拽画布」模式。

推荐模式:

  • 搭配编辑页顶部或主体是固定比例画布,建议 1:1。
  • 下方或底部抽屉是衣服选择区,可按分类、标签筛选衣服。
  • 用户点击衣服加入画布。
  • 画布内衣服支持拖拽移动、缩放、删除。
  • 第一版可以先不做旋转,降低手势复杂度。
  • 画布内衣服支持置顶/置底,或通过点击选中后调整层级。
  • 保存搭配时保存画布布局数据,并生成搭配缩略图。

原因:

  • 穿搭本质上是视觉组合,固定槽位会限制用户表达。
  • 用户需要自己控制衣服摆放位置,否则操作体验会显得僵硬。
  • 自由画布更接近“搭配板”,更符合用户对穿搭设计的预期。

第一版边界:

  • 画布比例固定为 1:1,不支持任意画布尺寸。
  • 每件衣服记录位置、尺寸、层级;第一版暂不支持旋转。
  • 不做撤销/重做。
  • 不做自动吸附、对齐辅助线。
  • 不做多选。
  • 不做复杂贴纸、文字、背景。
  • 画布背景固定为浅色或透明。

后续扩展:

  • 支持旋转。
  • 支持撤销/重做。
  • 支持吸附、对齐线、居中线。
  • 支持背景模板。
  • 支持文字说明或贴纸。

6. 数据对象草案

衣服 b_clothing_clothes

字段草案:

  • id
  • family_id
  • name
  • image_file_key
  • category_id
  • brand
  • remark
  • status
  • sort_number
  • create_time
  • update_time
  • create_by
  • update_by

说明:

  • family_id:衣服属于家庭空间。
  • image_file_key:走现有 S3 规则,上传到 family_id/年/月/日/...。
  • image_file_key 必填。
  • status:建议 1 启用,0 停用。
  • 颜色、季节这类检索信息不做结构化字段,由标签承载。

搭配 b_clothing_outfit

字段草案:

  • id
  • family_id
  • name
  • cover_file_key
  • layout_json
  • category_id
  • remark
  • status
  • sort_number
  • create_time
  • update_time
  • create_by
  • update_by

说明:

  • cover_file_key 建议保存一张搭配缩略图,用于搭配列表快速展示。
  • 缩略图只保存生成后的结果,列表不实时拼图。
  • 缩略图由前端生成后通过 S3 上传,保存时写入 cover_file_key。
  • 如果缩略图生成失败,可以降级使用搭配内第一件衣服图片作为封面。
  • layout_json 保存画布级配置,例如画布宽高比例、背景、版本号等。

搭配明细 b_clothing_outfit_clothes

字段草案:

  • id
  • outfit_id
  • clothes_id
  • x
  • y
  • width
  • height
  • z_index
  • sort_number
  • create_time

说明:

  • 一套搭配包含多件衣服。
  • x/y/width/height 建议使用归一化比例值,范围 0 到 1,便于不同屏幕尺寸还原。
  • z_index 用于控制叠放层级。
  • sort_number 可作为列表排序或备用顺序。
  • 第一版不保存旋转角度,后续如果支持旋转再增加 rotate 字段。

分类 b_clothing_category

字段草案:

  • id
  • family_id
  • name
  • type
  • sort_number
  • status

说明:

  • type = 0 衣服分类。
  • type = 1 搭配分类。
  • 衣服分类和搭配分类可以共用一张表,减少表数量。
  • 分类保持单层,不设置 parent_id。

标签组 b_clothing_tag_group

字段草案:

  • id
  • family_id
  • name
  • type
  • sort_number
  • status

说明:

  • type = 0 衣服标签组。
  • type = 1 搭配标签组。
  • 示例:尺寸、季节、风格、材质、颜色。
  • 标签组由用户自定义,不做默认初始化。

标签 b_clothing_tag

字段草案:

  • id
  • family_id
  • tag_group_id
  • name
  • type
  • emoji
  • sort_number
  • status

说明:

  • type = 0 衣服标签。
  • type = 1 搭配标签。
  • tag_group_id 指向所属标签组,例如“XL”属于“尺寸”。
  • emoji 用于标签视觉识别。颜色不做结构化配置。

标签关联 b_clothing_tag_relation

字段草案:

  • id
  • family_id
  • target_type
  • target_id
  • tag_id

说明:

  • target_type = 0 衣服。
  • target_type = 1 搭配。
  • 一个衣服/搭配可以有多个标签。

7. 第一版流程

新增衣服

  1. 进入「衣橱」。
  2. 点击新增。
  3. 上传或拍摄衣服图片。
  4. 填写名称、分类、标签。
  5. 保存。
  6. 返回衣橱列表并刷新。

校验规则:

  • 图片必填。
  • 分类可以为空,但如果用户输入新分类,应自动创建分类后再保存衣服。
  • 标签可以为空,支持选择已有标签或新建标签。

新增搭配

  1. 进入「搭配」。
  2. 点击新增。
  3. 进入自由画布编辑页。
  4. 从底部衣服选择区添加衣服到画布。
  5. 在画布中拖拽、缩放衣服,调整层级。
  6. 填写搭配名称、分类、标签。
  7. 生成搭配缩略图并上传。
  8. 保存搭配、搭配明细、画布布局和缩略图 key。
  9. 返回搭配列表并刷新。

校验规则:

  • 至少选择 1 件衣服。
  • 分类可以为空。
  • 标签可以为空。
  • 画布内每件衣服必须有有效的位置和尺寸。

自定义分类/标签组/标签

第一版采用组合方案:

  • 在底部 Tab 中提供独立「分类」页,统一维护衣服/搭配分类、标签组、标签。
  • 在新增/编辑表单里保留快速新建分类、标签组、标签能力,减少录入中断。

删除衣服

  1. 用户点击删除衣服。
  2. 后端检查是否存在搭配引用。
  3. 如果没有引用,删除衣服。
  4. 如果有引用,前端提示“该衣服已被 X 个搭配使用,是否同时删除这些搭配?”
  5. 用户确认后,后端在同一事务中删除衣服、相关搭配、相关搭配明细、相关标签关联。
  6. 用户取消后,不执行任何删除。

删除搭配

  1. 用户点击删除搭配。
  2. 后端删除搭配、搭配明细、搭配标签关联。
  3. 不删除任何衣服。

衣服快速记账

这是后置功能,可以最后再做。

  1. 用户在编辑衣服页点击记账按钮。
  2. 页面弹出新增记账 BottomSheet。
  3. BottomSheet 复用现有记账新增能力。
  4. 可选地把衣服名称带入备注,例如“衣服:白色衬衫”。
  5. 保存成功后关闭 BottomSheet,不影响衣服编辑状态。

8. MVP 范围建议

第一期建议做:

  • 衣服 CRUD。
  • 搭配 CRUD。
  • 衣服分类自定义。
  • 搭配分类自定义。
  • 衣服/搭配标签组自定义。
  • 衣服/搭配标签多选和新建。
  • 图片上传。
  • 自由拖拽画布。
  • 画布内衣服拖拽、缩放、层级调整、删除。
  • 搭配缩略图生成。
  • 基础筛选:分类、标签。

第一期暂缓:

  • AI 搭配推荐。
  • 穿搭日历。
  • 多成员衣橱隔离。
  • 画布旋转、撤销/重做、吸附对齐、多选。
  • 衣服编辑页快速记账。
  • 统计分析。

9. 剩余待确认问题

暂无。

10. 初步技术建议

  • 数据库建议新增独立表,不混入现有记账分类。
  • 图片上传复用现有 S3 上传接口,路径遵循 family_id/年/月/日。
  • 衣服、搭配、分类、标签组、标签保存优先复用当前公共接口 data/saveData。
  • 删除衣服前先用公共查询接口检查搭配引用;用户确认后,用 data/saveData 批量删除衣服、相关搭配、明细和标签关联。
  • 分类/标签组/标签创建也优先走公共接口。
  • 自由画布数据优先直接存入搭配明细字段;如果后续字段膨胀,再考虑使用 layout_json 承载更复杂的画布数据。
  • 搭配缩略图由前端生成,尺寸可先定为 512x512,S3 路径同样遵循 family_id/年/月/日。
  • 当前 react-native-view-shot 支持 jpg/png,首版使用 512x512 JPG;后续如果补图片转换链路,再升级为 WebP。
  • 前端缩略图生成可考虑使用 react-native-view-shot 截取画布视图,再走现有 S3 上传。
  • 衣服快速记账复用现有新增记账 BottomSheet,作为后置功能实现。
  • 前端状态可以新增 clothing store,负责衣服、搭配、分类、标签组、标签缓存。

11. 下一步

已确认核心业务规则。下一步可以进入:

  1. 数据库表结构设计。
  2. 页面与交互流程设计。
  3. 公共接口调用方案设计。
  4. 第一版任务拆分。

缩略图样式可以在页面流程设计阶段继续细化。

12. 实施计划

说明:

  • 每一步完成后,把 [ ] 改成 [x]。
  • 严格按阶段推进,前一阶段没有确认前,不进入下一阶段。
  • 默认优先使用通用接口;遇到通用接口明显无法覆盖的场景,再单独讨论是否增加特殊接口。

阶段 1:数据库表结构

  • 设计 b_clothing_clothes 表结构。
  • 设计 b_clothing_outfit 表结构。
  • 设计 b_clothing_outfit_clothes 表结构,包含画布坐标、尺寸、层级字段。
  • 设计 b_clothing_category 表结构,分类保持单层。
  • 设计 b_clothing_tag_group 表结构。
  • 设计 b_clothing_tag 表结构,关联 tag_group_id。
  • 设计 b_clothing_tag_relation 表结构。
  • 补充索引设计,例如 family_id/status/type/sort_number。
  • 生成 SQL 文件并确认命名、字段类型、默认值。
  • 执行 SQL 到 dev 数据库并验证 7 张表已创建。

产出文件:

  • app-go/db/clothing.sql

验收标准:

  • 表名全部使用 b_clothing_ 前缀。
  • 不出现 ref 表名。
  • 分类无父子结构。
  • 标签组和标签可以表达尺寸、季节、风格等自定义属性。

阶段 2:前端基础模型与公共接口封装

  • 新增衣服、搭配、分类、标签组、标签相关 TypeScript 类型。
  • 新增 clothing store,管理衣服、搭配、分类、标签组、标签缓存。
  • 在 clothing store 中封装基于公共接口的查询方法。
  • 在 clothing store 中封装基于公共接口的保存方法。
  • 在 clothing store 中封装图片上传复用逻辑,路径继续走 family_id/年/月/日。
  • 不新增 services 层,避免重复封装。

产出文件:

  • app-rn/src/types/clothing.ts
  • app-rn/src/store/clothing.ts
  • app-rn/src/store/index.ts

验收标准:

  • 前端类型和数据库字段一致。
  • 查询和保存优先使用现有 loadData、saveData。
  • 不引入不必要的后端特殊接口。

阶段 3:衣服管理

  • 新增衣橱列表页。
  • 支持按分类、标签筛选衣服。
  • 新增衣服编辑页或 BottomSheet。
  • 衣服图片必填,支持上传图片。
  • 支持创建或选择分类。
  • 支持创建或选择标签组/标签。
  • 支持编辑衣服。
  • 支持删除衣服前检查搭配引用。
  • 如果存在搭配引用,提示是否同时删除相关搭配。
  • 用户确认后批量删除衣服、相关搭配、搭配明细、标签关联。
  • 用户取消后不删除任何数据。

产出文件:

  • app-rn/src/app/clothes/(tabs)/_layout.tsx
  • app-rn/src/app/clothes/(tabs)/home/index.tsx
  • app-rn/src/app/clothes/(tabs)/outfit/index.tsx
  • app-rn/src/app/clothes/edit/index.tsx
  • app-rn/src/components/clothing/ClothingImage.tsx

验收标准:

  • 无图衣服不能保存。
  • 删除衣服的引用提示逻辑正确。
  • 删除搭配时不会误删衣服。

阶段 4:分类、标签组、标签管理

  • 在衣服编辑流程中支持快速新建分类。
  • 在衣服编辑流程中支持快速新建标签组。
  • 在衣服编辑流程中支持在标签组下新建标签。
  • 标签支持 emoji。
  • 衣服标签和搭配标签按 type 区分。
  • 独立分类/标签管理页放到底部 Tab。
  • 独立管理页支持维护衣服分类、搭配分类。
  • 独立管理页支持维护衣服标签组/标签、搭配标签组/标签。

产出文件:

  • app-rn/src/app/clothes/(tabs)/_layout.tsx
  • app-rn/src/app/clothes/(tabs)/manage/index.tsx

验收标准:

  • 分类单层。
  • 标签必须归属标签组。
  • 衣服标签和搭配标签互不混用。

阶段 5:自由拖拽搭配画布

  • 新增搭配列表页。
  • 新增搭配编辑页。
  • 搭配编辑页提供 1:1 固定比例画布。
  • 从衣服选择区添加衣服到画布。
  • 支持画布内拖拽移动。
  • 支持画布内缩放。
  • 支持删除画布中的衣服。
  • 支持调整层级,例如置顶、置底。
  • 保存每件衣服的 x/y/width/height/z_index。
  • 坐标和尺寸使用 0 到 1 的归一化比例。
  • 重新打开搭配时准确还原画布。

产出文件:

  • app-rn/src/app/clothes/(tabs)/outfit/index.tsx
  • app-rn/src/app/clothes/outfit/edit/index.tsx

第一版不做:

  • 旋转。
  • 撤销/重做。
  • 多选。
  • 吸附线和对齐线。
  • 文字、贴纸、背景模板。

验收标准:

  • 不同屏幕尺寸下画布能稳定还原。
  • 画布操作不卡顿。
  • 保存后再次进入,布局不丢失。

阶段 6:搭配保存与缩略图

  • 引入或确认 react-native-view-shot。
  • 保存搭配前截取画布生成缩略图。
  • 缩略图上传到 S3。
  • 保存搭配主表 cover_file_key。
  • 保存搭配明细和画布布局。
  • 搭配列表使用 cover_file_key 展示。
  • 缩略图生成失败时,降级使用第一件衣服图片作为封面。

产出文件:

  • app-rn/src/app/clothes/outfit/edit/index.tsx
  • app-rn/src/store/clothing.ts

验收标准:

  • 搭配列表不实时拼图,只加载缩略图。
  • 缩略图路径遵循 family_id/年/月/日。
  • 保存失败时不产生错误的半成品数据。

阶段 7:搭配管理

  • 支持搭配详情查看。
  • 支持编辑搭配基础信息。
  • 支持编辑搭配画布。
  • 支持删除搭配。
  • 删除搭配时删除搭配明细和搭配标签关联。
  • 删除搭配时不删除衣服。

产出文件:

  • app-rn/src/app/clothes/(tabs)/outfit/index.tsx
  • app-rn/src/app/clothes/outfit/detail/[id]/index.tsx
  • app-rn/src/app/clothes/outfit/edit/index.tsx

验收标准:

  • 搭配 CRUD 完整。
  • 删除搭配不影响衣橱。

阶段 8:收尾与体验优化

  • 补充空状态。
  • 补充加载状态。
  • 补充保存中和上传中状态。
  • 补充错误提示。
  • 检查移动端小屏布局。
  • 检查图片加载失败兜底。
  • 跑 lint/format/type check。
  • 根据实际结果更新本文档完成状态。

验证结果:

  • oxfmt --check 通过。
  • oxlint 通过。
  • tsc --noEmit 已执行,仅剩 src/components/iconfont/* SVG 类型问题,本阶段不处理。

验收标准:

  • 核心流程从新增衣服到保存搭配可完整走通。
  • 异常状态有明确反馈。
  • 文档计划状态和代码实现保持一致。

阶段 9:后置功能:衣服快速记账

  • 在衣服编辑页增加记账入口。
  • 点击后弹出新增记账 BottomSheet。
  • 复用现有记账新增能力。
  • 可选地把衣服名称带入备注。
  • 保存成功后关闭 BottomSheet。

验收标准:

  • 快速记账不影响衣服编辑状态。
  • 记账保存逻辑与现有记账模块一致。