|
@@ -1,16 +1,8 @@
|
|
|
<template>
|
|
|
<div class="fullBox white pa-3 relative" ref="boxRef">
|
|
|
- <!-- <div v-if="isIE">
|
|
|
- IE浏览器暂不支持浏览,请前往其他浏览器获取更好体验
|
|
|
- </div> -->
|
|
|
- <!-- <template v-else> -->
|
|
|
- <div ref="graphRef" v-loading="loading" class="fullBox"></div>
|
|
|
+ <e-charts ref="eCharts" class="fullBox"></e-charts>
|
|
|
<div class="btnBox pa-1">
|
|
|
- <!-- <el-upload class="el-button pa-0" action="#" :show-file-list="false" :http-request="onImport">
|
|
|
- <m-button type="orange" icon="el-icon-upload2" size="small" :loading="importLoading">导入</m-button>
|
|
|
- </el-upload> -->
|
|
|
<m-button type="orange" icon="el-icon-download" size="small" :loading="exportLoading" @click="onExport">导出</m-button>
|
|
|
- <!-- <m-button type="orange" icon="el-icon-download" size="small" :loading="downloadLoading" @click="onDownload">模板下载</m-button> -->
|
|
|
<m-button type="orange" icon="el-icon-plus" size="small" @click="onAdd">新增机构</m-button>
|
|
|
</div>
|
|
|
<div ref="contextMenuRefs" class="contextMenu">
|
|
@@ -27,31 +19,16 @@
|
|
|
</div>
|
|
|
<OrganizationEdit ref="organizationEditRefs" @refresh="onRefresh"></OrganizationEdit>
|
|
|
<OrganizationAdd ref="organizationAddRefs" @refresh="onRefresh"></OrganizationAdd>
|
|
|
- <!-- </template> -->
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
import OrganizationEdit from './organizationEdit.vue'
|
|
|
import OrganizationAdd from './organizationAdd.vue'
|
|
|
-import {
|
|
|
- CollapseExpandTree,
|
|
|
- MindMapNode
|
|
|
-} from '@/utils/antvG6'
|
|
|
-import {
|
|
|
- isIE
|
|
|
-} from '@/utils'
|
|
|
-import {
|
|
|
- Graph,
|
|
|
- register,
|
|
|
- NodeEvent,
|
|
|
- CommonEvent,
|
|
|
- CanvasEvent,
|
|
|
- ExtensionCategory
|
|
|
-} from '@antv/g6'
|
|
|
+
|
|
|
import {
|
|
|
getOrganizationAtlas,
|
|
|
- getOrganizationAtlasEmployee,
|
|
|
+ // getOrganizationAtlasEmployee,
|
|
|
importOrganization,
|
|
|
exportOrganization,
|
|
|
downloadOrganization,
|
|
@@ -63,28 +40,6 @@ import {
|
|
|
download
|
|
|
} from '@/utils/elementUploadAndDownload'
|
|
|
|
|
|
-const NODE_TYPE = {
|
|
|
- type: 'MindMapNode',
|
|
|
- style: function (d) {
|
|
|
- return {
|
|
|
- fill: '#ff650e',
|
|
|
- size: 15,
|
|
|
- label: true,
|
|
|
- labelFontSize: 14,
|
|
|
- labelLineHeight: 20,
|
|
|
- labelPlacement: 'right',
|
|
|
- labelPadding: [10],
|
|
|
- labelText: d.name,
|
|
|
- labelOffsetX: d.depth === 3 ? 20 : 50,
|
|
|
- labelBackground: true,
|
|
|
- labelBackgroundFill: '#EFF0F0',
|
|
|
- labelBackgroundRadius: 8,
|
|
|
- port: true,
|
|
|
- ports: [{ placement: 'right' }, { placement: 'left' }]
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
export default {
|
|
|
name: 'organization-structure',
|
|
|
components: {
|
|
@@ -93,7 +48,6 @@ export default {
|
|
|
},
|
|
|
data () {
|
|
|
return {
|
|
|
- isIE: isIE(),
|
|
|
menus: [
|
|
|
{ label: '编辑', prop: 'edit' },
|
|
|
{ label: '删除', prop: 'delete' }
|
|
@@ -103,55 +57,73 @@ export default {
|
|
|
importLoading: false,
|
|
|
exportLoading: false,
|
|
|
downloadLoading: false,
|
|
|
- graph: null
|
|
|
+ graph: null,
|
|
|
+ seriesData: {}
|
|
|
}
|
|
|
},
|
|
|
computed: {
|
|
|
- ...mapGetters(['organizationTree'])
|
|
|
- },
|
|
|
- async mounted () {
|
|
|
- // if (isIE()) {
|
|
|
- // return
|
|
|
- // }
|
|
|
- register(ExtensionCategory.BEHAVIOR, 'collapse-expand-tree', CollapseExpandTree)
|
|
|
- register(ExtensionCategory.NODE, 'MindMapNode', MindMapNode)
|
|
|
- const graphData = await this.onInit()
|
|
|
- this.$nextTick(() => {
|
|
|
- this.initGraph(graphData)
|
|
|
- this.$refs.boxRef.addEventListener('contextmenu', (e) => {
|
|
|
- e.preventDefault()
|
|
|
- })
|
|
|
- })
|
|
|
- },
|
|
|
- beforeDestroy () {
|
|
|
- // if (isIE()) {
|
|
|
- // return
|
|
|
- // }
|
|
|
- if (this.graph) {
|
|
|
- this.graph.off()
|
|
|
+ ...mapGetters(['organizationTree']),
|
|
|
+ option () {
|
|
|
+ return {
|
|
|
+ series: [
|
|
|
+ {
|
|
|
+ type: 'tree',
|
|
|
+ data: [this.seriesData],
|
|
|
+ top: '1%',
|
|
|
+ left: '7%',
|
|
|
+ bottom: '1%',
|
|
|
+ right: '20%',
|
|
|
+ symbolSize: 15,
|
|
|
+ label: {
|
|
|
+ position: 'left',
|
|
|
+ verticalAlign: 'middle',
|
|
|
+ align: 'right',
|
|
|
+ fontSize: 16
|
|
|
+ },
|
|
|
+ leaves: {
|
|
|
+ label: {
|
|
|
+ position: 'right',
|
|
|
+ verticalAlign: 'middle',
|
|
|
+ align: 'left'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ emphasis: {
|
|
|
+ focus: 'descendant'
|
|
|
+ },
|
|
|
+ initialTreeDepth: 1,
|
|
|
+ roam: true,
|
|
|
+ expandAndCollapse: true,
|
|
|
+ animationDuration: 550,
|
|
|
+ animationDurationUpdate: 750
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ }
|
|
|
}
|
|
|
- this.$refs.boxRef.removeEventListener('contextmenu', (e) => {
|
|
|
- e.preventDefault()
|
|
|
+ },
|
|
|
+ mounted () {
|
|
|
+ this.$nextTick(async () => {
|
|
|
+ this.graph = this.$refs.eCharts.onInit()
|
|
|
+ console.log(211, this.graph)
|
|
|
+ this.graph.showLoading()
|
|
|
+ const { data } = await this.onInit()
|
|
|
+ this.seriesData = data
|
|
|
+
|
|
|
+ this.graph.setOption(this.option)
|
|
|
+ this.graph.hideLoading()
|
|
|
})
|
|
|
+
|
|
|
+ // this.$nextTick(() => {
|
|
|
+ // this.$refs.boxRef.addEventListener('contextmenu', (e) => {
|
|
|
+ // e.preventDefault()
|
|
|
+ // })
|
|
|
+ // })
|
|
|
},
|
|
|
+ // beforeDestroy () {
|
|
|
+ // this.$refs.boxRef.removeEventListener('contextmenu', (e) => {
|
|
|
+ // e.preventDefault()
|
|
|
+ // })
|
|
|
+ // },
|
|
|
methods: {
|
|
|
- async initData () {
|
|
|
- await this.$store.dispatch('system/getOrganizationTree')
|
|
|
- const data = await this.onInit()
|
|
|
- return data
|
|
|
- },
|
|
|
- async onRefresh () {
|
|
|
- const data = await this.initData()
|
|
|
- this.renderGraph(data)
|
|
|
- },
|
|
|
- drawGraph (data) {
|
|
|
- this.graph.setData(data)
|
|
|
- this.graph.draw()
|
|
|
- },
|
|
|
- async renderGraph (data) {
|
|
|
- this.graph.setData(data)
|
|
|
- await this.graph.render()
|
|
|
- },
|
|
|
async onInit () {
|
|
|
this.loading = true
|
|
|
try {
|
|
@@ -174,134 +146,7 @@ export default {
|
|
|
this.loading = false
|
|
|
}
|
|
|
},
|
|
|
- async initGraph (data) {
|
|
|
- this.graph = new Graph({
|
|
|
- container: this.$refs.graphRef,
|
|
|
- width: this.$refs.graphRef.clientWidth,
|
|
|
- height: this.$refs.graphRef.clientHeight,
|
|
|
- data,
|
|
|
- autoFit: 'center',
|
|
|
- autoResize: false,
|
|
|
- enable: false,
|
|
|
- plugins: [
|
|
|
- // 'minimap',
|
|
|
- // 'contextmenu',
|
|
|
- {
|
|
|
- className: 'toolbar',
|
|
|
- position: 'right-top',
|
|
|
- type: 'toolbar',
|
|
|
- getItems: () => [
|
|
|
- { id: 'zoom-in', value: 'zoom-in' },
|
|
|
- { id: 'zoom-out', value: 'zoom-out' },
|
|
|
- { id: 'auto-fit', value: 'auto-fit' }
|
|
|
- ],
|
|
|
- onClick: (value) => {
|
|
|
- const zoom = this.graph.getZoom()
|
|
|
- // 处理按钮点击事件
|
|
|
- if (value === 'zoom-in') {
|
|
|
- if (zoom > 2) {
|
|
|
- return
|
|
|
- }
|
|
|
- this.graph.zoomTo(zoom + 0.1)
|
|
|
- } else if (value === 'zoom-out') {
|
|
|
- if (zoom < 0.5) {
|
|
|
- return
|
|
|
- }
|
|
|
- this.graph.zoomTo(zoom - 0.1)
|
|
|
- } else if (value === 'auto-fit') {
|
|
|
- this.graph.fitView()
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- ],
|
|
|
- behaviors: [
|
|
|
- 'drag-canvas',
|
|
|
- 'scroll-canvas',
|
|
|
- 'drag-element',
|
|
|
- 'collapse-expand-tree'
|
|
|
- ],
|
|
|
- animation: false,
|
|
|
- layout: {
|
|
|
- type: 'compact-box',
|
|
|
- getHeight: function getHeight () {
|
|
|
- return 32
|
|
|
- },
|
|
|
- getWidth: function getWidth () {
|
|
|
- return 32
|
|
|
- },
|
|
|
- getVGap: function getVGap (e) {
|
|
|
- return 8
|
|
|
- },
|
|
|
- getHGap: function getHGap (e) {
|
|
|
- return 150
|
|
|
- },
|
|
|
- radial: false
|
|
|
- },
|
|
|
- node: NODE_TYPE,
|
|
|
- edge: {
|
|
|
- type: 'cubic-horizontal',
|
|
|
- style: function (d) {
|
|
|
- return {
|
|
|
- endArrow: true,
|
|
|
- lineWidth: 1,
|
|
|
- stroke: '#aaa'
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- })
|
|
|
- this.onGraphHandles(this.graph)
|
|
|
- await this.graph.render()
|
|
|
- this.onSetClose(data.nodes)
|
|
|
- },
|
|
|
- onGraphHandles (graph) {
|
|
|
- const contextMenu = this.$refs.contextMenuRefs
|
|
|
- const { width, height } = this.$refs.boxRef.getBoundingClientRect()
|
|
|
- const { left, top } = this.$refs.boxRef.getBoundingClientRect()
|
|
|
- const content = {
|
|
|
- x: 0,
|
|
|
- y: 0,
|
|
|
- width,
|
|
|
- height
|
|
|
- }
|
|
|
|
|
|
- const contextMenuClick = (e) => {
|
|
|
- const { target } = e // 获取被点击节点的 ID
|
|
|
- this.nodes = graph.getNodeData(target.id)
|
|
|
- const { x, y } = e.client
|
|
|
- content.x = x
|
|
|
- content.y = y
|
|
|
- contextMenu.style.left = x - left + 'px'
|
|
|
- contextMenu.style.top = y - top + 'px'
|
|
|
- contextMenu.style.display = 'block'
|
|
|
- }
|
|
|
- const hideContextMenu = () => {
|
|
|
- contextMenu.style.display = 'none'
|
|
|
- }
|
|
|
- graph
|
|
|
- .on(NodeEvent.CONTEXT_MENU, contextMenuClick)
|
|
|
- .on(NodeEvent.CLICK, contextMenuClick)
|
|
|
- .on(CommonEvent.WHEEL, hideContextMenu) // 鼠标滚动
|
|
|
- .on(CanvasEvent.CONTEXT_MENU, hideContextMenu) // 画布空白右键
|
|
|
- // .on(CanvasEvent.CONTEXT_MENU, e => {
|
|
|
- // e.preventDefault()
|
|
|
- // document.body.style.cursor = 'default'
|
|
|
- // hideContextMenu()
|
|
|
- // }) // 画布空白右键
|
|
|
- .on(CanvasEvent.CLICK, hideContextMenu) // 画布空白点击
|
|
|
- .on(CanvasEvent.DRAG_START, hideContextMenu) // 画布拖拽
|
|
|
- .on(NodeEvent.DRAG_START, hideContextMenu) // 节点拖拽
|
|
|
- },
|
|
|
- // 设置默认展示格式
|
|
|
- onSetClose (nodes) {
|
|
|
- // 默认展示第一层
|
|
|
- nodes.forEach(e => {
|
|
|
- if (e.depth === 1) {
|
|
|
- this.graph.collapseElement(e.id)
|
|
|
- }
|
|
|
- })
|
|
|
- // 关闭之后重新排版计算
|
|
|
- this.graph.render()
|
|
|
- },
|
|
|
async onDelete (nodes) {
|
|
|
this.$confirm('是否删除该项', '提示').then(async () => {
|
|
|
try {
|
|
@@ -316,31 +161,7 @@ export default {
|
|
|
}
|
|
|
}).catch(_ => {})
|
|
|
},
|
|
|
- async getChildren (organizationNo) {
|
|
|
- try {
|
|
|
- const { data } = await getOrganizationAtlasEmployee({ organizationNo })
|
|
|
- return {
|
|
|
- nodes: data.nodes.map(e => {
|
|
|
- const { labelOffsetX, ...obj } = NODE_TYPE
|
|
|
- return {
|
|
|
- id: e.id,
|
|
|
- name: e.text,
|
|
|
- hasChildren: false,
|
|
|
- depth: 3,
|
|
|
- ...obj
|
|
|
- }
|
|
|
- }),
|
|
|
- edges: data.lines.map(e => {
|
|
|
- return {
|
|
|
- source: e.from,
|
|
|
- target: e.to
|
|
|
- }
|
|
|
- })
|
|
|
- }
|
|
|
- } catch (error) {
|
|
|
- this.$message.error(error)
|
|
|
- }
|
|
|
- },
|
|
|
+ onRefresh () {},
|
|
|
onMenuClick (prop) {
|
|
|
if (prop === 'edit') {
|
|
|
this.editTag(this.nodes)
|
|
@@ -388,7 +209,6 @@ export default {
|
|
|
width: 200px;
|
|
|
}
|
|
|
.fullBox {
|
|
|
- display: -ms-grid; /* IE10/11 */
|
|
|
width: 100%;
|
|
|
height: 100%;
|
|
|
box-sizing: border-box;
|