Files
2026-08-17 13:38:41 +08:00

199 lines
11 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 我的形象穿搭(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.dbdefault,用户域)
| 表 | 用途 |
|---|---|
| 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.dbplan,穿搭域)
| 表 | 用途 |
|---|---|
| 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.dbpay,支付域)
| 表 | 用途 |
|---|---|
| slogan_user_member | 用户会员(套餐/到期时间) |
| slogan_member_plan | 会员套餐(金额分/时长/权益,可配置) |
| slogan_payment_order | 支付订单(渠道/状态/回调原始报文) |
| slogan_pay_notify_log | 支付回调日志(幂等落库) |
| slogan_ad_reward_log | 广告激励领取记录(限频) |
### slogan_cps.dbcps,联盟域)
| 表 | 用途 |
|---|---|
| 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>`JWT7 天有效)。
| 模块 | 接口 | 说明 | 公开 |
|---|---|---|---|
| 用户 | `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/ 每表一 DAOinit 自动建表 + 索引 + 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**