| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141 |
- import { shallowRef, defineAsyncComponent, Component } from 'vue'
- import { useRoute, useRouter } from 'vue-router'
- import { useMenuStore } from '@/stores'
- import { AuthType } from '@/constants/menu'
- export function useMenu(authCode?: string) {
- const { userMenus } = useMenuStore()
- const route = useRoute()
- const router = useRouter()
- const componentMap = new Map<string, Component>()
- const componentId = shallowRef<string>() // 当前选中的组件
- // 过滤菜单
- const filterMenu = (data: Ermcp.UserMenu[], parentPath = '') => {
- const result: Ermcp.UserMenu[] = []
- data.forEach((e) => {
- if (!e.hidden && e.authType === AuthType.Menu) {
- const routePath = (parentPath ? parentPath + '/' : '') + e.url
- result.push({
- ...e,
- url: routePath,
- children: e.children ? filterMenu(e.children, routePath) : [],
- })
- }
- })
- return result
- }
- /**
- * 根据 code 查找对应的子菜单
- * @returns
- */
- const findChildren = (data: Ermcp.UserMenu[], code?: string): Ermcp.UserMenu[] => {
- const routeName = code ?? route.name?.toString()
- for (const item of data) {
- const { code, children } = item
- if (code === routeName) return children ?? []
- if (children) {
- const res = findChildren(children, routeName)
- if (res.length) return res
- }
- }
- return []
- }
- /**
- * 获取路由菜单(无限级)
- * @param level
- * @returns
- */
- const getMenus = (level = 0) => {
- // 过滤层级
- const filterLevel = (data: Ermcp.UserMenu[], n: number): Ermcp.UserMenu[] => {
- if (level) {
- return data.map((e) => ({ ...e, children: n <= 1 ? [] : filterLevel(e.children ?? [], n - 1) }))
- }
- return data
- }
- return filterMenu(filterLevel(userMenus.value, level))
- }
- /**
- * 获取路由子菜单
- * @param code
- * @returns
- */
- const getChildrenMenus = (code?: string) => {
- const children = findChildren(userMenus.value, code)
- return filterMenu(children)
- }
- /**
- * 获取操作权限
- * @returns
- */
- const getAuth = (authType: AuthType) => {
- const children = findChildren(userMenus.value, authCode)
- return children.reduce((res, cur) => {
- if (!cur.hidden && cur.authType === authType) {
- if (!componentMap.get(cur.code) && cur.component) {
- const componentString = cur.component.replace(/^\/+/, '') // 过滤字符串前面所有 '/' 字符
- const componentPath = componentString.replace(/\.\w+$/, '') // 过滤后缀名,为了让 import 加入 .vue ,不然会有警告提示...
- const asyncComponent = defineAsyncComponent({
- loader: () => import('/' + process.env.VUE_APP_ROOT + componentPath + '.vue'),
- })
- componentMap.set(cur.code, asyncComponent)
- }
- res.push(JSON.parse(JSON.stringify(cur)))
- }
- return res
- }, [] as Ermcp.UserMenu[])
- }
- /**
- * 过滤操作权限
- * @param filtered 过滤的数据项
- * @param reverse 是否反向过滤
- * @returns
- */
- const authFilter = (authType: AuthType, filtered: string[], reverse: boolean) => {
- const auth = getAuth(authType);
- if (filtered.length) {
- if (reverse) {
- // 返回除指定的权限代码
- return auth.filter((e) => !filtered.includes(e.code))
- } else {
- // 返回指定的权限代码
- return auth.filter((e) => filtered.includes(e.code))
- }
- }
- return auth
- }
- /**
- * 获取权限按钮
- * @param filtered
- * @param reverse
- * @returns
- */
- const getAuthButtons = (filtered: string[] = [], reverse = false) => authFilter(AuthType.Button, filtered, reverse)
- /**
- * 获取权限组件
- * @param filtered
- * @param reverse
- * @returns
- */
- const getAuthComponents = (filtered: string[] = [], reverse = false) => authFilter(AuthType.Component, filtered, reverse)
- return {
- route,
- router,
- userMenus,
- componentMap,
- componentId,
- getMenus,
- getChildrenMenus,
- getAuthButtons,
- getAuthComponents,
- }
- }
|