antv x6实现ER图

前端:安装相关依赖 npm install antv/x6   antv/x6-plugin-history  antv/x6-plugin-selection antv/x6-plugin-minimap  @antv/layout

代码参考来源learn-antv-x6: antv/X6学习

antv官网https://antv.antgroup.com/

代码包:链接: https://pan.baidu.com/s/1KotRLKw_1ZhLkTnmycIqpw 提取码: demr 
ErDiagram.vue

<template>
  <div id="dber" class="content">
    <!-- 操作区 -->
    <div class="operating">
      <slot name="titleLeft"></slot>
      <el-button-group key="scale-control">
        <slot name="buttonLeft"></slot>
        <el-tooltip
          class="item"
          effect="light"
          content="新增"
          placement="bottom"
        >
          <el-button size="small" @click="showTable">新增</el-button>
        </el-tooltip>
        <el-tooltip
          class="item"
          effect="light"
          content="删除节点"
          placement="bottom"
        >
          <el-button size="small" :disabled="!canDeleteNode" @click="clearFn">删除节点</el-button>
        </el-tooltip>
        <el-tooltip
          class="item"
          effect="light"
          content="删除关系"
          placement="bottom"
        >
          <el-button size="small" :disabled="!canDeleteEdge" @click="clearEdgeFn">删除关系</el-button>
        </el-tooltip>
        <el-tooltip
          class="item"
          effect="light"
          content="撤销"
          placement="bottom"
        >
          <el-button size="small" :disabled="!canUndo" @click="undoFn">撤销</el-button>
        </el-tooltip>
<!--        <el-tooltip
          class="item"
          effect="light"
          content="重做"
          placement="bottom"
        >
          <el-button size="small" :disabled="!canUndo" @click="redoFn">重做</el-button>
        </el-tooltip>-->
        <el-tooltip
          class="item"
          effect="light"
          content="全景"
          placement="bottom"
        >
          <el-button size="small" @click="getAllEr">全景</el-button>
        </el-tooltip>
        <el-tooltip
          class="item"
          effect="light"
          content="全屏"
          placement="bottom"
        >
          <el-button size="small" @click="toggle">全屏</el-button>
        </el-tooltip>
        <el-tooltip
          class="item"
          effect="light"
          content="组织布局"
          placement="bottom"
        >
          <el-button size="small" @click="getLayout('dagreLayout')">组织布局</el-button>
        </el-tooltip>
        <el-tooltip
          class="item"
          effect="light"
          content="网格布局"
          placement="bottom"
        >
          <el-button size="small" @click="getLayout('gridLayout')">网格布局</el-button>
        </el-tooltip>
        <el-tooltip
          class="item"
          effect="light"
          content="环形布局"
          placement="bottom"
        >
          <el-button size="small" @click="getLayout('circularLayout')">环形布局</el-button>
        </el-tooltip>
<!--        <el-tooltip
          class="item"
          effect="light"
          content="导向布局"
          placement="bottom"
        >
          <el-button size="small" @click="getLayout('forceLayout')">导向布局</el-button>
        </el-tooltip>-->
        <el-tooltip
          class="item"
          effect="light"
          content="放大"
          placement="bottom"
        >
          <el-button
            code="zoomIn"
            size="small"
            icon="el-icon-zoom-in"
            @click="zoomInFn"
          />
        </el-tooltip>
        <el-tooltip
          class="item"
          effect="light"
          content="缩小"
          placement="bottom"
        >
          <el-button
            code="zoomOut"
            size="small"
            icon="el-icon-zoom-out"
            @click="zoomOutFn"
          />
        </el-tooltip>
        <el-tooltip
          class="item"
          effect="light"
          content="返回"
          placement="bottom"
        >
          <el-button size="small" @click="goBack">返回</el-button>
        </el-tooltip>
      </el-button-group>
    </div>
    <div ref="containerRef" class="app-content">
    </div>
    <!-- 缩略图 -->
    <div ref="minimapContainer" class="app-mini"></div>
    <!-- 新增弹框 -->
    <Modal v-model="showTableList" style="padding:10px" width="70%" height="70%" @on-cancel="onClickCancel"
           @on-ok="addNodes">
      <EpSearchBox
        :has-highsearch="true"
        @onSearchBtnClick="onSearchBtnClick"
        @onResetBtnClick="onResetBtnClick">
        <!-- 默认基础搜索条件 -->
        <div slot="default">
          <div class="fn-inline inputel">
            <label class="fn-inline">源名称</label>
            <div class="fn-inline selectinput">
              <Select v-model="searchParams.sourceId" clearable>
                <Option
                  v-for="item in allSourceList"
                  :key="item.pkId"
                  :value="item.pkId"
                >{{ item.domainName }}-{{ item.sourceName }}
                </Option>
              </Select>
            </div>
          </div>
          <div class="fn-inline inputel">
            <label class="fn-inline">表名称</label>
            <div class="fn-inline selectinput">
              <Input
                v-model.trim="searchParams.tableName"
                clearable
                placeholder="按表名称搜索"
              />
            </div>
          </div>
          <div class="fn-inline inputel">
            <label class="fn-inline">是否发布</label>
            <div class="fn-inline selectinput">
              <Select v-model="searchParams.isPublish" clearable>
                <Option
                  v-for="item in isPerfectList"
                  :key="item.value"
                  :value="item.value"
                >{{ item.label }}
                </Option>
              </Select>
            </div>
          </div>
        </div>
      </EpSearchBox>
      <div class="tableBox tablebg">
        <div class="tableTitle">
          <EpTitle>列表</EpTitle>
        </div>
        <div class="table_quality">
          <Table
            ref="selection"
            :columns="tableColumns"
            :data="tableData"
            border
          >
          </Table>
        </div>
        <div class="pagenation">
          <Page
            :total="total"
            :page-size="pageSize"
            :current="pageNo"
            show-elevator
            show-sizer
            show-total
            @on-change="onPageChange"
            @on-page-size-change="onPageSizeChange"
          />
        </div>
      </div>
    </Modal>
  </div>
</template>

<script>
import { Graph, Shape } from '@antv/x6'
import { History } from '@antv/x6-plugin-history'
import { Selection } from '@antv/x6-plugin-selection'
import { MiniMap } from '@antv/x6-plugin-minimap'
// import ErJson from './er2.json'  // 打桩测试
import { random } from '@/utils/commonUtil'
import { fullScreen, exitFullScreen, isFullScreen } from './bom.js'
import Design from '@/components/erDiagram/design'
import metaErApi from '@/api/metaManage/metaErApi.js'
import { GridLayout, DagreLayout, CircularLayout, ForceLayout } from '@antv/layout'
import commonDataSourceManage from '@/api/metaManage/commonDataSourceManage'

const LINE_HEIGHT = 24
const NODE_WIDTH = 250

