fix(流程图编辑器): Ctrl+Y 没接、清空画布不问一声、存档里塞满 vue-flow 内部字段
## 存档里的一大半是运行时内部状态 画布上的 node 是 vue-flow 的 GraphNode,除了我们自己塞的字段,还挂着 `dimensions` / `computedPosition` / `handleBounds` / `selected` / `dragging` / `resizing` / `initialized` / `isParent` / `events`(见 vue-flow 的 parseNode)。 这些会跟着一起写进 localStorage、进 20 份历史快照被反复深拷贝、还压缩后提交进 数据库**长期存着**。而重新挂载时它们全都会被重新算一遍 —— 存下来没有任何意义, 还把存档格式和 vue-flow 的内部实现绑死了,将来升级或迁移数据都得跟着动。 `handleBounds` 尤其占地方:一个循环节点有 4 个 handle,每个 6 个数字。 抽一个 `serialize.ts`,落盘/入历史/提交前统一裁成 id / type / position / data / style 五个字段。`style` 保留 —— 它是建节点时按类型算好的,丢了恢复出来的图会变样。 实测:一个两节点带连线的图,存档 600 字节、节点上只剩那五个字段,九个内部字段 一个不剩;提交上去压缩后 396 字节。 ## Ctrl+Y 是假的 工具栏按钮的 title 写着「重做 (Ctrl+Y)」,但只实现了 Ctrl+Shift+Z,按 Y 没反应。 顺手把 key 比较改成小写不敏感(按住 Shift 时 event.key 是大写的 "Z")。 ## 清空画布点一下就没了 那个按钮不但清空画布,`clearCache()` 还会把这道题存着的草稿一起删掉,刷新也找 不回来。学生误点的代价太大,加一道确认;画布本来就是空的时候不弹。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
9e41855610
commit
f5ad5318a0
4 files changed
+81
-12
No files matched your search
@@ -19,6 +19,7 @@ import { getNodeTypeConfig } from "./useNodeStyles"
|
||||
import { useHistory } from "./useHistory"
|
||||
import { useFlowOperations } from "./useFlowOperations"
|
||||
import { useCache } from "./useCache"
|
||||
import { toPortableEdges, toPortableNodes } from "./serialize"
|
||||
import CustomNode from "./CustomNode.vue"
|
||||
import { useProblemStore } from "oj/store/problem"
|
||||
|
||||
@@ -120,10 +121,21 @@ const handleRedo = () => {
|
||||
}
|
||||
}
|
||||
|
||||
// 清空画布
|
||||
// 清空画布。工具栏那个按钮点一下就全没了,且 clearCache() 会连本题存着的草稿
|
||||
// 一起删掉,刷新也找不回来 —— 学生误点的代价太大,加一道确认
|
||||
const dialog = useDialog()
|
||||
const handleClear = () => {
|
||||
clearCanvas()
|
||||
clearCache()
|
||||
if (nodes.value.length === 0 && edges.value.length === 0) return
|
||||
dialog.warning({
|
||||
title: "清空画布",
|
||||
content: "画布上的内容会被清掉,这道题存着的草稿也会一起删除。确定吗?",
|
||||
positiveText: "清空",
|
||||
negativeText: "再想想",
|
||||
onPositiveClick: () => {
|
||||
clearCanvas()
|
||||
clearCache()
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// 键盘事件
|
||||
@@ -139,10 +151,12 @@ const handleKeyDown = (event: KeyboardEvent) => {
|
||||
}
|
||||
|
||||
if (event.ctrlKey || event.metaKey) {
|
||||
if (event.key === "z" && !event.shiftKey) {
|
||||
const key = event.key.toLowerCase()
|
||||
if (key === "z" && !event.shiftKey) {
|
||||
event.preventDefault()
|
||||
handleUndo()
|
||||
} else if (event.key === "z" && event.shiftKey) {
|
||||
} else if ((key === "z" && event.shiftKey) || key === "y") {
|
||||
// 工具栏上的提示写的就是 Ctrl+Y,但原来只实现了 Ctrl+Shift+Z,按 Y 没反应
|
||||
event.preventDefault()
|
||||
handleRedo()
|
||||
}
|
||||
@@ -188,9 +202,10 @@ const setFlowchartData = (data: { nodes: Node[]; edges: Edge[] }) => {
|
||||
defineExpose({
|
||||
nodes,
|
||||
edges,
|
||||
// 提交出去的这份会压缩后长期存进数据库,同样裁掉运行时内部字段
|
||||
getFlowchartData: () => ({
|
||||
nodes: nodes.value,
|
||||
edges: edges.value,
|
||||
nodes: toPortableNodes(nodes.value),
|
||||
edges: toPortableEdges(edges.value),
|
||||
}),
|
||||
setFlowchartData,
|
||||
})
|
||||
|
||||
Reference in new issue
Block a user