ai_images/portal-ui/src/layout/components/Menu.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>