index.vue 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. <template>
  2. <div class="workflow">
  3. <TeleportContainer/>
  4. <el-button style="position: absolute; top: 0;left: 0; z-index: 2" type="primary" @click="getJsonData">保存配置</el-button>
  5. <div class="workflow-chart">
  6. <workflowChart :data="state.workflowData" ref="ref_workflow"/>
  7. </div>
  8. <workflowPanel v-model:show="state.showPanel" :node="state.currentNode"/>
  9. </div>
  10. </template>
  11. <script setup lang="ts">
  12. import {getCurrentInstance, onMounted, provide, reactive, ref} from "vue";
  13. import workflowChart from './chart/index.vue'
  14. import workflowPanel from './panel/index.vue'
  15. import { getTeleport, register } from '@antv/x6-vue-shape'
  16. import {data} from './mockJson'
  17. import {WorkflowFunc} from "@/views/workflow/types";
  18. import WorkflowNode from "@/views/workflow/nodes/index.vue";
  19. import {lineStyle, portStyle} from "@/views/workflow/config";
  20. import {Markup} from "@antv/x6";
  21. const TeleportContainer = getTeleport()
  22. register({
  23. shape: 'workflow-node',
  24. component: WorkflowNode,
  25. })
  26. const emits = defineEmits([])
  27. const props = defineProps({})
  28. const {proxy}: any = getCurrentInstance()
  29. const state: any = reactive({
  30. workflowData: null,
  31. showPanel: false,
  32. currentNode: null,
  33. })
  34. const ref_workflow = ref()
  35. provide('workflowFunc', <WorkflowFunc>{
  36. nodeClick: (node) => {
  37. state.currentNode = node
  38. state.showPanel = true
  39. }
  40. })
  41. const getJsonData = () => {
  42. const data = ref_workflow.value.toJSON()
  43. console.log(data)
  44. }
  45. const initData = () => {
  46. const formatData = (data) => {
  47. const res: any = {
  48. nodes: [],
  49. edges: [],
  50. }
  51. data.nodes.forEach((v) => {
  52. const node = {
  53. ...v,
  54. shape: 'workflow-node',
  55. portMarkup: [Markup.getForeignObjectMarkup()],
  56. ports: {
  57. groups: {
  58. start: {
  59. ...portStyle,
  60. position: {
  61. name: 'left',
  62. }
  63. },
  64. end: portStyle,
  65. more: portStyle,
  66. },
  67. items: []
  68. }
  69. }
  70. if (v.data.type !== 'root') {
  71. node.ports.items.push({
  72. id: `${v.id}_start`,
  73. group: 'start'
  74. },)
  75. }
  76. if (v.data.ports?.length > 0) {
  77. v.data.ports.forEach((p, pI) => {
  78. const offset = 50
  79. node.ports.items.push({
  80. id: p.id,
  81. group: 'more',
  82. args: {
  83. dy: offset
  84. }
  85. },)
  86. })
  87. } else {
  88. node.ports.items.push({
  89. id: `${v.id}_end`,
  90. group: 'end'
  91. })
  92. }
  93. res.nodes.push(node)
  94. })
  95. data.edges.forEach((v) => {
  96. const edge = {
  97. ...v,
  98. shape: 'edge',
  99. attrs: lineStyle,
  100. router: {
  101. name: 'manhattan',
  102. args: {
  103. startDirections: ['right'],
  104. endDirections: ['left'],
  105. },
  106. },
  107. }
  108. edge.source = {
  109. cell: v.source,
  110. port: v.port || `${v.source}_end`
  111. }
  112. edge.target = {
  113. cell: v.target,
  114. port: `${v.target}_start`
  115. }
  116. res.edges.push(edge)
  117. })
  118. return res
  119. }
  120. state.workflowData = formatData(data)
  121. }
  122. onMounted(() => {
  123. initData()
  124. })
  125. </script>
  126. <style lang="scss" scoped>
  127. .workflow {
  128. width: 100%;
  129. height: 100%;
  130. display: flex;
  131. align-items: center;
  132. justify-content: center;
  133. position: relative;
  134. .workflow-chart {
  135. width: 100%;
  136. height: 100%;
  137. z-index: 1;
  138. }
  139. }
  140. </style>