fix: preserve psd static layers on export
Some checks failed
Lint / build (20) (push) Has been cancelled
Playwright Tests / test (push) Has been cancelled

This commit is contained in:
Your Name 2026-05-19 15:02:24 +08:00
parent 7792d1a740
commit 1db3d108d4
2 changed files with 62 additions and 27 deletions

View File

@ -9330,7 +9330,7 @@ export function CanvasChatPanel({
const isAgentTargetClarificationActive =
shouldShowAgentTargetLockCard && activeAgentTargetLock?.stage === "clarify";
const shouldShowAgentProgressCard =
false;
activeComposerMode === "agent" && Boolean(activeAgentProgress);
const agentTargetLockPreviewItems = useMemo(() => {
if (!activeAgentTargetLock) return [] as AgentTargetLockRefPreview[];
const targets = Array.isArray(activeAgentTargetLock.targets) ? activeAgentTargetLock.targets : [];

View File

@ -451,14 +451,22 @@ export async function renderAgentPsdTemplate(params: {
),
];
const renderBaseUrl = String(template.renderBaseUrl || "").trim();
const canUseDedicatedRenderBase =
const hasDedicatedRenderBase =
Boolean(renderBaseUrl) &&
renderBaseUrl !== String(template.previewUrl || "").trim() &&
!orderedTemplateLayers.some(
(layer) =>
!isAgentPsdTemplateLayerUserEditable(layer) &&
hiddenLayerIdSet.has(layer.id)
);
renderBaseUrl !== String(template.previewUrl || "").trim();
const hasHiddenStaticLayer = orderedTemplateLayers.some(
(layer) =>
!isAgentPsdTemplateLayerUserEditable(layer) &&
hiddenLayerIdSet.has(layer.id)
);
const hasMissingVisibleStoredLayerSource = orderedTemplateLayers.some(
(layer) =>
!hiddenLayerIdSet.has(layer.id) && !getStoredLayerSourceUrl(layer)
);
const shouldUseRenderBaseFallback =
hasDedicatedRenderBase &&
!hasHiddenStaticLayer &&
hasMissingVisibleStoredLayerSource;
function getLayerPositionOffset(layerId: string) {
return normalizeTextPositionOffset(layerPositionOffsets[layerId]);
@ -500,7 +508,7 @@ export async function renderAgentPsdTemplate(params: {
assetCandidates.push({ url: normalizedUrl, label, optional });
};
if (canUseDedicatedRenderBase) {
if (shouldUseRenderBaseFallback) {
pushAsset(renderBaseUrl, "PSD 模板底图");
}
@ -511,9 +519,11 @@ export async function renderAgentPsdTemplate(params: {
const storedLayerSourceUrl = getStoredLayerSourceUrl(layer);
if (!isAgentPsdTemplateLayerUserEditable(layer)) {
if (!canUseDedicatedRenderBase) {
pushAsset(storedLayerSourceUrl, "PSD 图层素材");
}
pushAsset(
storedLayerSourceUrl,
"PSD 图层素材",
shouldUseRenderBaseFallback
);
continue;
}
@ -523,7 +533,11 @@ export async function renderAgentPsdTemplate(params: {
pushAsset(assignmentUrl, "PSD 套版素材");
pushAsset(layer.maskUrl, "PSD 蒙版资源", true);
} else {
pushAsset(storedLayerSourceUrl, "PSD 图层素材");
pushAsset(
storedLayerSourceUrl,
"PSD 图层素材",
shouldUseRenderBaseFallback
);
}
continue;
}
@ -550,7 +564,11 @@ export async function renderAgentPsdTemplate(params: {
(!text && !hasTextAssignment) ||
(text === defaultText && !hasColorChange && !hasPositionChange)
) {
pushAsset(storedLayerSourceUrl, "PSD 图层素材");
pushAsset(
storedLayerSourceUrl,
"PSD 图层素材",
shouldUseRenderBaseFallback
);
} else {
const font = layer.fontId ? fontMap.get(layer.fontId) : undefined;
pushAsset(font?.fileUrl, "PSD 字体资源", true);
@ -567,7 +585,9 @@ export async function renderAgentPsdTemplate(params: {
uniqueAssetMap.set(asset.url, {
...asset,
label: previous?.label || asset.label,
optional: Boolean(previous?.optional) && Boolean(asset.optional),
optional: previous
? Boolean(previous.optional) && Boolean(asset.optional)
: Boolean(asset.optional),
});
}
const uniqueAssets = Array.from(uniqueAssetMap.values());
@ -610,9 +630,18 @@ export async function renderAgentPsdTemplate(params: {
return true;
}
async function appendStoredLayer(layer: AgentPsdTemplate["layers"][number]) {
async function appendStoredLayer(
layer: AgentPsdTemplate["layers"][number],
options: { optional?: boolean } = {}
) {
const sourceUrl = getStoredLayerSourceUrl(layer);
if (!hasAgentPsdTemplateStoredLayerSource(layer) && !sourceUrl) {
if (
(!hasAgentPsdTemplateStoredLayerSource(layer) && !sourceUrl) ||
!sourceUrl
) {
if (options.optional) {
return false;
}
throw new Error(
`PSD 模板图层“${layer.layerName}”缺少已打包资源,请在后台重新解析该模板`
);
@ -629,8 +658,9 @@ export async function renderAgentPsdTemplate(params: {
height: layer.height,
});
if (didAppend) {
return;
return true;
}
return false;
} catch (error) {
console.warn(
"[PSD Template] failed to reuse stored layer asset during render:",
@ -640,6 +670,9 @@ export async function renderAgentPsdTemplate(params: {
error,
}
);
if (options.optional) {
return false;
}
throw new Error(
`PSD 模板图层“${layer.layerName}”资源加载失败,请稍后重试或在后台重新解析该模板`
);
@ -648,7 +681,7 @@ export async function renderAgentPsdTemplate(params: {
await prefetchRenderAssets();
if (canUseDedicatedRenderBase) {
if (shouldUseRenderBaseFallback) {
const renderBaseBuffer = await readCachedBuffer(renderBaseUrl, "PSD 模板底图");
await appendBufferOverlay({
input: renderBaseBuffer,
@ -665,18 +698,16 @@ export async function renderAgentPsdTemplate(params: {
}
if (!isAgentPsdTemplateLayerUserEditable(layer)) {
if (canUseDedicatedRenderBase) {
continue;
}
await appendStoredLayer(layer);
await appendStoredLayer(layer, { optional: shouldUseRenderBaseFallback });
continue;
}
if (isAgentPsdImageLayerSlot(layer)) {
const assignmentUrl = String(imageAssignments[layer.id] || "").trim();
if (!assignmentUrl) {
await appendStoredLayer(layer);
await appendStoredLayer(layer, {
optional: shouldUseRenderBaseFallback,
});
continue;
}
@ -837,12 +868,16 @@ export async function renderAgentPsdTemplate(params: {
const hasPositionChange = hasTextPositionOffset(textPositionOffset);
if (!text) {
if (!hasTextAssignment) {
await appendStoredLayer(layer);
await appendStoredLayer(layer, {
optional: shouldUseRenderBaseFallback,
});
}
continue;
}
if (text === defaultText && !hasColorChange && !hasPositionChange) {
await appendStoredLayer(layer);
await appendStoredLayer(layer, {
optional: shouldUseRenderBaseFallback,
});
continue;
}
const textAlign = resolveAgentPsdTextLayerEffectiveAlign(layer);