tangjunhao 3 mesiacov pred
rodič
commit
722eb51853

+ 6 - 9
src/views/model/vueflow/defaultnode.vue

@@ -6,13 +6,10 @@ const props = defineProps({
     type: Object,
     required: true,
   },
-  sourcePosition: {
-    type: String,
-  },
-  targetPosition: {
-    type: String,
-  },
 })
+const nodeData = toRef(props.node, 'data') // 保留响应式引用
+
+const idCodeser = computed(() => nodeData.value?.idCodeser || '')
 onMounted(() => {
 });
 </script>
@@ -21,7 +18,7 @@ onMounted(() => {
   <div v-if="props.node.data!=null">
     <div class="custom-node icons  " :id="`node-${node.id}`"  >
       <img :src="props.node.data.image"/>
-      <span>{{props.node.data.uid }}</span>
+      <span>{{idCodeser }}</span>
     </div>
   <Handle id="target-a" type="source" :position="Position.Right"  />
   <Handle id="target-c" type="source" :position="Position.Top"  /> 
@@ -45,8 +42,8 @@ onMounted(() => {
 </style>
 <style>
 .vue-flow__node-default, .vue-flow__node-input, .vue-flow__node-output{
-  width: 60px;
-  height: 58px;
+  width: 50px;
+  height: 50px;
   pointer-events: auto;
   border: none;
 }

+ 66 - 38
src/views/model/vueflow/index.vue

@@ -8,11 +8,11 @@
     
     <!-- 自定义节点类型为default的节点 -->
     <template  #node-default="props">
-      <defaultnode :node="props" />
+      <defaultnode :node="props" :key="props.data.idCodeser || props.id" />
     </template>
 
     <template  #node-point-only="props">
-      <PointOnlyNode :node="props" />
+      <PointOnlyNode :node="props" :key="props.data.idCodeser || props.id"/>
     </template>
 
     <Background pattern-color="#aaa" :gap="16" 
@@ -66,13 +66,12 @@ import "./main.css";//重置样式
 import defaultnode from './defaultnode.vue'
 import PointOnlyNode from './pointonlynode.vue'
 import useDragAndDrop from './useDnD';
-import {getNodeCount, setNodeCount} from './useDnD';
 import changebak from './changebak.vue'
 import { useProjectStore } from '@/store/project'
 import emitter from "@/utils/emitter";
 import { onMounted } from 'vue';
 
-const { onInit, onNodeDragStop, onConnect, addEdges, setViewport, toObject,addNodes,updateEdgeData,onConnectStart} = useVueFlow()
+const { onInit, onNodeDragStop, onConnect, addEdges, setViewport, toObject,addNodes,updateEdgeData,onConnectStart,updateNode,updateNodeInternals} = useVueFlow()
 
 const { onDragOver, onDrop, onDragLeave, isDragOver } = useDragAndDrop();
 
@@ -144,10 +143,10 @@ watch(edges, (newEdges) => {
 
       // 判断 source 或 target 是否为中间点 comId === '3'
       if (sourceNode.data?.comId === '3') {
-        npcId = sourceNode.data.npcId;
+        npcId = sourceNode.data.pcId;
         pcId = targetNode.data?.pcId;
       } else if (targetNode.data?.comId === '3') {
-        npcId = targetNode.data.npcId;
+        npcId = targetNode.data.pcId;
         pcId = sourceNode.data?.pcId;
       }
 
@@ -182,8 +181,6 @@ const saveproject = () => {
   let obj = { 
     nodes: toObject().nodes,
     edges: toObject().edges,
-    midNodeCounter: midNodeCounter, // 添加中间节点计数器
-    nodeCount: getNodeCount(), // 获取当前节点计数
   };
   mergedObj.value=JSON.stringify(obj);
 
@@ -266,7 +263,7 @@ const comdelete = (pcId) => {
   }
   request(params)
     .then((res) => {
-      // console.log('组件删除成功')
+      console.log('组件删除成功')
     })
     .catch((err) => {
       ElMessage.error(err.returnMsg);
@@ -282,7 +279,7 @@ const comlinedelete = (npcId,pcId) => {
   }
   request(params)
     .then((res) => {
-      // console.log('组件连线删除成功')
+      console.log('组件连线删除成功')
     })
     .catch((err) => {
       ElMessage.error(err.returnMsg);
@@ -290,11 +287,12 @@ const comlinedelete = (npcId,pcId) => {
 }
 
 
-const customOnDrop = (event) => {
+const customOnDrop = async (event) => {
   console.log('自定义拖放事件', event);
-  onDrop(event);
-  saveproject();
-}
+
+  await onDrop(event); // 等待 onDrop 执行完成
+  saveproject();       // onDrop 执行完之后再保存项目
+};
 
 
 
@@ -359,9 +357,6 @@ onConnectStart(() => {
 // 线的类型 default
 let lineType = ref('default');
 
-// 线序号
-let linecount = ref(0);
-
 onConnect(async (connection) => {
   console.log('线连接', connection);
 
@@ -378,6 +373,41 @@ onConnect(async (connection) => {
     return;
   }
 
+  const hasDuplicateEdge = edges.value.some(edge =>
+    (edge.source === connection.source && edge.target === connection.target) ||
+    (edge.source === connection.target && edge.target === connection.source)
+  );
+
+  if (hasDuplicateEdge) {
+    console.warn('禁止重复连接:起点和终点已连接');
+    return;
+  }
+
+  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.target === middleNodeId && edge2.source === connection.target)
+      );
+    }
+    return false;
+  });
+
+  if (isDuplicate) {
+    console.warn('禁止重复连接:这两个节点已经通过中间组件连接过了');
+    return;
+  }
+
   // 是否需要中间节点
   const isCom3 = sourceNode.data.comId === '3' || targetNode.data.comId === '3';
 
@@ -399,8 +429,6 @@ onConnect(async (connection) => {
 
     addEdges(connection);
     seledge.value = null;
-    linecount.value++;
-    const newName = `Seg${linecount.value}`;
 
     const pcId1 = sourceNode.data.comId === '3' ? targetNode.data.pcId : sourceNode.data.pcId;
     const npcId = sourceNode.data.comId === '3' ? sourceNode.data.pcId : targetNode.data.pcId;
@@ -409,7 +437,6 @@ onConnect(async (connection) => {
       const { pccId1 } = await createEdge(pid.value, 0, npcId, pcId1);
       updateEdgeData(connection.id, {
         pcid: pccId1,
-        uid: newName,
         type: lineType.value,
         frompcId: sourceNode.data.pcId,
         topcId: targetNode.data.pcId,
@@ -446,10 +473,6 @@ onConnect(async (connection) => {
     ? (dxTarget < 0 ? 'left' : 'right') 
     : (dyTarget < 0 ? 'top' : 'bottom');
 
-
-    midNodeCounter++;
-    const uid = `N${midNodeCounter}`;
-
     nodes.value.push({
       id: pointNodeId,
       type: 'point-only',
@@ -457,18 +480,27 @@ onConnect(async (connection) => {
       data: {
         comId:'3',
         label: '节点',
-        uid: uid,
        },
     });
 
     try {
       // 创建 comID 为 3 的中间组件
-      const npcId = await createCom3(pid.value);
+      const {pcId: npcId ,ser ,idCode} = await createCom3(pid.value);
 
       const pointNode = nodes.value.find(n => n.id === pointNodeId);
-      if (pointNode) {
-        pointNode.data.pcId = npcId; // 写入 data
-      }
+      // if (pointNode) {
+      //   pointNode.data.pcId = npcId; // 写入 data
+      //   pointNode.data.idCodeser = `${idCode}${ser}`;
+      // }
+      updateNode(pointNodeId, (node) => ({
+        ...node,
+        data: {
+          ...node.data,
+          pcId: npcId,
+          idCodeser: `${idCode}${ser}`,
+        }
+      }));
+      updateNodeInternals(pointNodeId);
 
       // edge1: source -> pointNode
       const edgeId1 = `${lineType.value}-${connection.source}-${connection.sourceHandle}-${pointNodeId}`;
@@ -497,15 +529,12 @@ onConnect(async (connection) => {
       };
 
       addEdges([edge1, edge2]);
-      linecount.value++;
-      const newName = `Seg${linecount.value}`;
 
       // 保存后端 edge 数据(分别对应两条边)
       const { pccId1, pccId2 } = await createEdge(pid.value, 0, npcId, sourceNode.data.pcId, targetNode.data.pcId);
 
       updateEdgeData(edgeId1, {
         pcid: pccId1,
-        uid: newName,
         type: lineType.value,
         frompcId: sourceNode.data.pcId,
         topcId: npcId
@@ -513,7 +542,6 @@ onConnect(async (connection) => {
 
       updateEdgeData(edgeId2, {
         pcid: pccId2,
-        uid: newName,
         type: lineType.value,
         frompcId: npcId,
         topcId: targetNode.data.pcId
@@ -560,7 +588,11 @@ const createCom3 = async (pid) => {
 
   try {
     const res = await request(params)
-    return res.pcId // 返回新创建的组件在项目中的ID
+    return {
+      pcId: res.pcId,
+      ser: res.ser,
+      idCode: res.idCode
+    }
   } catch (err) {
     ElMessage.error(err.returnMsg)
   }
@@ -573,10 +605,6 @@ const flowInit = () => {
   console.log('初始化流程数据:', nodesflow);
   nodes.value = nodesflow.nodes;
   edges.value = nodesflow.edges;
-  // 提取中间节点计数器
-  midNodeCounter = nodesflow.midNodeCounter || 0;
-  // 提取节点计数
-  setNodeCount(nodesflow.nodeCount || 0);
 }
 
 const cleanEdgeselect = () => {

+ 1 - 1
src/views/model/vueflow/pointonlynode.vue

@@ -10,7 +10,7 @@ const props = defineProps({
   <div class="point-only-node" :id="`node-${props.node.id}`">
     <div class="custom-node icons  " :id="`node-${node.id}`"  >
       <img :src="props.node.data.image"/>
-      <span>{{props.node.data.uid }}</span>
+      <span>{{props.node.data.idCodeser }}</span>
     </div>
     <!-- 连接点 -->
     <Handle id="source-top" type="source" :position="Position.Top" />

+ 57 - 58
src/views/model/vueflow/useDnD.js

@@ -5,6 +5,7 @@ import { ElMessage, ElButton, ElDialog, ElSelect } from "element-plus"
 import { request, getImage } from "@/utils/request"
 import emitter from "@/utils/emitter"
 import { useProjectStore } from "@/store/project"
+import {nextTick} from "vue" 
 
 import tempic from "@/assets/img/temp.png"
 
@@ -15,29 +16,26 @@ let nodecount = 0
 let treeobj = ref([])
 let datas = {}
 
-
 // 用于存储组件的临时数据
 let com = {}
 
-export function getNodeCount() {
-  return nodecount;
-}
-
-export function setNodeCount(val) {
-  nodecount = val;
-  console.log("nodecount:",nodecount)
-}
-
-
 /**
  * @returns {string} - A unique id.
  */
 function getId() {
-  return `${nid}${nodecount++}`
+  const timestamp = Date.now() // 获取当前时间的毫秒数
+  return `${nid}${nodecount++}_${timestamp}`
 }
 function imagefun() {
   console.log(nid)
-  return (datas = { comId: com.comId ,label: com.name, image: getImage(com.image) || tempic, idCode: com.idCode });
+  return (datas = {
+    comId: com.comId,
+    label: com.name,
+    image: getImage(com.image) || tempic,
+    idCode: com.idCode,
+    pcId: "",
+    idCodeser: ""
+  })
 }
 
 /**
@@ -58,15 +56,15 @@ const createComponent = async (pid, comId) => {
   const params = {
     transCode: "ES0004",
     pid: pid || "",
-    comId: comId || "", // 组件ID
+    comId: comId || "" // 组件ID
   }
 
   try {
     const res = await request(params)
     return {
-      pcId:res.pcId,
+      pcId: res.pcId,
       ser: res.ser,
-      idCode: res.idCode,
+      idCode: res.idCode
     }
   } catch (err) {
     ElMessage.error(err.returnMsg)
@@ -82,9 +80,11 @@ export default function useDragAndDrop() {
   const {
     addNodes,
     addEdges,
+    findNode,
     screenToFlowCoordinate,
     onNodesInitialized,
-    updateNode
+    updateNode,
+    updateNodeInternals
   } = useVueFlow()
 
   watch(isDragging, (dragging) => {
@@ -93,8 +93,8 @@ export default function useDragAndDrop() {
 
   function onDragStart(event, type, data) {
     if (event.dataTransfer) {
-      com = data//传递组件数据
-      nid = data.comId//传递组件ID
+      com = data //传递组件数据
+      nid = data.comId //传递组件ID
       event.dataTransfer.setData("application/vueflow", type)
       event.dataTransfer.effectAllowed = "move"
     }
@@ -147,70 +147,69 @@ export default function useDragAndDrop() {
     })
 
     const pid = projectStore.pid
-    // console.log('Store:', projectStore)
-    const newpcId = ""
-
     const nodeId = getId()
     const image1 = imagefun()
-    // 获取当前组件的名称
     const componentName = image1.idCode
 
-    // 如果该组件的名称已存在,给名称添加序号
     if (!nameCount[componentName]) {
       nameCount[componentName] = 0
     }
 
-    const newName = `${componentName}${nodecount}` // 新的名称加上序号
+    const newName = `${componentName}${nameCount[componentName]}`
 
-    let snodes = ref([])
-    let sedges = ref([])
-
-    // 创建初始的节点数据,不包含 pcId
+    // 创建初始节点(pcId 和 idCodeser 初始为空)
     const newNode = {
       id: nodeId,
       type: draggedType.value,
       position,
-      data: { ...image1, uid: newName }
+      data: {
+        ...image1,
+        uid: newName
+      }
     }
 
-    snodes.value.push(newNode)
-
-    // 异步保存数据并更新 pcId
-    createComponent(pid, nid)
-      .then(({ pcId, ser, idCode }) => {
-        // 更新节点数据中的 pcId
-        newNode.data.pcId = pcId
-
-        // 使用 onNodesInitialized 来更新节点数据
-        onNodesInitialized(() => {
-          // 更新节点的其他数据
-          updateNode(nodeId, (node) => ({
-            ...node,
-            data: {
-              ...node.data,
-              pcId: newNode.data.pcId, // 更新节点中的 pcId
-            },
-          }))
-        })
-      })
-      .catch((err) => {
-        console.error("添加组件失败:", err.message)
-        ElMessage.error("添加组件失败")
-      })
+    // 1. 先添加节点到画布
+    addNodes([newNode])
 
+    // 2. 立即调整位置(使用 onNodesInitialized 确保节点已渲染)
     const { off } = onNodesInitialized(() => {
       updateNode(nodeId, (node) => ({
+        ...node,
         position: {
           x: node.position.x - node.dimensions.width / 2,
           y: node.position.y - node.dimensions.height / 2
         },
         dimensions: { height: 58, width: 60 }
       }))
-
-      off()
+      off() // 移除监听,避免重复执行
     })
-    addNodes(snodes.value)
-    treeobj.value = snodes.value
+
+    // 3. 异步获取 pcId 和 idCodeser,并更新节点
+    try {
+      // 等待 createComponent 完成再继续执行
+      const { pcId, ser, idCode } = await createComponent(pid, nid)
+
+      // 更新前检查节点
+      console.log('更新前的节点:', findNode(nodeId))
+      updateNode(nodeId, (node) => ({
+        ...node,
+        data: {
+          ...node.data,
+          pcId,
+          idCodeser: `${idCode}${ser}`,
+        }
+      }))
+      updateNodeInternals(nodeId);
+      // 更新后检查节点
+      nextTick(() => {
+        console.log('更新后的节点:', findNode(nodeId))
+      })
+    } catch (err) {
+      console.error("添加组件失败:", err.message)
+      ElMessage.error("添加组件失败")
+      // 如果失败,可以考虑移除节点:
+      // removeNodes([nodeId]);
+    }
   }
   return {
     treeobj,