需求 1:系统确定以 GLB / VRM 为模型主力格式
- 服务端新增支持库:
- model-inspector.ts:解析 GLB/VRM 的面数、顶点、材质、贴图、形变目标、
**骨骼树(名称/层级/是否蒙皮/humanoid 映射/子节点数)**、humanoid 覆盖率与可驱动性
- model-thumbnail.ts:**纯 TS 软件光栅化**(z-buffer + Lambert + 完整蒙皮矩阵)
生成 512×512 PNG 缩略图,零原生依赖、不装 headless-gl
- vrm-writer.ts:GLB → VRM 1.0(写入 VRMC_vrm 扩展与 humanoid 映射)
- gltf-packer.ts:glTF(.gltf + .bin + 贴图)→ 单文件 GLB
- humanoid 候选表与 Godot 客户端 humanoid_map.gd **逐字对齐**,并有单测断言两边一致
(服务端判定的"可驱动" = 客户端实际能否驱动)
需求 2:模型管理
- .glb / .vrm / .gltf **直接导入**(不重编码,GLB 含 VRM 扩展会自动识别为 VRM)
- .pmx / .fbx 服务端转换:assimp → .glb →(失败)→ .gltf 后自行打包成 GLB
→(MODEL_CONVERT_FORMAT=vrm 时)补 VRMC_vrm 产出 VRM 1.0;每步 assimp info 回读校验
- .zip **自动搜索包内可用模型**:.vrm → .glb → .gltf(直接导入)优先,
其次 .pmx → .fbx(转换);同优先级内按"指名字 → 目录最浅 → 文件最大"
- 入库后自动分析(models.stats)与生成缩略图(models.thumbnail_asset_id),
失败均不阻断入库;管理端列表显示小缩略图、预览放开到 vrm/glb/gltf
需求 3:审核功能
- 上传的模型状态**一律 pending**(不再自动发布、不再自动设默认)
- 审核界面新增模型面板:体积、面数、顶点、材质、贴图、骨骼、形变目标等指标,
humanoid 覆盖进度、可驱动性结论(缺哪些必需骨骼)、warnings,以及
**骨骼详细预览**(层级缩进、蒙皮/Humanoid 徽章、子节点数、搜索保留祖先链、
仅看蒙皮、限高滚动 + 只渲染前 400 行)
- 审核通过可带 setPrimary=true 一并设为默认模型(此时才写源码种子);
POST /api/models/:id/primary 仅允许 published(否则 409)
- scripts/import-default-model.mjs 改为"上传 → 审核通过 + 设默认"流程
其它:
- models 新增 stats 列(迁移 AddModelStats1789460000000,已在真实库执行)
- 契约升至 rest-api/data-models/model-formats 0.4.0、database 0.3.0(另两库已同步)
- 版本号 0.1.0 → 0.2.0(package.json ×2 + lockfile + project.yaml)
- 文档:README.txt / DSH.md / project.yaml / tasks 005·007·010 全面更新;
顶层开发书更新为 v1.4
验证:168 项单测通过(10 文件);契约 6 项与 29 条路由一致;typecheck/build 通过;
真实端到端:MMD 压缩包 → GLB + 分析(面数 9071/骨骼 238/humanoid 0-22) + 缩略图(15KB PNG);
GLB 直接导入 sha256 与源文件一致;审核通过后 defaultModelId 由 VRM 变为该模型
66 lines
2.7 KiB
Markdown
66 lines
2.7 KiB
Markdown
# contracts/database.md — 数据库契约 v0.1.0
|
||
|
||
## 环境
|
||
|
||
- 类型:MySQL 兼容实例(外部提供)。**当前部署实际为 MariaDB 10.11.19**,TypeORM
|
||
使用 `mysql` driver(`mysql2`)连接,SQL 语法限制在 MySQL 5.7 / MariaDB 10.5+
|
||
共同子集内,不使用 MySQL 8 专有语法(窗口函数 CTE 递归除外)。
|
||
- 数据库名:`dpendance`(由部署方提供,通过 `DB_NAME` 注入;文档默认值 `opendance` 可覆盖)
|
||
- 字符集:`utf8mb4` / `utf8mb4_general_ci`(沿用现有实例默认排序规则)
|
||
- 迁移工具:TypeORM migration,**不使用 `DB_SYNCHRONIZE`**
|
||
|
||
## 连接信息(由部署方提供)
|
||
|
||
host / port / user / password 一律通过环境变量注入,**不入库、不入仓**。
|
||
|
||
```bash
|
||
DB_HOST=192.168.150.10
|
||
DB_PORT=3306
|
||
DB_USER=dpendance
|
||
DB_PASS=<部署方提供>
|
||
DB_NAME=dpendance
|
||
DB_SYNCHRONIZE=false
|
||
DB_LOGGING=false
|
||
```
|
||
|
||
## 约定
|
||
|
||
- 所有表名使用 `snake_case`,复数形式(`songs` / `motions` / `models`)
|
||
- 主键统一为 `BIGINT AUTO_INCREMENT`,字段名 `id`
|
||
- 时间字段统一 `DATETIME`,`created_at` / `updated_at`,`updated_at` 由应用层维护
|
||
- 软删除统一使用 `deleted_at DATETIME NULL`(`@DeleteDateColumn`)
|
||
- 布尔字段使用 `TINYINT(1)`
|
||
- 来源(出处)字段为 5 元组,任何资产入库必须齐备:
|
||
`source_type` / `source_name` / `source_url` / `license` / `author`
|
||
- 不使用 `DB_SYNCHRONIZE`,所有表结构变更走 migration
|
||
- 每个 migration 必须可逆(提供 `down` 方法)
|
||
- 迁移文件名格式:`<timestamp>-<kebab-name>.ts`
|
||
|
||
## 增量迁移(v0.2.0 / v0.3.0)
|
||
|
||
| 迁移 | 变更 |
|
||
|---|---|
|
||
| `AddModelConversionFields` | `models` 增加 `source_asset_id BIGINT NULL`(上传的压缩包,用于溯源)与 `conversion_note VARCHAR(500) NULL`(转换说明,见 model-formats.md §1.1) |
|
||
| `AddModelStats` | `models` 增加 `stats TEXT NULL`(模型分析结果:面数、骨骼树、humanoid 覆盖、可驱动性),供审核界面展示 |
|
||
|
||
## 表清单(v0.1.0)
|
||
|
||
| 表 | 用途 | 任务 |
|
||
|---|---|---|
|
||
| `songs` | 曲目元数据 | T-WEB-003 |
|
||
| `assets` | 上传文件元数据(去重、sha256、物理路径) | T-WEB-004 |
|
||
| `motions` | 动作数据(BVH/FBX…)+ 来源 + 预处理产物 | T-WEB-004 / 006 |
|
||
| `models` | 角色模型(VRM 优先)+ 来源 + 压缩包转换溯源 | T-WEB-005 |
|
||
| `review_records` | 上传审核流水 | T-WEB-007 |
|
||
|
||
## 状态机(`status` 列,v0.1.0)
|
||
|
||
```
|
||
draft ──submit──▶ pending ──approve──▶ published
|
||
│
|
||
└──reject──▶ rejected ──submit──▶ pending
|
||
```
|
||
|
||
- `published` 才可被 Windows 客户端 / Android App 消费
|
||
- `/api/catalog/export` 只导出 `published` 记录
|