170 lines
3.8 KiB
Vue
170 lines
3.8 KiB
Vue
<template>
|
|
<div class="menu-wrapper">
|
|
<a-scrollbar>
|
|
<a-menu
|
|
:collapsed="collapsed"
|
|
:selected-keys="selectedKeys"
|
|
:open-keys="openedKeys"
|
|
@menu-item-click="menuItemClick"
|
|
@sub-menu-click="subMenuClick">
|
|
<template v-for="item in menuItems">
|
|
<template v-if="item.children.length > 0">
|
|
<a-sub-menu
|
|
:key="item.key"
|
|
:title="item.label">
|
|
<a-menu-item
|
|
v-for="child in item.children"
|
|
:key="child.key">
|
|
{{ child.label }}
|
|
</a-menu-item>
|
|
</a-sub-menu>
|
|
</template>
|
|
<template v-else>
|
|
<a-menu-item :key="item.key">
|
|
<template #icon>
|
|
<a-image
|
|
:width="24"
|
|
:preview="false"
|
|
:height="24"
|
|
:src="`/images/nav/${
|
|
selectedKeys.indexOf(item.key) > -1
|
|
? item.icon + '-a'
|
|
: item.icon
|
|
}.png`" />
|
|
</template>
|
|
<div class="menu-item">
|
|
{{ item.label }}
|
|
</div>
|
|
</a-menu-item>
|
|
</template>
|
|
</template>
|
|
</a-menu>
|
|
</a-scrollbar>
|
|
</div>
|
|
</template>
|
|
<script setup>
|
|
import { computed, ref, watch, inject } from 'vue'
|
|
import { useRoute, useRouter } from 'vue-router'
|
|
import { useStore } from 'vuex'
|
|
import cloneDeep from 'lodash-es/cloneDeep'
|
|
import { constantRoutes } from '@/router/index'
|
|
import { generateTitle, generateLang } from '@/utils/i18n'
|
|
|
|
defineProps({
|
|
collapsed: Boolean
|
|
})
|
|
|
|
const store = useStore()
|
|
const route = useRoute()
|
|
const router = useRouter()
|
|
|
|
const $base = inject('$base')
|
|
const $message = inject('$message')
|
|
|
|
const menuItems = computed(() => {
|
|
return constantRoutes
|
|
.find((d) => d.path == '/')
|
|
.children.map((route) => ({
|
|
key: route.name,
|
|
label: generateTitle(route.meta?.title),
|
|
meta: route.meta,
|
|
icon: route.meta?.icon,
|
|
children: (route.children || []).map((i) => ({
|
|
key: i.name,
|
|
label: generateTitle(i.meta?.title),
|
|
meta: i.meta,
|
|
icon: i.meta?.icon
|
|
}))
|
|
}))
|
|
})
|
|
|
|
const menuSelectedKeys = computed(() => store.getters.selectedKeys)
|
|
|
|
const defaultOpenedKeys = computed(() => {
|
|
let system = store.getters.system
|
|
if (system == 'service') {
|
|
return ['service-order', 'service-permission']
|
|
} else if (system == 'agency') {
|
|
return ['agency-order', 'agency-permission']
|
|
} else {
|
|
return []
|
|
}
|
|
})
|
|
|
|
const selectedKeys = ref([])
|
|
|
|
const openedKeys = computed(() => {
|
|
return store.getters.openedKeys
|
|
})
|
|
|
|
const menuItemClick = (key) => {
|
|
if (key == 'change-face-video') {
|
|
$message.warning(generateLang('isDevelop'))
|
|
}else {
|
|
router.push({ name: key })
|
|
if ($base.isMobile()) {
|
|
store.dispatch('main/closeSideBar')
|
|
}
|
|
}
|
|
}
|
|
|
|
const subMenuClick = (key, _openKeys) => {
|
|
store.dispatch('main/setOpenedKeys', _openKeys)
|
|
}
|
|
|
|
watch(
|
|
() => route.name,
|
|
() => {
|
|
let sk = route.matched.filter((i) => i.meta.menuItem).map((j) => j.name)
|
|
selectedKeys.value = sk
|
|
let matchKeys = route.matched
|
|
.filter((i) => i.meta.menuItem && i.children?.length > 0)
|
|
.map((j) => j.name)
|
|
let cloneOpenedKeys = cloneDeep(openedKeys.value)
|
|
matchKeys.concat(defaultOpenedKeys.value).map((item) => {
|
|
if (!cloneOpenedKeys.includes(item)) {
|
|
cloneOpenedKeys.push(item)
|
|
}
|
|
})
|
|
store.dispatch('main/setOpenedKeys', cloneOpenedKeys)
|
|
},
|
|
{
|
|
immediate: true
|
|
}
|
|
)
|
|
|
|
const servicePolicyCount = computed(() => store.getters.servicePolicyCount)
|
|
const agencyPolicyCount = computed(() => store.getters.agencyPolicyCount)
|
|
const count = (system) => {
|
|
return system === 'service'
|
|
? servicePolicyCount.value
|
|
: agencyPolicyCount.value
|
|
}
|
|
</script>
|
|
<style lang="less">
|
|
.arco-tooltip-content {
|
|
display: none;
|
|
}
|
|
</style>
|
|
<style lang="less" scoped>
|
|
.menu-wrapper {
|
|
height: 100%;
|
|
|
|
.arco-scrollbar {
|
|
height: 100%;
|
|
|
|
:deep(.arco-scrollbar-container) {
|
|
height: 100%;
|
|
overflow-x: hidden;
|
|
overflow-y: auto;
|
|
}
|
|
}
|
|
}
|
|
|
|
.menu-item {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
}
|
|
</style>
|