diff --git a/.memory/worklog.json b/.memory/worklog.json index 67eb8c4..6d65dd6 100644 --- a/.memory/worklog.json +++ b/.memory/worklog.json @@ -1,25 +1,5 @@ { "entries": [ - { - "files_changed": 3, - "hash": "3a52628", - "message": "auto-save 2026-05-20 19:05 (~3)", - "ts": "2026-05-20T19:05:46+08:00", - "type": "commit" - }, - { - "files_changed": 2, - "hash": "f35bfe0", - "message": "fix: render scaled workbench text sharply", - "ts": "2026-05-20T19:07:06+08:00", - "type": "commit" - }, - { - "files_changed": 1, - "message": "Codex 会话活跃 · 最近命令:codex · 分支 main · 1 项未提交变更 · 最近提交:fix: render scaled workbench text sharply", - "ts": "2026-05-20T11:15:31Z", - "type": "session-heartbeat" - }, { "files_changed": 1, "hash": "ddaa795", @@ -3193,6 +3173,27 @@ "message": "auto-save 2026-05-27 14:53 (+1, ~6)", "hash": "3c146d6", "files_changed": 8 + }, + { + "ts": "2026-05-27T14:58:42+08:00", + "type": "commit", + "message": "auto-save 2026-05-27 14:58 (+2, ~2)", + "hash": "284296d", + "files_changed": 4 + }, + { + "ts": "2026-05-27T14:59:39+08:00", + "type": "commit", + "message": "fix: auto-sync completed canvas videos", + "hash": "f3c0500", + "files_changed": 6 + }, + { + "ts": "2026-05-27T15:06:31+08:00", + "type": "commit", + "message": "docs: codify marketing product baseline", + "hash": "3035efc", + "files_changed": 3 } ] } diff --git a/web/canvas-app/src/stores/canvas.js b/web/canvas-app/src/stores/canvas.js index d2c73f3..32c28ca 100644 --- a/web/canvas-app/src/stores/canvas.js +++ b/web/canvas-app/src/stores/canvas.js @@ -165,14 +165,14 @@ const checkSignificantChanges = (oldState, newState) => { return false } -// Add a new node | 添加新节点 -export const addNode = (type, position = { x: 100, y: 100 }, data = {}) => { +const createNode = (type, position, data = {}, rootProps = {}, now = Date.now()) => { const id = getNodeId() - const now = Date.now() - const newNode = { + + return { id, type, position, + ...rootProps, data: { ...getDefaultNodeData(type), ...data, @@ -180,9 +180,14 @@ export const addNode = (type, position = { x: 100, y: 100 }, data = {}) => { updatedAt: data.updatedAt || now } } - nodes.value = [...nodes.value, newNode] +} + +// Add a new node | 添加新节点 +export const addNode = (type, position = { x: 100, y: 100 }, data = {}, rootProps = {}) => { + const newNode = createNode(type, position, data, rootProps) + nodes.value.push(newNode) saveToHistory() // Save after adding node | 添加节点后保存 - return id + return newNode.id } /** @@ -200,33 +205,20 @@ export const addNodes = (nodeSpecs, autoBatch = true) => { startBatchOperation() } - const ids = [] const now = Date.now() - - nodeSpecs.forEach(spec => { - const { type, position = { x: 100, y: 100 }, data = {} } = spec - const id = getNodeId() - const newNode = { - id, - type, - position, - data: { - ...getDefaultNodeData(type), - ...data, - createdAt: data.createdAt || now, - updatedAt: data.updatedAt || now - } - } - nodes.value = [...nodes.value, newNode] - ids.push(id) + const newNodes = nodeSpecs.map(spec => { + const { type, position = { x: 100, y: 100 }, data = {}, rootProps = {} } = spec + return createNode(type, position, data, rootProps, now) }) + nodes.value.push(...newNodes) + // End batch operation if auto | 如果自动管理则结束批量操作并保存到历史 if (autoBatch) { endBatchOperation() } - return ids + return newNodes.map(node => node.id) } // Get default data for node type | 获取节点类型的默认数据 @@ -318,7 +310,7 @@ export const duplicateNode = (id) => { data: { ...sourceNode.data }, zIndex: maxZIndex + 1 } - nodes.value = [...nodes.value, newNode] + nodes.value.push(newNode) saveToHistory() // Save after duplicating node | 复制节点后保存 return newId } @@ -329,7 +321,7 @@ export const addEdge = (params) => { id: `edge_${params.source}_${params.target}`, ...params } - edges.value = [...edges.value, newEdge] + edges.value.push(newEdge) saveToHistory() // Save after adding edge | 添加连线后保存 } @@ -348,23 +340,19 @@ export const addEdges = (edgeSpecs, autoBatch = true) => { startBatchOperation() } - const ids = [] - - edgeSpecs.forEach(params => { - const newEdge = { + const newEdges = edgeSpecs.map(params => ({ id: `edge_${params.source}_${params.target}`, ...params - } - edges.value = [...edges.value, newEdge] - ids.push(newEdge.id) - }) + })) + + edges.value.push(...newEdges) // End batch operation if auto | 如果自动管理则结束批量操作并保存到历史 if (autoBatch) { endBatchOperation() } - return ids + return newEdges.map(edge => edge.id) } // Update edge data | 更新边数据 diff --git a/web/canvas-app/src/views/Canvas.vue b/web/canvas-app/src/views/Canvas.vue index cc1170f..48fa230 100644 --- a/web/canvas-app/src/views/Canvas.vue +++ b/web/canvas-app/src/views/Canvas.vue @@ -483,13 +483,15 @@ const addNewNode = async (type) => { // Calculate viewport center position | 计算视口中心位置 const viewportCenterX = -viewport.value.x / viewport.value.zoom + (window.innerWidth / 2) / viewport.value.zoom const viewportCenterY = -viewport.value.y / viewport.value.zoom + (window.innerHeight / 2) / viewport.value.zoom + const maxZIndex = Math.max(0, ...nodes.value.map(n => n.zIndex || 0)) // Add node at viewport center | 在视口中心添加节点 - const nodeId = addNode(type, { x: viewportCenterX - 100, y: viewportCenterY - 100 }) - - // Set highest z-index | 设置最高层级 - const maxZIndex = Math.max(0, ...nodes.value.map(n => n.zIndex || 0)) - updateNode(nodeId, { zIndex: maxZIndex + 1 }) + const nodeId = addNode( + type, + { x: viewportCenterX - 100, y: viewportCenterY - 100 }, + {}, + { zIndex: maxZIndex + 1 } + ) // Force Vue Flow to recalculate node dimensions | 强制 Vue Flow 重新计算节点尺寸 setTimeout(() => {