schangxiang@126.com
2025-05-07 cace264ad9d86a7831099810b079da1141957add
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
import G6, { Graph } from '@antv/g6'
import styles from './ToolBar.module.scss'
import { h, createApp } from 'vue'
import ToolBar from './ToolBar'
import { generateFlowXml, importXmlInit } from '../../core/transformHelp'
import { ElMessage } from 'element-plus'
import { injectStore } from '../../core/store'
import { _t } from '@/libs/Language/Language'
 
export default class ToolBarDefine {
  #className: string
  #toolBarInstance: any
  #downName: string | undefined
  #format?: () => void
  #animateCfg = { duration: 200, easing: 'easeCubic' }
  constructor({ className, format, downName }: any) {
    this.#className = className
    this.#format = format
    this.#downName = downName
  }
  get container() {
    return document.querySelector(`.${this.#className}`)
  }
  get getContent() {
    return () => {
      const div = document.createElement('div')
 
      const app = createApp(() => {
        return <ToolBar />
      })
      app.mount(div)
      return div
    }
  }
 
  removeNode(dom: HTMLElement | HTMLInputElement) {
    const t = setTimeout(() => {
      dom.remove()
      clearTimeout(t)
    }, 2000)
  }
  handleClick(code: string, graph: Graph) {
    const { flowBaseConfig } = injectStore()
    if (this.#toolBarInstance) {
      const toolBar: typeof G6.ToolBar | any = this.#toolBarInstance
 
      const fnMap: Record<string, () => void> = {
        redo: () => {
          toolBar.redo()
        },
        undo: () => {
          toolBar.undo()
        },
        enlarge: () => {
          graph.zoom(1.1, { x: 0, y: 0 }, true, this.#animateCfg)
        },
        reduce: () => {
          graph.zoom(0.9, { x: 0, y: 0 }, true, this.#animateCfg)
        },
        format: () => {
          this.#format && this.#format()
        },
        export: () => {
          const xml = generateFlowXml(graph)
          const blob = new Blob([xml], { type: 'text/xml' })
          const url = URL.createObjectURL(blob)
          const a = document.createElement('a')
          a.href = url
          const { name, type, version } = flowBaseConfig.value
          const flowName = `${name}_${type}_${version}`
          a.download = flowName + '.pfd'
          a.click()
          ElMessage.success(_t('导出成功'))
          URL.revokeObjectURL(url)
          this.removeNode(a)
        },
        import: () => {
          const fileInput = document.createElement('input')
          fileInput.type = 'file'
          fileInput.accept = 'application/pfd'
          fileInput.click()
          fileInput.onchange = (e: any) => {
            const file = e.target.files[0]
            const reader = new FileReader()
            reader.readAsText(file)
            reader.onload = (e: any) => {
              const xml = e.target.result
              importXmlInit(graph, xml)
              ElMessage.success(_t('导入成功'))
              this.removeNode(fileInput)
            }
          }
        },
        download: () => {
          const oldRatio = window.devicePixelRatio
          window.devicePixelRatio = 3
          graph.downloadFullImage(this.#downName, 'image/png', {
            backgroundColor: '#fff',
            padding: 10,
          })
          setTimeout(() => {
            window.devicePixelRatio = oldRatio
          }, 0)
        },
      }
      const fn = fnMap[code]
      fn && fn()
    }
  }
  instanceToolBar() {
    this.#toolBarInstance = new G6.ToolBar({
      container: this.container as any,
      getContent: this.getContent,
      handleClick: this.handleClick.bind(this) as () => void,
    })
    return this.#toolBarInstance
  }
}