lichunyang 2 долоо хоног өмнө
parent
commit
f58ecefade

+ 38 - 2
src/views/model/vueflow/defaultnode.vue

@@ -7,6 +7,32 @@ const props = defineProps({
     required: true,
   },
 })
+
+// 计算 Handle 的位置(基于时钟方位角度,调整为 0° 对应右边)
+const getHandleStyles = (point) => {
+  // 将时钟方位 (0-11) 转换为角度,0° 对应右边(3点)
+  const angle = ((parseInt(point) * 30 - 90) % 360) * (Math.PI / 180) // 顺时针旋转,减去 90° 偏移
+  const radius = 25 // 节点宽高为 50px,Handle 位于边缘
+  const centerX = 25 // 节点中心 x 坐标(50px / 2)
+  const centerY = 25 // 节点中心 y 坐标(50px / 2)
+
+  const x = centerX + radius * Math.cos(angle)
+  const y = centerY + radius * Math.sin(angle) // y 轴向下为正
+
+  return {
+    position: 'absolute',
+    left: `${x}px`,
+    top: `${y}px`,
+    transform: 'translate(-50%, -50%)' // 居中 Handle
+  }
+}
+
+// 解析 ptsite,获取需要渲染的方位
+const getHandlePositions = () => {
+  const ptsite = props.node.data.ptsite || ""
+  if (!ptsite) return [] // 如果 ptsite 为空,返回空数组
+  return ptsite.split("/").filter(pos => !isNaN(parseInt(pos))) // 过滤有效点位(数字)
+}
 onMounted(() => {
 });
 </script>