export default {
  name: 'Er',
  props: {
    // 表ID
    tableId: {
      type: String,
      default: () => {
        return ''
      }
    }
  },
  data() {
    return {
      graph: null,
      canRedo: false,
      canUndo: false,
      canZoomOut: true,
      canDeleteNode: false,
      canDeleteEdge: false,
      selectedNode: {},
      selectedEdge: {},
      type: 'node',
      showTableList: false,
      isFullScreen: false,
      allSourceList: [],
      searchParams: {
        tableName: '',
        tableId: this.tableId,
        sourceId: '',
        isPerfect: '',
        isPublish: ''
      },
      data: {},
      selectedNodeId: '',
      isPerfectList: [
        {
          value: 0,
          label: '未发布'
        },
        {
          value: 1,
          label: '已发布'
        }
      ],
      gridLayout: {},
      circularLayout: {},
      dagreLayout: {},
      forceLayout: {},
      tableColumns: [
        {
          type: 'selection',
          width: 50
        },
        {
          title: '序号',
          type: 'index',
          align: 'center',
          width: 50
        },
        {
          title: '表名称',
          key: 'tableName',
          align: 'center',
          tooltip: true
        },
        {
          title: '表描述',
          key: 'tableDesc',
          align: 'center',
          tooltip: true,
          render: (h, params) => {
            let level = params.row.tableDesc
            let color
            switch (level) {
              case '':
                level = '暂无注释'
                color = '#5f78cf'
                break
              case null:
                level = '暂无注释'
                color = '#5f78cf'
                break
              // 编码不规范,表名称代替
              case '??????????':
                level = params.row.tableName
                color = '#5f78cf'
                break
            }
            return h(
              'span',
              {
                style: {
                  color: color
                }
              },
              level
            )
          }
        },
        {
          title: '所属数据源',
          key: 'schemaName',
          align: 'center',
          tooltip: true
        },
        {
          title: '版本',
          key: 'version',
          align: 'center',
          tooltip: true,
          width: 80,
          render: (h, params) => {
            let level = params.row.version
            let color
            switch (level) {
              case null:
                level = '-'
                color = '#5f78cf'
                break
            }
            return h(
              'span',
              {
                style: {
                  color: color
                }
              },
              level
            )
          }
        },
        {
          title: '状态',
          key: 'status',
          align: 'center',
          width: 80,
          tooltip: true,
          render: (h, params) => {
            let status = params.row.status
            let state, color
            switch (status) {
              case '1':
                state = '已发布'
                color = '#4afa6a'
                break
              default:
                state = '未发布'
                color = '#ff0000'
                break
            }
            return h(
              'span',
              {
                style: { color }
              },
              state
            )
          }
        },
        {
          title: '更新时间',
          key: 'updateTime',
          align: 'center',
          tooltip: true
        }
      ],
      tableData: [],
      total: 0,
      pageNo: 1,
      pageSize: 10,
      count: 10
    }
  },
  mounted() {
    this.getsubear()
    this.getErData()
  },
  updated() {
    const that = this
    window.addEventListener('resize', function () {
      if (!isFullScreen()) {
        if (!isFullScreen()) {
          that.isFullScreen = false
        }
      }
    })
  },
  methods: {
    init() {
      Graph.registerPortLayout(
        'erPortPosition',
        (portsPositionArgs) => {
          return portsPositionArgs.map((_, index) => {
            return {
              position: {
                x: 0,
                y: (index + 1) * LINE_HEIGHT
              },
              angle: 0
            }
          })
        },
        true
      )

      Graph.registerNode(
        'er-rect',
        {
          inherit: 'rect',
          markup: [
            {
              tagName: 'rect',
              selector: 'body'
            },
            {
              tagName: 'text',
              selector: 'label'
            }
          ],
          attrs: {
            rect: {
              strokeWidth: 1,
              stroke: '#5F95FF',
              fill: '#5F95FF'
            },
            label: {
              fontWeight: 'bold',
              fill: '#ffffff',
              fontSize: 12
            }
          },
          ports: {
            groups: {
              list: {
                markup: [
                  {
                    tagName: 'rect',
                    selector: 'portBody'
                  },
                  {
                    tagName: 'text',
                    selector: 'portNameLabel'
                  },
                  {
                    tagName: 'text',
                    selector: 'portTypeLabel'
                  }
                ],
                attrs: {
                  portBody: {
                    width: NODE_WIDTH,
                    height: LINE_HEIGHT,
                    strokeWidth: 1,
                    stroke: '#5F95FF',
                    fill: '#EFF4FF',
                    magnet: true
                  },
                  portNameLabel: {
                    ref: 'portBody',
                    refX: 6,
                    refY: 6,
                    fontSize: 10
                  },
                  portTypeLabel: {
                    ref: 'portBody',
                    refX: 195,
                    refY: 6,
                    fontSize: 10
                  }
                },
                position: 'erPortPosition'
              }
            }
          }
        },
        true
      )
      const containerRef = this.$refs.containerRef
      const graph = new Graph({
        container: containerRef,
        background: {
          color: '#F2F7FA'
        },
        // minZoom: 0.5,
        // maxZoom: 2,
        // 设置边框高亮
        highlighting: {
          // 当连接桩可以被链接时,在连接桩外围渲染一个 2px 宽的红色矩形框
          magnetAvailable: {
            name: 'stroke',
            args: {
              padding: 4,
              attrs: {
                'stroke-width': 2,
                stroke: 'red'
              }
            }
          }
        },
        grid: {
          size: 10, // 网格大小 10px
          visible: true, // 绘制网格,默认绘制 dot 类型网格
          type: 'doubleMesh',
          args: [
            {
              color: '#E7E8EA',
              thickness: 1
            },
            {
              color: '#CBCED3',
              thickness: 1,
              factor: 5
            }
          ]
        },
        connecting: {
          router: {
            name: 'er',
            args: {
              offset: 25,
              direction: 'H'
            }
          },
          createEdge() {
            return new Shape.Edge({
              attrs: {
                line: {
                  sourceMarker: 'block',
                  stroke: '#A2B1C3',
                  strokeWidth: 2
                }
              }
            })
          }
        }
      })
      // 历史插件
      graph.use(
        new History({
          enabled: true
        })
      )
      // 边框选择插件
      graph.use(
        new Selection({
          enabled: true
        })
      )
      const minimapContainer = this.$refs.minimapContainer
      // 小地图
      graph.use(
        new MiniMap({
          container: minimapContainer,
          scalable: true
        })
      )
      /**
       * 布局设置
       */
      // 网格布局
      const gridLayout = new GridLayout({
        type: 'grid',
        // begin: [1, 1], // 开始位置
        center: [200, 200],
        width: 738,
        height: 360,
        sortBy: 'label',
        preventOverlap: true, // 防止重叠
        rows: 3,
        cols: 7,
        nodeSize: [100, 100]
      })
      this.gridLayout = gridLayout
      // 环形布局
      const circularLayout = new CircularLayout({
        type: 'circular',
        center: [350, 250]
      })
      this.circularLayout = circularLayout
      // 组织架构布局
      const dagreLayout = new DagreLayout({
        type: 'dagre',
        begin: [-200, -200],
        preventOverlap: true, // 防止重叠
        rankdir: 'LR', // TB|BT|LR|RL布局的方向。T:top(上);B:bottom(下);L:left(左);R:right(右)
        // align: 'UR', // UL|UR|DL|DR|undefined节点对齐方式。U:upper(上);D:down(下);L:left(左);R:right(右);undefined (居中)
        ranksep: 150, // 节点间距(px)。在 rankdir 为 TB 或 BT 时是节点的水平间距;在 rankdir 为 LR 或 RL 时代表节点的竖直方向间距
        nodesep: 100 // 层间距(px)。在 rankdir 为 TB 或 BT 时是竖直方向相邻层间距;在 rankdir 为 LR 或 RL 时代表水平方向相邻层间距
      })
      this.dagreLayout = dagreLayout
      // 导向布局
      const forceLayout = new ForceLayout({
        type: 'force',
        // center: [369, 180],
        begin: [-200, -200],
        preventOverlap: true
        // linkDistance: (d) => {
        //   if (d.source.id === 'node0') {
        //     return 100
        //   }
        //   return 30
        // },
        // nodeStrength: (d) => {
        //   if (d.isLeaf) {
        //     return -50
        //   }
        //   return -10
        // }
      })
      this.forceLayout = forceLayout
      // 初始化事件
      this.initEvents(graph)
      graph.zoomToFit({ padding: 10, maxScale: 1 })
      console.log('data is ', this.data)
      const model = dagreLayout.layout(this.data)
      // const model = dagreLayout.layout(ErJson)
      graph.fromJSON(model)
      this.graph = graph
    },
    // 初始化事件
    initEvents(graph) {
      // 节点点击
      graph.on('node:click', ({ e, x, y, node, view }) => {
        this.type = 'node'
        console.log(`${this.type}: ${JSON.stringify(node)}`)
        this.canDeleteNode = true
        this.selectedNode = node
      })
      // 监听选中事件
      graph.on('node:selected', ({ node }) => {
        console.log('选择了', node)
        // node.setAttrs({
        //   body: {
        //     stroke: 'red',
        //     strokeWidth: 2
        //   }
        // })
        this.canDeleteNode = true
        this.selectedNode = node
      })

      // 监听取消选中事件
      graph.on('node:unselected', ({ node }) => {
        // 取消高亮节点
        console.log('取消选择', node)
        this.canDeleteNode = false
        this.selectedNode = {}
      })
      // 线单击事件
      graph.on('edge:click', ({ e, x, y, edge, view }) => {
        this.type = 'edge'
        console.log(`${this.type}: ${JSON.stringify(edge)}`)
        this.canDeleteEdge = true
        this.selectedEdge = edge
      })
      // 监听连接取消
      graph.on('edge:unselected', ({ e, x, y, edge, view }) => {
        console.log(`${this.type}: ${JSON.stringify(edge)}`)
        this.canDeleteEdge = false
        this.selectedEdge = {}
      })
      // 线连接事件
      graph.on('edge:connected', ({ isNew, edge }) => {
        if (isNew) {
          // 对新创建的边进行插入数据库等持久化操作
          const source = edge.getSourceCell()
          console.info('source cell of the newly connected edge', JSON.stringify(source))
          console.info('newly created edge', JSON.stringify(edge))
          var params = {
            id: edge.id,
            nodeId: edge.source.cell,
            nodeColumn: edge.source.port,
            targetNodeId: edge.target.cell,
            targetNodeColumn: edge.target.port
          }
          metaErApi.saveEdge(params).then(res => {
            if (res.code === 200) {
              this.canDeleteEdge = true
              this.selectedEdge = edge
            } else {
              this.graph.removeEdge(edge)
              this.$Message.error('请连接正确的字段')
            }
          }).catch(error => {
            this.$Message.error(error)
          })
        }
      })
      // 撤销重做监听
      graph.on('history:change', () => {
        this.canRedo = graph.canRedo()
        this.canUndo = graph.canUndo()
      })
    },
    showTable() {
      this.showTableList = true
      this.getDataAccessInfo()
    },
    addNodes() {
      let self = this
      let rows = this.$refs.selection.getSelection()
      if (rows && rows.length > 0) {
        let pkIds = []
        if (rows) {
          for (let i = 0; i < rows.length; i++) {
            let id = rows[i]['pkId']
            pkIds.push(id)
          }
        }
        let params = {
          ids: pkIds
        }
        metaErApi.createNodes(params).then(res => {
          if (res.code === 200 && res.data) {
            self.graph.addNodes(res.data.nodes)
            // self.graph.addEdges(model.edges)
          } else {
            self.$Message.error('添加数据失败!')
          }
        }).catch(error => {
          self.$Message.error(error)
        })
      } else {
        this.$Message.warning('请选择要添加的数据!')
      }
    },
    onClickCancel() {
      this.showTableList = false
    },
    // 新增节点demo
    addTable() {
      this.count++
      const model = {
        id: this.count,
        shape: 'er-rect',
        label: '测试',
        width: 150,
        height: 24,
        position: {
          x: random(10, 400),
          y: random(10, 400)
        },
        ports: [
          {
            id: '2-1',
            group: 'list',
            attrs: {
              portNameLabel: {
                text: 'ID'
              },
              portTypeLabel: {
                text: 'STRING'
              }
            }
          },
          {
            id: '2-2',
            group: 'list',
            attrs: {
              portNameLabel: {
                text: 'Name'
              },
              portTypeLabel: {
                text: 'STRING'
              }
            }
          }
        ]
      }
      const graph = this.graph
      graph.addNode(model)
    },
    // 重做
    redoFn() {
      if (!this.canRedo) return
      this.graph.redo()
    },
    // 撤消
    undoFn() {
      if (!this.canUndo) return
      this.graph.undo()
    },
    // 删除节点
    clearFn() {
      // this.graph.clearCells()
      metaErApi.deleteNode({ id: this.selectedNode.id }).then(res => {
        if (res.code === 200) {
          this.graph.removeNode(this.selectedNode)
          this.canDeleteNode = false
        }
      }).catch(error => {
        this.$Message.error(error)
      })
    },
    clearEdgeFn() {
      // this.graph.clearCells()
      var params = {
        id: this.selectedEdge.id,
        nodeId: this.selectedEdge.source.cell,
        nodeColumn: this.selectedEdge.source.port,
        targetNodeId: this.selectedEdge.target.cell,
        targetNodeColumn: this.selectedEdge.target.port
      }
      metaErApi.deleteEdge(params).then(res => {
        if (res.code === 200) {
          this.graph.removeEdge(this.selectedEdge)
          this.canDeleteEdge = false
        }
      }).catch(error => {
        this.$Message.error(error)
      })
    },
    // 全屏
    toggle() {
      Design.toggle('dber', this, exitFullScreen, fullScreen)
    },
    // 获取ER图的全景图,展示所有节点的树形关联关系
    getAllEr() {
      metaErApi.findAllNodesByTableId({ id: this.tableId }).then(res => {
        if (res.code === 200) {
          // self.data = JSON.parse(JSON.stringify(res.data))
          this.data = res.data
          const model = this.dagreLayout.layout(this.data)
          this.graph.fromJSON(model)
        } else {
          this.$Message.error('初始化ER图失败!')
        }
      }).catch(error => {
        this.$Message.error(error)
      })
    },
    getLayout(type) {
      switch (type) {
        case 'dagreLayout':
          this.graph.fromJSON(this.dagreLayout.layout(this.data))
          break
        case 'gridLayout':
          this.graph.fromJSON(this.gridLayout.layout(this.data))
          break
        case 'circularLayout':
          this.graph.fromJSON(this.circularLayout.layout(this.data))
          break
        case 'forceLayout':
          this.graph.fromJSON(this.forceLayout.layout(this.data))
          break
        default:
          this.graph.fromJSON(this.dagreLayout.layout(this.data))
          break
      }
    },
    // 放大
    zoomInFn() {
      this.graph.zoom(0.1)
      this.canZoomOut = true
    },
    // 缩小
    zoomOutFn() {
      if (!this.canZoomOut) return
      const Num = Number(this.graph.zoom().toFixed(1))

      if (Num > 0.1) {
        this.graph.zoom(-0.1)
      } else {
        this.canZoomOut = false
      }
    },
    goBack() {
      let crumbsData = this.$store.getters.getCrumbsData
      crumbsData.pop()
      this.$store.commit('dataAccess', crumbsData)
      this.$store.commit('setSourceId', this.$route.params.rows)
      this.$router.go(-1)
    },
    // 分页
    onPageChange(currentPage) {
      this.pageNo = currentPage
      this.getDataAccessInfo()
    },
    onPageSizeChange(pagesize) {
      this.pageNo = 1
      this.pageSize = pagesize
      this.getDataAccessInfo()
    },
    onResetBtnClick() {
      this.searchParams = {
        tableName: '',
        tableId: this.tableId,
        sourceId: '',
        isPerfect: '',
        isPublish: ''
      }
      this.pageNo = 1
      this.pageSize = 10
      this.getDataAccessInfo()
    },
    onSearchBtnClick() {
      this.pageNo = 1
      this.getDataAccessInfo()
    },
    // 查询表已关联的表之外的数据库表列表
    getDataAccessInfo() {
      let self = this
      let params = {
        pageNo: self.pageNo,
        pageSize: self.pageSize
      }
      Object.assign(params, this.searchParams)
      metaErApi.getDataAccessInfoForEr(params).then(res => {
        if (res.code === 200) {
          self.tableData = res.data.items
          self.total = res.data.totalRows
        }
      })
    },
    getsubear() {
      let self = this
      commonDataSourceManage.getShortDbSourceList({}).then(res => {
        if (res.code === 200 && res.data) {
          self.allSourceList = res.data
        } else {
          self.$Message['error']({
            background: true,
            content: '查询数据源数据失败'
          })
        }
      })
    },
    // 查询表已关联的表之外的数据库表列表
    getErData() {
      let self = this
      metaErApi.findNodesByTableId({ id: this.tableId }).then(res => {
        if (res.code === 200) {
          // self.data = JSON.parse(JSON.stringify(res.data))
          self.data = res.data
          console.log(res.data)
          // self.data = ErJson
          self.init()
        } else {
          self.$Message.error('初始化ER图失败!')
        }
      }).catch(error => {
        self.$Message.error(error)
      })
    }
  }
}

