Files
slogan/app/docs/superpowers/specs/2026-07-31-slogan-app-design.md
T
admin b53c57e02d Add 'app/' from commit 'a11a66886941bba128d89c1124115e1b1c87a128'
git-subtree-dir: app
git-subtree-mainline: 6ebd902c6b
git-subtree-split: a11a668869
2026-08-04 14:59:55 +08:00

10 KiB
Raw Blame History

slogan-app 客户端设计方案

日期:2026-07-31 关联:slogan-agent 服务端方案(Go + GoFrame)见 slogan-agent 仓库对应文档

1. 项目概述

slogan 是一个"人形象设计"应用:用户上传大头照和全身多角度照片、维护个人服装资产(衣橱),指定日期范围和地点后一键生成最适合的穿搭方案(含发型、发色、服装穿搭),方案以 3D 化身 + 2D 效果图双形态呈现,手指滑动切换方案与查看角度。

本仓库为客户端(slogan-app),Flutter 实现,一次编写双端(iOS/Android)运行,追求类原生用户操作体验。

2. 技术选型

决策点 选择 理由
语言/框架 Flutter (Dart) 一次编写双端;自绘引擎保证体验一致;动画/手势流畅
状态管理 Riverpod 类型安全、可测试,适合表单/异步任务/缓存类状态
网络层 Dio + 拦截器 JWT 自动注入、统一响应解析 {code,message,data}、超时重试
3D 渲染 three_dart v1 + 渲染抽象层 稳定发布版(v0.3.0GLTF/GLB loader,纯 Dart 双端);flutter_scene 进 stable 后经抽象层无缝替换
图片缓存 cached_network_image 效果图/服装照片懒加载缓存
拍照/相册 camera + image_picker 大头照/全身多角度拍摄引导
本地存储 shared_preferences token/偏好;身形微调参数本地实时生效
手势 原生 GestureDetector 组合 方案横滑切换(PageView)+ 化身旋转拖拽/捏合缩放 + 惯性滚动

3D 渲染层风险控制AvatarViewer 接口抽象(loadGLB / setHairstyle / setHairColor / rotate / zoom / switchOutfit),v1 实现为 three_dartflutter_scene(官方,基于 Flutter GPU)进入 stable 后提供第二实现,业务代码零改动。

3. 项目结构

slogan-app/
├── lib/
│   ├── main.dart                  # 入口 + 路由 + 主题
│   ├── core/
│   │   ├── network/               # Dio 封装:JWT 拦截器/统一响应/错误码映射
│   │   ├── auth/                  # 登录页 + token 管理(账号密码,复用服务端 /user/login
│   │   ├── config/                # API 地址/环境
│   │   ├── storage/               # shared_preferences 封装(token/偏好)
│   │   └── router/                # go_router(未登录 → 登录页)
│   ├── features/
│   │   ├── profile/               # Tab1 我的形象
│   │   │   ├── photo_guide/       #   拍照引导页(大头照/全身多角度拍摄指引)
│   │   │   ├── avatar_viewer/     #   3D 化身查看(AvatarViewer 抽象层实现)
│   │   │   └── body_tune/         #   滑杆微调(身高/胖瘦/肤色,本地实时)
│   │   ├── wardrobe/              # Tab2 我的衣橱
│   │   │   ├── upload/            #   服装照片上传 + 分类标签
│   │   │   └── item_grid/         #   服装资产网格/详情
│   │   ├── outfit/                # Tab3 穿搭方案
│   │   │   ├── generate/          #   生成入口(日期范围选择器/地点选择)
│   │   │   ├── task_status/       #   生成任务进度(轮询)
│   │   │   ├── plan_flow/         #   方案流(PageView 横滑切换方案)
│   │   │   ├── viewer_3d/         #   3D 方案查看(发型切换/发色取色/旋转/捏合)
│   │   │   ├── effect_images/     #   2D 效果图(正面/侧面/背面切换)
│   │   │   └── review/            #   收藏/反馈
│   │   └── commercial/            # Tab4 门店/电商
│   │       ├── stores/            #   LBS 附近门店(形象设计/服装)
│   │       ├── leads/             #   导流订单/到店核销
│   │       ├── products/          #   CPS 商品跳转
│   │       └── subscription/      #   会员订阅
│   └── shared/                    # 组件/主题/工具(日期选择器/评分展示等)
├── assets/
│   ├── avatars/                   # 模板/发型 GLB 缓存(与后端 assets 对应,v1 从服务端拉取)
│   └── images/                    # 图标/占位图
└── test/                          # 单元/widget 测试

4. 页面与交互设计(4 Tab 主框架)

┌─────────────────────────────────────────┐
│  Tab 架构(底部导航,类原生体验)            │
│  ┌────────┬────────┬────────┬─────────┐  │
│  │ 我的形象│ 我的衣橱│ 穿搭方案 │ 门店/电商│  │
│  └────────┴────────┴────────┴─────────┘  │
└─────────────────────────────────────────┘

Tab1 我的形象

  • 首次进入:拍照引导流程(大头照 + 全身正面/侧面/背面 4 张,含姿势示例图)
  • 化身构建进度(后端任务轮询)
  • 3D 化身查看:单指拖拽旋转、双指捏合缩放
  • 滑杆微调:身高/胖瘦/肤色,调参即时反映(本地计算,GLB 缩放参数 + 肤色材质)

