|
@@ -167,6 +167,19 @@ const debouncedSave = debounce(() => {
|
|
|
saveproject()
|
|
saveproject()
|
|
|
}, 500) // 500ms 防抖
|
|
}, 500) // 500ms 防抖
|
|
|
|
|
|
|
|
|
|
+onMounted(() => {
|
|
|
|
|
+ flowInit()
|
|
|
|
|
+ // 点击其他区域取消线段选中
|
|
|
|
|
+ if (vueFlowRef.value) {
|
|
|
|
|
+ vueFlowRef.value.$el.addEventListener("click", (event) => {
|
|
|
|
|
+ // 确保点击的不是边缘
|
|
|
|
|
+ if (seledge.value && !event.target.closest(".vue-flow__edge")) {
|
|
|
|
|
+ cleanEdgeselect()
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+})
|
|
|
|
|
+
|
|
|
|
|
|
|
|
// 处理节点拖动时的网格吸附
|
|
// 处理节点拖动时的网格吸附
|
|
|
onNodeDrag(({ node }) => {
|
|
onNodeDrag(({ node }) => {
|
|
@@ -186,82 +199,97 @@ onNodeDrag(({ node }) => {
|
|
|
let prevNodes = [...nodes.value]
|
|
let prevNodes = [...nodes.value]
|
|
|
let prevEdges = [...edges.value]
|
|
let prevEdges = [...edges.value]
|
|
|
|
|
|
|
|
|
|
+// 标记是否为初始化
|
|
|
|
|
+let isInitializing = ref(true);
|
|
|
|
|
+
|
|
|
// 监听节点变化
|
|
// 监听节点变化
|
|
|
watch(
|
|
watch(
|
|
|
nodes,
|
|
nodes,
|
|
|
(newNodes) => {
|
|
(newNodes) => {
|
|
|
- const deletedNodes = prevNodes.filter(
|
|
|
|
|
|
|
+ console.log("节点变化:", newNodes);
|
|
|
|
|
+
|
|
|
|
|
+ if (isInitializing.value) {
|
|
|
|
|
+ prevNodes.value = [...newNodes];
|
|
|
|
|
+ isInitializing.value = false;
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const deletedNodes = prevNodes.value.filter(
|
|
|
(node) => !newNodes.some((n) => n.id === node.id)
|
|
(node) => !newNodes.some((n) => n.id === node.id)
|
|
|
- )
|
|
|
|
|
|
|
+ );
|
|
|
const addedNodes = newNodes.filter(
|
|
const addedNodes = newNodes.filter(
|
|
|
- (node) => !prevNodes.some((n) => n.id === node.id)
|
|
|
|
|
- )
|
|
|
|
|
|
|
+ (node) => !prevNodes.value.some((n) => n.id === node.id)
|
|
|
|
|
+ );
|
|
|
|
|
|
|
|
if (deletedNodes.length > 0) {
|
|
if (deletedNodes.length > 0) {
|
|
|
- console.log("Deleted Nodes:", deletedNodes)
|
|
|
|
|
|
|
+ console.log('Deleted Nodes:', deletedNodes);
|
|
|
deletedNodes.forEach((node) => {
|
|
deletedNodes.forEach((node) => {
|
|
|
if (node.data?.pcId) {
|
|
if (node.data?.pcId) {
|
|
|
- comdelete(node.data.pcId)
|
|
|
|
|
|
|
+ comdelete(node.data.pcId);
|
|
|
}
|
|
}
|
|
|
- })
|
|
|
|
|
|
|
+ });
|
|
|
}
|
|
}
|
|
|
if (addedNodes.length > 0) {
|
|
if (addedNodes.length > 0) {
|
|
|
- // console.log('Added Nodes:', addedNodes);
|
|
|
|
|
|
|
+ console.log('Added Nodes:', addedNodes);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // 更新快照
|
|
|
|
|
- prevNodes = [...newNodes]
|
|
|
|
|
-
|
|
|
|
|
- debouncedSave();
|
|
|
|
|
|
|
+ prevNodes.value = [...newNodes];
|
|
|
},
|
|
},
|
|
|
{ deep: true }
|
|
{ deep: true }
|
|
|
-)
|
|
|
|
|
|
|
+);
|
|
|
|
|
|
|
|
// 监听连线变化
|
|
// 监听连线变化
|
|
|
watch(
|
|
watch(
|
|
|
edges,
|
|
edges,
|
|
|
(newEdges) => {
|
|
(newEdges) => {
|
|
|
- const deletedEdges = prevEdges.filter(
|
|
|
|
|
|
|
+ if (isInitializing.value) {
|
|
|
|
|
+ console.log("初始化连线数据:", newEdges);
|
|
|
|
|
+
|
|
|
|
|
+ prevEdges.value = [...newEdges];
|
|
|
|
|
+ isInitializing.value = false;
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const deletedEdges = prevEdges.value.filter(
|
|
|
(edge) => !newEdges.some((e) => e.id === edge.id)
|
|
(edge) => !newEdges.some((e) => e.id === edge.id)
|
|
|
- )
|
|
|
|
|
|
|
+ );
|
|
|
const addedEdges = newEdges.filter(
|
|
const addedEdges = newEdges.filter(
|
|
|
- (edge) => !prevEdges.some((e) => e.id === edge.id)
|
|
|
|
|
- )
|
|
|
|
|
|
|
+ (edge) => !prevEdges.value.some((e) => e.id === edge.id)
|
|
|
|
|
+ );
|
|
|
|
|
|
|
|
if (deletedEdges.length > 0) {
|
|
if (deletedEdges.length > 0) {
|
|
|
- console.log("Deleted Edges:", deletedEdges)
|
|
|
|
|
|
|
+ console.log('Deleted Edges:', deletedEdges);
|
|
|
deletedEdges.forEach((edge) => {
|
|
deletedEdges.forEach((edge) => {
|
|
|
- const sourceNode = prevNodes.find((n) => n.id === edge.source)
|
|
|
|
|
- const targetNode = prevNodes.find((n) => n.id === edge.target)
|
|
|
|
|
|
|
+ const sourceNode = prevNodes.value.find((n) => n.id === edge.source);
|
|
|
|
|
+ const targetNode = prevNodes.value.find((n) => n.id === edge.target);
|
|
|
|
|
|
|
|
- if (!sourceNode || !targetNode) return
|
|
|
|
|
|
|
+ if (!sourceNode || !targetNode) return;
|
|
|
|
|
|
|
|
- let npcId = ""
|
|
|
|
|
- let pcId = ""
|
|
|
|
|
|
|
+ let npcId = '';
|
|
|
|
|
+ let pcId = '';
|
|
|
|
|
|
|
|
- // 判断 source 或 target 是否为中间点 comId === '3'
|
|
|
|
|
- if (sourceNode.data?.comId === "3") {
|
|
|
|
|
- npcId = sourceNode.data.pcId
|
|
|
|
|
- pcId = targetNode.data?.pcId
|
|
|
|
|
- } else if (targetNode.data?.comId === "3") {
|
|
|
|
|
- npcId = targetNode.data.pcId
|
|
|
|
|
- pcId = sourceNode.data?.pcId
|
|
|
|
|
|
|
+ if (sourceNode.data?.comId === '3') {
|
|
|
|
|
+ npcId = sourceNode.data.pcId;
|
|
|
|
|
+ pcId = targetNode.data?.pcId;
|
|
|
|
|
+ } else if (targetNode.data?.comId === '3') {
|
|
|
|
|
+ npcId = targetNode.data.pcId;
|
|
|
|
|
+ pcId = sourceNode.data?.pcId;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if (npcId && pcId) {
|
|
if (npcId && pcId) {
|
|
|
- comlinedelete(npcId, pcId)
|
|
|
|
|
|
|
+ comlinedelete(npcId, pcId);
|
|
|
}
|
|
}
|
|
|
- })
|
|
|
|
|
|
|
+ });
|
|
|
}
|
|
}
|
|
|
if (addedEdges.length > 0) {
|
|
if (addedEdges.length > 0) {
|
|
|
|
|
+ console.log('Added Edges:', addedEdges);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // 更新快照
|
|
|
|
|
- prevEdges = [...newEdges]
|
|
|
|
|
|
|
+ prevEdges.value = [...newEdges];
|
|
|
debouncedSave();
|
|
debouncedSave();
|
|
|
},
|
|
},
|
|
|
{ deep: true }
|
|
{ deep: true }
|
|
|
-)
|
|
|
|
|
|
|
+);
|
|
|
|
|
|
|
|
const resetTransform = () => {
|
|
const resetTransform = () => {
|
|
|
setViewport({ x: 0, y: 0, zoom: 1 })
|
|
setViewport({ x: 0, y: 0, zoom: 1 })
|
|
@@ -278,41 +306,48 @@ const toggleDarkMode = () => {
|
|
|
|
|
|
|
|
const saveproject = async () => {
|
|
const saveproject = async () => {
|
|
|
try {
|
|
try {
|
|
|
- let obj = {
|
|
|
|
|
|
|
+ const obj = {
|
|
|
nodes: toObject().nodes,
|
|
nodes: toObject().nodes,
|
|
|
- edges: toObject().edges
|
|
|
|
|
- }
|
|
|
|
|
- // 移除每个节点的 image 字段,保留 imageIdentify
|
|
|
|
|
- obj.nodes = obj.nodes.map(node => ({
|
|
|
|
|
|
|
+ edges: toObject().edges,
|
|
|
|
|
+ };
|
|
|
|
|
+ obj.nodes = obj.nodes.map((node) => ({
|
|
|
...node,
|
|
...node,
|
|
|
data: {
|
|
data: {
|
|
|
...node.data,
|
|
...node.data,
|
|
|
- image: undefined // 移除 image 字段
|
|
|
|
|
- }
|
|
|
|
|
- }))
|
|
|
|
|
-
|
|
|
|
|
- mergedObj.value = JSON.stringify(obj)
|
|
|
|
|
|
|
+ image: undefined, // 移除 image 字段
|
|
|
|
|
+ },
|
|
|
|
|
+ }));
|
|
|
|
|
+
|
|
|
|
|
+ mergedObj.value = JSON.stringify(obj);
|
|
|
|
|
+
|
|
|
|
|
+ const activeProject = projectStore.getActiveProject();
|
|
|
|
|
+ if (!activeProject) {
|
|
|
|
|
+ throw new Error('当前没有激活的项目');
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
const params = {
|
|
const params = {
|
|
|
- transCode: "ES0002",
|
|
|
|
|
|
|
+ transCode: 'ES0002',
|
|
|
pid: pid.value,
|
|
pid: pid.value,
|
|
|
flow: mergedObj.value,
|
|
flow: mergedObj.value,
|
|
|
- name: projectStore.projectInfo.name || "",
|
|
|
|
|
- remark: projectStore.projectInfo.remark || "",
|
|
|
|
|
- keywords: projectStore.projectInfo.keywords || ""
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- await request(params)
|
|
|
|
|
- projectStore.setProjectInfo({
|
|
|
|
|
- ...projectStore.projectInfo,
|
|
|
|
|
- flow: mergedObj.value || ""
|
|
|
|
|
- })
|
|
|
|
|
- console.log('保存成功')
|
|
|
|
|
|
|
+ name: activeProject.projectName || '',
|
|
|
|
|
+ remark: activeProject.remark || '',
|
|
|
|
|
+ keywords: activeProject.keywords || '',
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ await request(params);
|
|
|
|
|
+
|
|
|
|
|
+ projectStore.updateProjectInfo(projectStore.activeProjectId, {
|
|
|
|
|
+ ...activeProject,
|
|
|
|
|
+ flow: mergedObj.value,
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ console.log('保存成功');
|
|
|
|
|
+ ElMessage.success('保存成功');
|
|
|
} catch (error) {
|
|
} catch (error) {
|
|
|
- console.error("保存失败:", error)
|
|
|
|
|
- ElMessage.error("保存失败,请稍后重试")
|
|
|
|
|
|
|
+ console.error('保存失败:', error);
|
|
|
|
|
+ ElMessage.error('保存失败,请稍后重试');
|
|
|
}
|
|
}
|
|
|
-}
|
|
|
|
|
|
|
+};
|
|
|
|
|
|
|
|
const removeNode = () => {
|
|
const removeNode = () => {
|
|
|
if (!noid.value) {
|
|
if (!noid.value) {
|
|
@@ -756,59 +791,69 @@ const createCom3 = async (pid) => {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+// 在 flowInit 后重置 isInitializing
|
|
|
const flowInit = async () => {
|
|
const flowInit = async () => {
|
|
|
try {
|
|
try {
|
|
|
- const flow = JSON.parse(projectStore.projectInfo.flow || '{"nodes":[],"edges":[]}')
|
|
|
|
|
- if (!flow.nodes || !flow.edges) {
|
|
|
|
|
- throw new Error("无效的 flow 数据")
|
|
|
|
|
|
|
+ const activeProject = projectStore.getActiveProject();
|
|
|
|
|
+ console.log("Active Project:", activeProject);
|
|
|
|
|
+
|
|
|
|
|
+ if (!activeProject) {
|
|
|
|
|
+ throw new Error('当前没有激活的项目');
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ let flow;
|
|
|
|
|
+ try {
|
|
|
|
|
+ console.log('解析 flow 数据:', activeProject.flow);
|
|
|
|
|
+ console.log('解析 flow 数据aaaaa:', typeof activeProject.flow);
|
|
|
|
|
+ console.log('Raw flow data:', JSON.parse(activeProject.flow));
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ flow = JSON.parse(activeProject.flow || '{"nodes":[], "edges":[] }' );
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ console.error('解析 flow 数据失败:', activeProject.flow, error);
|
|
|
|
|
+ flow = JSON.parse('{"nodes": [], "edges": [] }');
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
const updatedNodes = await Promise.all(
|
|
const updatedNodes = await Promise.all(
|
|
|
flow.nodes.map(async (node) => {
|
|
flow.nodes.map(async (node) => {
|
|
|
if (node.data?.imageIdentify) {
|
|
if (node.data?.imageIdentify) {
|
|
|
- if (node.data.imageIdentify === "point-only") {
|
|
|
|
|
- // point-only 节点使用本地图片
|
|
|
|
|
|
|
+ if (node.data.imageIdentify === 'point-only') {
|
|
|
return {
|
|
return {
|
|
|
...node,
|
|
...node,
|
|
|
- data: {
|
|
|
|
|
- ...node.data,
|
|
|
|
|
- image: nodePoint
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ data: { ...node.data, image: nodePoint },
|
|
|
|
|
+ };
|
|
|
}
|
|
}
|
|
|
- // 普通节点调用接口获取图片
|
|
|
|
|
try {
|
|
try {
|
|
|
- const imageData = await getImageBase64(node.data.imageIdentify)
|
|
|
|
|
|
|
+ const imageData = await getImageBase64(node.data.imageIdentify);
|
|
|
return {
|
|
return {
|
|
|
...node,
|
|
...node,
|
|
|
- data: {
|
|
|
|
|
- ...node.data,
|
|
|
|
|
- image: imageData || tempic
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ data: { ...node.data, image: imageData || tempic },
|
|
|
|
|
+ };
|
|
|
} catch (err) {
|
|
} catch (err) {
|
|
|
- console.error(`获取图片 ${node.data.imageIdentify} 失败:`, err.message)
|
|
|
|
|
|
|
+ console.error(`获取图片 ${node.data.imageIdentify} 失败:`, err.message);
|
|
|
return {
|
|
return {
|
|
|
...node,
|
|
...node,
|
|
|
- data: {
|
|
|
|
|
- ...node.data,
|
|
|
|
|
- image: tempic
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ data: { ...node.data, image: tempic },
|
|
|
|
|
+ };
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- return node // 如果没有 imageIdentify,直接返回
|
|
|
|
|
|
|
+ return node;
|
|
|
})
|
|
})
|
|
|
- )
|
|
|
|
|
|
|
+ );
|
|
|
|
|
|
|
|
- nodes.value = updatedNodes
|
|
|
|
|
- edges.value = flow.edges
|
|
|
|
|
|
|
+ nodes.value = updatedNodes;
|
|
|
|
|
+ edges.value = flow.edges;
|
|
|
|
|
+ prevNodes.value = [...updatedNodes];
|
|
|
|
|
+ prevEdges.value = [...flow.edges];
|
|
|
|
|
+ isInitializing.value = true; // 标记为初始化
|
|
|
|
|
|
|
|
- console.log("加载项目成功")
|
|
|
|
|
|
|
+ console.log('加载项目成功');
|
|
|
} catch (error) {
|
|
} catch (error) {
|
|
|
- console.error("加载项目失败:", error)
|
|
|
|
|
|
|
+ console.error('加载项目失败:', error);
|
|
|
|
|
+ ElMessage.error('加载项目失败,请检查项目数据');
|
|
|
}
|
|
}
|
|
|
-}
|
|
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
const cleanEdgeselect = () => {
|
|
const cleanEdgeselect = () => {
|
|
|
if (seledge.value) {
|
|
if (seledge.value) {
|
|
|
// 恢复选中边缘的原始样式
|
|
// 恢复选中边缘的原始样式
|
|
@@ -825,19 +870,6 @@ const cleanEdgeselect = () => {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-onMounted(() => {
|
|
|
|
|
- flowInit()
|
|
|
|
|
-
|
|
|
|
|
- // 点击其他区域取消线段选中
|
|
|
|
|
- if (vueFlowRef.value) {
|
|
|
|
|
- vueFlowRef.value.$el.addEventListener("click", (event) => {
|
|
|
|
|
- // 确保点击的不是边缘
|
|
|
|
|
- if (seledge.value && !event.target.closest(".vue-flow__edge")) {
|
|
|
|
|
- cleanEdgeselect()
|
|
|
|
|
- }
|
|
|
|
|
- })
|
|
|
|
|
- }
|
|
|
|
|
-})
|
|
|
|
|
|
|
|
|
|
const closePanel = () => {
|
|
const closePanel = () => {
|
|
|
setTimeout(() => {
|
|
setTimeout(() => {
|
|
@@ -845,26 +877,6 @@ const closePanel = () => {
|
|
|
}, 100) // 延迟 100ms 销毁组件,避免 Splitpanes 销毁错误
|
|
}, 100) // 延迟 100ms 销毁组件,避免 Splitpanes 销毁错误
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-// 路由切换前保存
|
|
|
|
|
-// router.beforeEach(async (to, from, next) => {
|
|
|
|
|
-// if (to.path !== from.path) {
|
|
|
|
|
-// try {
|
|
|
|
|
-// await saveproject() // 直接调用 saveproject
|
|
|
|
|
-// next()
|
|
|
|
|
-// } catch (error) {
|
|
|
|
|
-// console.error("路由切换保存失败:", error)
|
|
|
|
|
-// next() // 即使保存失败也允许切换路由
|
|
|
|
|
-// }
|
|
|
|
|
-// } else {
|
|
|
|
|
-// next()
|
|
|
|
|
-// }
|
|
|
|
|
-// })
|
|
|
|
|
-
|
|
|
|
|
-// // 组件卸载前保存
|
|
|
|
|
-// onBeforeUnmount(async () => {
|
|
|
|
|
-// await saveproject() // 直接调用 saveproject
|
|
|
|
|
-// })
|
|
|
|
|
-
|
|
|
|
|
defineExpose({
|
|
defineExpose({
|
|
|
resetTransform,
|
|
resetTransform,
|
|
|
toggleDarkMode,
|
|
toggleDarkMode,
|