</script>
<style scoped>

.content {
  font-family: sans-serif;
  display: flex;
}

.operating {
  display: flex;
  justify-content: space-between;
  position: absolute;
  z-index: 999;
  background-color: #ffffff;
  padding: 10px;
  width: 100%;
  box-shadow: 1px 1px 4px 0 #0a0a0a2e;

  i {
    font-size: 24px;
    cursor: pointer;
    margin: 0 10px;
    color: #515a6e;

    &:hover {
      color: #2d8cf0;
    }

    &.opacity {
      opacity: 0.5;
    }
  }
}

.app-stencil {
  width: 250px;
  border: 1px solid #f0f0f0;
  position: relative;
}

.app-mini {
  position: fixed;
  z-index: 999;
  bottom: 20px;
  right: 20px;
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
}

.app-content {
  flex: 1;
  height: 700px;
//margin-left: 8px; //margin-right: 8px; box-shadow: 0 0 10px 1px #e9e9e9;
}

.x6-graph-scroller {
  border: 1px solid #f0f0f0;
  margin-left: -1px;
}
</style>

bom.js

/**
 *  BOM 模块
 *  @module $ui/utils/bom
 */

/**
 * 浏览器全屏
 * @param {HTMLElement} [el=document] 全屏元素
 */
export function fullScreen(el) {
  el = el || document.documentElement
  const rfs = el.requestFullScreen || el.webkitRequestFullScreen || el.mozRequestFullScreen || el.msRequestFullscreen
  if (typeof rfs !== 'undefined' && rfs) {
    rfs.call(el)
  }
}

/**
 * 退出全屏
 */
