@@ -2379,18 +2379,66 @@ const useCanvasStore = create(
23792379 const ts = Date . now ( )
23802380 const rand = ( ) => Math . random ( ) . toString ( 36 ) . slice ( 2 , 8 )
23812381 const COL_W = 240
2382- const ROW_H = 150
2382+ const CARD_H = 170
2383+ const PAD = 30
23832384 const newNodes = [ ]
23842385 const newEdges = [ ]
23852386
2386- // 子节点排成一横排, 在父节点下面
2387- const startX = src . position . x - ( ( subitems . length - 1 ) * COL_W ) / 2
2387+ // === 决定 decomposeGroup 容器 ===
2388+ // 拆解子节点散落在源下方会撞 ROLE/AGENT 行 (用户图 34 反馈)
2389+ // 改为统一收到 projectGroup 下方独立容器, 每个源节点一个 decomposeGroup
2390+ const projectGroup = src . parentNode ? nodes . find ( ( n ) => n . id === src . parentNode && n . type === 'group' ) : null
2391+
2392+ let dgId , dgPos
2393+ if ( projectGroup ) {
2394+ dgId = `${ projectGroup . id } -decompose-${ ontoNodeId } `
2395+ const groupX = projectGroup . position ?. x || 0
2396+ const groupY = projectGroup . position ?. y || 0
2397+ const groupH = Number ( projectGroup . style ?. height ) || 1100
2398+ // 同一 projectGroup 下方按已有 decompose 容器数量错开 Y
2399+ const existingDgs = nodes . filter ( ( n ) => n . type === 'group' && n . data ?. isDecomposeGroup && n . data ?. relatedProjectGroupId === projectGroup . id )
2400+ dgPos = { x : groupX , y : groupY + groupH + 60 + existingDgs . length * ( CARD_H + PAD * 2 + 40 ) }
2401+ } else {
2402+ dgId = `decomposeGroup-floating-${ ontoNodeId } `
2403+ dgPos = { x : ( src . position ?. x || 0 ) , y : ( src . position ?. y || 0 ) + 320 }
2404+ }
2405+
2406+ const existing = nodes . find ( ( n ) => n . id === dgId )
2407+ const existingChildren = nodes . filter ( ( n ) => n . parentNode === dgId && n . type === 'ontologyNode' )
2408+ const startIdx = existingChildren . length
2409+ const totalAfter = startIdx + subitems . length
2410+ const containerW = Math . max ( COL_W * totalAfter + PAD * 2 , COL_W * 5 + PAD * 2 )
2411+
2412+ if ( ! existing ) {
2413+ newNodes . push ( {
2414+ id : dgId ,
2415+ type : 'group' ,
2416+ position : dgPos ,
2417+ style : {
2418+ width : containerW ,
2419+ height : CARD_H + PAD * 2 + 24 ,
2420+ background : 'rgba(200,168,130,0.04)' ,
2421+ border : '1px dashed rgba(200,168,130,0.45)' ,
2422+ borderRadius : 14 ,
2423+ } ,
2424+ data : {
2425+ isDecomposeGroup : true ,
2426+ label : `拆解 · ${ src . data ?. title || '' } ` . slice ( 0 , 32 ) ,
2427+ relatedProjectGroupId : projectGroup ?. id || null ,
2428+ sourceNodeId : ontoNodeId ,
2429+ } ,
2430+ } )
2431+ }
2432+
23882433 subitems . forEach ( ( s , i ) => {
23892434 const cid = `onto-${ ts } -${ rand ( ) } `
2435+ const slotIdx = startIdx + i
23902436 newNodes . push ( {
23912437 id : cid ,
23922438 type : 'ontologyNode' ,
2393- position : { x : startX + i * COL_W , y : src . position . y + ROW_H } ,
2439+ parentNode : dgId ,
2440+ extent : 'parent' ,
2441+ position : { x : PAD + slotIdx * COL_W , y : PAD } ,
23942442 data : {
23952443 variant : 'entity' , // 二次拆出来的统一作为 entity, 用户可手动改
23962444 title : s . title ,
@@ -2410,9 +2458,15 @@ const useCanvasStore = create(
24102458 } )
24112459 } )
24122460
2461+ stampNodesInPlace ( newNodes )
24132462 set ( ( state ) => {
24142463 state . nodes . push ( ...newNodes )
24152464 state . edges . push ( ...newEdges )
2465+ // 复用已有容器: 撑大宽度
2466+ if ( existing ) {
2467+ const grp = state . nodes . find ( ( n ) => n . id === dgId )
2468+ if ( grp ) grp . style = { ...grp . style , width : containerW }
2469+ }
24162470 } )
24172471 return subitems
24182472 } ,
0 commit comments