依据 Gitea v1.27.3 modules/charset/escape_stream.go 的判定规则 (analyzeDetectResults:仅当左右相邻字符都不是非 ASCII 时才标记, 且 _common 表恒定生效),把说明文档中会被标记的全角标点 (,:;?!() 等)改为半角,并保证成对括号宽度一致。 中文语境中的全角标点(左右均为中文)保持原样,不动代码与契约语义。 同时删除临时探针目录 _probe/(仅用于确认 Gitea 判定规则)。
2.9 KiB
2.9 KiB
T-WEB-004 动作数据上传 + 来源字段
- 状态: done
- 依赖: T-WEB-002
目标
上传动作文件(BVH / VMD / FBX / glTF / GLB / keypoints-json),强制填写来源五元组。
load
DSH.md
contracts/rest-api.yaml # 锚点:#/paths/~1api~1motions
contracts/data-models.md # 锚点:3 Motion
contracts/model-formats.md # 锚点:2 动作格式、3 上传限制
web-server/src/motions/*
web-server/src/storage/storage.service.ts
web-server/src/preprocess/vmd-parser.ts # VMD 上传后的预处理链路
web-server/src/preprocess/mmd-skeleton.ts
web-server/src/preprocess/mmd-pose.ts
web-server/src/preprocess/retarget.ts # worldFramesToKeypointFrames()
端点
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /api/motions |
分页 + q/songId/format/status 过滤 |
| POST | /api/motions |
multipart 上传 |
| GET | /api/motions/:id |
详情 |
| PATCH | /api/motions/:id |
更新元数据(含 detachSong) |
| DELETE | /api/motions/:id |
软删除 |
存储策略(contracts/model-formats.md 3)
${STORAGE_DIR}/{kind}/{yyyy}/{mm}/{sha256前2位}/{sha256}.{ext}
- 上传先落
${STORAGE_DIR}/tmp(multer diskStorage),避免大文件占用内存 StorageService流式计算 sha256; 相同内容只落盘一次,复用assets记录- 并发同文件上传靠
assets.sha256唯一索引兜底,冲突后回退到已存在记录 - 路径永不使用原始文件名;
absolutePath()拒绝逃逸存储根目录
校验
- 扩展名白名单:
.bvh.vmd.fbx.gltf.glb.json,其他 -> 400 - 来源五元组缺任一项 -> 400
songId指向不存在的曲目 -> 400- 单文件上限
UPLOAD_MAX_BYTES(默认 512 MiB)
VMD 支持(.vmd)
- 管理端上传控件已支持
.vmd(accept、格式筛选、中文标签「VMD(MMD)」) - 入库后
format=vmd;预处理走内置链路,不依赖 Assimp:vmd-parser.ts(二进制 + Shift-JIS + 贝塞尔插值)->mmd-skeleton.ts(标准骨架) ->mmd-pose.ts(FK + 腿部 IK + Z 镜像)->retarget.ts的worldFramesToKeypointFrames()(与 BVH 共用骨盆归零 / 自适应缩放 / 投影 / 关节角) - 固定 30 fps;腿部按
足IK是否带位移自动选 IK 或 FK - 上传后处理失败与 BVH 一致:写入
preprocessState=failed与可读错误
验收
npm run test:smoke
冒烟 [2] 段落:上传 201、自动识别 format=bvh、fileSize 记录、缺来源 400、
evil.exe 400。
VMD 实测(用 ../示例文件/ 下的两个样本):
| 样本 | 帧数 | 腿部驱动 | 结果 |
|---|---|---|---|
【动作】霜雪千年.vmd(0.79 MiB) |
2901 | 足IK 驱动(IK) |
0 NaN / 0 越界,预处理约 0.4s |
恋爱循环.vmd(20.24 MiB) |
4604 | 烘焙 FK | 0 NaN / 0 越界,预处理约 2.5s |
上传前可先用诊断工具自查(只读):
node scripts/inspect-vmd.mjs 动作.vmd [--frames N] [--json out.json]