export function exitFullScreen() {
  if (document.exitFullscreen) {
    document.exitFullscreen()
  } else if (document.mozCancelFullScreen) {
    document.mozCancelFullScreen()
  } else if (document.webkitCancelFullScreen) {
    document.webkitCancelFullScreen()
  } else if (document.msExitFullscreen) {
    document.msExitFullscreen()
  }
}

/**
 * 浏览器当前是否全屏
 * @return {*|boolean}
 */
export function isFullScreen() {
  return document.isFullScreen || document.mozIsFullScreen || document.webkitIsFullScreen
}

design.js 打桩数据

// TODO:外部js使用vue实例设计
function testVueThis(that) {
  console.log('tool', that, that.type, that.modelId)
}

// 全局加载---覆盖弹窗
function onLoading(that) {
  return that.$loading({
    lock: true,
    text: '正在加载中...',
    spinner: 'el-icon-right',
    background: 'rgba(0, 0, 0, 0.7)'
  })
}

function toggle(ele, that, exitFullScreen, fullScreen) {
  if (that.isFullScreen) {
    exitFullScreen()
    that.isFullScreen = false
  } else {
    fullScreen(document.getElementById(ele))
    that.isFullScreen = true
  }
}

function toggleClass(ele, that, exitFullScreen, fullScreen) {
  if (that.isFullScreen) {
    exitFullScreen()
    that.isFullScreen = false
  } else {
    fullScreen(document.getElementsByClassName(ele))
    that.isFullScreen = true
  }
}

export default {
  testVueThis,
  onLoading,
  toggle,
  toggleClass
}

er2.json

