// import { useVueFlow,Position,MarkerType } from '@vue-flow/core'; import { useVueFlow, Position, MarkerType } from "@vue-flow/core" import { ref, watch } from "vue" 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" const projectStore = useProjectStore() let nid = 0 // 用于计数 let nodecount = 0 let treeobj = ref([]) let datas = {} // 用于存储组件的临时数据 let com = {} /** * @returns {string} - A unique id. */ function getId() { 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, pcId: "", idCodeser: "" }) } /** * In a real world scenario you'd want to avoid creating refs in a global scope like this as they might not be cleaned up properly. * @type {{draggedType: Ref, isDragOver: Ref, isDragging: Ref}} */ const state = { /** * The type of the node being dragged. */ draggedType: ref(null), isDragOver: ref(false), isDragging: ref(false) } // 组件创建 const createComponent = async (pid, comId) => { const params = { transCode: "ES0004", pid: pid || "", comId: comId || "" // 组件ID } try { const res = await request(params) return { pcId: res.pcId, ser: res.ser, idCode: res.idCode } } catch (err) { ElMessage.error(err.returnMsg) } } // 用来存储每种组件名称出现次数的对象 const nameCount = {} export default function useDragAndDrop() { const { draggedType, isDragOver, isDragging } = state const { addNodes, addEdges, findNode, screenToFlowCoordinate, onNodesInitialized, updateNode, updateNodeInternals } = useVueFlow() watch(isDragging, (dragging) => { document.body.style.userSelect = dragging ? "none" : "" }) function onDragStart(event, type, data) { if (event.dataTransfer) { com = data //传递组件数据 nid = data.comId //传递组件ID event.dataTransfer.setData("application/vueflow", type) event.dataTransfer.effectAllowed = "move" } draggedType.value = type //draggedType.value = 'smoothstep' isDragging.value = true document.addEventListener("drop", onDragEnd) } /** * Handles the drag over event. * * @param {DragEvent} event */ function onDragOver(event) { event.preventDefault() if (draggedType.value) { isDragOver.value = true if (event.dataTransfer) { event.dataTransfer.dropEffect = "move" } } } function handleNodeDrop(e) { } function onDragLeave(e) { isDragOver.value = false } function onDragEnd() { isDragging.value = false isDragOver.value = false draggedType.value = null nid = "" document.removeEventListener("drop", onDragEnd) } /** * Handles the drop event. * * @param {DragEvent} event */ async function onDrop(event) { const GRID_SIZE = 5; // 网格大小,调整为需要的对齐单位(如 10 或 50) const position = screenToFlowCoordinate({ x: event.clientX, y: event.clientY }); // 对齐到网格 const alignedX = Math.round(position.x / GRID_SIZE) * GRID_SIZE; const alignedY = Math.round(position.y / GRID_SIZE) * GRID_SIZE; const pid = projectStore.pid; const nodeId = getId(); const image1 = imagefun(); const componentName = image1.idCode; if (!nameCount[componentName]) { nameCount[componentName] = 0; } const newName = `${componentName}${nameCount[componentName]}`; // 创建初始节点(使用对齐后的位置) const newNode = { id: nodeId, type: draggedType.value, position: { x: alignedX, y: alignedY }, data: { ...image1, uid: newName } }; // 1. 先添加节点到画布 addNodes([newNode]); // 2. 调整位置(确保对齐效果保留,居中调整后仍对齐到网格) const { off } = onNodesInitialized(() => { updateNode(nodeId, (node) => { const adjustedX = Math.round((node.position.x - node.dimensions.width / 2) / GRID_SIZE) * GRID_SIZE; const adjustedY = Math.round((node.position.y - node.dimensions.height / 2) / GRID_SIZE) * GRID_SIZE; return { ...node, position: { x: adjustedX, y: adjustedY }, dimensions: { height: 58, width: 60 } }; }); off(); // 移除监听,避免重复执行 }); // 3. 异步获取 pcId 和 idCodeser,并更新节点 try { const { pcId, ser, idCode } = await createComponent(pid, nid); updateNode(nodeId, (node) => ({ ...node, data: { ...node.data, pcId, idCodeser: `${idCode}${ser}`, } })); updateNodeInternals(nodeId); } catch (err) { console.error("添加组件失败:", err.message); ElMessage.error("添加组件失败"); // 如果失败,可以考虑移除节点: // removeNodes([nodeId]); } } return { treeobj, draggedType, isDragOver, isDragging, onDragStart, onDragLeave, onDragOver, onDrop, handleNodeDrop } }