199 lines
11 KiB
Markdown
199 lines
11 KiB
Markdown
# 我的形象穿搭(slogan)
|
||
|
||
AI 形象穿搭应用:用户上传个人照片与服装照片,指定日期地点后由大模型生成穿搭方案(含发型与场合建议),支持 3D 化身查看、效果图生成、CPS 联盟商品推荐与会员订阅。
|
||
|
||
## 技术栈与架构
|
||
|
||
- **前端** `app-uni/`:uni-app (Vue 3 + Vite + Pinia) 多端工程(Android/iOS/微信小程序/H5),H5 构建产物由后端托管
|
||
- **后端** `server/`:Go 1.22+ / GoFrame v2 / SQLite / JWT
|
||
- 依赖服务:OpenAI 兼容大模型(穿搭方案生成)、通义万相(效果图出图)、Tripo(图像转 3D 化身)、和风天气 + 高德地理编码、虎皮棋聚合支付、美团/京东/淘宝 CPS 联盟
|
||
- **部署**:Docker 单镜像,前后端一体单端口 **8080**(`server/Dockerfile`)
|
||
|
||
```
|
||
app-uni/ ──H5 构建产物──▶ server 静态托管(:8080)
|
||
server/ ──▶ 4 个 SQLite 库(data/)+ 文件存储(workspace/)
|
||
```
|
||
|
||
## 快速开始
|
||
|
||
```bash
|
||
# 后端(server/ 目录)
|
||
go mod tidy
|
||
go build -o slogan-agent .
|
||
./slogan-agent # 监听 :8080,首次启动自动建库建表(server/data/ 下 4 个 SQLite)
|
||
|
||
# 前端 H5 开发(app-uni/ 目录,BASE_URL 指向 http://127.0.0.1:8080)
|
||
npm install
|
||
npm run dev:h5
|
||
```
|
||
|
||
- 测试账号:`wenwu901` / `123456`(登录页自带「测试账号一键登录」按钮)
|
||
- OpenAPI 文档:`http://127.0.0.1:8080/api.json`
|
||
- 联调与测试规范:**必须使用真实用户数据**(测试账号),禁止用临时注册新账号验证业务链路
|
||
|
||
## 配置说明(server/config.yml)
|
||
|
||
| 配置节 | 说明 |
|
||
|---|---|
|
||
| `database.*` | 4 个 SQLite 分组(default/plan/pay/cps),落盘 `data/`;`cache.ttl` 查询缓存秒数 |
|
||
| `server.address` | 监听地址(:8080);`clientMaxBodySize` 上传大小上限 |
|
||
| `llm` | 大模型(OpenAI 兼容),未配置时生成任务失败并返回明确错误 |
|
||
| `imagegen` | 效果图供应商:`wanx`(通义万相,需 `wanx_api_key`) |
|
||
| `weather.geo` | 和风天气 v7 Key + 高德地理编码 Key,未配置时穿搭生成跳过天气/地理推荐 |
|
||
| `payment` | 虎皮棋聚合支付(`xunhu_appid/appsecret` 为空则支付功能降级关闭) |
|
||
| `avatar` | Tripo 3D 生成(`tripo_api_key` 为空则 /avatar/build 返回失败提示) |
|
||
| `cps` | 美团/京东/淘宝联盟(key 全空则联盟入口优雅降级隐藏) |
|
||
| `ad` | 广告激励限频(自然日):`effect_extra` 2 次 / `vip_trial` 1 次 |
|
||
|
||
> 注:`wanx_api_key` 与 `llm.api_key` 为真实 Key 占位,提交前请勿携带真实密钥。
|
||
|
||
## 数据库(4 库 22 表)
|
||
|
||
### slogan.db(default,用户域)
|
||
| 表 | 用途 |
|
||
|---|---|
|
||
| slogan_user | 用户账号(username/phone/password/role) |
|
||
| slogan_user_photo | 用户照片(type: 1 大头照 / 2 全身正面 / 3 全身侧面 / 4 全身背面) |
|
||
| slogan_wardrobe_item | 衣橱单品(分类/季节/风格标签/颜色) |
|
||
| slogan_body_measurement | 身形参数(身高/体重/三围/肩宽/肤色) |
|
||
| slogan_avatar_model | 3D 化身(Tripo 构建状态 + GLB URL) |
|
||
| slogan_scoring_rule | 方案评分规则(5 维权重,可配置) |
|
||
| slogan_partner_store | 合作门店(形象设计/服装门店) |
|
||
|
||
### slogan_plan.db(plan,穿搭域)
|
||
| 表 | 用途 |
|
||
|---|---|
|
||
| slogan_hairstyle_asset | 发型资产库(GLB + 预览图,seed 8 款) |
|
||
| slogan_outfit_generation_task | 穿搭生成任务(状态机 pending→planning→scoring→rendering→done/failed) |
|
||
| slogan_outfit_plan | 穿搭方案(日期地点/标题/来源/评分/主方案标记/发型引用) |
|
||
| slogan_plan_outfit_item | 方案穿衣清单(slot 槽位,来源:衣橱 or AI 新品) |
|
||
| slogan_plan_effect_image | 方案效果图(角度: front/side/back,万相出图) |
|
||
| slogan_plan_review | 方案反馈(fav/unfav) |
|
||
|
||
### slogan_pay.db(pay,支付域)
|
||
| 表 | 用途 |
|
||
|---|---|
|
||
| slogan_user_member | 用户会员(套餐/到期时间) |
|
||
| slogan_member_plan | 会员套餐(金额分/时长/权益,可配置) |
|
||
| slogan_payment_order | 支付订单(渠道/状态/回调原始报文) |
|
||
| slogan_pay_notify_log | 支付回调日志(幂等落库) |
|
||
| slogan_ad_reward_log | 广告激励领取记录(限频) |
|
||
|
||
### slogan_cps.db(cps,联盟域)
|
||
| 表 | 用途 |
|
||
|---|---|
|
||
| slogan_cps_category | 联盟统一分类树(三源归一) |
|
||
| slogan_cps_product | 联盟商品池(美团/京东/淘宝,金额单位:分) |
|
||
| slogan_cps_click_log | 商品点击/转链记录 |
|
||
| slogan_scene_category_map | 业务场景 → 联盟分类映射(发型/买同款/升级款/延伸优惠/会员权益) |
|
||
|
||
## 功能模块与接口(35 个)
|
||
|
||
统一响应格式 `{"code":0,"message":"OK","data":...}`,`code != 0` 为业务错误;除公开接口外需 `Authorization: Bearer <token>`(JWT,7 天有效)。
|
||
|
||
| 模块 | 接口 | 说明 | 公开 |
|
||
|---|---|---|---|
|
||
| 用户 | `POST /user/register` | 注册 | 是 |
|
||
| 用户 | `POST /user/login` | 登录返回 token | 是 |
|
||
| 用户 | `POST /user/change-password` | 修改密码 | |
|
||
| 用户 | `GET /user/profile` | 我的资料 | |
|
||
| 照片 | `POST /user-photo/upload` | 上传照片 | |
|
||
| 照片 | `GET /user-photo/list` | 照片列表(type 筛选) | |
|
||
| 照片 | `POST /user-photo/delete` | 删除照片 | |
|
||
| 衣橱 | `POST /wardrobe/upload` | 上传服装(multipart: file + category/season/style_tags/color_info) | |
|
||
| 衣橱 | `GET /wardrobe/list` | 衣橱列表 | |
|
||
| 衣橱 | `POST /wardrobe/update` | 更新服装信息 | |
|
||
| 衣橱 | `POST /wardrobe/delete` | 删除服装 | |
|
||
| 身形 | `POST /body-measurement/save` | 保存身形参数(身高/体重/三围/肩宽/肤色) | |
|
||
| 身形 | `GET /body-measurement/get` | 查询身形参数 | |
|
||
| 化身 | `POST /avatar/build` | 构建 3D 化身(Tripo 图像转 3D,异步) | |
|
||
| 化身 | `GET /avatar/get` | 我的化身(GLB/构建状态) | |
|
||
| 发型 | `GET /hairstyle/list` | 发型资产库 | 是 |
|
||
| 穿搭 | `POST /outfit/generate` | 生成穿搭方案(异步任务) | |
|
||
| 穿搭 | `GET /outfit/task/status` | 任务状态 | |
|
||
| 穿搭 | `GET /outfit/plan/list` | 方案列表 | |
|
||
| 穿搭 | `GET /outfit/plan/detail` | 方案详情(穿衣清单 + 发型 + 效果图) | |
|
||
| 穿搭 | `POST /outfit/plan/select-main` | 选定主方案(触发 3 视角效果图生成) | |
|
||
| 穿搭 | `POST /outfit/plan/review` | 方案反馈 | |
|
||
| 门店 | `GET /partner-store/list` | 合作门店(type: 0 全部 / 1 形象设计 / 2 服装门店) | |
|
||
| 会员 | `GET /member/plan/list` | 会员套餐列表 | |
|
||
| 会员 | `GET /member/status` | 我的会员状态(含剩余广告权益) | |
|
||
| 会员 | `POST /member/order/create` | 创建支付订单 | |
|
||
| 会员 | `GET /member/order/status` | 订单状态(轮询) | |
|
||
| 会员 | `POST /member/order/notify` | 支付回调(裸文本 "success",幂等) | 是 |
|
||
| 广告 | `POST /ad/reward/claim` | 领取广告激励(看视频领效果图次数/体验会员,自然日限频) | |
|
||
| CPS | `GET /cps/category/list` | 统一分类列表 | |
|
||
| CPS | `GET /cps/product/list` | 商品池分页列表(分类/城市/场景筛选) | |
|
||
| CPS | `GET /cps/my/recent` | 我的优惠记录(点击去重) | |
|
||
| CPS | `POST /cps/product/link` | 商品转链(返回可打开链接) | |
|
||
| CPS | `GET /cps/plan/recommend` | 方案驱动推荐(延伸优惠) | |
|
||
| CPS | `GET /cps/wardrobe/upgrade` | 衣橱升级款 | |
|
||
| 静态 | `GET /workspace/*` | 上传文件与模板资产(鉴权放行) | |
|
||
|
||
## 核心业务流程
|
||
|
||
### 穿搭生成(outfit/generate)
|
||
```
|
||
pending → planning(天气获取 → 规则预筛 3 套候选 → LLM 规划 1 次调用)
|
||
→ scoring(规则引擎 5 维评分:天气 25/场合 25/色彩 20/完整度 20/风格 10,阈值 75)
|
||
→ 全低分 → LLM 兜底创作(1 次调用,recommend 方案)
|
||
→ 落库 outfit_plan + plan_outfit_item → done
|
||
```
|
||
- 衣橱不足 3 件、日期倒挂、Key 未配置等均在任务结果中返回明确错误
|
||
- 服务重启时未完成任务标记 failed(避免重复消耗模型费用)
|
||
|
||
### 效果图
|
||
- 选定主方案后异步生成 正面/侧面/背面 3 张(通义万相 wan2.7-image-pro),内容 hash 缓存 24h,每日限 3 次(`scoring_rule` 表 `effect_limit` 维度)
|
||
- 效果图次数可通过广告激励补充(`/ad/reward/claim`,`effect_extra` 自然日 2 次)
|
||
|
||
### 3D 化身
|
||
- 基于三视角全身照(正面/侧面/背面)→ Tripo 图像转 3D 生成 GLB(异步任务,`GET /avatar/get` 轮询状态;服务重启未完成任务标记失败)
|
||
- 展示端为前端 three.js 渲染(H5):GLTFLoader 加载 GLB,包围盒居中 + 相机自适应,空闲自动旋转,触摸/鼠标拖拽全角度旋转;非 H5 端提示"数字人仅支持 H5 查看"
|
||
|
||
### 会员支付
|
||
- 套餐下单 → 虎皮棋聚合支付(alipay/wechat)→ `pay_url` 拉起支付 → 前端轮询订单状态 → 回调 `/member/order/notify` 幂等更新会员
|
||
- `xunhu_appid/appsecret` 未配置时支付功能降级关闭
|
||
|
||
### CPS 联盟
|
||
- 美团/京东/淘宝三联盟商品定时同步(`cps.sync_cron`,默认每日 4 点),分类归一到 `slogan_cps_category`
|
||
- 业务场景映射(发型卡/买同款/到店试穿/延伸优惠/找升级款/会员权益)→ 场景推荐接口
|
||
- key 全空时联盟入口优雅降级隐藏
|
||
|
||
## 目录结构
|
||
|
||
```
|
||
server/
|
||
main.go 入口:路由注册 + workspace 静态服务 + 任务恢复 + CPS 定时同步
|
||
common/ 通用层:HTTP/RouteRegister/JWT 鉴权/DAO 基类/缓存/锁/协程池/DB 组访问器
|
||
styleagent/
|
||
controller/ Controller 层(反射路由,struct 名 → kebab-case URL)
|
||
service/ 业务层(生成编排/化身/衣橱/效果图/支付/会员/CPS/广告)
|
||
dao/ 每表一 DAO(init 自动建表 + 索引 + seed)
|
||
model/entity/ 实体(与表一一对应)
|
||
model/dto/ 请求/响应结构(g.Meta 定义路由)
|
||
agent/ LLM 调用(OpenAI 兼容)+ 方案规划/兜底 + 万相出图
|
||
scoring/ 规则评分引擎(零 LLM 成本)
|
||
weather/ 和风天气 + 高德地理编码
|
||
avatar/ Tripo 3D 客户端(图像转 3D + GLB 下载)
|
||
cps/ 三联盟客户端(美团/京东/淘宝)
|
||
consts/ 常量(表名/状态/数据库组)
|
||
app-uni/ uni-app (Vue3) 多端工程(three.js 化身 3D 展示)
|
||
```
|
||
|
||
## 部署
|
||
|
||
```bash
|
||
docker build -t slogan-agent server/
|
||
docker run -d -p 8080:8080 \
|
||
-v /data/slogan/data:/app/data \ # 数据库目录(小而关键)
|
||
-v /data/slogan/workspace:/app/workspace \ # 上传/生成文件(大而可重建)
|
||
slogan-agent
|
||
```
|
||
|
||
- **备份 = 打包 `data/`(数据库)+ `workspace/`(文件)两个目录**;迁移 = 拷贝到新机器
|
||
- 生产部署前在 config.yml 填写 llm/weather/geo/imagegen/payment/avatar/cps 的真实 Key
|
||
|
||
## 开发规范
|
||
|
||
分层职责(controller → service → dao)、并发/事务/缓存/金额单位等硬性约束见根目录 **CLAUDE.md**;实现细节与技术决策见 **技术设计.md**。
|