From 2dfb60a34e7a3cc374051eabfa551987647861b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=BE=B7=E5=AE=87?= Date: Thu, 24 Sep 2026 19:51:25 +0800 Subject: [PATCH] =?UTF-8?q?=E6=A0=BC=E5=BC=8F=E5=88=A4=E5=AE=9A=E7=9A=84?= =?UTF-8?q?=E6=B3=A8=E9=87=8A=E4=B8=8E=E6=96=87=E6=A1=A3=E6=94=B9=E6=88=90?= =?UTF-8?q?=E3=80=8C=E4=BF=A1=E4=BB=BB=E5=90=8E=E7=AB=AF=E7=9A=84=E6=A3=80?= =?UTF-8?q?=E6=B5=8B=E7=BB=93=E6=9E=9C=E3=80=8D=EF=BC=8C=E4=B8=8D=E5=86=8D?= =?UTF-8?q?=E8=AF=B4=E9=AD=94=E6=95=B0=E7=BA=A0=E6=AD=A3=E9=94=99=E8=AF=AF?= =?UTF-8?q?=E5=A3=B0=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - packages/model3d-viewer:`resolveModel3dViewerFormat` 与字节识别函数的注释改写——声明优先是因为后端的 `content_type` 写入前已按字节核过,魔数只在声明缺失或认不出来时兜住,不负责纠错一个认得出来但不对的声明 - docs/technical Tripo 集成方案:补上同一条口径,与实现里「声明 → 字节魔数 → 地址扩展名」的顺序对齐 行为不变,只改注释与文档。 --- .../【技术方案】Tripo 3D生成API集成-2026-09-21.md | 2 +- packages/model3d-viewer/src/loader.ts | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/docs/technical/【技术方案】Tripo 3D生成API集成-2026-09-21.md b/docs/technical/【技术方案】Tripo 3D生成API集成-2026-09-21.md index 0b0c7aa9d..0710e599c 100644 --- a/docs/technical/【技术方案】Tripo 3D生成API集成-2026-09-21.md +++ b/docs/technical/【技术方案】Tripo 3D生成API集成-2026-09-21.md @@ -162,7 +162,7 @@ thumbnailSrc = 预览图 width/height = 预览图像素尺寸 ``` -模型格式与体积由 `AssetObject` 承担(`content_type`、`content_length`、`content_hash`),因此不新增 `model_format`、`size_bytes`、`poly_count` 等列。两个槽位的 `content_type` 都在写入前按字节识别真实产物:模型按魔数认 GLB 的 `glTF` 头、FBX 的 `Kaydara FBX Binary` 头与 glTF 的 JSON 正文,预览按魔数认 PNG / JPEG / WebP;不直接采信 provider 返回或下载响应头声明的类型,对象键扩展名由该内容类型派生。只有字节判不出来时才采信声明值,且声明值必须落在该槽位的白名单内(模型:`model/gltf-binary`、`model/gltf+json`、`model/fbx`、`application/x-fbx`;预览:`image/png`、`image/jpeg`、`image/jpg`、`image/webp`);两边都对不上就直接按上游内容不合法失败并退款,不做任何兜底 —— 放行 `text/plain` 这类未知类型只会落成「错的 content type + 拼出来的扩展名」。客户端不复制这份格式清单:画布只按「`assetKind=model3d` 且 `objectKey` 非空」放行,能否交给 3D 查看器由 `packages/model3d-viewer` 判定,判据依次是读接口声明的 `Content-Type`、字节魔数、地址扩展名,全判不出来即按 `unsupported-format` 报错。 +模型格式与体积由 `AssetObject` 承担(`content_type`、`content_length`、`content_hash`),因此不新增 `model_format`、`size_bytes`、`poly_count` 等列。两个槽位的 `content_type` 都在写入前按字节识别真实产物:模型按魔数认 GLB 的 `glTF` 头、FBX 的 `Kaydara FBX Binary` 头与 glTF 的 JSON 正文,预览按魔数认 PNG / JPEG / WebP;不直接采信 provider 返回或下载响应头声明的类型,对象键扩展名由该内容类型派生。只有字节判不出来时才采信声明值,且声明值必须落在该槽位的白名单内(模型:`model/gltf-binary`、`model/gltf+json`、`model/fbx`、`application/x-fbx`;预览:`image/png`、`image/jpeg`、`image/jpg`、`image/webp`);两边都对不上就直接按上游内容不合法失败并退款,不做任何兜底 —— 放行 `text/plain` 这类未知类型只会落成「错的 content type + 拼出来的扩展名」。客户端不复制这份格式清单:画布只按「`assetKind=model3d` 且 `objectKey` 非空」放行,能否交给 3D 查看器由 `packages/model3d-viewer` 判定,判据依次是读接口声明的 `Content-Type`、字节魔数、地址扩展名,全判不出来即按 `unsupported-format` 报错。这里的顺序是「信任后端的检测结果」:`content_type` 在后端写入前已经按字节核过,所以客户端以声明为先;字节魔数只兜住声明缺失或认不出来(例如 `application/octet-stream`)的情况,不负责纠正一个「认得出来但不对」的声明。 `external_generation_job.phase` 的取值集合不变,仍只允许现有两种执行阶段;阶段文案由 api-server 映射,不扩展 schema 常量。 diff --git a/packages/model3d-viewer/src/loader.ts b/packages/model3d-viewer/src/loader.ts index 7b122b6db..2e9264811 100644 --- a/packages/model3d-viewer/src/loader.ts +++ b/packages/model3d-viewer/src/loader.ts @@ -105,7 +105,7 @@ export function resolveModel3dViewerFormatFromMimeType( ); } -/** 按字节魔数识别格式;声明不可信时以它为准,识别不出返回 null。 */ +/** 按字节魔数识别格式;声明缺失或认不出来时才轮到它,识别不出返回 null。 */ export function resolveModel3dViewerFormatFromBytes( bytes: ArrayBuffer | Uint8Array, ): Model3DViewerFormat | null { @@ -139,8 +139,10 @@ export function resolveModel3dViewerFormatFromUrl( /** * 模型格式的判定顺序:声明 → 字节魔数 → 地址扩展名。 * - * 声明(响应内容类型 / OSS metadata / `asset_object.content_type`)是主线索,魔数兜住 - * 写歪的声明,扩展名是同源派生出来的最后一条线索。三处都判不出就返回 null,由加载流程 + * 声明(响应内容类型 / OSS metadata / `asset_object.content_type`)优先:后端的 + * `content_type` 在写入前已经按字节核过,客户端信任这份检测结果,不再自己纠正一个 + * 「认得出来但不对」的声明。魔数只在声明缺失或认不出来(例如 `application/octet-stream`) + * 时兜住,扩展名是同源派生出来的最后一条线索。三处都判不出就返回 null,由加载流程 * 报 `unsupported-format`,宿主把原因显示给用户 —— 不猜、不半渲染。 */ export function resolveModel3dViewerFormat({