Tab2 我的衣橱

  • 服装照片上传(多选)+ 分类(上衣/下装/鞋/配饰)+ 季节/风格标签自动识别(后端 AI 辅助,本地可手改)
  • 网格展示 + 详情编辑/删除

Tab3 穿搭方案(核心)

  • 生成入口:日期范围选择器 + 地点选择(定位/搜索)
  • 生成任务进度页(规则规划 → 方案评分 → 完成)
  • 方案流:PageView 左右滑动切换 3 套方案;每套方案卡片 = 3D 化身 + 方案摘要(评分/来源标签:衣橱组合/AI 推荐)
  • 3D 查看:发型点击切换 + 发色取色盘(HSV 调色实时渲染)+ 拖拽旋转 + 捏合缩放
  • 主方案选定 → 触发 2D 效果图生成(3 视角:正面/侧面/背面,切换查看)
  • 方案条目明细:每件服装(衣橱照片 或 电商商品图)+ 单品操作(跳转商品/加入衣橱)
  • 收藏/反馈 → 回流 Agent 优化下次生成

Tab4 门店/电商

  • LBS 附近合作门店(类型筛选:形象设计/服装),导航/预约/到店核销
  • CPS 商品推荐列表(跳转电商)
  • 会员订阅入口与权益展示

5. 3D 查看器设计(核心模块)

AvatarViewer 抽象接口

abstract class AvatarViewer extends StatelessWidget {
  // 由具体实现提供(three_dart v1 / flutter_scene v2
}

abstract class AvatarViewerController {
  Future<void> loadAvatar(AvatarSpec spec);      // 头像 + 体型 + 皮肤贴图
  Future<void> loadHairstyle(String glbUrl);      // 加载发型
  void setHairColor(Color color);                 // 发色(PBR baseColor 调色)
  void setOutfit(List<OutfitLayer> layers);       // 换装(简模 GLB 层)
  void rotateBy(double dx, double dy);            // 旋转
  void zoomBy(double scale);                      // 缩放
  void resetView();
}
  • v1 实现(three_dart:加载服务端 avatar_model.glb(头部/身体/发型分离分层),发型切换 = 换层 + 发色材质 HSV 调整
  • 性能GLB 经服务端 glTF-Transform 压缩;发型资产首次加载后本地缓存;页面级预取下一套方案
  • 降级:GLB 加载失败 → 显示用户大头照 + 方案文本卡片(核心功能不受 3D 影响)

手势实现

  • 方案切换:PageView(水平滑动 + 惯性 + 阻尼边缘效果)
  • 化身旋转:GestureDetector.onPanUpdate → controller.rotateBy,松手无惯性(或轻量衰减)
  • 缩放:ScaleGestureRecognizer 双指捏合,1.0-4.0 范围限制
  • 发色:HSVColorPicker 自定义取色盘,onChanged 实时 setHairColor

6. 网络层与状态管理

  • ApiClientDio):baseUrl 可配置、token 注入、code==0 判定、401 自动登出、超时 30s
  • 任务轮询:outfit/task/status 每 3s 轮询(Riverpod StreamProvider),任务完成自动停止
  • 上传:Multipart,进度条反馈
  • 缓存:效果图/服装照片 cached_network_image;化身 GLB 本地文件缓存(LRU,256MB 上限)

7. 拍摄引导设计

  • 大头照:正面、面部无遮挡、光线均匀说明图;相机取景框对齐提示
  • 全身照:距镜 2-3 米、全身入框、正面/侧面/背面 三角度示例图(类原生"手势引导"UI
  • 照片本地压缩(宽边 ≤ 2048)后上传

8. 错误处理与加载状态

  • 统一 ErrorView / LoadingView 组件(骨架屏)
  • 生成任务失败:明确错误文案("衣橱为空,请先添加服装"等)+ 重试按钮
  • 网络离线:离线提示 + 本地缓存优先展示(方案历史本地快照)
  • 轮询超时(>10 分钟):提示"生成时间较长"并提供结果通知路径(v2 推送)

9. 测试策略

  • 单元测试:手势计算/发色 HSV 调色/方案缓存 key 逻辑
  • Widget 测试:方案流滑动切换、3D 查看器骨架降级、拍照引导流程
  • 集成(v1 手工 + 冒烟脚本):登录 → 上传 → 生成 → 查看全链路
  • 渲染层测试:AvatarViewer 接口 mock,业务测试不依赖具体 3D 实现

10. 与后端 API 对接清单

见 slogan-agent 方案第 11 节 API 路由表。App 端关键时序:

登录 → 上传照片(4张) → 填写身形 → [build 化身(异步)] → 上传衣橱服装
  → 生成穿搭 {日期范围, 地点} → 轮询任务 → 方案流(3D 即时查看)
  → 选主方案 → 效果图生成(异步) → 3 视角查看 → 收藏/跳转商品/门店预约

11. 开发规范约束(App 端)

  • 状态管理统一 Riverpod,禁止 setState 在页面间传递业务状态
  • 所有网络请求必须走 ApiClient,禁止散落 Dio 实例
  • 3D 渲染只允许通过 AvatarViewer 抽象层,禁止业务代码直接依赖 three_dart 类型
  • 命名:目录 features/<domain>/,组件 shared/;文件 snake_case,类 PascalCase
  • 测试随功能同步编写(TDD:先写失败测试再实现)