{
  "nodes": [
    {
      "id": "C4C6BA714D62413D904ED6B0F4932EF6",
      "shape": "er-rect",
      "label": "t_task_analysis_info",
      "width": 250,
      "height": 24,
      "ports": [
        {
          "id": "C4C6BA714D62413D904ED6B0F4932EF6-PK_ID",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "PK_ID(主键)"
            },
            "portTypeLabel": {
              "text": "varchar(32)"
            }
          }
        },
        {
          "id": "C4C6BA714D62413D904ED6B0F4932EF6-TASK_CODE",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "TASK_CODE(任务编码)"
            },
            "portTypeLabel": {
              "text": "varchar(50)"
            }
          }
        },
        {
          "id": "C4C6BA714D62413D904ED6B0F4932EF6-TASK_NAME",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "TASK_NAME(任务名称)"
            },
            "portTypeLabel": {
              "text": "varchar(200)"
            }
          }
        },
        {
          "id": "C4C6BA714D62413D904ED6B0F4932EF6-TASK_GROUP",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "TASK_GROUP(任务分组)"
            },
            "portTypeLabel": {
              "text": "varchar(50)"
            }
          }
        },
        {
          "id": "C4C6BA714D62413D904ED6B0F4932EF6-CRON",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "CRON(时间表达式)"
            },
            "portTypeLabel": {
              "text": "varchar(50)"
            }
          }
        },
        {
          "id": "C4C6BA714D62413D904ED6B0F4932EF6-MISFIRE_POLICY",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "MISFIRE_POLICY"
            },
            "portTypeLabel": {
              "text": "varchar(50)"
            }
          }
        },
        {
          "id": "C4C6BA714D62413D904ED6B0F4932EF6-COUNT_POLICY",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "COUNT_POLICY(统计策略1全量2按全年3按月4按日)"
            },
            "portTypeLabel": {
              "text": "varchar(50)"
            }
          }
        },
        {
          "id": "C4C6BA714D62413D904ED6B0F4932EF6-LAST_SYN_TIME",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "LAST_SYN_TIME(最后执行时间)"
            },
            "portTypeLabel": {
              "text": "timestamp"
            }
          }
        },
        {
          "id": "C4C6BA714D62413D904ED6B0F4932EF6-JOB_CONFIG_JSON",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "JOB_CONFIG_JSON(配置JSON)"
            },
            "portTypeLabel": {
              "text": "longtext(4294967295)"
            }
          }
        },
        {
          "id": "C4C6BA714D62413D904ED6B0F4932EF6-REMARK",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "REMARK(备注)"
            },
            "portTypeLabel": {
              "text": "varchar(255)"
            }
          }
        },
        {
          "id": "C4C6BA714D62413D904ED6B0F4932EF6-STATUS",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "STATUS(调度情况0移除调度1加入调度)"
            },
            "portTypeLabel": {
              "text": "varchar(50)"
            }
          }
        },
        {
          "id": "C4C6BA714D62413D904ED6B0F4932EF6-CREATE_TIME",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "CREATE_TIME"
            },
            "portTypeLabel": {
              "text": "timestamp"
            }
          }
        },
        {
          "id": "C4C6BA714D62413D904ED6B0F4932EF6-CREATE_USER_ID",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "CREATE_USER_ID"
            },
            "portTypeLabel": {
              "text": "varchar(32)"
            }
          }
        },
        {
          "id": "C4C6BA714D62413D904ED6B0F4932EF6-CREATE_USER_NAME",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "CREATE_USER_NAME"
            },
            "portTypeLabel": {
              "text": "varchar(50)"
            }
          }
        },
        {
          "id": "C4C6BA714D62413D904ED6B0F4932EF6-UPDATE_TIME",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "UPDATE_TIME"
            },
            "portTypeLabel": {
              "text": "timestamp"
            }
          }
        },
        {
          "id": "C4C6BA714D62413D904ED6B0F4932EF6-UPDATE_USER_ID",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "UPDATE_USER_ID"
            },
            "portTypeLabel": {
              "text": "varchar(32)"
            }
          }
        },
        {
          "id": "C4C6BA714D62413D904ED6B0F4932EF6-UPDATE_USER_NAME",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "UPDATE_USER_NAME"
            },
            "portTypeLabel": {
              "text": "varchar(50)"
            }
          }
        },
        {
          "id": "C4C6BA714D62413D904ED6B0F4932EF6-ORG_ID",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "ORG_ID"
            },
            "portTypeLabel": {
              "text": "varchar(32)"
            }
          }
        },
        {
          "id": "C4C6BA714D62413D904ED6B0F4932EF6-ORG_NAME",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "ORG_NAME"
            },
            "portTypeLabel": {
              "text": "varchar(50)"
            }
          }
        },
        {
          "id": "C4C6BA714D62413D904ED6B0F4932EF6-FLAG_EEMP",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "FLAG_EEMP"
            },
            "portTypeLabel": {
              "text": "char(1)"
            }
          }
        },
        {
          "id": "C4C6BA714D62413D904ED6B0F4932EF6-STATUS_EEMP",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "STATUS_EEMP"
            },
            "portTypeLabel": {
              "text": "char(1)"
            }
          }
        },
        {
          "id": "C4C6BA714D62413D904ED6B0F4932EF6-CONCURRENT",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "CONCURRENT(是否允许并发执行)"
            },
            "portTypeLabel": {
              "text": "varchar(50)"
            }
          }
        },
        {
          "id": "C4C6BA714D62413D904ED6B0F4932EF6-INCREMENT_POINT",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "INCREMENT_POINT"
            },
            "portTypeLabel": {
              "text": "varchar(50)"
            }
          }
        },
        {
          "id": "C4C6BA714D62413D904ED6B0F4932EF6-CRON_NAME",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "CRON_NAME(调度策略)"
            },
            "portTypeLabel": {
              "text": "varchar(50)"
            }
          }
        },
        {
          "id": "C4C6BA714D62413D904ED6B0F4932EF6-COLUMN_ID",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "COLUMN_ID"
            },
            "portTypeLabel": {
              "text": "varchar(32)"
            }
          }
        },
        {
          "id": "C4C6BA714D62413D904ED6B0F4932EF6-SCOLUMN_KEY",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "SCOLUMN_KEY"
            },
            "portTypeLabel": {
              "text": "varchar(20)"
            }
          }
        },
        {
          "id": "C4C6BA714D62413D904ED6B0F4932EF6-DOMAIN_CODE",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "DOMAIN_CODE(数据库分区编码)"
            },
            "portTypeLabel": {
              "text": "varchar(20)"
            }
          }
        },
        {
          "id": "C4C6BA714D62413D904ED6B0F4932EF6-DOMAIN_NAME",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "DOMAIN_NAME(数据库分区名称)"
            },
            "portTypeLabel": {
              "text": "varchar(20)"
            }
          }
        },
        {
          "id": "C4C6BA714D62413D904ED6B0F4932EF6-DATA_SOURCE_ID",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "DATA_SOURCE_ID(数据源ID)"
            },
            "portTypeLabel": {
              "text": "varchar(50)"
            }
          }
        },
        {
          "id": "C4C6BA714D62413D904ED6B0F4932EF6-DATA_SOURCE_NAME",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "DATA_SOURCE_NAME(数据源名称)"
            },
            "portTypeLabel": {
              "text": "varchar(50)"
            }
          }
        },
        {
          "id": "C4C6BA714D62413D904ED6B0F4932EF6-TABLE_NAME",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "TABLE_NAME(源表名称)"
            },
            "portTypeLabel": {
              "text": "varchar(100)"
            }
          }
        },
        {
          "id": "C4C6BA714D62413D904ED6B0F4932EF6-TABLE_COMMENT",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "TABLE_COMMENT(源表注释)"
            },
            "portTypeLabel": {
              "text": "varchar(100)"
            }
          }
        },
        {
          "id": "C4C6BA714D62413D904ED6B0F4932EF6-COLUMN_NAME",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "COLUMN_NAME(原表时间字段名称)"
            },
            "portTypeLabel": {
              "text": "varchar(200)"
            }
          }
        },
        {
          "id": "C4C6BA714D62413D904ED6B0F4932EF6-COLUMN_TYPE",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "COLUMN_TYPE(源表字段类型)"
            },
            "portTypeLabel": {
              "text": "varchar(20)"
            }
          }
        },
        {
          "id": "C4C6BA714D62413D904ED6B0F4932EF6-COLUMN_COMMENT",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "COLUMN_COMMENT(字段注释)"
            },
            "portTypeLabel": {
              "text": "varchar(200)"
            }
          }
        },
        {
          "id": "C4C6BA714D62413D904ED6B0F4932EF6-ORIGIN_CONDITION",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "ORIGIN_CONDITION(源表补充SQL条件)"
            },
            "portTypeLabel": {
              "text": "varchar(200)"
            }
          }
        },
        {
          "id": "C4C6BA714D62413D904ED6B0F4932EF6-TARGET_DOMAIN_CODE",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "TARGET_DOMAIN_CODE(目标源分区)"
            },
            "portTypeLabel": {
              "text": "varchar(20)"
            }
          }
        },
        {
          "id": "C4C6BA714D62413D904ED6B0F4932EF6-TARGET_DOMAIN_NAME",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "TARGET_DOMAIN_NAME(目标源名称)"
            },
            "portTypeLabel": {
              "text": "varchar(50)"
            }
          }
        },
        {
          "id": "C4C6BA714D62413D904ED6B0F4932EF6-TARGET_SOURCE_ID",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "TARGET_SOURCE_ID(目标源ID)"
            },
            "portTypeLabel": {
              "text": "varchar(50)"
            }
          }
        },
        {
          "id": "C4C6BA714D62413D904ED6B0F4932EF6-TARGET_SOURCE_NAME",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "TARGET_SOURCE_NAME(目标源名称)"
            },
            "portTypeLabel": {
              "text": "varchar(50)"
            }
          }
        },
        {
          "id": "C4C6BA714D62413D904ED6B0F4932EF6-TARGET_TABLE_NAME",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "TARGET_TABLE_NAME(目标表名称)"
            },
            "portTypeLabel": {
              "text": "varchar(50)"
            }
          }
        },
        {
          "id": "C4C6BA714D62413D904ED6B0F4932EF6-TARGET_TABLE_COMMENT",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "TARGET_TABLE_COMMENT(目标表注释)"
            },
            "portTypeLabel": {
              "text": "varchar(200)"
            }
          }
        },
        {
          "id": "C4C6BA714D62413D904ED6B0F4932EF6-TARGET_COLUMN_NAME",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "TARGET_COLUMN_NAME(目标表时间字段)"
            },
            "portTypeLabel": {
              "text": "varchar(200)"
            }
          }
        },
        {
          "id": "C4C6BA714D62413D904ED6B0F4932EF6-TARGET_COLUMN_TYPE",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "TARGET_COLUMN_TYPE(目标表时间字段类型)"
            },
            "portTypeLabel": {
              "text": "varchar(20)"
            }
          }
        },
        {
          "id": "C4C6BA714D62413D904ED6B0F4932EF6-TARGET_COLUMN_COMMENT",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "TARGET_COLUMN_COMMENT(目标表时间字段注释)"
            },
            "portTypeLabel": {
              "text": "varchar(200)"
            }
          }
        },
        {
          "id": "C4C6BA714D62413D904ED6B0F4932EF6-TARGET_CONDITION",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "TARGET_CONDITION(目标表补充SQL条件)"
            },
            "portTypeLabel": {
              "text": "varchar(200)"
            }
          }
        },
        {
          "id": "C4C6BA714D62413D904ED6B0F4932EF6-ANALYSIS_CONTENT",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "ANALYSIS_CONTENT(比对内容分析)"
            },
            "portTypeLabel": {
              "text": "text(65535)"
            }
          }
        },
        {
          "id": "C4C6BA714D62413D904ED6B0F4932EF6-ORIGIN_RESULT",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "ORIGIN_RESULT(源表统计信息)"
            },
            "portTypeLabel": {
              "text": "text(65535)"
            }
          }
        },
        {
          "id": "C4C6BA714D62413D904ED6B0F4932EF6-TARGET_RESULT",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "TARGET_RESULT(目标表统计信息)"
            },
            "portTypeLabel": {
              "text": "text(65535)"
            }
          }
        },
        {
          "id": "C4C6BA714D62413D904ED6B0F4932EF6-UPDATE_RULE_SQL",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "UPDATE_RULE_SQL(回调查询语句)"
            },
            "portTypeLabel": {
              "text": "varchar(1000)"
            }
          }
        },
        {
          "id": "C4C6BA714D62413D904ED6B0F4932EF6-LAST_SYN_STATUS",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "LAST_SYN_STATUS(最后执行结果状态0未执行1一致2不一致3异常)"
            },
            "portTypeLabel": {
              "text": "varchar(3)"
            }
          }
        },
        {
          "id": "C4C6BA714D62413D904ED6B0F4932EF6-LAST_SYN_DES",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "LAST_SYN_DES(最后执行情况描述)"
            },
            "portTypeLabel": {
              "text": "text(65535)"
            }
          }
        },
        {
          "id": "C4C6BA714D62413D904ED6B0F4932EF6-DEL_STATUS",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "DEL_STATUS(是否删除)"
            },
            "portTypeLabel": {
              "text": "varchar(1)"
            }
          }
        },
        {
          "id": "C4C6BA714D62413D904ED6B0F4932EF6-JOB_STATUS",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "JOB_STATUS(任务状态)"
            },
            "portTypeLabel": {
              "text": "varchar(10)"
            }
          }
        }
      ]
    },
    {
      "id": "BC0B92A39A5848C597B04033F4BB9F7D",
      "shape": "er-rect",
      "label": "t_task_analysis_log",
      "width": 250,
      "height": 24,
      "ports": [
        {
          "id": "BC0B92A39A5848C597B04033F4BB9F7D-PK_ID",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "PK_ID(主键)"
            },
            "portTypeLabel": {
              "text": "varchar(32)"
            }
          }
        },
        {
          "id": "BC0B92A39A5848C597B04033F4BB9F7D-TASK_ID",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "TASK_ID(任务ID)"
            },
            "portTypeLabel": {
              "text": "varchar(50)"
            }
          }
        },
        {
          "id": "BC0B92A39A5848C597B04033F4BB9F7D-TASK_NAME",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "TASK_NAME(任务名称)"
            },
            "portTypeLabel": {
              "text": "varchar(50)"
            }
          }
        },
        {
          "id": "BC0B92A39A5848C597B04033F4BB9F7D-IP",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "IP(执行IP)"
            },
            "portTypeLabel": {
              "text": "varchar(50)"
            }
          }
        },
        {
          "id": "BC0B92A39A5848C597B04033F4BB9F7D-TASK_GROUP",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "TASK_GROUP(任务分组)"
            },
            "portTypeLabel": {
              "text": "varchar(50)"
            }
          }
        },
        {
          "id": "BC0B92A39A5848C597B04033F4BB9F7D-MESSAGE",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "MESSAGE(任务执行描述)"
            },
            "portTypeLabel": {
              "text": "longtext(4294967295)"
            }
          }
        },
        {
          "id": "BC0B92A39A5848C597B04033F4BB9F7D-STATUS",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "STATUS(任务状态)"
            },
            "portTypeLabel": {
              "text": "varchar(50)"
            }
          }
        },
        {
          "id": "BC0B92A39A5848C597B04033F4BB9F7D-START_TIME",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "START_TIME(开始时间)"
            },
            "portTypeLabel": {
              "text": "timestamp"
            }
          }
        },
        {
          "id": "BC0B92A39A5848C597B04033F4BB9F7D-STOP_TIME",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "STOP_TIME(完成时间)"
            },
            "portTypeLabel": {
              "text": "timestamp"
            }
          }
        },
        {
          "id": "BC0B92A39A5848C597B04033F4BB9F7D-TASK_CREATE_TIME",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "TASK_CREATE_TIME(任务创建时间)"
            },
            "portTypeLabel": {
              "text": "timestamp"
            }
          }
        },
        {
          "id": "BC0B92A39A5848C597B04033F4BB9F7D-TASK_CREATE_USER",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "TASK_CREATE_USER(任务创建人)"
            },
            "portTypeLabel": {
              "text": "varchar(50)"
            }
          }
        },
        {
          "id": "BC0B92A39A5848C597B04033F4BB9F7D-CREATE_TIME",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "CREATE_TIME"
            },
            "portTypeLabel": {
              "text": "timestamp"
            }
          }
        },
        {
          "id": "BC0B92A39A5848C597B04033F4BB9F7D-CREATE_USER_ID",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "CREATE_USER_ID"
            },
            "portTypeLabel": {
              "text": "varchar(32)"
            }
          }
        },
        {
          "id": "BC0B92A39A5848C597B04033F4BB9F7D-CREATE_USER_NAME",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "CREATE_USER_NAME"
            },
            "portTypeLabel": {
              "text": "varchar(50)"
            }
          }
        },
        {
          "id": "BC0B92A39A5848C597B04033F4BB9F7D-UPDATE_TIME",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "UPDATE_TIME"
            },
            "portTypeLabel": {
              "text": "timestamp"
            }
          }
        },
        {
          "id": "BC0B92A39A5848C597B04033F4BB9F7D-UPDATE_USER_ID",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "UPDATE_USER_ID"
            },
            "portTypeLabel": {
              "text": "varchar(32)"
            }
          }
        },
        {
          "id": "BC0B92A39A5848C597B04033F4BB9F7D-UPDATE_USER_NAME",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "UPDATE_USER_NAME"
            },
            "portTypeLabel": {
              "text": "varchar(50)"
            }
          }
        },
        {
          "id": "BC0B92A39A5848C597B04033F4BB9F7D-ORG_ID",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "ORG_ID"
            },
            "portTypeLabel": {
              "text": "varchar(32)"
            }
          }
        },
        {
          "id": "BC0B92A39A5848C597B04033F4BB9F7D-ORG_NAME",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "ORG_NAME"
            },
            "portTypeLabel": {
              "text": "varchar(50)"
            }
          }
        },
        {
          "id": "BC0B92A39A5848C597B04033F4BB9F7D-FLAG_EEMP",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "FLAG_EEMP"
            },
            "portTypeLabel": {
              "text": "char(1)"
            }
          }
        },
        {
          "id": "BC0B92A39A5848C597B04033F4BB9F7D-STATUS_EEMP",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "STATUS_EEMP"
            },
            "portTypeLabel": {
              "text": "char(1)"
            }
          }
        },
        {
          "id": "BC0B92A39A5848C597B04033F4BB9F7D-SPEND",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "SPEND"
            },
            "portTypeLabel": {
              "text": "int"
            }
          }
        },
        {
          "id": "BC0B92A39A5848C597B04033F4BB9F7D-BATCH_ID",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "BATCH_ID(批次ID)"
            },
            "portTypeLabel": {
              "text": "bigint"
            }
          }
        },
        {
          "id": "BC0B92A39A5848C597B04033F4BB9F7D-SIZE",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "SIZE"
            },
            "portTypeLabel": {
              "text": "int"
            }
          }
        },
        {
          "id": "BC0B92A39A5848C597B04033F4BB9F7D-ANALYSIS_CONTENT",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "ANALYSIS_CONTENT(比对内容分析)"
            },
            "portTypeLabel": {
              "text": "text(65535)"
            }
          }
        },
        {
          "id": "BC0B92A39A5848C597B04033F4BB9F7D-ORIGIN_RESULT",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "ORIGIN_RESULT(源表统计信息)"
            },
            "portTypeLabel": {
              "text": "text(65535)"
            }
          }
        },
        {
          "id": "BC0B92A39A5848C597B04033F4BB9F7D-TARGET_RESULT",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "TARGET_RESULT(目标表统计信息)"
            },
            "portTypeLabel": {
              "text": "text(65535)"
            }
          }
        },
        {
          "id": "BC0B92A39A5848C597B04033F4BB9F7D-SYN_STATUS",
          "group": "list",
          "attrs": {
            "portNameLabel": {
              "text": "SYN_STATUS(执行结果状态0未执行1一致2不一致3异常)"
            },
            "portTypeLabel": {
              "text": "varchar(3)"
            }
          }
        }
      ]
    }
  ],
  "edges": [
    {
      "id": "2",
      "shape": "edge",
      "source": {
        "cell": "C4C6BA714D62413D904ED6B0F4932EF6",
        "port": "C4C6BA714D62413D904ED6B0F4932EF6-PK_ID"
      },
      "target": {
        "cell": "BC0B92A39A5848C597B04033F4BB9F7D",
        "port": "BC0B92A39A5848C597B04033F4BB9F7D-TASK_ID"
      },
      "attrs": {
        "line": {
          "stroke": "#A2B1C3",
          "strokeWidth": "2"
        }
      },
      "zIndex": 2
    },
    {
      "shape": "edge",
      "attrs": {
        "line": {
          "stroke": "#A2B1C3",
          "sourceMarker": "block"
        }
      },
      "id": "bf898356-7b05-4b3b-81c7-0f391b97db01",
      "source": {
        "cell": "C4C6BA714D62413D904ED6B0F4932EF6",
        "port": "C4C6BA714D62413D904ED6B0F4932EF6-STATUS"
      },
      "target": {
        "cell": "BC0B92A39A5848C597B04033F4BB9F7D",
        "port": "BC0B92A39A5848C597B04033F4BB9F7D-TASK_CREATE_TIME"
      },
      "zIndex": 2
    }
  ]
}

