From 8e2e0de679520cf8fa27163bb827c2d51aa2d224 Mon Sep 17 00:00:00 2001 From: xieyonghong <18010623010@163.com> Date: Tue, 31 Jan 2023 17:50:47 +0800 Subject: [PATCH] =?UTF-8?q?update:=201.=E4=BC=98=E5=8C=96=E5=8A=A8?= =?UTF-8?q?=E6=80=81=E8=B7=AF=E7=94=B1,=E5=A4=84=E7=90=86=E8=B7=AF?= =?UTF-8?q?=E7=94=B1=E6=95=B0=E6=8D=AE=E6=A0=BC=E5=BC=8F=EF=BC=9B=E4=BC=98?= =?UTF-8?q?=E5=8C=96layout=E6=A0=B7=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Layout/BasicLayoutPage.vue | 3 +- .../Layout/components/Header/index.tsx | 2 +- .../components/SiderMenu/SiderMenu.less | 4 + src/main.ts | 4 +- src/router/index.ts | 6 +- src/router/menu.ts | 2 +- src/store/menu.ts | 7 +- src/utils/menu.ts | 157 +++++++++++++++--- src/views/home/index.vue | 125 +++++++------- 9 files changed, 220 insertions(+), 90 deletions(-) diff --git a/src/components/Layout/BasicLayoutPage.vue b/src/components/Layout/BasicLayoutPage.vue index 054f54ad..ebc3adc4 100644 --- a/src/components/Layout/BasicLayoutPage.vue +++ b/src/components/Layout/BasicLayoutPage.vue @@ -21,6 +21,7 @@ import { ProLayout } from '@/components/Layout' import DefaultSetting from '../../../config/config' import { useMenuStore } from '@/store/menu' +import { clearMenuItem } from 'components/Layout/utils' type StateType = { collapsed: boolean @@ -39,7 +40,7 @@ const layoutConf = reactive({ siderWidth: DefaultSetting.layout.siderWidth, logo: DefaultSetting.layout.logo, title: DefaultSetting.layout.title, - menuData: menu.menus, + menuData: clearMenuItem(menu.siderMenus), }); const state = reactive({ diff --git a/src/components/Layout/components/Header/index.tsx b/src/components/Layout/components/Header/index.tsx index c4bfc014..a804a3a2 100644 --- a/src/components/Layout/components/Header/index.tsx +++ b/src/components/Layout/components/Header/index.tsx @@ -32,7 +32,7 @@ export const HeaderView = defineComponent({ height: `${headerHeight.value}px`, lineHeight: `${headerHeight.value}px`, width: `100%`, - + background: 'transparent' }} /> { menuData.forEach(r => { router.addRoute('base', r) }) - router.addRoute('base',{ - path: '/:pathMatch(.*)*', + path: '/:pathMatch(.*)', + name: 'error', component: () => NotFindPage }) - console.log(to) + next({ ...to, replace: true }) }) }).catch(() => { diff --git a/src/router/menu.ts b/src/router/menu.ts index 056aa40d..7e97e255 100644 --- a/src/router/menu.ts +++ b/src/router/menu.ts @@ -18,7 +18,7 @@ export default [ // path: '/initsetting', // component: () => import('@/view/Login/initSet.vue') // } - + { path: '/*', redirect: '/'}, // start: 测试用, 可删除 { path: '/login', diff --git a/src/store/menu.ts b/src/store/menu.ts index 70e1ced9..7d1a675e 100644 --- a/src/store/menu.ts +++ b/src/store/menu.ts @@ -1,12 +1,14 @@ import { defineStore } from "pinia"; import { queryOwnThree } from '@/api/system/menu' import { filterAsnycRouter } from '@/utils/menu' +import { cloneDeep } from 'lodash-es' export const useMenuStore = defineStore({ id: 'menu', state: () => ({ menus: {}, menuData: [], + siderMenus: [], menusKey: [] }), getters: { @@ -52,7 +54,8 @@ export const useMenuStore = defineStore({ ]; const resp = await queryOwnThree({ paging: false, terms: params }) if (resp.success) { - const menus = filterAsnycRouter(resp.result) + const silderMenus = filterAsnycRouter(cloneDeep(resp.result)) + const menus = filterAsnycRouter(cloneDeep(resp.result)) menus.push({ path: '/', redirect: menus[0]?.path, @@ -61,6 +64,8 @@ export const useMenuStore = defineStore({ } }) this.menuData = menus + this.siderMenus = silderMenus + console.log('silderMenus', silderMenus) res(menus) } }) diff --git a/src/utils/menu.ts b/src/utils/menu.ts index e860b162..2907f1c2 100644 --- a/src/utils/menu.ts +++ b/src/utils/menu.ts @@ -1,11 +1,99 @@ const pagesComponent = import.meta.glob('../views/**/*.vue', { eager: true }); import { BlankLayoutPage, BasicLayoutPage } from 'components/Layout' -type ExtraRouteItem = { - code: string - name: string - url?: string -} +/** + * 权限信息 + */ +export type PermissionInfo = { + permission: string; + actions: string[]; +}; + +/** + * 按钮信息 + */ +export type MenuButtonInfo = { + id: string; + name: string; + permissions: PermissionInfo; + createTime: number; + describe?: string; + options: Record; +}; + + +export type MenuItem = { + id: string; + /** + * 名称 + */ + name: string; + /** + * 编码 + */ + code: string; + /** + * 所属应用 + */ + application: string; + /** + * 描述 + */ + describe: string; + /** + * url,路由 + */ + url: string; + /** + * 图标 + */ + icon: string; + /** + * 状态, 0为禁用,1为启用 + */ + status: number; + /** + * 绑定权限信息 + */ + permissions: PermissionInfo[]; + /** + * 按钮定义信息 + */ + buttons: MenuButtonInfo[]; + /** + * 其他配置信息 + */ + options: Record; + /** + * 父级ID + */ + parentId: string; + /** + * 树结构路径 + */ + path: string; + /** + * 排序序号 + */ + sortIndex: number; + /** + * 树层级 + */ + level: number; + createTime: number; + redirect?: string; + children?: MenuItem[]; + accessSupport?: { text: string; value: string }; + appId?: string; //应用id + isShow?: boolean; + meta?: { + title?: string + icon?: string + [key: string]: any + }, + component?: any +}; + // 额外子级路由 const extraRouteObj = { 'media/Cascade': { @@ -59,51 +147,82 @@ const extraRouteObj = { const resolveComponent = (name: any) => { - // TODO 暂时用system进行测试 const importPage = pagesComponent[`../views/${name}/index.vue`]; if (!importPage) { console.warn(`Unknown page ${name}. Is it located under Pages with a .vue extension?`) } //@ts-ignore - return !!importPage ? importPage.default : BlankLayoutPage + return !!importPage ? importPage.default : undefined } -const findChildrenRoute = (code: string, url: string): ExtraRouteItem[] => { +const findChildrenRoute = (code: string, url: string): MenuItem[] => { if (extraRouteObj[code]) { - return extraRouteObj[code].children.map((route: ExtraRouteItem) => { + return extraRouteObj[code].children.map((route: MenuItem) => { return { url: `${url}/${route.code}`, code: route.code, - name: route.name + name: route.name, + isShow: false } }) } return [] } +const findDetailRouteItem = (code: string, url: string): Partial | null => { + const detailComponent = resolveComponent(`${code}/Detail`) + if (detailComponent) { + return { + url: `${url}/Detail/:id`, + component: detailComponent, + name: '详情信息', + isShow: false + } + } + return null +} + +const findDetailRoutes = (routes: any[]): any[] => { + const newRoutes: any[] = [] + routes.forEach((route: any) => { + newRoutes.push(route) + const detail = findDetailRouteItem(route.code, route.url) + if (detail) { + newRoutes.push(detail) + } + }) + return newRoutes +} + export function filterAsnycRouter(asyncRouterMap: any, parentCode = '', level = 1) { + return asyncRouterMap.map((route: any) => { - console.log(route.name, route) + route.path = `${route.url}` route.meta = { icon: route.icon, - title: route.name + title: route.name, + hideInMenu: route.isShow === false } // 查看是否有隐藏子路由 const extraChildren = findChildrenRoute(route.code, route.url) route.children = route.children && route.children.length ? [...route.children, ...extraChildren] : extraChildren - - // TODO 查看是否具有详情页 - // route.children = [...route.children, ] + route.children = findDetailRoutes(route.children) if (route.children && route.children.length) { - route.component = () => level === 1 ? BasicLayoutPage : BlankLayoutPage + // TODO 查看是否具有详情页 route.children = filterAsnycRouter(route.children, `${parentCode}/${route.code}`, level + 1) - route.redirect = route.children[0].url + const showChildren = route.children.some((r: any) => !r.meta.hideInMenu) + if (showChildren) { + route.component = () => level === 1 ? BasicLayoutPage : BlankLayoutPage + route.redirect = route.children[0].url + } else { + route.component = resolveComponent(route.code) || BlankLayoutPage; + } } else { - route.component = resolveComponent(route.code); + route.component = resolveComponent(route.code) || BlankLayoutPage; } - + delete route.name return route }) } \ No newline at end of file diff --git a/src/views/home/index.vue b/src/views/home/index.vue index 1327a1eb..d438a522 100644 --- a/src/views/home/index.vue +++ b/src/views/home/index.vue @@ -1,79 +1,80 @@ - -