@@ -17,10 +43,20 @@ onMounted(() => {
       <img :src="props.node.data.image"/>
       <span>{{props.node.data.idCodeser }}</span>
     </div>
-  <Handle id="target-a" type="source" :position="Position.Right" class="custom-handle"/>
+    <!-- 动态渲染 Handle -->
+    <Handle
+      v-for="pos in getHandlePositions()"
+      :key="`source-${pos}`"
+      :id="`source-${pos}`"
+      type="source"
+      :position="Position.Custom"
+      :style="getHandleStyles(pos)"
+      class="custom-handle"
+    />
+  <!-- <Handle id="target-a" type="source" :position="Position.Right" class="custom-handle"/>
   <Handle id="target-c" type="source" :position="Position.Top"  class="custom-handle"/> 
   <Handle id="target-b" type="source" :position="Position.Left" class="custom-handle"/> 
-  <Handle id="target-d" type="source" :position="Position.Bottom"  class="custom-handle"/> 
+  <Handle id="target-d" type="source" :position="Position.Bottom"  class="custom-handle"/>  -->
   </div>
 <!-- </div> -->
 </template>

+ 52 - 56
src/views/model/vueflow/index.vue

@@ -470,7 +470,6 @@ let lineType = ref("default")
 
 onConnect(async (connection) => {
   console.log("线连接", connection)
-
   if (connection.source === connection.target) {
     console.warn("禁止节点自连")
     return
@@ -484,10 +483,16 @@ onConnect(async (connection) => {
     return
   }
 
+  // 验证 Handle ID 格式(source-${point} 或 source-${direction})
+  const validHandleRegex = /^source-(\d+|[a-z]+)$/
+  if (!validHandleRegex.test(connection.sourceHandle) || !validHandleRegex.test(connection.targetHandle)) {
+    console.warn("无效的 Handle ID:", connection.sourceHandle, connection.targetHandle)
+    return
+  }
+
   const hasDuplicateEdge = edges.value.some(
     (edge) =>
-      (edge.source === connection.source &&
-        edge.target === connection.target) ||
+      (edge.source === connection.source && edge.target === connection.target) ||
       (edge.source === connection.target && edge.target === connection.source)
   )
 
@@ -497,23 +502,17 @@ onConnect(async (connection) => {
   }
 
   const isDuplicate = edges.value.some((edge1) => {
-    // edge1: source -> 中间节点
     if (
       edge1.source === connection.source ||
       edge1.target === connection.source
     ) {
       const middleNodeId =
         edge1.source === connection.source ? edge1.target : edge1.source
-
-      // 确保 middleNode 是中间组件(comId === '3')
       const middleNode = vueFlowRef.value.getNode(middleNodeId)
       if (!middleNode || middleNode.data.comId !== "3") return false
-
-      // 查找是否还有另一条边连接 middleNode <-> target
       return edges.value.some(
         (edge2) =>
-          (edge2.source === middleNodeId &&
-            edge2.target === connection.target) ||
+          (edge2.source === middleNodeId && edge2.target === connection.target) ||
           (edge2.target === middleNodeId && edge2.source === connection.target)
       )
     }
@@ -525,19 +524,14 @@ onConnect(async (connection) => {
     return
   }
 
-  // 是否需要中间节点
   const isCom3 = sourceNode.data.comId === "3" || targetNode.data.comId === "3"
 
   if (isCom3) {
-    //(comID == 3)
     const edgeId = `${lineType.value}-${connection.source}-${connection.sourceHandle}-${connection.target}-${connection.targetHandle}`
     connection.id = edgeId
     connection.type = "smoothstep"
     connection.color = linecolor.value
     connection.style = { strokeWidth: linewidth.value, stroke: linecolor.value }
-    // connection.markerEnd = lineType.value === 'data'
-    //   ? { type: MarkerType.ArrowClosed, width: 6, height: 6, color: linecolor.value }
-    //   : MarkerType.ArrowClosed;
 
     const sameEdge = edges.value.find((edge) => edge.id === edgeId)
     if (sameEdge) {
@@ -548,13 +542,9 @@ onConnect(async (connection) => {
     seledge.value = null
 
     const pcId1 =
-      sourceNode.data.comId === "3"
-        ? targetNode.data.pcId
-        : sourceNode.data.pcId
+      sourceNode.data.comId === "3" ? targetNode.data.pcId : sourceNode.data.pcId
     const npcId =
-      sourceNode.data.comId === "3"
-        ? sourceNode.data.pcId
-        : targetNode.data.pcId
+      sourceNode.data.comId === "3" ? sourceNode.data.pcId : targetNode.data.pcId
 
     try {
       const { pccId1 } = await createEdge(pid.value, 0, npcId, pcId1)
@@ -568,8 +558,7 @@ onConnect(async (connection) => {
       console.error("保存流程失败:", error)
     }
   } else {
-    // 添加 point-only 中间节点
-    const pointNodeId = `point-${connection.source}-${connection.target}}`
+    const pointNodeId = `point-${connection.source}-${connection.target}`
     const sourceCenterX = sourceNode.position.x + 60 / 2
     const sourceCenterY = sourceNode.position.y + 58 / 2
     const targetCenterX = targetNode.position.x + 60 / 2
@@ -578,31 +567,15 @@ onConnect(async (connection) => {
     const midX = (sourceCenterX + targetCenterX) / 2
     const midY = (sourceCenterY + targetCenterY) / 2
 
-    // 计算 sourceNode 和 targetNode 相对于 pointNode 的位置
-    const dxSource = sourceNode.position.x - midX
-    const dySource = sourceNode.position.y - midY
-    const dxTarget = targetNode.position.x - midX
-    const dyTarget = targetNode.position.y - midY
-
-    // 判断 sourceNode 的主要方向(水平 or 垂直)
-    const isSourceHorizontal = Math.abs(dxSource) > Math.abs(dySource)
-    const sourceDirection = isSourceHorizontal
-      ? dxSource < 0
-        ? "left"
-        : "right"
-      : dySource < 0
-      ? "top"
-      : "bottom"
-
-    // 判断 targetNode 的主要方向
-    const isTargetHorizontal = Math.abs(dxTarget) > Math.abs(dyTarget)
-    const targetDirection = isTargetHorizontal
-      ? dxTarget < 0
-        ? "left"
-        : "right"
-      : dyTarget < 0
-      ? "top"
-      : "bottom"
+    // 使用 source 和 target 的点位方向
+    const sourceHandlePoint = connection.sourceHandle.replace("source-", "")
+    const targetHandlePoint = connection.targetHandle.replace("source-", "")
+    const sourceDirection = getDirectionFromPoint(sourceHandlePoint)
+    const targetDirection = getDirectionFromPoint(targetHandlePoint)
+
+    // point-only 节点的 Handle 使用对侧方向(source 到 point)和服务方向(point 到 target)
+    const pointTargetHandle = `source-${getOppositeDirection(sourceHandlePoint)}`
+    const pointSourceHandle = `source-${getDirectionFromPoint(targetHandlePoint)}`
 
     nodes.value.push({
       id: pointNodeId,
@@ -612,14 +585,12 @@ onConnect(async (connection) => {
         comId: "3",
         label: "节点",
         image: node,
-        imageIdentify: "point-only"
+        imageIdentify: "66"
       }
     })
 
     try {
-      // 创建 comID 为 3 的中间组件
       const { pcId: npcId, ser, idCode } = await createCom3(pid.value)
-
       const pointNode = nodes.value.find((n) => n.id === pointNodeId)
       updateNode(pointNodeId, (node) => ({
         ...node,
@@ -631,25 +602,23 @@ onConnect(async (connection) => {
       }))
       updateNodeInternals(pointNodeId)
 
-      // edge1: source -> pointNode
       const edgeId1 = `${lineType.value}-${connection.source}-${connection.sourceHandle}-${pointNodeId}`
       const edge1 = {
         id: edgeId1,
         source: connection.source,
         sourceHandle: connection.sourceHandle,
         target: pointNodeId,
-        targetHandle: `source-${sourceDirection}`,
+        targetHandle: pointTargetHandle,
         type: "smoothstep",
         color: linecolor.value,
         style: { strokeWidth: linewidth.value, stroke: linecolor.value }
       }
 
-      // edge2: pointNode -> target
       const edgeId2 = `${lineType.value}-${pointNodeId}-${connection.targetHandle}-${connection.target}`
       const edge2 = {
         id: edgeId2,
         source: pointNodeId,
-        sourceHandle: `source-${targetDirection}`, // 使用计算的方向
+        sourceHandle: pointSourceHandle,
         target: connection.target,
         targetHandle: connection.targetHandle,
         type: "smoothstep",
@@ -657,9 +626,11 @@ onConnect(async (connection) => {
         style: { strokeWidth: linewidth.value, stroke: linecolor.value }
       }
 
+      console.log("Edge1:", { id: edgeId1, sourceHandle: connection.sourceHandle, targetHandle: pointTargetHandle })
+      console.log("Edge2:", { id: edgeId2, sourceHandle: pointSourceHandle, targetHandle: connection.targetHandle })
+
       addEdges([edge1, edge2])
 
-      // 保存后端 edge 数据(分别对应两条边)
       const { pccId1, pccId2 } = await createEdge(
         pid.value,
         0,
@@ -689,6 +660,31 @@ onConnect(async (connection) => {
   saveproject()
 })
 
+// 将点位转换为方向(与 defaultnode.vue 的角度映射一致)
+function getDirectionFromPoint(point) {
+  if (!isNaN(parseInt(point))) {
+    const angle = ((parseInt(point) * 30) % 360 + 360) % 360 // 移除 -90° 偏移,与 defaultnode.vue 同步
+    if (angle >= 315 || angle < 45) return "right"   // 315° to 45° -> 3
+    if (angle >= 45 && angle < 135) return "bottom"  // 45° to 135° -> 6
+    if (angle >= 135 && angle < 225) return "left"   // 135° to 225° -> 9
+    if (angle >= 225 && angle < 315) return "top"    // 225° to 315° -> 0
+  }
+  return point // 直接使用字符串(如果 point 不是数字)
+}
+
+// 计算 point-only 节点的 Handle 方向,匹配 source 和 target 的点位
+function getOppositeDirection(point) {
+  if (!isNaN(parseInt(point))) {
+    const oppositePoint = (parseInt(point) + 6) % 12 // 对侧点位(180° 偏移)
+    return getDirectionFromPoint(oppositePoint.toString())
+  }
+  // 如果是自定义方向,返回对侧
+  return point === "top" ? "bottom" :
+         point === "bottom" ? "top" :
+         point === "left" ? "right" :
+         point === "right" ? "left" : point
+}
+
 const createEdge = async (pid, type, npcId, pcId1, pcId2) => {
   const params = {
     transCode: "ES0006",

+ 2 - 1
src/views/model/vueflow/useDnD.js

@@ -36,7 +36,8 @@ async function imagefun() {
     imageIdentify: imageSer,
     idCode: com.idCode,
     pcId: "",
-    idCodeser: ""
+    idCodeser: "",
+    ptsite: com.ptsite || ""
   })
 }