|
|
|
@ -45,6 +45,10 @@ const initTrees = async () => { |
|
|
|
const leftData = JSON.parse(JSON.stringify(wbData)); |
|
|
|
const rightData = JSON.parse(JSON.stringify(wbData)); |
|
|
|
|
|
|
|
// 跨树拖拽时,目标树的 DnD 扩展实例拿不到 sourceNode(各树实例独立), |
|
|
|
// 因此用闭包变量在 dragStart 中记住源节点,drop 中做 fallback。 |
|
|
|
let currentDragNode: any = null; |
|
|
|
|
|
|
|
// 共享的 DnD 配置 |
|
|
|
const dndOptions = { |
|
|
|
preventForeignNodes: false, // 允许跨树拖拽 |
|
|
|
@ -53,21 +57,30 @@ const initTrees = async () => { |
|
|
|
dropEffectDefault: 'move' as const, |
|
|
|
effectAllowed: 'all' as const, |
|
|
|
guessDropEffect: true, |
|
|
|
dragStart: () => true, |
|
|
|
dragStart: (e: any) => { |
|
|
|
currentDragNode = e.node; |
|
|
|
return true; |
|
|
|
}, |
|
|
|
dragEnd: () => { |
|
|
|
currentDragNode = null; |
|
|
|
}, |
|
|
|
dragEnter: () => { |
|
|
|
// 允许放置在 before / after / over 三个位置 |
|
|
|
return new Set(['before', 'after', 'over'] as const); |
|
|
|
}, |
|
|
|
drop: (e: any) => { |
|
|
|
const sourceNode = e.sourceNode; |
|
|
|
// 同树拖拽时 e.sourceNode 有值;跨树拖拽时为 null,回退到闭包变量 |
|
|
|
const sourceNode = e.sourceNode || currentDragNode; |
|
|
|
const targetNode = e.node; |
|
|
|
const suggestedDropMode = e.suggestedDropMode; |
|
|
|
|
|
|
|
if (sourceNode && targetNode) { |
|
|
|
sourceNode.moveTo(targetNode, suggestedDropMode); |
|
|
|
// 更新两棵树的渲染 |
|
|
|
leftTree?.update('structure' as any); |
|
|
|
rightTree?.update('structure' as any); |
|
|
|
// moveTo 内部仅通过 setTimeout 更新源树,需额外更新目标树 |
|
|
|
setTimeout(() => { |
|
|
|
leftTree?.update('any' as any); |
|
|
|
rightTree?.update('any' as any); |
|
|
|
}, 0); |
|
|
|
} |
|
|
|
} |
|
|
|
}; |
|
|
|
|