后端交互js  metaErApi.js

import {
  post
} from '@/api/http'
// 左侧树
const getDataAccessInfoForErUrl = '/meta/metaData/metaEr/getDataAccessInfoForEr'
// 获取所选表创建节点数据
const createNodesUrl = '/meta/metaData/metaEr/createNodes'
// 删除ER图节点
const deleteNodeUrl = '/meta/metaData/metaEr/deleteNode'
// 保存ER图边缘关系
const saveEdgeUrl = '/meta/metaData/metaEr/saveEdge'
// 删除ER图边缘关系
const deleteEdgeUrl = '/meta/metaData/metaEr/deleteEdge'
// 获取表的ER图节点和边缘数据
const findNodesByTableIdUrl = '/meta/metaData/metaEr/findNodesByTableId'
// 获取表的ER图节点和边缘数据
const findAllNodesByTableIdUrl = '/meta/metaData/metaEr/findAllNodesByTableId'
export default {
  getDataAccessInfoForEr(data) {
    return new Promise((resolve, reject) => {
      post(getDataAccessInfoForErUrl, data)
        .then((res) => {
          resolve(res)
        })
        .catch((error) => {
          reject(error)
        })
    })
  },
  // 创建节点数据
  createNodes(data) {
    return new Promise((resolve, reject) => {
      post(createNodesUrl, data)
        .then((res) => {
          resolve(res)
        })
        .catch((error) => {
          reject(error)
        })
    })
  },
  // 获取表的ER图节点直接边缘关系数据
  findNodesByTableId(data) {
    return new Promise((resolve, reject) => {
      post(findNodesByTableIdUrl, data)
        .then((res) => {
          resolve(res)
        })
        .catch((error) => {
          reject(error)
        })
    })
  },
  // 获取表的ER图所有节点边缘关系数据
  findAllNodesByTableId(data) {
    return new Promise((resolve, reject) => {
      post(findAllNodesByTableIdUrl, data)
        .then((res) => {
          resolve(res)
        })
        .catch((error) => {
          reject(error)
        })
    })
  },
  // 删除节点
  deleteNode(data) {
    return new Promise((resolve, reject) => {
      post(deleteNodeUrl, data)
        .then((res) => {
          resolve(res)
        })
        .catch((error) => {
          reject(error)
        })
    })
  },
  // 保存表边缘关系
  saveEdge(data) {
    return new Promise((resolve, reject) => {
      post(saveEdgeUrl, data)
        .then((res) => {
          resolve(res)
        })
        .catch((error) => {
          reject(error)
        })
    })
  },
  // 删除表边缘关系
  deleteEdge(data) {
    return new Promise((resolve, reject) => {
      post(deleteEdgeUrl, data)
        .then((res) => {
          resolve(res)
        })
        .catch((error) => {
          reject(error)
        })
    })
  }
}

