From 74f2d052acb8174029d344dfc975614933a5907a Mon Sep 17 00:00:00 2001 From: Your Name Date: Thu, 4 Jun 2026 13:37:05 +0800 Subject: [PATCH] fix: keep psb upload with compatibility errors --- .../psd-templates-settings-client.tsx | 10 +++--- .../admin/psd-templates/[id]/parse/route.ts | 33 ++++++++++++++++--- app/api/admin/psd-templates/route.ts | 14 +++----- lib/agents/psd-template-format.ts | 15 ++++----- 4 files changed, 44 insertions(+), 28 deletions(-) diff --git a/app/(admin)/settings/agent-workflow/psd-templates/psd-templates-settings-client.tsx b/app/(admin)/settings/agent-workflow/psd-templates/psd-templates-settings-client.tsx index daf6b6f66..cb853df57 100644 --- a/app/(admin)/settings/agent-workflow/psd-templates/psd-templates-settings-client.tsx +++ b/app/(admin)/settings/agent-workflow/psd-templates/psd-templates-settings-client.tsx @@ -751,7 +751,7 @@ export function PsdTemplatesSettingsClient({ async function handleCreateTemplate(options?: { parseAfterUpload?: boolean }) { const parseAfterUpload = options?.parseAfterUpload === true; if (!uploadFile) { - toast.error("请先选择 PSD 文件"); + toast.error("请先选择 PSD / PSB 文件"); return; } @@ -2582,8 +2582,8 @@ export function PsdTemplatesSettingsClient({ 上传新模板 - 支持 Photoshop PSD(.psd),建议图层命名清晰,便于后台配置图片位和文字位。PSB - 请先在 Photoshop 中另存为 PSD 后上传。 + 支持 PSD / PSB,建议图层命名清晰,便于后台配置图片位和文字位。复杂 PSB + 如提示不兼容,请先在 Photoshop 中另存为 PSD 后上传。 @@ -2745,11 +2745,11 @@ export function PsdTemplatesSettingsClient({

- {uploadFile ? `已选择:${uploadFile.name}` : "支持 80MB 以内 PSD 文件"} + {uploadFile ? `已选择:${uploadFile.name}` : "支持 80MB 以内 PSD / PSB 文件"}

diff --git a/app/api/admin/psd-templates/[id]/parse/route.ts b/app/api/admin/psd-templates/[id]/parse/route.ts index 2fd7bbcac..db045ea28 100644 --- a/app/api/admin/psd-templates/[id]/parse/route.ts +++ b/app/api/admin/psd-templates/[id]/parse/route.ts @@ -13,8 +13,10 @@ import { import { pickPrimaryPsdImageLayerId } from "@/lib/agents/psd-template-image-slot-selection"; import { schedulePsdTemplateAssetBackfill } from "@/lib/agents/psd-template-asset-backfill"; import { - AGENT_PSD_TEMPLATE_UNSUPPORTED_PSB_MESSAGE, + AGENT_PSD_TEMPLATE_INCOMPATIBLE_PSB_MESSAGE, + AGENT_PSD_TEMPLATE_INVALID_FORMAT_MESSAGE, assertSupportedAgentPsdTemplateFile, + type AgentPsdTemplateFileInspection, } from "@/lib/agents/psd-template-format"; import { createAgentPsdTemplateParseHeartbeat, @@ -55,6 +57,22 @@ function getErrorMessage(error: unknown) { return "PSD 解析失败"; } +function getPsdTemplateParseErrorMessage(params: { + error: unknown; + fileInspection?: AgentPsdTemplateFileInspection; +}) { + const message = getErrorMessage(params.error); + + if ( + params.fileInspection?.format === "psb" && + /invalid signature/i.test(message) + ) { + return AGENT_PSD_TEMPLATE_INCOMPATIBLE_PSB_MESSAGE; + } + + return message; +} + function pickPrimaryImageLayerId(params: { parsedLayers: Awaited>["layers"]; canvasWidth: number; @@ -185,6 +203,7 @@ export async function POST( } const { id } = await context.params; + let fileInspection: AgentPsdTemplateFileInspection | undefined; let latestProgress = { progress: 0, stage: "准备解析 PSD", @@ -289,7 +308,7 @@ export async function POST( } await setParseProgress(22, "正在校验 PSD 文件格式"); - assertSupportedAgentPsdTemplateFile(fileBuffer); + fileInspection = assertSupportedAgentPsdTemplateFile(fileBuffer); await setParseProgress(24, "正在解析 PSD 图层结构与预览"); const parsedTemplate = await parsePsdTemplateFile(fileBuffer, { @@ -361,7 +380,10 @@ export async function POST( throw error; } } catch (error) { - const message = getErrorMessage(error); + const message = getPsdTemplateParseErrorMessage({ + error, + fileInspection, + }); const existingTemplate = (await readAgentPsdTemplates()).find((entry) => entry.id === id); if (existingTemplate) { @@ -400,11 +422,12 @@ export async function POST( fileName: existingTemplate?.fileName, progress: latestProgress.progress, stage: latestProgress.stage, + fileFormat: fileInspection?.format, error, }); return jsonError( - message === AGENT_PSD_TEMPLATE_UNSUPPORTED_PSB_MESSAGE || - message.startsWith("模板文件格式不正确") + message === AGENT_PSD_TEMPLATE_INCOMPATIBLE_PSB_MESSAGE || + message === AGENT_PSD_TEMPLATE_INVALID_FORMAT_MESSAGE ? 400 : 502, message diff --git a/app/api/admin/psd-templates/route.ts b/app/api/admin/psd-templates/route.ts index 07bb06497..0897809c0 100644 --- a/app/api/admin/psd-templates/route.ts +++ b/app/api/admin/psd-templates/route.ts @@ -16,7 +16,7 @@ import { } from "@/lib/agents/psd-template-config"; import { normalizeAgentPsdTemplateCategoryTags } from "@/lib/agents/psd-template-category-tag-config"; import { - AGENT_PSD_TEMPLATE_UNSUPPORTED_PSB_MESSAGE, + AGENT_PSD_TEMPLATE_INVALID_FORMAT_MESSAGE, assertSupportedAgentPsdTemplateFile, } from "@/lib/agents/psd-template-format"; import { cacheAgentPsdSourceLocally } from "@/lib/agents/psd-local-cache"; @@ -26,7 +26,7 @@ import { failTimedOutAgentPsdTemplates } from "@/lib/agents/psd-template-timeout export const runtime = "nodejs"; const MAX_TEMPLATE_FILE_SIZE = 80 * 1024 * 1024; -const ALLOWED_TEMPLATE_EXTENSIONS = new Set(["psd"]); +const ALLOWED_TEMPLATE_EXTENSIONS = new Set(["psd", "psb"]); const PLACEHOLDER_PREVIEW_PNG = Buffer.from( "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO2+p4kAAAAASUVORK5CYII=", "base64" @@ -226,12 +226,7 @@ export async function POST(request: NextRequest) { const extension = getFileExtension(file.name); if (!ALLOWED_TEMPLATE_EXTENSIONS.has(extension)) { - return jsonMutationError( - 400, - extension === "psb" - ? AGENT_PSD_TEMPLATE_UNSUPPORTED_PSB_MESSAGE - : "模板文件仅支持 Photoshop PSD(.psd)" - ); + return jsonMutationError(400, "模板文件仅支持 Photoshop PSD / PSB"); } if (file.size <= 0) { @@ -326,8 +321,7 @@ export async function POST(request: NextRequest) { console.error("[PSD Templates][Admin] create failed:", error); if (error instanceof Error && error.message.trim()) { if ( - error.message === AGENT_PSD_TEMPLATE_UNSUPPORTED_PSB_MESSAGE || - error.message.startsWith("模板文件格式不正确") + error.message === AGENT_PSD_TEMPLATE_INVALID_FORMAT_MESSAGE ) { return jsonMutationError(400, error.message); } diff --git a/lib/agents/psd-template-format.ts b/lib/agents/psd-template-format.ts index 7f3c26165..22d9a4dda 100644 --- a/lib/agents/psd-template-format.ts +++ b/lib/agents/psd-template-format.ts @@ -13,8 +13,11 @@ export interface AgentPsdTemplateFileInspection { colorMode: number; } -export const AGENT_PSD_TEMPLATE_UNSUPPORTED_PSB_MESSAGE = - "当前生产模板解析仅支持 Photoshop PSD(.psd)。检测到 PSB / Large Document 格式,请在 Photoshop 中另存为 PSD 后再上传解析。"; +export const AGENT_PSD_TEMPLATE_INVALID_FORMAT_MESSAGE = + "模板文件格式不正确,请上传 Photoshop PSD / PSB 文件。"; + +export const AGENT_PSD_TEMPLATE_INCOMPATIBLE_PSB_MESSAGE = + "当前 PSB 文件包含现有解析器暂不兼容的图层扩展信息,请在 Photoshop 中另存为 PSD 后再上传解析。"; export function inspectAgentPsdTemplateFile( value: ArrayBuffer | Buffer @@ -62,13 +65,9 @@ export function assertSupportedAgentPsdTemplateFile( ) { const inspection = inspectAgentPsdTemplateFile(value); - if (inspection.format === "psd") { + if (inspection.format === "psd" || inspection.format === "psb") { return inspection; } - if (inspection.format === "psb") { - throw new Error(AGENT_PSD_TEMPLATE_UNSUPPORTED_PSB_MESSAGE); - } - - throw new Error("模板文件格式不正确,请上传 Photoshop PSD(.psd)文件。"); + throw new Error(AGENT_PSD_TEMPLATE_INVALID_FORMAT_MESSAGE); }