Procházet zdrojové kódy

替换机构树图

zhengnaiwen_citu před 5 měsíci
rodič
revize
85aa863d1d

+ 5 - 0
src/api/system.js

@@ -169,6 +169,11 @@ export function getOrganizationAtlasEmployee (params) {
   return http.post('/organization/employee/atlas', params)
 }
 
+// 机构人员 树状结构
+export function getOrganizationAndEmployeeTree (params) {
+  return http.post('/digitizationData/employee/organization/tree/all', params)
+}
+
 // 机构图钻取岗位图例
 export function getOrganizationAtlasPostName (params) {
   return http.post('/digitizationData/employee/postName/atlas', params)

+ 0 - 5
src/components/AutoComponents/ECharts/eCharts.js

@@ -42,11 +42,6 @@ class EChartsComponent {
   getEl () {
     return this.el
   }
-
-  // 设置属性
-  setOption (options) {
-    this.el.setOption(options)
-  }
 }
 
 export default EChartsComponent

+ 98 - 54
src/views/humanResources/organizationStructure/index.vue

@@ -1,24 +1,24 @@
 <template>
   <div class="fullBox white pa-3 relative" ref="boxRef">
     <e-charts ref="eCharts" class="fullBox"></e-charts>
-      <div class="btnBox pa-1">
-        <m-button type="orange" icon="el-icon-download" size="small" :loading="exportLoading" @click="onExport">导出</m-button>
-        <m-button type="orange" icon="el-icon-plus" size="small" @click="onAdd">新增机构</m-button>
-      </div>
-      <div ref="contextMenuRefs" class="contextMenu">
-        <el-card shadow="always" :body-style="{padding: 0}">
-          <div
-            v-for="menu in menus"
-            :key="menu.prop"
-            class="contextMenuItem pa-3"
-            @click="onMenuClick(menu.prop)"
-          >
-            {{ menu.label }}
-          </div>
-        </el-card>
-      </div>
-      <OrganizationEdit ref="organizationEditRefs" @refresh="onRefresh"></OrganizationEdit>
-      <OrganizationAdd ref="organizationAddRefs" @refresh="onRefresh"></OrganizationAdd>
+    <div class="btnBox pa-1">
+      <m-button type="orange" icon="el-icon-download" size="small" :loading="exportLoading" @click="onExport">导出</m-button>
+      <m-button type="orange" icon="el-icon-plus" size="small" @click="onAdd">新增机构</m-button>
+    </div>
+    <div ref="contextMenuRefs" class="contextMenu" v-show="contextMenuShow">
+      <el-card shadow="always" :body-style="{padding: 0}">
+        <div
+          v-for="menu in menus"
+          :key="menu.prop"
+          class="contextMenuItem pa-3"
+          @click="onMenuClick(menu.prop)"
+        >
+          {{ menu.label }}
+        </div>
+      </el-card>
+    </div>
+    <OrganizationEdit ref="organizationEditRefs" @refresh="onRefresh"></OrganizationEdit>
+    <OrganizationAdd ref="organizationAddRefs" @refresh="onRefresh"></OrganizationAdd>
   </div>
 </template>
 
@@ -27,7 +27,7 @@ import OrganizationEdit from './organizationEdit.vue'
 import OrganizationAdd from './organizationAdd.vue'
 
 import {
-  getOrganizationAtlas,
+  getOrganizationAndEmployeeTree,
   // getOrganizationAtlasEmployee,
   importOrganization,
   exportOrganization,
@@ -39,7 +39,6 @@ import {
   upload,
   download
 } from '@/utils/elementUploadAndDownload'
-
 export default {
   name: 'organization-structure',
   components: {
@@ -48,6 +47,7 @@ export default {
   },
   data () {
     return {
+      contextMenuShow: false,
       menus: [
         { label: '编辑', prop: 'edit' },
         { label: '删除', prop: 'delete' }
@@ -76,9 +76,12 @@ export default {
             symbolSize: 15,
             label: {
               position: 'left',
-              verticalAlign: 'middle',
+              borderColor: '#000',
+              // backgroundColor: '#ff650e',
+              // verticalAlign: 'middle',
               align: 'right',
-              fontSize: 16
+              fontSize: 16,
+              silent: false
             },
             leaves: {
               label: {
@@ -87,12 +90,9 @@ export default {
                 align: 'left'
               }
             },
-            emphasis: {
-              focus: 'descendant'
-            },
             initialTreeDepth: 1,
             roam: true,
-            expandAndCollapse: true,
+            expandAndCollapse: false,
             animationDuration: 550,
             animationDurationUpdate: 750
           }
@@ -103,50 +103,95 @@ export default {
   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.seriesData = await this.onInit()
       this.graph.setOption(this.option)
       this.graph.hideLoading()
+      this.graph.on('click', (params) => {
+        const data = getData(params.data.id, this.seriesData)
+        if (params.event.target.type === 'tspan') {
+          this.nodes = data
+          this.onGraphHandles(params.event.event)
+          return
+        }
+        this.show = false
+        if (!params.data.children || !params.data.children.length) {
+          return
+        }
+        data.collapsed = !data.collapsed
+        this.graph.setOption(this.option)
+      })
+      // 关闭
+      this.graph.getZr().on('click', (event) => {
+        if (event.target?.type !== 'tspan') {
+          this.contextMenuShow = false
+        }
+      })
+      this.graph.on('treeroam', (event) => {
+        this.contextMenuShow = false
+      })
     })
 
-    // this.$nextTick(() => {
-    //   this.$refs.boxRef.addEventListener('contextmenu', (e) => {
-    //     e.preventDefault()
-    //   })
-    // })
+    function getData (id, data) {
+      if (data.id === id) {
+        return data
+      }
+      if (data.children && data.children.length) {
+        for (const item of data.children) {
+          const result = getData(id, item)
+          if (result) {
+            return result
+          }
+        }
+      }
+      return null
+    }
+  },
+  beforeDestroy () {
+    if (!this.graph) {
+      return
+    }
+    this.graph.off('click')
+    this.graph.off('treeroam')
   },
-  // beforeDestroy () {
-  //   this.$refs.boxRef.removeEventListener('contextmenu', (e) => {
-  //     e.preventDefault()
-  //   })
-  // },
   methods: {
     async onInit () {
       this.loading = true
       try {
-        const { data } = await getOrganizationAtlas()
-        const { nodes, edges } = data
-        const graphData = {
-          nodes: nodes.map(e => {
-            return {
-              ...e,
-              getChildren: this.getChildren
-            }
-          }),
-          edges
+        const { data } = await getOrganizationAndEmployeeTree({})
+        return changeChildToChildren(data)
+        function changeChildToChildren (obj, currentDepth = 1, maxDepth = 2) {
+          const { child, ..._obj } = obj
+          _obj.collapsed = currentDepth >= maxDepth
+          if (child && child.length) {
+            _obj.children = child.map(e => changeChildToChildren(e, currentDepth + 1, maxDepth))
+          }
+          return _obj
         }
-        return graphData
       } catch (error) {
         this.$message.error(error)
-        return { nodes: [], edges: [] }
+        return {}
       } finally {
         this.loading = false
       }
     },
-
+    onGraphHandles (e) {
+      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 { x, y } = e
+      content.x = x
+      content.y = y
+      contextMenu.style.left = x - left + 'px'
+      contextMenu.style.top = y - top + 'px'
+      this.contextMenuShow = true
+    },
     async onDelete (nodes) {
       this.$confirm('是否删除该项', '提示').then(async () => {
         try {
@@ -204,7 +249,6 @@ export default {
 
 <style lang="scss" scoped>
 .contextMenu {
-  display: none;
   position: absolute;
   width: 200px;
 }