浏览代码

feat: 子流程编辑弹框

wanggaokun 1 周之前
父节点
当前提交
1d45123d62

+ 1 - 0
src/types/auto-components.d.ts

@@ -39,6 +39,7 @@ declare module 'vue' {
     ElTooltip: typeof import('element-plus/es')['ElTooltip']
     RouterLink: typeof import('vue-router')['RouterLink']
     RouterView: typeof import('vue-router')['RouterView']
+    SubFlow: typeof import('./../views/test/components/subFlow.vue')['default']
     ToolBar: typeof import('./../views/components/ToolBar/index.vue')['default']
   }
 }

+ 0 - 1
src/views/components/ToolBar/index.vue

@@ -209,7 +209,6 @@ function handleClick(event: Event) {
 <style scoped>
 .bar {
   width: 100%;
-  z-index: 99999;
   margin-right: 16px;
 }
 .item-space {

+ 48 - 48
src/views/graph/index.ts

@@ -389,47 +389,47 @@ export default class FlowGraph {
   }
 
   // 右键菜单
-  public static handleContextmenu = (e: { pageX: any; pageY: any }, cell) => {
-    const cells = this.graph.getSelectedCells()
-    ContextMenu.showContextMenu({
-      x: e.pageX,
-      y: e.pageY,
-      items: [
-        {
-          label: '编辑子流程',
-          onClick: () => {
-            if (cell) {
-              console.log('cell', cell)
-            }
-          }
-        },
-        {
-          label: '删除节点',
-          onClick: () => {
-            if (cells.length) {
-              this.graph.removeCells(cells)
-            }
-          }
-        },
-        {
-          label: '置顶',
-          onClick: () => {
-            if (cells.length) {
-              cells.forEach(item => item.toFront({ deep: true }))
-            }
-          }
-        },
-        {
-          label: '置底',
-          onClick: () => {
-            if (cells.length) {
-              cells.forEach(item => item.toBack({ deep: true }))
-            }
-          }
-        }
-      ]
-    })
-  }
+  // public static handleContextmenu = (e: { pageX: any; pageY: any }, cell) => {
+  //   const cells = this.graph.getSelectedCells()
+  //   ContextMenu.showContextMenu({
+  //     x: e.pageX,
+  //     y: e.pageY,
+  //     items: [
+  //       {
+  //         label: '编辑子流程',
+  //         onClick: () => {
+  //           if (cell) {
+  //             console.log('cell', cell)
+  //           }
+  //         }
+  //       },
+  //       {
+  //         label: '删除节点',
+  //         onClick: () => {
+  //           if (cells.length) {
+  //             this.graph.removeCells(cells)
+  //           }
+  //         }
+  //       },
+  //       {
+  //         label: '置顶',
+  //         onClick: () => {
+  //           if (cells.length) {
+  //             cells.forEach(item => item.toFront({ deep: true }))
+  //           }
+  //         }
+  //       },
+  //       {
+  //         label: '置底',
+  //         onClick: () => {
+  //           if (cells.length) {
+  //             cells.forEach(item => item.toBack({ deep: true }))
+  //           }
+  //         }
+  //       }
+  //     ]
+  //   })
+  // }
 
   // 事件相关
   private static initEvent() {
@@ -508,13 +508,13 @@ export default class FlowGraph {
       }
     })
 
-    graph.on('node:contextmenu', ({ e, x, y, cell, view }) => {
-      const cells = this.graph.getSelectedCells()
-      if (!cells.length) {
-        return
-      }
-      this.handleContextmenu(e, cell)
-    })
+    // graph.on('node:contextmenu', ({ e, x, y, cell, view }) => {
+    //   const cells = this.graph.getSelectedCells()
+    //   if (!cells.length) {
+    //     return
+    //   }
+    //   this.handleContextmenu(e, cell)
+    // })
     // 鼠标动态添加/删除小工具。
     graph.on('edge:mouseenter', ({ cell }) => {
       /**

+ 66 - 0
src/views/test/components/subFlow.vue

@@ -0,0 +1,66 @@
+<template>
+  <el-dialog
+    v-model="visible"
+    :title="`${paramsProps.title}`"
+    :destroy-on-close="true"
+    fullscreen
+    append-to-body>
+    <div>子流程编辑</div>
+    <template #footer>
+      <el-button @click="visible = false"> 取消 </el-button>
+      <el-button type="primary" @click="handleConfirm"> 确定 </el-button>
+    </template>
+  </el-dialog>
+</template>
+
+<script setup lang="ts" name="AddTestCase">
+import { ElMessage } from 'element-plus'
+import { FormInstance } from 'element-plus'
+
+interface DialogProps {
+  api?: (params: any) => Promise<any> // 调用接口
+  title: string // 顶部标题
+  row: Partial<any>
+  getTableList?: () => void
+}
+const visible = ref(false)
+const paramsProps = ref<DialogProps>({
+  title: '',
+  row: {},
+  api: undefined,
+  getTableList: undefined
+})
+
+// emit
+const emit = defineEmits(['submit'])
+
+// 接收父组件传过来的参数
+const acceptParams = (params: DialogProps) => {
+  paramsProps.value = params
+  visible.value = true
+}
+// 提交数据(新增/编辑)
+const ruleFormRef = ref<FormInstance>()
+const handleConfirm = async () => {
+  ruleFormRef.value!.validate(async valid => {
+    if (!valid) return
+    try {
+      const { code } = await paramsProps.value.api!(paramsProps.value.row)
+      if (code == 200) {
+        ElMessage.success({ message: `${paramsProps.value.title}成功!` })
+        paramsProps.value.getTableList!()
+        emit('submit')
+        visible.value = false
+      }
+    } catch (error) {
+      console.log(error)
+    }
+  })
+}
+
+defineExpose({
+  acceptParams
+})
+</script>
+
+<style scoped lang="scss"></style>

+ 71 - 3
src/views/test/flow.vue

@@ -17,12 +17,16 @@
         <ConfigPanel v-if="isReady" />
       </div>
     </div>
+    <SubFlowDialog ref="dialogRef"></SubFlowDialog>
   </div>
 </template>
 <script setup lang="ts">
 import { $, getContainerSize } from '@/utils'
 import FlowGraph from '../graph'
+import ContextMenu from '@imengyu/vue3-context-menu'
+import SubFlowDialog from './components/subFlow.vue'
 
+import { Graph } from '@antv/x6'
 let isReady = ref(false)
 let destroyFn = ref<Function>(() => {})
 onMounted(() => {
@@ -32,23 +36,87 @@ onMounted(() => {
 onUnmounted(() => {
   destroyFn.value()
 })
+
+const graph = ref<Graph>()
+
 const initGraph = () => {
-  const graph = FlowGraph.init(
+  graph.value = FlowGraph.init(
     $('#container'),
     $('#container').getBoundingClientRect().width,
     $('#container').getBoundingClientRect().height
   )
+  graph.value?.on('node:contextmenu', ({ e, x, y, cell, view }) => {
+    const cells = graph.value?.getSelectedCells() || []
+    if (!cells.length) {
+      return
+    }
+    handleContextmenu(e, cell)
+  })
   isReady.value = true
   const resizeFn = () => {
     const { width, height } = getContainerSize($('.panel'))
-    graph.resize(width, height - 38)
+    graph.value?.resize(width, height - 38)
   }
   resizeFn()
   window.addEventListener('resize', resizeFn)
   return () => {
     window.removeEventListener('resize', resizeFn)
-    graph.dispose()
+    graph.value?.dispose()
+  }
+}
+
+// 右键菜单
+const handleContextmenu = (e: { pageX: any; pageY: any }, cell) => {
+  const cells = graph.value?.getSelectedCells() || []
+  ContextMenu.showContextMenu({
+    x: e.pageX,
+    y: e.pageY,
+    items: [
+      {
+        label: '编辑子流程',
+        onClick: () => {
+          if (cell) {
+            openDialog('编辑子流程', null)
+          }
+        }
+      },
+      {
+        label: '删除节点',
+        onClick: () => {
+          if (cells.length) {
+            graph.value?.removeCells(cells)
+          }
+        }
+      },
+      {
+        label: '置顶',
+        onClick: () => {
+          if (cells.length) {
+            cells.forEach(item => item.toFront({ deep: true }))
+          }
+        }
+      },
+      {
+        label: '置底',
+        onClick: () => {
+          if (cells.length) {
+            cells.forEach(item => item.toBack({ deep: true }))
+          }
+        }
+      }
+    ]
+  })
+}
+
+// 打开 dialog
+const dialogRef = ref<InstanceType<typeof SubFlowDialog> | null>(null)
+const openDialog = (title: string, row) => {
+  const params = {
+    title,
+    row: { ...row },
+    isView: title === '查看'
   }
+  dialogRef.value?.acceptParams(params)
 }
 </script>
 <style lang="scss" scoped>