This commit is contained in:
2026-08-17 13:38:41 +08:00
parent ebf744a70e
commit 7c9699b425
8 changed files with 13 additions and 23 deletions
+6 -8
View File
@@ -42,7 +42,6 @@ npm run dev:h5
| `weather.geo` | 和风天气 v7 Key + 高德地理编码 Key,未配置时穿搭生成跳过天气/地理推荐 |
| `payment` | 虎皮棋聚合支付(`xunhu_appid/appsecret` 为空则支付功能降级关闭) |
| `avatar` | Tripo 3D 生成(`tripo_api_key` 为空则 /avatar/build 返回失败提示) |
| `render` | 化身帧序列预渲染(Node + headless-gl |
| `cps` | 美团/京东/淘宝联盟(key 全空则联盟入口优雅降级隐藏) |
| `ad` | 广告激励限频(自然日):`effect_extra` 2 次 / `vip_trial` 1 次 |
@@ -57,7 +56,7 @@ npm run dev:h5
| slogan_user_photo | 用户照片(type: 1 大头照 / 2 全身正面 / 3 全身侧面 / 4 全身背面) |
| slogan_wardrobe_item | 衣橱单品(分类/季节/风格标签/颜色) |
| slogan_body_measurement | 身形参数(身高/体重/三围/肩宽/肤色) |
| slogan_avatar_model | 3D 化身(Tripo 构建状态 + GLB/帧序列 URL |
| slogan_avatar_model | 3D 化身(Tripo 构建状态 + GLB URL |
| slogan_scoring_rule | 方案评分规则(5 维权重,可配置) |
| slogan_partner_store | 合作门店(形象设计/服装门店) |
@@ -108,7 +107,7 @@ npm run dev:h5
| 身形 | `POST /body-measurement/save` | 保存身形参数(身高/体重/三围/肩宽/肤色) | |
| 身形 | `GET /body-measurement/get` | 查询身形参数 | |
| 化身 | `POST /avatar/build` | 构建 3D 化身(Tripo 图像转 3D,异步) | |
| 化身 | `GET /avatar/get` | 我的化身(GLB/帧序列/构建状态) | |
| 化身 | `GET /avatar/get` | 我的化身(GLB/构建状态) | |
| 发型 | `GET /hairstyle/list` | 发型资产库 | 是 |
| 穿搭 | `POST /outfit/generate` | 生成穿搭方案(异步任务) | |
| 穿搭 | `GET /outfit/task/status` | 任务状态 | |
@@ -148,8 +147,8 @@ pending → planning(天气获取 → 规则预筛 3 套候选 → LLM 规划
- 效果图次数可通过广告激励补充(`/ad/reward/claim``effect_extra` 自然日 2 次)
### 3D 化身
- 基于三视角全身照(正面/侧面/背面)→ Tripo 图像转 3D 生成 GLB → 本地 Nodeheadless-gl)渲染 36 帧旋转预览
- 构建为异步任务,`GET /avatar/get` 轮询状态;服务重启未完成任务标记失败
- 基于三视角全身照(正面/侧面/背面)→ Tripo 图像转 3D 生成 GLB(异步任务,`GET /avatar/get` 轮询状态;服务重启未完成任务标记失败)
- 展示端为前端 three.js 渲染(H5):GLTFLoader 加载 GLB,包围盒居中 + 相机自适应,空闲自动旋转,触摸/鼠标拖拽全角度旋转;非 H5 端提示"数字人仅支持 H5 查看"
### 会员支付
- 套餐下单 → 虎皮棋聚合支付(alipay/wechat)→ `pay_url` 拉起支付 → 前端轮询订单状态 → 回调 `/member/order/notify` 幂等更新会员
@@ -175,11 +174,10 @@ server/
agent/ LLM 调用(OpenAI 兼容)+ 方案规划/兜底 + 万相出图
scoring/ 规则评分引擎(零 LLM 成本)
weather/ 和风天气 + 高德地理编码
avatar/ Tripo 3D 客户端 + GLB 帧渲染
avatar/ Tripo 3D 客户端(图像转 3D + GLB 下载)
cps/ 三联盟客户端(美团/京东/淘宝)
consts/ 常量(表名/状态/数据库组)
scripts/ avatar-renderGLB 帧渲染,Dockerfile 依赖
app-uni/ uni-app (Vue3) 多端工程
app-uni/ uni-app (Vue3) 多端工程(three.js 化身 3D 展示
```
## 部署
Binary file not shown.
Binary file not shown.
@@ -5,7 +5,6 @@ import (
"slogan-agent/common"
"slogan-agent/styleagent/consts"
"slogan-agent/styleagent/model/entity"
"strings"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/frame/g"
@@ -34,12 +33,6 @@ func init() {
if err != nil {
g.Log().Warningf(ctx, "create avatar_model table failed: %v", err)
}
// 旧库补列(CREATE TABLE IF NOT EXISTS 不给已存在表加列,忽略 duplicate column 错误)
if _, err := g.DB().Exec(ctx, "ALTER TABLE "+consts.TableNameAvatarModel+" ADD COLUMN frames_url TEXT NOT NULL DEFAULT ''"); err != nil {
if !strings.Contains(err.Error(), "duplicate column") {
g.Log().Warningf(ctx, "alter avatar_model add frames_url failed: %v", err)
}
}
}
func (d *avatarModelDao) Insert(ctx context.Context, data *entity.AvatarModel) (int64, error) {
@@ -22,7 +22,6 @@ type AvatarGetRes struct {
BodyTemplateId int `json:"body_template_id"`
SkinToneIndex int `json:"skin_tone_index"`
GlbUrl string `json:"glb_url"`
FramesUrl string `json:"frames_url"`
BuildStatus string `json:"build_status"`
Error string `json:"error"`
}
@@ -10,7 +10,6 @@ type AvatarModel struct {
SkinToneIndex int `orm:"skin_tone_index" json:"skin_tone_index"`
FaceTextureUrl string `orm:"face_texture_url" json:"face_texture_url"`
GlbUrl string `orm:"glb_url" json:"glb_url"`
FramesUrl string `orm:"frames_url" json:"frames_url"`
BuildStatus string `orm:"build_status" json:"build_status"`
Error string `orm:"error" json:"error"`
ParamsSnapshot string `orm:"params_snapshot" json:"params_snapshot"`
@@ -67,7 +67,7 @@ func (s *avatarService) Build(ctx context.Context, userId int64) (*dto.AvatarBui
}
if err := dao.AvatarModel.Update(ctx, existing.Id, map[string]any{
"face_template_id": 0, "body_template_id": 0, "skin_tone_index": 0,
"glb_url": "", "frames_url": "",
"glb_url": "",
"build_status": consts.AvatarBuildProcessing, "error": "",
"params_snapshot": snapshot,
}); err != nil {
@@ -202,7 +202,7 @@ func (s *avatarService) Get(ctx context.Context, userId int64) (*dto.AvatarGetRe
}
return &dto.AvatarGetRes{
FaceTemplateId: a.FaceTemplateId, BodyTemplateId: a.BodyTemplateId,
SkinToneIndex: a.SkinToneIndex, GlbUrl: a.GlbUrl, FramesUrl: a.FramesUrl,
SkinToneIndex: a.SkinToneIndex, GlbUrl: a.GlbUrl,
BuildStatus: a.BuildStatus, Error: a.Error,
}, nil
}
+5 -4
View File
@@ -42,7 +42,7 @@ SQLite 无 WAL 并发写,写一律回主 goroutine;跨表数据拆多条单
| slogan_user_photo | user_id/type/url/status | type: 1 大头照 2 正面 3 侧面 4 背面;(user_id,type) 唯一,重复上传覆盖 |
| slogan_wardrobe_item | user_id/photo_url/name/category/season/style_tags/color_info | category: 上衣/下装/鞋/配饰 |
| slogan_body_measurement | user_id/height/weight/bust/waist/hip/shoulder/skin_tone/fit_params | 每用户一行 |
| slogan_avatar_model | user_id/glb_url/frames_url/build_status/params_snapshot | 每用户一行;params_snapshot 存构建参数 JSON |
| slogan_avatar_model | user_id/glb_url/build_status/params_snapshot | 每用户一行;params_snapshot 存构建参数 JSONGLB 由前端 three.js 直接加载 |
| slogan_scoring_rule | dimension/rule_type/rules_json/enabled | 评分规则(5 维权重、效果图限次),seed 数据 |
| slogan_partner_store | name/type/lat/lng/address/commission_policy | 合作门店,seed 4 家 |
@@ -112,13 +112,14 @@ POST /outfit/plan/select-main → 置 main_flag → 触发 front/side/back 三
```
POST /avatar/build(用户维度 WithLock 防重复构建)
→ 校验三视角照片齐全(type 2/3/4+ config 已配 tripo_api_key
→ 落库 build_status=pending → 提交协程池
→ 落库 build_status=processing → 提交协程池
→ Tripo 图像转 3Dv2.5-20250123,多视角图 → GLB)→ 轮询任务(5s,上限 900s)
成功后本地渲染 36 帧旋转预览(Node + headless-glrender.node_bin)→ frames_url → done
下载 GLB 到 workspace/avatar/{user}/avatar.glb → done
```
- 构建结果经 `GET /avatar/get` 轮询(前端 2s × 30);重启未完成任务标记 failed
- 帧序列目录:`workspace/avatar_frames/{user}/frame_001.png...`GLB`workspace/avatar/{user}.glb`
- **展示端为前端 three.js 渲染**H5):GLTFLoader 加载 GLB,包围盒居中 + 相机自适应,空闲自动旋转,触摸/鼠标拖拽全角度旋转;非 H5 端提示"数字人仅支持 H5 查看"
- GLB 路径:`workspace/avatar/{user}/avatar.glb`
### 4.4 会员支付(虎皮棋聚合支付)