blob: 4d3515c9ae5f65800400831212084a672ebd751d [file]
<!--
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
-->
<template>
<div class="custom-menu" v-if="fromType">
<!-- <div class="menu-title">内容管理</div>
<div class="menu-search">
<el-input
placeholder="搜索"
v-model="keyWord">
<i slot="suffix" class="el-input__icon el-icon-search"></i>
</el-input>
<div class="menu-search-container" v-show="searchBox">
<div class="menu-search-item" v-for="item in searchList"
:key="item.id" @click="handleSearchMenuClick(item)">{{item.title}}</div>
<div class="menu-search--empty" v-show="searchList.length == 0">暂无数据</div>
</div>
</div> -->
<el-menu
:default-active="defaultActive"
class="custom-menu-container"
@open="handleOpen"
@close="handleClose">
<div v-for="(item, index) in menuList" :key="index">
<el-submenu v-if="item.children.length >= 0" :index="item.id">
<template slot="title">{{item.name}}</template>
<el-menu-item :index="String(child.id)" @click="handleMenuClick(child)"
:data-index="child.id"
v-for="(child, childIdx) in item.children"
:key="childIdx">{{child.name}}</el-menu-item>
</el-submenu>
<!-- <el-menu-item v-if="item.children.length === 0"
:index="item.index"
:data-index="item.index"
@click="handleMenuClick(item)">{{item.title}}</el-menu-item> -->
</div>
</el-menu>
</div>
</template>
<script>
import {getLocationSearchObj} from '@/utils/common.js'
import {mapMutations, mapGetters} from 'vuex'
import {clearLocalStorage} from '@/utils/auth.js'
const debounce = require('lodash/debounce')
import {menuList} from '@/api/menu-config.js'
export default {
name: 'CustomMenu',
data () {
return {
defaultActive: '', // active menu
menuList: menuList, // menu list
searchList: [], // search list
keyWord: '', // keyword
searchBox: false, // search area
fromType: true, // true: 显示原有内容, false:隐藏部分内容 是否嵌入到其他项目中,需要对应隐藏部分内容(菜单,header)
}
},
watch: {
keyWord (val) {
if (val !== '' && val !== undefined) {
this.searchBox = true
this.handleSearch()
} else {
this.searchBox = false
}
}
},
methods: {
...mapMutations(['setOrgId', 'setCurrentMenu']),
// clear page cache
clearPagination () {
clearLocalStorage('picTxtIdx')
clearLocalStorage('picTxtSize')
},
// 搜索过滤菜单内容
handleSearch: debounce(function () {
this.$get('/menu/search', {
keyWord: this.keyWord
}).then(res => {
if (res.code === 200) {
this.searchList = res.data
}
}).catch(err => {
console.log(err)
})
}, 200),
handleScrollPosition () {
let el = document.querySelector('.custom-menu-container')
let top = el.scrollTop
let current = document.querySelector(`[data-index=${this.defaultActive}]`)
let y = current.getBoundingClientRect().y
top = top + y - 60 - 56
el.scrollTop = top
},
handleSearchMenuClick (item) {
this.keyWord = ''
this.searchBox = false
this.searchList = []
this.handleMenuClick(item)
this.defaultActive = item.index
setTimeout(() => {
this.handleScrollPosition()
}, 300)
},
switchRouter (item) {
this.clearPagination()
this.$router.push({
path: item.componentName,
query: {
id: new Date().getTime()
}
})
let el = document.querySelector('.page-content .el-scrollbar__wrap')
if (el) {
el.scrollTop = 0
}
},
handleMenuClick (item) {
this.switchRouter(item)
},
handleOpen(key, keyPath) {
// console.log(key, keyPath)
},
handleClose(key, keyPath) {
// console.log(key, keyPath)
},
initMenu () {
// 0: default load method
// 1: external tool open
// 2: new window open
// 3: cover current window open
// 4: cloud listen backend content embed
// 5: notice not open
// 6: application router jump
console.log(this.menuList)
let findShow = this.menuList.find(item => item.children.length>0)
if(findShow){
this.initDefaultActive()
}else{
// this.$router.push({
// path:'/403'
// })
}
return;
// var type = current.openType
this.$get('/menu/getMenuList').then(res => {
if (res.code === 200 && res.data && res.data.length > 0) {
this.menuList = res.data
let findShow = this.menuList.find(item => item.children.length>0)
if(findShow){
this.initDefaultActive()
}else{
this.$router.push({
path:'/403'
})
}
} else {
this.$router.push({
path:'/403'
})
// this.$message.error(res.msg)
}
}).catch(err => {
console.log(err)
})
},
// special active menu
initDefaultActive () {
let index, current
// if set active menu, then show active menu
let params = getLocationSearchObj()
if (params.menuId !== undefined) {
let list = this.menuList
list = list.map(item => {
return [item].concat(item.children)
})
list = list.flat(Infinity)
current = list.find(item => item.id == params.menuId)
index = current.id
} else {
// using the first menu item, if there is a submenu, then use the first active
for (let i = 0; i < this.menuList.length; i++) {
let item = this.menuList[i]
if (item.children && item.children.length > 0) {
current = item.children[0]
index = current.id
break
}
}
}
if (current) {
this.defaultActive = index
this.switchRouter(current)
}
},
init() {
let params = getLocationSearchObj()
this.fromType = params.from == 1 ? false : true // hide header and menu on formType = 1
},
},
created () {
this.initMenu()
this.init()
}
}
</script>
<style lang="less" scoped>
.custom-menu {
height: 100vh;
}
.menu-title {
height: 60px;
line-height: 60px;
font-size: 15px;
font-weight: 600;
color: #000000;
padding-left: 20px;
border-bottom: 1px solid #dcdfe6;
box-sizing: border-box;
}
.custom-menu-container {
height: calc(100% - 60px - 56px);
overflow-y: auto;
overflow-x: hidden;
}
.menu-search {
position: relative;
height: 56px;
padding: 12px 8px;
box-sizing: border-box;
}
.menu-search-container {
position: absolute;
top: 45px;
left: 8px;
width: 134px;
min-height: 178px;
max-height: 300px;
border-radius: 4px;
border: 1px solid #DCDFE6;
z-index: 200;
background: #FFF;
overflow-x: hidden;
overflow-y: auto;
box-sizing: border-box;
}
.menu-search-item {
height: 40px;
line-height: 40px;
padding-left: 30px;
min-width: auto;
cursor: pointer;
box-sizing: border-box;
&:hover {
background-color: #E6E6E6 !important;
color: #303133 !important;
}
}
.menu-search--empty {
text-align: center;
padding-top: 40px;
color: #909399;
}
</style>