AppMenuTree.vue
1.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
<template>
<template v-for="menu in menus" :key="menu.code">
<a-sub-menu v-if="menu.children?.length" :key="menu.code">
<template #icon>
<component :is="resolveIcon(menu.icon, menu.code)" v-if="resolveIcon(menu.icon, menu.code)" />
</template>
<template #title>{{ menu.name }}</template>
<AppMenuTree :menus="menu.children" />
</a-sub-menu>
<a-menu-item v-else :key="menu.path || menu.code">
<template #icon>
<component :is="resolveIcon(menu.icon, menu.code)" v-if="resolveIcon(menu.icon, menu.code)" />
</template>
{{ menu.name }}
</a-menu-item>
</template>
</template>
<script setup lang="ts">
import type { Component } from 'vue'
import type { MenuNode } from '@/types/auth'
import {
ApiOutlined,
ApartmentOutlined,
ControlOutlined,
GlobalOutlined,
HomeOutlined,
MessageOutlined,
SettingOutlined,
ShopOutlined,
StarOutlined,
TeamOutlined,
TrophyOutlined,
UnorderedListOutlined,
UserOutlined,
} from '@ant-design/icons-vue'
withDefaults(defineProps<{ menus: MenuNode[] }>(), {
menus: () => [],
})
const iconMap: Record<string, Component> = {
HomeOutlined,
GlobalOutlined,
ApartmentOutlined,
ShopOutlined,
UserOutlined,
StarOutlined,
UnorderedListOutlined,
ControlOutlined,
ApiOutlined,
TeamOutlined,
TrophyOutlined,
SettingOutlined,
MessageOutlined,
}
const codeIconMap: Record<string, Component> = {
'substation.user': TeamOutlined,
'rider.level': TrophyOutlined,
'system.sub_root': SettingOutlined,
'system.sub_role': TeamOutlined,
'system.sub_role_menu': SettingOutlined,
}
function resolveIcon(icon?: string, code?: string) {
if (icon && iconMap[icon]) return iconMap[icon]
if (code && codeIconMap[code]) return codeIconMap[code]
return null
}
</script>