280 lines
		
	
	
		
			7.7 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
			
		
		
	
	
			280 lines
		
	
	
		
			7.7 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
| <template>
 | |
|   <div class="AiGrid" ref="container">
 | |
|     <div
 | |
|       class="AiGrid-wrapper"
 | |
|       ref="tree"
 | |
|       id="tree"
 | |
|       :style="{left: x, top: y, transform: `scale(${scale}) translate(-50%, -50%) `, 'transform-origin': `${0} ${0}`}">
 | |
|       <VueOkrTree
 | |
|         :props="props"
 | |
|         node-key="id"
 | |
|         show-collapsable
 | |
|         show-node-num
 | |
|         current-lable-class-name="aigrid-active"
 | |
|         :default-expanded-keys="defaultExpandedKeys"
 | |
|         ref="VueOkrTree"
 | |
|         @node-click="onNodeClick"
 | |
|         :data="treeData">
 | |
|       </VueOkrTree>
 | |
|     </div>
 | |
|   </div>
 | |
| </template>
 | |
| 
 | |
| <script>
 | |
|   import { VueOkrTree } from 'vue-okr-tree'
 | |
|   import 'vue-okr-tree/dist/vue-okr-tree.css'
 | |
| 
 | |
|   export default {
 | |
|     name: 'AiGrid',
 | |
| 
 | |
|     props: ['instance'],
 | |
| 
 | |
|     components: {
 | |
|       VueOkrTree
 | |
|     },
 | |
| 
 | |
|     data () {
 | |
|       return {
 | |
|         scale: 1,
 | |
|         x: '50%',
 | |
|         y: '50%',
 | |
|         defaultExpandedKeys: [],
 | |
|         treeData: [],
 | |
|         props: {
 | |
|           label: 'girdName',
 | |
|           children: 'children'
 | |
|         }
 | |
|       }
 | |
|     },
 | |
| 
 | |
|     mounted () {
 | |
|       this.bindEvent()
 | |
|       this.getPartyOrg()
 | |
|     },
 | |
| 
 | |
|     destroyed () {
 | |
|       document.querySelector('body').removeEventListener('mousewheel', this.onMousewheel)
 | |
|       document.querySelector('body').removeEventListener('mouseup', this.onMouseUp)
 | |
|       document.querySelector('body').removeEventListener('mousedown', this.onMousedown)
 | |
|       document.querySelector('body').removeEventListener('mousemove', this.onMouseMove)
 | |
|     },
 | |
| 
 | |
|     methods: {
 | |
|       bindEvent () {
 | |
|         document.querySelector('body').addEventListener('mousewheel', this.onMousewheel, true)
 | |
|         document.querySelector('body').addEventListener('mouseup', this.onMouseUp, true)
 | |
|         document.querySelector('body').addEventListener('mousedown', this.onMousedown, true)
 | |
|         document.querySelector('body').addEventListener('mousemove', this.onMouseMove, true)
 | |
|       },
 | |
| 
 | |
|       onMousewheel (event) {
 | |
|         if (!event) return false
 | |
|         const elClass = event.target.className
 | |
|         if (elClass === 'tree' || elClass === 'middle' || (elClass && (elClass.indexOf('chart') > -1 || elClass.indexOf('user') > -1))) {
 | |
|           var dir = event.deltaY > 0 ? 'Up' : 'Down'
 | |
|           if (dir === 'Up') {
 | |
|             this.scale = this.scale - 0.2 <= 0.1 ? 0.1 : this.scale - 0.2
 | |
|           } else {
 | |
|             this.scale = this.scale + 0.2
 | |
|           }
 | |
|         }
 | |
| 
 | |
|         return false
 | |
|       },
 | |
| 
 | |
|       onMousedown (e) {
 | |
|         const elClass = e.target.className
 | |
|         if ((elClass && (elClass.indexOf('chart') > -1 || elClass.indexOf('user') > -1))) {
 | |
|           const left = document.querySelector('#tree').offsetLeft
 | |
|           const top = document.querySelector('#tree').offsetTop
 | |
|           this.isMove = true
 | |
|           this.offsetX = e.clientX - left
 | |
|           this.offsetY = e.clientY - top
 | |
|         }
 | |
|       },
 | |
| 
 | |
|       onMouseMove (e) {
 | |
|         if (!this.isMove) return
 | |
| 
 | |
|         this.x = (e.clientX - this.offsetX) + 'px'
 | |
|         this.y = (e.clientY - this.offsetY) + 'px'
 | |
|       },
 | |
| 
 | |
|       onMouseUp () {
 | |
|         this.isMove = false
 | |
|       },
 | |
| 
 | |
|       onNodeClick (e) {
 | |
|         this.$emit('nodeClick', e)
 | |
|       },
 | |
| 
 | |
|       getPartyOrg () {
 | |
|         this.instance.post('/app/appgirdinfo/listAll3').then(res => {
 | |
|           if (res.code === 0) {
 | |
|             this.treeData = res.data.filter(e => !e.parentGirdId)
 | |
|             const parentGirdId = this.treeData[0].id
 | |
|             const arr = res.data.filter(v => {
 | |
|               return v.parentGirdId === parentGirdId || !v.parentGirdId
 | |
|             })
 | |
|             this.treeData.map(p => this.addChild(p, arr.map(v => {
 | |
|               if (v.id === parentGirdId) {
 | |
|                 this.defaultExpandedKeys.push(v.id)
 | |
|               }
 | |
| 
 | |
|               return {
 | |
|                 ...v,
 | |
|                 girdName: v.girdName.substr(0, 8)
 | |
|               }
 | |
|             }), {
 | |
|               parent: 'parentGirdId'
 | |
|             }))
 | |
| 
 | |
|             this.$nextTick(() => {
 | |
|               this.autoScale()
 | |
|               this.$refs.VueOkrTree.setCurrentKey(parentGirdId)
 | |
|             })
 | |
|           }
 | |
|         })
 | |
|       },
 | |
| 
 | |
|       autoScale () {
 | |
|         const treeWidth = this.$refs.tree.offsetWidth
 | |
|         const containerWidth = this.$refs.container.offsetWidth - 100
 | |
|         this.scale = treeWidth < containerWidth ? 1 : containerWidth / treeWidth
 | |
|         this.x = '50%'
 | |
|         this.y = '50%'
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| </script>
 | |
| 
 | |
| <style lang="scss" scoped>
 | |
|   .AiGrid {
 | |
|     position: relative;
 | |
|     width: 100%;
 | |
|     height: 100%;
 | |
|     overflow: hidden;
 | |
|     box-sizing: border-box;
 | |
| 
 | |
|     .AiGrid-wrapper {
 | |
|       display: flex;
 | |
|       position: absolute;
 | |
|       align-items: center;
 | |
|       left: 50%;
 | |
|       top: 50%;
 | |
|       padding: 20px;
 | |
|       overflow: hidden;
 | |
|       width: max-content;
 | |
|       height: 300%;
 | |
|     }
 | |
| 
 | |
|     .aigrid-active {
 | |
|       background: linear-gradient(180deg, #42C6CE 0%, #307598 100%);
 | |
|     }
 | |
| 
 | |
|     ::v-deep .org-chart-container {
 | |
|       color: #FFFFFF;
 | |
|       font-size: 16px;
 | |
| 
 | |
|       .org-chart-node-btn {
 | |
|         border: 1px solid #23A0AC!important;
 | |
|         font-size: 16px;
 | |
|         font-weight: bold;
 | |
|         background: #071030;
 | |
|         color: #FF9A02;
 | |
| 
 | |
|         &:after, &::before {
 | |
|           display: none;
 | |
|         }
 | |
| 
 | |
|         &.expanded::before {
 | |
|           display: block;
 | |
|           position: absolute;
 | |
|           top: 50%;
 | |
|           left: 4px;
 | |
|           right: 4px;
 | |
|           height: 0;
 | |
|           border-top: 1px solid #FF9A02;
 | |
|           content: "";
 | |
|         }
 | |
| 
 | |
|         .org-chart-node-btn-text {
 | |
|           background: transparent;
 | |
|           color: #FF9A02;
 | |
|         }
 | |
|       }
 | |
| 
 | |
|       .org-chart-node {
 | |
|         // overflow: hidden;
 | |
| 
 | |
|         .org-chart-node-label {
 | |
|           width: 40px;
 | |
|           height: 230px;
 | |
|           margin-right: 15px;
 | |
|           padding: 0 0;
 | |
| 
 | |
|           .org-chart-node-label-inner {
 | |
|             width: 40px!important;
 | |
|             height: 230px!important;
 | |
|             border: 1px solid;
 | |
|             background: linear-gradient(180deg, rgba(69,210,218,0.2500) 0%, rgba(69,210,218,0.1000) 100%)!important;
 | |
|             border-image: linear-gradient(180deg, rgba(5, 185, 203, 1), rgba(73, 214, 207, 1)) 1 1!important;
 | |
|             line-height: 1.3;
 | |
|             padding: 10px 4px;
 | |
|             text-align: center;
 | |
|             font-size: 18px;
 | |
|             color: rgba(255, 255, 255, 0.8);
 | |
| 
 | |
|             &.aigrid-active {
 | |
|               background: linear-gradient(180deg, #42C6CE 0%, #307598 100%)!important;
 | |
|             }
 | |
|           }
 | |
| 
 | |
|           &.is-root-label {
 | |
|             width: auto!important;
 | |
|             min-width: 240px;
 | |
|             height: 40px!important;
 | |
|             line-height: 40px!important;
 | |
|             min-height: 40px!important;
 | |
|             text-align: center;
 | |
| 
 | |
|             .org-chart-node-label-inner {
 | |
|               padding: 0 30px!important;
 | |
|               color: #fff!important;
 | |
|               width: auto!important;
 | |
|               min-width: 240px;
 | |
|               height: 40px!important;
 | |
|               line-height: 40px!important;
 | |
|               min-height: 40px!important;
 | |
|               text-align: center;
 | |
|               background: linear-gradient(180deg, rgba(69,210,218,0.2500) 0%, rgba(69,210,218,0.1000) 100%)!important;
 | |
|               border-image: linear-gradient(180deg, rgba(5, 185, 203, 1), rgba(73, 214, 207, 1)) 1 1!important;
 | |
| 
 | |
|               &.aigrid-active {
 | |
|                 background: linear-gradient(180deg, #42C6CE 0%, #307598 100%)!important;
 | |
|               }
 | |
|             }
 | |
|           }
 | |
|         }
 | |
| 
 | |
|         &:last-child {
 | |
|           .org-chart-node-label {
 | |
|             margin-right: 0;
 | |
|           }
 | |
|         }
 | |
|       }
 | |
| 
 | |
|       .org-chart-node-children:before, .org-chart-node:after, .org-chart-node:last-child:before,
 | |
|       .org-chart-node.is-leaf:before {
 | |
|         border-radius: 0;
 | |
|         border-color: #23A0AC!important;
 | |
|       }
 | |
| 
 | |
|       .vertical .org-chart-node:after, .vertical .org-chart-node:before {
 | |
|         border-radius: 0;
 | |
|         border-color: #23A0AC!important;
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| </style>
 |