fix(canvas): 画布批量生成 - 修复节点丢失、资源引用及刷新状态不一致
This commit is contained in:
1 parent
dc1ad68015
commit
6f45240599
26 files changed
+533
-179
No files matched your search
@@ -2,10 +2,10 @@ import { nanoid } from "nanoid";
|
||||
|
||||
import { NODE_DEFAULT_SIZE } from "@/constant/canvas";
|
||||
import { canGenerateImageInPlace, findAvailableGenerationGroupPosition, imageGenerationChildPosition, imageGenerationGroupSize } from "@/lib/canvas/canvas-generation-layout";
|
||||
import { cancelIncompleteImageBatch, retireImageBatchChildren } from "@/lib/canvas/canvas-image-batch-retry";
|
||||
import { cancelIncompleteImageBatch, hasImageBatchResult, reconcileImageBatchRoot, retireImageBatchChildren } from "@/lib/canvas/canvas-image-batch-retry";
|
||||
import { buildImageGenerationNodeTitle } from "@/lib/canvas/canvas-generation-title";
|
||||
import { nodeSizeFromRatio } from "@/lib/canvas/canvas-node-size";
|
||||
import { canvasImageReferenceLimitError, buildImageGenerationMetadata, getGenerationCount, isGenerationCanceled, runCanvasGenerationTaskToConsumer } from "@/lib/canvas/canvas-project-generation";
|
||||
import { canvasImageReferenceLimitError, buildImageGenerationMetadata, getGenerationCount, isGenerationCanceled, resetGenerationTaskMetadata, runCanvasGenerationTaskToConsumer } from "@/lib/canvas/canvas-project-generation";
|
||||
import { imageGenerationReferenceConnections } from "@/lib/canvas/canvas-resource-references";
|
||||
import { canvasGenerationPromptMetadata } from "@/lib/canvas/canvas-generation-submission";
|
||||
import { CONTENT_MODERATION_ERROR_CODE, generationFailureMetadata, type GenerationFailureMetadata } from "@/lib/generation-error";
|
||||
@@ -54,7 +54,7 @@ export async function executeImageGeneration({
|
||||
const count = getGenerationCount(generationConfig.count);
|
||||
const isConfigNode = sourceNode?.type === CanvasNodeType.Config;
|
||||
const isImageNode = sourceNode?.type === CanvasNodeType.Image;
|
||||
const isExistingImageNode = isImageNode && Boolean(sourceNode?.metadata?.content);
|
||||
const isExistingImageNode = isImageNode && hasImageBatchResult(sourceNode);
|
||||
const reuseSourceNode = canGenerateImageInPlace(sourceNode);
|
||||
const retired = reuseSourceNode && sourceNode ? retireImageBatchChildren(sourceNode, canvasNodes, canvasConnections) : { nodes: canvasNodes, connections: canvasConnections, removedIds: [] as string[] };
|
||||
const workingNodes = retired.nodes;
|
||||
@@ -70,7 +70,7 @@ export async function executeImageGeneration({
|
||||
const imageConfig = requestedImageSize || imageDefaults;
|
||||
// auto 图生图沿用来源节点尺寸;用户明确选择比例时必须以目标比例创建节点。
|
||||
const referenceNode = referenceImages.length === 1 ? canvasNodes.find((node) => node.id === referenceImages[0].id && node.type === CanvasNodeType.Image) : undefined;
|
||||
const imageSizeSource = requestedImageSize ? undefined : isImageNode && sourceNode?.metadata?.content ? sourceNode : referenceNode;
|
||||
const imageSizeSource = requestedImageSize ? undefined : isExistingImageNode ? sourceNode : referenceNode;
|
||||
const outputNodeSize = imageSizeSource ? { width: imageSizeSource.width, height: imageSizeSource.height } : imageConfig;
|
||||
const parentPosition = sourceNode?.position || { x: 0, y: 0 };
|
||||
const parentWidth = sourceNode?.width || parentConfig.width;
|
||||
@@ -95,7 +95,7 @@ export async function executeImageGeneration({
|
||||
width: rootWidth,
|
||||
height: rootHeight,
|
||||
metadata: {
|
||||
...(reuseSourceNode ? sourceNode?.metadata || {} : {}),
|
||||
...resetGenerationTaskMetadata(reuseSourceNode ? sourceNode?.metadata : undefined, NODE_STATUS_LOADING),
|
||||
...canvasGenerationPromptMetadata(prompt, effectivePrompt),
|
||||
status: NODE_STATUS_LOADING,
|
||||
size: generationConfig.size,
|
||||
@@ -105,6 +105,8 @@ export async function executeImageGeneration({
|
||||
batchUsesReferenceImages: referenceImages.length > 0,
|
||||
primaryImageId: undefined,
|
||||
content: reuseSourceNode ? "" : undefined,
|
||||
storageKey: undefined,
|
||||
assetId: undefined,
|
||||
...generationMetadata,
|
||||
...styleMetadata,
|
||||
...skillMetadata,
|
||||
@@ -145,7 +147,7 @@ export async function executeImageGeneration({
|
||||
...workingNodes.map((node) => {
|
||||
if (node.id !== nodeId) return node;
|
||||
if (isConfigNode) return { ...node, metadata: { ...node.metadata, ...canvasGenerationPromptMetadata(prompt, effectivePrompt), status: NODE_STATUS_LOADING, errorDetails: undefined } };
|
||||
if (reuseSourceNode) return { ...node, position: rootNode.position, width: rootNode.width, height: rootNode.height, title: rootNode.title, metadata: { ...node.metadata, ...rootNode.metadata, errorDetails: undefined } };
|
||||
if (reuseSourceNode) return { ...node, position: rootNode.position, width: rootNode.width, height: rootNode.height, title: rootNode.title, metadata: rootNode.metadata };
|
||||
if (isImageNode) return node;
|
||||
return {
|
||||
...node,
|
||||
@@ -211,7 +213,7 @@ export async function executeImageGeneration({
|
||||
setNodes((current) => {
|
||||
const child = current.find((node) => node.id === targetId);
|
||||
const root = current.find((node) => node.id === rootId);
|
||||
if (!child?.metadata?.content || !root || root.metadata?.primaryImageId) return current;
|
||||
if (!child || !hasImageBatchResult(child) || !root || root.metadata?.primaryImageId) return current;
|
||||
const center = { x: root.position.x + root.width / 2, y: root.position.y + root.height / 2 };
|
||||
const geometry = root.metadata?.locked
|
||||
? {}
|
||||
@@ -290,6 +292,7 @@ export async function executeImageGeneration({
|
||||
};
|
||||
}
|
||||
if (node.id === rootId) {
|
||||
if (count > 1) return reconcileImageBatchRoot(node, current);
|
||||
return {
|
||||
...node,
|
||||
metadata: {
|
||||
|
||||
Reference in new issue
Block a user