62 lines
1.9 KiB
Markdown
62 lines
1.9 KiB
Markdown
# T-WEB-005 模型上传 + VRM 优先 + 来源字段
|
||
|
||
- **状态**:done
|
||
- **依赖**:T-WEB-002
|
||
|
||
## 目标
|
||
|
||
上传角色模型,**VRM 优先**,识别 VRM 版本,并维护全局默认模型。
|
||
|
||
## load
|
||
|
||
```
|
||
DSH.md
|
||
contracts/rest-api.yaml # 锚点:#/paths/~1api~1models
|
||
contracts/data-models.md # 锚点:§4 Model、§4.1 VRM 优先规则
|
||
contracts/model-formats.md # 锚点:§1 角色模型
|
||
web-server/src/models/*
|
||
web-server/src/models/vrm-inspector.ts
|
||
```
|
||
|
||
## 端点
|
||
|
||
| 方法 | 路径 | 说明 |
|
||
|---|---|---|
|
||
| GET | `/api/models` | 分页 + `q`/`format`/`status`/`primaryOnly` |
|
||
| POST | `/api/models` | multipart 上传(`file` + 名称 + 来源五元组 + `isPrimary`) |
|
||
| GET | `/api/models/:id` | 详情 |
|
||
| PATCH | `/api/models/:id` | 更新 |
|
||
| DELETE | `/api/models/:id` | 软删除 |
|
||
| POST | `/api/models/:id/primary` | 设为全局默认模型 |
|
||
|
||
## VRM 优先规则(`contracts/data-models.md` §4.1,已实现于 `resolveDefaultModelId()`)
|
||
|
||
```
|
||
1. 显式 modelId(客户端侧)
|
||
2. format='vrm' 且 published 且 is_primary=1
|
||
3. format='vrm' 且 published,按 id 升序取第一个
|
||
4. published,按 (format='vrm' DESC, id ASC) 取第一个
|
||
5. 无 → 客户端使用内置占位模型
|
||
```
|
||
|
||
`POST /:id/primary` 在**同一事务**内先清零其余 `is_primary`,保证互斥。
|
||
|
||
## VRM 版本识别
|
||
|
||
`vrm-inspector.ts` 直接读取 GLB 头部 JSON chunk,不依赖完整 3D 库:
|
||
|
||
- `extensions.VRMC_vrm` → VRM **1.0**(取 `specVersion`)
|
||
- `extensions.VRM` → VRM **0.x**
|
||
- 两者皆无 → `null`(普通 GLB)
|
||
|
||
## 验收
|
||
|
||
```bash
|
||
npm run test # test/vrm-inspector.spec.ts,6 例
|
||
npm run test:smoke # 冒烟 [4] 段落
|
||
```
|
||
|
||
覆盖:真实 GLB 构造下识别 1.0 / 0.0 / null、文本 glTF 不误判、过小文件报错、
|
||
非 JSON 首 chunk 报错、上传 201、`isPrimary` 置位、缺来源 400、按格式过滤列表、
|
||
列表含来源信息(管理端展示用)。
|