CREATE TABLE `t_meta_table`  (
  `PK_ID` varchar(50) CHARACTER SET gbk COLLATE gbk_chinese_ci NOT NULL,
  `SOURCE_ID` varchar(50) CHARACTER SET gbk COLLATE gbk_chinese_ci NULL DEFAULT NULL COMMENT '数据源id',
  `SOURCE_NAME` varchar(50) CHARACTER SET gbk COLLATE gbk_chinese_ci NULL DEFAULT NULL COMMENT '数据源名称',
  `TABLE_NAME` varchar(50) CHARACTER SET gbk COLLATE gbk_chinese_ci NULL DEFAULT NULL COMMENT '表名称',
  `TABLE_DESC` varchar(100) CHARACTER SET gbk COLLATE gbk_chinese_ci NULL DEFAULT NULL COMMENT '表注释',
  `BUSINESS_CODE` varchar(50) CHARACTER SET gbk COLLATE gbk_chinese_ci NULL DEFAULT NULL COMMENT '业务code',
  `BUSINESS_NAME` varchar(100) CHARACTER SET gbk COLLATE gbk_chinese_ci NULL DEFAULT NULL COMMENT '业务名称',
  `SYS_MODULE` varchar(50) CHARACTER SET gbk COLLATE gbk_chinese_ci NULL DEFAULT NULL COMMENT '所属菜单模块',
  `SYS_FUNCTION` varchar(50) CHARACTER SET gbk COLLATE gbk_chinese_ci NULL DEFAULT NULL COMMENT '所属功能',
  `DATA_SOURCE` varchar(50) CHARACTER SET gbk COLLATE gbk_chinese_ci NULL DEFAULT NULL COMMENT '数据来源',
  `USE_DESC` varchar(500) CHARACTER SET gbk COLLATE gbk_chinese_ci NULL DEFAULT NULL COMMENT '使用说明',
  `IS_PERFECT` varchar(50) CHARACTER SET gbk COLLATE gbk_chinese_ci NULL DEFAULT NULL COMMENT '是否完善',
  `DEPARTMENT` varchar(50) CHARACTER SET gbk COLLATE gbk_chinese_ci NULL DEFAULT NULL COMMENT '部门',
  `GENERATION_MODE` varchar(50) CHARACTER SET gbk COLLATE gbk_chinese_ci NULL DEFAULT NULL COMMENT '生成方式',
  `DATA_NUM` varchar(50) CHARACTER SET gbk COLLATE gbk_chinese_ci NULL DEFAULT NULL COMMENT '数据量',
  `DATA_SIZE` varchar(50) CHARACTER SET gbk COLLATE gbk_chinese_ci NULL DEFAULT NULL COMMENT '数据大小',
  `IS_PROSPECT` varchar(50) CHARACTER SET gbk COLLATE gbk_chinese_ci NULL DEFAULT NULL COMMENT '是否勘探',
  `VERSION` varchar(50) CHARACTER SET gbk COLLATE gbk_chinese_ci NULL DEFAULT NULL COMMENT '版本',
  `DEL_STATUS` varchar(50) CHARACTER SET gbk COLLATE gbk_chinese_ci NULL DEFAULT NULL COMMENT '删除状态',
  `CREATE_TIME` varchar(50) CHARACTER SET gbk COLLATE gbk_chinese_ci NULL DEFAULT NULL,
  `UPDATE_TIME` varchar(50) CHARACTER SET gbk COLLATE gbk_chinese_ci NULL DEFAULT NULL,
  `STATUS` char(1) CHARACTER SET gbk COLLATE gbk_chinese_ci NULL DEFAULT NULL COMMENT '状态  0 未发布 1 已发布',
  `DATA_SOURCE_DEPT` varchar(50) CHARACTER SET gbk COLLATE gbk_chinese_ci NULL DEFAULT NULL COMMENT '数据来源部门',
  `IS_COLUMN_PERFECT` varchar(50) CHARACTER SET gbk COLLATE gbk_chinese_ci NULL DEFAULT NULL,
  `UPDATE_TABLE_DETAIL_INFO` longtext CHARACTER SET gbk COLLATE gbk_chinese_ci NULL COMMENT '更新表详细信息JSON',
  `META_TAG` varchar(3500) CHARACTER SET gbk COLLATE gbk_chinese_ci NULL DEFAULT NULL,
  `BACKUPS_STATUS` varchar(1) CHARACTER SET gbk COLLATE gbk_chinese_ci NULL DEFAULT NULL COMMENT '集方式,0自动采集,1手动采集',
  `USE_STATUS` varchar(50) CHARACTER SET gbk COLLATE gbk_chinese_ci NULL DEFAULT NULL COMMENT '是否使用,1:正在使用,0:已停止',
  `SERVICE_PUBLISH` varchar(50) CHARACTER SET gbk COLLATE gbk_chinese_ci NULL DEFAULT NULL,
  PRIMARY KEY (`PK_ID`) USING BTREE,
  INDEX `index_db_tab_isper`(`IS_PERFECT`) USING BTREE,
  INDEX `index_db_tab_tab_name`(`TABLE_NAME`) USING BTREE,
  INDEX `index_db_tab_sou_id`(`SOURCE_ID`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = gbk COLLATE = gbk_chinese_ci ROW_FORMAT = Dynamic;

CREATE TABLE `t_meta_er_node`  (
  `PK_ID` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '主键ID',
  `NODE_LABEL` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '节点名称',
  `META_TABLE_ID` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '表ID',
  `CREATE_TIME` timestamp(0) NULL DEFAULT NULL COMMENT '创建时间',
  `CREATE_USER_ID` varchar(32) CHARACTER SET gbk COLLATE gbk_chinese_ci NULL DEFAULT NULL COMMENT '创建人ID',
  `CREATE_USER_NAME` varchar(50) CHARACTER SET gbk COLLATE gbk_chinese_ci NULL DEFAULT NULL COMMENT '创建人名称',
  `UPDATE_TIME` timestamp(0) NULL DEFAULT NULL COMMENT '更新时间',
  `UPDATE_USER_ID` varchar(32) CHARACTER SET gbk COLLATE gbk_chinese_ci NULL DEFAULT NULL COMMENT '更新人ID',
  `UPDATE_USER_NAME` varchar(50) CHARACTER SET gbk COLLATE gbk_chinese_ci NULL DEFAULT NULL COMMENT '更新人名称',
  `ORG_ID` varchar(32) CHARACTER SET gbk COLLATE gbk_chinese_ci NULL DEFAULT NULL COMMENT '组织ID',
  `ORG_NAME` varchar(50) CHARACTER SET gbk COLLATE gbk_chinese_ci NULL DEFAULT NULL COMMENT '组织名称',
  `FLAG_EEMP` char(1) CHARACTER SET gbk COLLATE gbk_chinese_ci NULL DEFAULT NULL COMMENT '是否删除标志',
  `STATUS_EEMP` char(1) CHARACTER SET gbk COLLATE gbk_chinese_ci NULL DEFAULT NULL COMMENT '操作标记',
  PRIMARY KEY (`PK_ID`) USING BTREE,
  INDEX `idx_er_node_table`(`META_TABLE_ID`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'ER图节点' ROW_FORMAT = Dynamic;

CREATE TABLE `t_meta_er_relation`  (
  `PK_ID` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '主键ID',
  `NODE_ID` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '节点ID',
  `TARGET_NODE_ID` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '对象节点ID',
  `NODE_COLUMN` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '节点关联字段',
  `TARGET_NODE_COLUMN` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '对象节点关联字段',
  `CREATE_TIME` timestamp(0) NULL DEFAULT NULL COMMENT '创建时间',
  `CREATE_USER_ID` varchar(32) CHARACTER SET gbk COLLATE gbk_chinese_ci NULL DEFAULT NULL COMMENT '创建人ID',
  `CREATE_USER_NAME` varchar(50) CHARACTER SET gbk COLLATE gbk_chinese_ci NULL DEFAULT NULL COMMENT '创建人名称',
  `UPDATE_TIME` timestamp(0) NULL DEFAULT NULL COMMENT '更新时间',
  `UPDATE_USER_ID` varchar(32) CHARACTER SET gbk COLLATE gbk_chinese_ci NULL DEFAULT NULL COMMENT '更新人ID',
  `UPDATE_USER_NAME` varchar(50) CHARACTER SET gbk COLLATE gbk_chinese_ci NULL DEFAULT NULL COMMENT '更新人名称',
  `ORG_ID` varchar(32) CHARACTER SET gbk COLLATE gbk_chinese_ci NULL DEFAULT NULL COMMENT '组织ID',
  `ORG_NAME` varchar(50) CHARACTER SET gbk COLLATE gbk_chinese_ci NULL DEFAULT NULL COMMENT '组织名称',
  `FLAG_EEMP` char(1) CHARACTER SET gbk COLLATE gbk_chinese_ci NULL DEFAULT NULL COMMENT '是否删除标志',
  `STATUS_EEMP` char(1) CHARACTER SET gbk COLLATE gbk_chinese_ci NULL DEFAULT NULL COMMENT '操作标记',
  PRIMARY KEY (`PK_ID`) USING BTREE,
  INDEX `idx_unique_relation`(`NODE_ID`, `TARGET_NODE_ID`, `NODE_COLUMN`, `TARGET_NODE_COLUMN`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'ER图关系表(关联关系会相互保存)' ROW_FORMAT = Dynamic;

效果图

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/624946.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C++笔试强训day22

目录 1.添加字符 2.数组变换 3.装箱问题 常规一维优化&#xff1a; 1.添加字符 链接 因为lenA < lenB < 50&#xff0c;因此可以无脑暴力解题&#xff1a; 遍历所有符合条件的匹配方法&#xff0c;找出最小的不同的数量&#xff0c;即最大的相同的数量 #include &…

react18【系列实用教程】useEffect —— 副作用操作 (2024最新版)

什么是副作用操作&#xff1f; useEffect 用于编写由渲染本身引起的对接组件外部的操作&#xff08;官方称呼为&#xff1a;副作用操作&#xff09; 以下情况会触发页面渲染 初次加载页面&#xff08;组的挂载&#xff09;响应式变量发生变化&#xff0c;触发页面根据新值重新…

生活服务商家拥抱数字化,鸿运果系统加速“服务生意数字化”进程

在数字化转型的大潮中&#xff0c;生活服务商家正积极拥抱变革&#xff0c;以适应新的市场环境和消费者需求。鸿运果系统作为专业的“服务生意”数字化解决方案提供商&#xff0c;正助力商家加速数字化转型&#xff0c;推动行业向智能化、个性化服务转型。 数字化转型的背景 …

ORACLE ODA一体机存储节点电源故障的分析处理

近期&#xff0c;某用户的ORACLE ODA一体机在例行机房巡检时出现亮黄灯告警&#xff1b;用户反馈次问题后我们立刻通过远程方式&#xff0c;登陆ODA的控制台进行查看&#xff1b; 对于ODA一体机&#xff08;2个计算节点1个存储节点&#xff09;&#xff0c;计算节点可以通过il…

USB3.0接口——(3)协议层(包格式)

7.协议层 7.1.超高速传输事务 超高速事务&#xff08;SuperSpeed transactions&#xff09;由主机对设备端点请求或发送数据开始&#xff0c;并在端点发送数据或确认收到数据时完成。超高速总线上的数据传输&#xff08;transfer&#xff09;是主机请求设备应用程序生成的数据…

在做题中学习(58):和为K的子数组

560. 和为 K 的子数组 - 力扣&#xff08;LeetCode&#xff09; 因为是判断子数组的和 要返回 k 的次数&#xff0c;所以 解法&#xff1a;前缀和 哈希表 提出一个概念&#xff1a;以下标i为结尾的所有子数组 那要找出所有和 k的子数组 就相当于&#xff1a;找出所有值为…

高端智能终端RK3399主板在配送机器人项目的应用,支持免费定制

基于高端智能终端主板IoT-3399E推出了系列配送机器人&#xff0c;面向各类线下门店的配送服务。配送机器人可实现智能识别、精准配送、自动避障、自主调度系统、语音播报、信息互动等功能&#xff0c;大幅提升服务效率&#xff0c;为消费者带来更加便捷、智能的服务体验。 核心…

Zab之光:照亮分布式系统数据一致性迷宫的智慧火把

关注微信公众号 “程序员小胖” 每日技术干货&#xff0c;第一时间送达&#xff01; 引言 在构建大型分布式系统时&#xff0c;数据一致性是我们必须面对的挑战之一。随着业务的增长和系统规模的扩大&#xff0c;如何保证在多个节点间复制的数据保持一致&#xff0c;成为了一…

keepalived双机热备超详细入门介绍

keepalived 一、keepalived入门介绍 1.keepalived简介 2.keepalived服务的三个重要功能 2.1.管理LVS负载均衡软件 2.2.实现对LVS集群节点健康检查功能 2.3.作为系统网络服务的高可用功能 3.keepalived高可用故障切换转移原理 4.keepalived安装及主配置文件介绍 …

图搜索算法-最短路径算法-贝尔曼-福特算法

相关文章&#xff1a; 数据结构–图的概念 图搜索算法 - 深度优先搜索法&#xff08;DFS&#xff09; 图搜索算法 - 广度优先搜索法&#xff08;BFS&#xff09; 图搜索算法 - 拓扑排序 图搜索算法-最短路径算法-戴克斯特拉算法 贝尔曼-福特算法&#xff08;Bellman-Ford&#…

OpenAI春季发布会, GPT-4o引爆科技圈 |千字文全面解读

今天&#xff0c;OpenAI再一次引爆了科技圈。这次的核心亮点无疑是他们的全新模型&#xff1a;GPT-4o&#xff0c;以及基于此模型构建的全新ChatGPT版本。 GPT-4o是什么&#xff1f; OpenAI 最新推出的 GPT-4o&#xff0c;“o”代表“Omni”&#xff0c;这一拉丁词根在英语中常…

CentOS报错: Fontconfig head is null, check your fonts or fonts configuration

错误 解决方案 这个报错的原因时java读取本地字体时发现字体损坏或者缺失&#xff0c;只需要补充一下字体就可以了&#xff0c;解决方法安装FontConfig组件即可&#xff1a; sudo yum install fontconfig

弥合孤岛:克服构建 DevOps 文化的挑战

持续变革正在发生软件开发行业。DevOps 因其对自动化、协作和持续改进的关注而成为优化软件交付并弥合开发和运营团队之间鸿沟的重要方法。然而&#xff0c;过渡到真正的 DevOps 文化并非没有挑战。本文探讨了您在追求 DevOps 时可能面临的障碍并提供了解决方案。 01 了解 Dev…

JINGWHALE 数字认证体系 · 进阶知识库

JINGWHALE 数字认证体系 是 JINGWHALE 数字科学艺术创新中心 的数字认证服务。 ◢◤ 宗旨 致力于数字化知行合一的知识赋能&#xff01; ◥ 数字化人才培养 培养数字化思维&#xff0c;传播数字化知识&#xff0c;赋能各行业数字化。 ◥ 职业人才发展 无缝衔接学校高等…

Databend 开源周报第 144 期

Databend 是一款现代云数仓。专为弹性和高效设计&#xff0c;为您的大规模分析需求保驾护航。自由且开源。即刻体验云服务&#xff1a;https://app.databend.cn 。 Whats On In Databend 探索 Databend 本周新进展&#xff0c;遇到更贴近你心意的 Databend 。 了解 Databend …

有一个21年的前端vue项目,死活安不上依赖

在公司开发的时候遇到的一个很玄幻的问题,这个项目是21年开发的,现在我是24年中途二开增加新功能 这个项目经过多人之手,现在已经出现了问题------项目依赖安不上,我能启动完全是因为在23年的时候写这个项目的时候将依赖费九牛二虎之力下载好后打成了压缩包发给另外一个安不上依…

分析 vs2019 c++ 中的 decltype 与 declval

&#xff08;1&#xff09; decltype 可以让推断其参数的类型。按住 ctrl 点击 decltype &#xff0c;会发现无法查阅 其定义 &#xff1a; &#xff08;2&#xff09; 但 STL 库里咱们可以查阅函数 declval 的 定义&#xff0c;很短&#xff0c;摘抄如下&#xff1a; templat…

PostgreSQL源码安装

文章目录 一、先决条件检查二、源码安装1、获取源代码2、编译安装1.运行 configure2.运行make 3、PostgreSQL的配置4、安装contrib目录下的工具 三、初始化数据库1、创建数据库管理员2、创建数据库实例3、启动和停止数据库4、设置数据库密码 四、PostgreSQL的简单配置1、pg_hba…

Java项目实现报文数据校验注解方式(必输项、值大小)

普通项目 导入校验依赖 <dependency><groupId>org.hibernate</groupId><artifactId>hibernate-validator</artifactId><version>4.1.0.Final</version></dependency><dependency><groupId>javax.validation</…

系统定期执行命令的方法

系统定期执行命令的方法 一、进入超级用户下 执行命令&#xff1a;sudo su 二、添加要执行的命令 例子&#xff1a;每天0点执行一次myapp.sh命令 先后输入&#xff1a;crontab -e、 1、 回车 设置每天0点执行一次myapp.sh操作&#xff0c;需要写绝对路径 含义&#xff1…