feat(models): 模型一律转 VRM(契约 0.5.0)+ 可用性门槛 + 管理端版本号展示
按《DSH 开发文档 v1.6》4.9 与第十一章实现,Web 端第一步:
1. 契约先行(先改 contracts/ 再同步三端):
* model-formats.md -> 0.5.0:模型主力格式改为 VRM,所有上传模型一律转 VRM
(.pmx/.fbx: assimp -> GLB -> VRM;glb/gltf: 包装为 VRM);
新增 humanoid 硬门槛与"不达标回退 GLB + usable=false"的交付表;
* data-models.md -> 0.5.0:Model 新增 usable / unusableReason,明确
usable=false 不进入 catalog/export;format 说明改为主力 vrm;
* VERSION 与 contract-versions.ts 同步(三端契约文件逐字节一致)。
2. 实现:
* MODEL_CONVERT_FORMAT 默认改为 vrm(deploy/.env.example 同步);
* 新增 isUsableModel()/unusableReason():usable 等价于"已产出 VRM",
原因从 stats 里带出 humanoid 覆盖度;
* catalog/export 与 catalog/version 指纹都只统计 format=vrm 的已发布模型,
resolveDefaultModelId 同样只在可用模型中选;
* 管理端:模型列表与审核面板显示「不可用」及原因;
* 管理端左下角展示当前版本号(构建期从 web-server/package.json 注入
__APP_VERSION__,与 GET /health 同源),并去掉写死的"契约 rest-api 0.1.0"。
3. 测试:新增 test/model-usability.spec.ts 5 项;规模 16 文件 / 225 项。
4. 版本 0.3.0。
This commit is contained in:
@@ -2,7 +2,7 @@ import { Injectable } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { createHash } from 'node:crypto';
|
||||
import { Repository } from 'typeorm';
|
||||
import { PublishStatus } from '../common/enums';
|
||||
import { ModelFormat, PublishStatus } from '../common/enums';
|
||||
import { AppConfig } from '../config/configuration';
|
||||
import { CharacterModel } from '../entities/model.entity';
|
||||
import { Motion } from '../entities/motion.entity';
|
||||
@@ -43,7 +43,11 @@ export class CatalogService {
|
||||
const [songs, motions, models] = await Promise.all([
|
||||
this.songs.find({ where: { status: PublishStatus.Published }, order: { id: 'ASC' } }),
|
||||
this.motions.find({ where: { status: PublishStatus.Published }, order: { id: 'ASC' } }),
|
||||
this.models.find({ where: { status: PublishStatus.Published }, order: { id: 'ASC' } }),
|
||||
// v0.5.0:只交付**已产出 VRM** 的模型(usable),未产出 VRM 的不进入客户端目录
|
||||
this.models.find({
|
||||
where: { status: PublishStatus.Published, format: ModelFormat.Vrm },
|
||||
order: { id: 'ASC' },
|
||||
}),
|
||||
]);
|
||||
|
||||
const [songDtos, motionDtos, modelDtos, defaultModelId] = await Promise.all([
|
||||
@@ -71,7 +75,11 @@ export class CatalogService {
|
||||
const [songs, motions, models] = await Promise.all([
|
||||
this.songs.find({ where: { status: PublishStatus.Published }, order: { id: 'ASC' } }),
|
||||
this.motions.find({ where: { status: PublishStatus.Published }, order: { id: 'ASC' } }),
|
||||
this.models.find({ where: { status: PublishStatus.Published }, order: { id: 'ASC' } }),
|
||||
// v0.5.0:只交付**已产出 VRM** 的模型(usable),未产出 VRM 的不进入客户端目录
|
||||
this.models.find({
|
||||
where: { status: PublishStatus.Published, format: ModelFormat.Vrm },
|
||||
order: { id: 'ASC' },
|
||||
}),
|
||||
]);
|
||||
|
||||
const fingerprint = JSON.stringify({
|
||||
|
||||
Reference in New Issue
Block a user