fix(canvas): 预演合并 - 场景时间戳采用服务端快照,带 id 数组按条目合并

每次预演变更都会改 updatedAt,不再把它当成用户编辑冲突;带 id 的对象数组按条目合并,仅刷新场景时保留本地视口。
This commit is contained in:
ddcat666
2026-10-08 10:54:41 +08:00
parent 0907fe0e6b
commit cd4bfb9c54
3 changed files with 124 additions and 9 deletions

View File

@@ -68,12 +68,60 @@ test("task progress ahead of the server checkpoint still accepts terminal state"
expect(isCanvasNodeGenerating(result.nodes[0])).toBe(false);
});
test("full Agent refresh removes unchanged nodes but preserves conflicting local edits", () => {
const remaining = { ...node, id: "remaining", metadata: {} };
const previous = { ...project, nodes: [node, remaining] };
const incoming = { ...previous, nodes: [remaining] };
expect(mergeAgentCanvasEditor(previous, incoming, previous.nodes, []).nodes).toEqual([remaining]);
const local = { ...node, title: "Unsaved local title" };
expect(() => mergeAgentCanvasEditor(previous, incoming, [local, remaining], [])).toThrow("冲突");
expect(local.title).toBe("Unsaved local title");
test("full Previs refresh merges scene bookkeeping and preserves the local viewport", () => {
const scene = {
id: "scene-1",
version: 1 as const,
title: "镜头",
background: "#111111",
environmentIntensity: 0.7,
environment: { mode: "color" as const },
gridVisible: true,
objects: [],
cameras: [],
lights: [],
shots: [],
activeShotId: "shot-1",
createdAt: "2026-09-13T00:00:00Z",
updatedAt: "2026-09-13T00:00:00Z",
};
const previous = { ...project, previsScenes: [scene] };
const incoming = {
...previous,
revision: 2,
updatedAt: "2026-09-13T12:00:00Z",
previsScenes: [{ ...scene, updatedAt: "2026-09-13T12:00:00Z", objects: [{ id: "actor-1", name: "Agent 演员" }] }],
};
const local = {
...previous,
viewport: { x: -480, y: -220, k: 0.72 },
previsScenes: [{ ...scene, updatedAt: "2026-09-13T11:59:00Z" }],
};
const merged = mergeAgentCanvasEditor(previous, incoming, local.nodes, local.connections, local);
expect(merged.previsScenes[0].objects).toEqual(incoming.previsScenes[0].objects);
expect(merged.previsScenes[0].updatedAt).toBe(incoming.previsScenes[0].updatedAt);
expect(merged.viewport).toEqual(local.viewport);
});
test("full Previs refresh still rejects a same-field scene edit", () => {
const scene = {
id: "scene-1",
version: 1 as const,
title: "镜头",
background: "#111111",
environmentIntensity: 0.7,
environment: { mode: "color" as const },
gridVisible: true,
objects: [],
cameras: [],
lights: [],
shots: [],
activeShotId: "shot-1",
createdAt: "2026-09-13T00:00:00Z",
updatedAt: "2026-09-13T00:00:00Z",
};
const previous = { ...project, previsScenes: [scene] };
const incoming = { ...previous, revision: 2, previsScenes: [{ ...scene, title: "云端镜头", updatedAt: "2026-09-13T12:00:00Z" }] };
const local = { ...previous, previsScenes: [{ ...scene, title: "本地镜头", updatedAt: "2026-09-13T11:59:00Z" }] };
expect(() => mergeAgentCanvasEditor(previous, incoming, local.nodes, local.connections, local)).toThrow("冲突");
});