<template>
<el-menu
:default-active="activeMenu"
class="flex1"
:collapse="menuStore.menuIsCollapse"
:collapse-transition="false"
popper-effect="dark"
>
<!-- 快捷菜单 -->
<el-sub-menu
index="1"
v-if="
!menuStore.menuIsCollapse ||
(menuStore.menuIsCollapse &&
personalStore.quickMenu &&
personalStore.quickMenu.length)
"
>
<template #title>
<img src="@/img/shortcutMenu.png" alt="" class="menuIcon" />
<span>快捷菜单</span>
</template>
<el-menu-item
class="menuItem"
:index="item.url"
v-for="(item, index) in personalStore.quickMenu"
:key="index"
@click="changeMenu(item.url)"
@mouseover="showIcon(item.url, true)"
@mouseleave="hideIcon"
>
{{ item.name }}
<img
v-if="item.url + 'quick' === hoverMenu"
src="@/img/subIcon.png"
alt=""
class="operateBtn"
@click.stop="delQuickMenu(index)"
/>
</el-menu-item>
</el-sub-menu>
<el-menu-item index="1" v-else>
<img src="@/img/shortcutMenu.png" alt="" class="menuIcon" />
<template #title>
<span>快捷菜单</span>
</template>
</el-menu-item>
<!-- 标准菜单 -->
<el-sub-menu
:index="item.code"
v-for="item in menuStore.menu"
:key="item.code"
>
<template #title>
<img src="@/img/normalIcon.png" alt="" class="menuIcon" />
<span>{{ item.name }}</span>
</template>
<el-menu-item
:index="item1.url"
v-for="item1 in item.children"
:key="item1.code"
@click="changeMenu(item1.url)"
@mouseover="showIcon(item1.url)"
@mouseleave="hideIcon"
>
<div class="name-box">
{{ item1.name }}
<img
src="@/img/addIcon.png"
alt=""
class="operateBtn"
v-if="isShowAdd(item1.code) && item1.url === hoverMenu"
@click.stop="addQuickMenu(item1)"
/>
</div>
</el-menu-item>
</el-sub-menu>
</el-menu>
</template>
<script lang="ts" setup>
import { computed, ref } from 'vue'
import { useMenuStore } from '@/store/menu'
import { usePersonalStore } from '@/store/personal'
import usePage from '@/hooks/page'
import { url } from '@/api/url'
import { type menuType } from '@/type/menu'
import _, { find } from 'lodash'
import { quickMenuMaxLength } from '@/util/enum'
import { post } from '@/api'
import { useRoute } from 'vue-router'
const route = useRoute() || {}
const { addPage, params, pageName } = usePage()
const menuStore = useMenuStore()
const personalStore = usePersonalStore()
onMounted(() => {
getQuickMenu()
})
/**
* 获取快捷菜单(如果有值就不再获取)
*/
const getQuickMenu = async () => {
if (personalStore.quickMenu !== null) return
const res = await (post(url.URL_AUTH_GET_USER_SETTING, {
type: 'quickMenu'
}) as any)
if (res && res[0] && res[0].body) {
const body = res[0].body
try {
const menu = JSON.parse(body).data
// 需要过滤一下权限是否有
personalStore.quickMenu = menu.filter(
(item: any) => _.findIndex(menuStore.menuList, { code: item.code }) > -1
)
} catch (e) {
personalStore.quickMenu = []
}
} else {
personalStore.quickMenu = []
}
}
/**
* 是否显示+号
* @param code
*/
const isShowAdd = (code: string) => {
return (
_.findIndex(personalStore.quickMenu, { code }) <= -1 &&
personalStore.quickMenu &&
personalStore.quickMenu.length < quickMenuMaxLength
)
}
/**
* 换菜单
* @param path
*/
const changeMenu = (path: string) => {
addPage(path)
}
/**
* 去除快捷菜单
*/
const delQuickMenu = (idx: number) => {
const quick = _.cloneDeep(personalStore.quickMenu) || []
quick.splice(idx, 1)
post(url.URL_AUTH_SAVE_USER_SETTING, {
type: 'quickMenu',
body: JSON.stringify({ data: quick })
}).then((res: any) => {
personalStore.quickMenu = _.cloneDeep(quick)
})
}
/**
* 添加快捷菜单
* @param menu
*/
const addQuickMenu = async (menu: menuType) => {
await getQuickMenu()
const quick = _.cloneDeep(personalStore.quickMenu || [])
quick.push(menu)
post(url.URL_AUTH_SAVE_USER_SETTING, {
type: 'quickMenu',
body: JSON.stringify({ data: quick })
}).then((res: any) => {
personalStore.quickMenu = _.cloneDeep(quick)
}).catch(() => {})
}
/**
* 当前选中的菜单
*/
const activeMenu = computed(() => {
let menu: string = ''
const page = find(menuStore.menuList, { url: route.name })
if (typeof page === 'object') {
menu = page?.url || ''
} else {
const btn = find(menuStore.btnList, { url: route.name })
if (typeof btn === 'object') {
menu = btn?.pageName || ''
}
}
return menu
})
const hoverMenu = ref('')
const showIcon = (url: string, isQuick?: boolean) => {
hoverMenu.value = isQuick ? url + 'quick' : url
}
const hideIcon = () => {
hoverMenu.value = ''
}
</script>
<style lang="scss">
.el-menu {
border-right: 0;
border-radius: 4px;
--el-menu-bg-color: var(--el-color-primary);
--el-menu-text-color: #ffffff;
--el-menu-active-color: #ffffff;
--el-menu-hover-bg-color: var(--el-color-primary);
.el-sub-menu {
.operateBtn {
position: absolute;
right: 22px;
}
}
.menu-li {
display: inline-block;
width: 100%;
text-align: left;
}
.el-menu--inline {
.el-menu-item {
&::before {
margin-left: -17px;
margin-right: 12px;
content: "";
width: 20px;
height: 50px;
background-image: url("@/img/subfield1.png");
background-size: cover;
background-repeat: no-repeat;
}
&.is-active {
background: rgba($color: #24b5c6, $alpha: 1);
&::after {
position: absolute;
right: 0;
content: " ";
width: 4px;
height: 100%;
background: #fbce07;
}
}
&:last-child {
&::before {
margin-left: -17px;
margin-right: 12px;
content: "";
width: 20px;
height: 50px;
background-image: url("@/img/subfield2.png");
background-size: cover;
background-repeat: no-repeat;
}
}
}
}
.el-menu-item {
.el-icon.icon-right {
width: 16px;
height: 16px;
background: rgba(255, 255, 255, 0.9);
border-radius: 3px;
opacity: 0.8;
position: absolute;
right: 10px;
border: 1px solid #fff;
color: var(--el-color-primary);
font-size: 12px;
}
}
.el-menu--collapse {
width: 70px;
}
.menuIcon {
margin: 0 15px 0 6px;
}
}
.el-menu--popup-container{
.el-menu--popup {
min-width: 150px;
padding: 0;
.operateBtn {
margin-left: 45px;
}
}
}
</style>