feat(scenes): 场景管理后端 + 契约 0.5.0/0.7.0/0.4.0(T-WEB-015)
契约先行(三端逐字节一致,已同步 windows/android):
- rest-api -> 0.5.0:新增 GET/POST /api/scenes、GET/PATCH/DELETE /api/scenes/{id}
- data-models -> 0.7.0:新增 §7 Scene 与 7.1 SceneConfig(物理/环境/出生点/相机)
- database -> 0.4.0:新增 scenes 表(config/stats 用 MEDIUMTEXT,迁移可逆)
后端:
- entities/scene.entity.ts + 迁移 AddScenes1789650000000(scenes 表)
- scenes/scene-config.ts:SceneConfig 定义 + 默认值 + **边界收敛**(越界夹紧、
非法枚举回退),保证客户端拿到的参数一定可解释;服务端只存参数不跑物理
- scenes/scenes.service.ts:上传(.glb/.gltf 直接导入;.zip/.pmx/.fbx 转 GLB,
场景不做 humanoid 重绑定、不转 VRM)、列表/详情/更新/软删除、缩略图复用模型
光栅化器、分析复用模型检查器、config 同时接受 JSON 字符串与平铺字段
- scenes/scenes.controller.ts + scenes.module.ts(app.module 注册)
- 审核复用 /api/reviews/:type/:id:TargetType.Scene 接入待审列表与状态流转
- catalog/export 增 scenes[],目录指纹纳入场景变更
- 枚举:TargetType.Scene、AssetKind.Scene / SceneThumbnail
测试:新增 test/scene-config.spec.ts 6 项(默认值/夹紧/枚举回退/出生点上限/颜色/
序列化);规模 19 文件 / 243 项;check-routes 35 条一致。版本 0.6.0。
注:管理端场景页(GLB 预览 + 物理参数可视化)与 Windows 场景选择留待下一轮。
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
import { MigrationInterface, QueryRunner } from "typeorm";
|
||||
|
||||
/**
|
||||
* 场景管理(T-WEB-015,契约 database 0.4.0 / data-models 0.7.0)。
|
||||
*
|
||||
* 场景以 **GLB 为主**:`glb_asset_id` 指向存储里的场景文件;
|
||||
* `config` 存物理参数(重力 / 风向动态 / 地面 / 碰撞体)与环境、出生点、相机;
|
||||
* `stats` 复用模型检查器的分析结果。服务端**只存参数、不跑物理**。
|
||||
*/
|
||||
export class AddScenes1789650000000 implements MigrationInterface {
|
||||
name = 'AddScenes1789650000000'
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`
|
||||
CREATE TABLE \`scenes\` (
|
||||
\`id\` bigint NOT NULL AUTO_INCREMENT,
|
||||
\`name\` varchar(200) NOT NULL,
|
||||
\`glb_asset_id\` bigint NULL,
|
||||
\`thumbnail_asset_id\` bigint NULL,
|
||||
\`config\` mediumtext NULL,
|
||||
\`stats\` mediumtext NULL,
|
||||
\`file_size\` bigint NULL,
|
||||
\`file_sha256\` varchar(64) NULL,
|
||||
\`conversion_note\` varchar(500) NULL,
|
||||
\`source_type\` varchar(32) NOT NULL,
|
||||
\`source_name\` varchar(200) NOT NULL,
|
||||
\`source_url\` varchar(500) NOT NULL,
|
||||
\`license\` varchar(100) NOT NULL,
|
||||
\`author\` varchar(200) NOT NULL,
|
||||
\`status\` varchar(16) NOT NULL DEFAULT 'pending',
|
||||
\`created_at\` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
\`updated_at\` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
\`deleted_at\` datetime NULL,
|
||||
INDEX \`idx_scenes_status\` (\`status\`),
|
||||
PRIMARY KEY (\`id\`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
||||
`);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`DROP TABLE \`scenes\``);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user