feat(canvas): 画布工作台 - 新增生成副本并修复大型画布性能、素材同步与删除校验
统一图片与视频副本的生成落点并保留参考连接。\n优化大型画布节点虚拟化、媒体懒加载、拖拽与详情进入路径。\n修复素材主版本 ID 同步及删除时的画布独立引用校验。
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
import { describe, expect, test } from "bun:test";
|
||||
|
||||
import { nextCopiedNodeTitle } from "@/lib/canvas/canvas-node-copy";
|
||||
import { isolateCopiedNodeMetadata, nextCopiedNodeTitle } from "@/lib/canvas/canvas-node-copy";
|
||||
import { buildNodeGenerationContext } from "@/components/canvas/canvas-node-generation";
|
||||
import { CanvasNodeType, type CanvasNodeData } from "@/types/canvas";
|
||||
|
||||
describe("canvas node copy title", () => {
|
||||
test("首次复制使用 copy1,后续按已有最大序号递增", () => {
|
||||
@@ -25,3 +27,57 @@ describe("canvas node copy title", () => {
|
||||
expect([first, second]).toEqual(["节点_copy2", "节点_copy3"]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("canvas generation copy metadata", () => {
|
||||
test("媒体副本保留提示词与参考字段,并明确原地回填生成结果", () => {
|
||||
const source: CanvasNodeData = {
|
||||
id: "source",
|
||||
type: CanvasNodeType.Video,
|
||||
title: "镜头",
|
||||
position: { x: 0, y: 0 },
|
||||
width: 340,
|
||||
height: 240,
|
||||
metadata: {
|
||||
content: "video-url",
|
||||
prompt: "相同提示词",
|
||||
videoStartFrameNodeId: "reference-start",
|
||||
videoEndFrameNodeId: "reference-end",
|
||||
generationResultPlacement: "new-version",
|
||||
},
|
||||
};
|
||||
|
||||
const metadata = isolateCopiedNodeMetadata(source, new Map([[source.id, "copy"]]));
|
||||
|
||||
expect(metadata.prompt).toBe("相同提示词");
|
||||
expect(metadata.videoStartFrameNodeId).toBe("reference-start");
|
||||
expect(metadata.videoEndFrameNodeId).toBe("reference-end");
|
||||
expect(metadata.copiedFromNodeId).toBe("source");
|
||||
expect(metadata.generationResultPlacement).toBe("replace-node");
|
||||
});
|
||||
|
||||
test("复制到副本的入边继续解析为同一张参考图", () => {
|
||||
const reference: CanvasNodeData = {
|
||||
id: "reference",
|
||||
type: CanvasNodeType.Image,
|
||||
title: "角色参考",
|
||||
position: { x: 0, y: 0 },
|
||||
width: 340,
|
||||
height: 240,
|
||||
metadata: { content: "reference-url", mimeType: "image/png" },
|
||||
};
|
||||
const copy: CanvasNodeData = {
|
||||
id: "copy",
|
||||
type: CanvasNodeType.Image,
|
||||
title: "结果_copy1",
|
||||
position: { x: 400, y: 0 },
|
||||
width: 340,
|
||||
height: 240,
|
||||
metadata: { content: "old-result", prompt: "保持角色一致", copiedFromNodeId: "source", generationResultPlacement: "replace-node" },
|
||||
};
|
||||
|
||||
const context = buildNodeGenerationContext(copy.id, [reference, copy], [{ id: "copy-reference", fromNodeId: reference.id, toNodeId: copy.id }], copy.metadata!.prompt!, []);
|
||||
|
||||
expect(context.prompt).toBe("保持角色一致");
|
||||
expect(context.referenceImages.map((image) => image.id)).toEqual([reference.id]);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user