feat(admin): 场景管理页——列表/上传/物理参数编辑 + 3D 预览(T-WEB-015 补齐)

- 新增 admin/src/pages/Scenes.tsx(路由 /scenes + 侧栏「场景管理」入口):
  * 列表:40px 缩略图(点击进详情)、物理摘要、体积、状态、软删除;
  * 上传表单:GLB 文件 + 名称 + 来源五元组 + 物理参数(重力、风基础向量、
    阵风幅度/频率、地面摩擦/坡度、碰撞体、环境光),multipart 走 POST /api/scenes;
  * 详情:复用 VrmPreview(懒加载 three.js 分包)预览场景 GLB + 参数可视化编辑
    并通过 PATCH /api/scenes/:id 保存;
- 新增 admin/src/lib/scene-physics.ts:DEFAULT_SCENE_CONFIG(与契约 7.1、服务端
  scene-config.ts 单一真源,测试断言两端一致)与 physicsSummary();
- 场景页两栏自适应样式;types/endpoints 补齐场景五接口。
- 测试:场景用例增至 9 项;规模 19 文件 / 245 项。版本 0.7.0。
This commit is contained in:
opendance
2026-09-17 00:32:05 +08:00
parent 584b7eaca9
commit f2e231c0b2
13 changed files with 821 additions and 21 deletions
+32
View File
@@ -1,6 +1,7 @@
import { describe, expect, it } from 'vitest';
import { normalizeSceneConfig, SCENE_CONFIG_DEFAULTS } from '../src/scenes/scene-config';
import { DEFAULT_SCENE_CONFIG, physicsSummary } from '../admin/src/lib/scene-physics';
import { toSceneDto } from '../src/scenes/scene.serializer';
import { PublishStatus, SourceType } from '../src/common/enums';
import type { Scene } from '../src/entities/scene.entity';
@@ -105,3 +106,34 @@ describe('SceneDto 序列化', () => {
expect(dto.createdAt).toBe('2026-01-01T00:00:00.000Z');
});
});
describe('场景列表的物理摘要(管理端)', () => {
it('展示重力与风速,并在有阵风时标注幅度/频率', () => {
const calm = physicsSummary(normalizeSceneConfig(undefined));
expect(calm).toContain('重力 -9.8');
expect(calm).toContain('风 0.0m/s');
expect(calm).not.toContain('阵风');
const windy = physicsSummary(
normalizeSceneConfig({
physics: {
wind: {
base: { x: 3, y: 0, z: 4 },
gustAmplitude: 2.5,
gustFrequency: 0.5,
},
},
}),
);
expect(windy).toContain('风 5.0m/s');
expect(windy).toContain('阵风 2.5m/s@0.5Hz');
});
it('没有 config 时显示占位符(不抛错)', () => {
expect(physicsSummary(null)).toBe('—');
});
it('管理端默认值与服务端一致(契约 7.1 单一真源)', () => {
expect(DEFAULT_SCENE_CONFIG).toEqual(SCENE_CONFIG_DEFAULTS);
});
});