From 5644602b3a8edd0a99737feb613e1cce33fc6a1b Mon Sep 17 00:00:00 2001 From: fangyunong Date: Wed, 16 Jul 2025 16:40:30 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E5=88=9D=E6=AD=A5=E5=8A=A8=E6=80=81?= =?UTF-8?q?=E8=8F=9C=E5=8D=95=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/menu.ts | 3 + src/router/index.ts | 31 +-- src/store/app.ts | 33 ++- src/utils/permission.ts | 4 +- src/views/404/index.vue | 138 ++++++++++ src/views/layout/components/LayoutNav.vue | 111 +++----- src/views/login/OauthCallBack.vue | 10 + src/views/system/menu/index.vue | 295 ++++++++++++++-------- 8 files changed, 402 insertions(+), 223 deletions(-) create mode 100644 src/views/404/index.vue diff --git a/src/api/menu.ts b/src/api/menu.ts index aa52cbe..310ec67 100644 --- a/src/api/menu.ts +++ b/src/api/menu.ts @@ -7,6 +7,7 @@ export interface RawMenu { label: string; icon: string; menuCode: string; + menuName:string; adaptability: string; component: string; sort: number; @@ -21,6 +22,7 @@ export type MenuTree = { label: string; icon: string; menuCode: string; + menuName:string; adaptability: string; component: string; sort: number; @@ -36,6 +38,7 @@ export type MenuNode = { label: string; icon: string; menuCode: string; + menuName:string; adaptability: string; component: string; sort: number; diff --git a/src/router/index.ts b/src/router/index.ts index 1ba3f21..4080a01 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -37,36 +37,9 @@ const routes: Array = [ children: [ { path: "", // 匹配 /layout - name: "home", + name: "HOME", component: Home, - }, - { - path: "role", - name: "Role", - component: RouterView, - children: [ - { - path: "auth", // 匹配 /layout/role - name: "roleAuth", - component: Auth, - }, - ], - }, - { - path: "menu", - name: "menu", - component: Menu, - }, - { - path: "dict", - name: "dict", - component: Dict, - }, - { - path: "globalSys", - name: "globalSys", - component: GlobalSys, - }, + } ], }, ]; diff --git a/src/store/app.ts b/src/store/app.ts index 7fa073c..9872925 100644 --- a/src/store/app.ts +++ b/src/store/app.ts @@ -1,14 +1,25 @@ +import type { MenuNode } from "@/api/menu"; import { defineStore } from "pinia"; -export const useAppStore = defineStore('App', () => { - - //左侧菜单相关 - const menuApp = reactive({ - isExpaned:true, //折叠控制 - }); - return { - menuApp - } -}, +export const useAppStore = defineStore( + "App", + () => { + //左侧菜单相关 + const menuApp = reactive({ + isExpaned: true, //折叠控制 + menuList: [], + }); + // 设置菜单列表 + const setMenuList = (menu: MenuNode[]) => { + menuApp.menuList.length = 0; + menu.forEach(item => { + menuApp.menuList.push(item); + }) + }; + return { + menuApp, + setMenuList + }; + }, { persist: true } -) \ No newline at end of file +); diff --git a/src/utils/permission.ts b/src/utils/permission.ts index 67b3c4b..aca4453 100644 --- a/src/utils/permission.ts +++ b/src/utils/permission.ts @@ -1,4 +1,4 @@ -import { RouteMeta, RouteRecordRaw, RouterView } from "vue-router"; +import { RouteRecordRaw, RouterView } from "vue-router"; import NotFound from "@/views/404/index.vue" interface MenuItem { uuid: string; @@ -24,7 +24,7 @@ function getComponent(componentPath: string) { return () => { try { // 尝试动态导入组件 - const componentPromise = import(`@/views/${componentPath}`) + const componentPromise = import(`../views/${componentPath}`) // 成功加载则返回组件 return componentPromise.catch(() => { diff --git a/src/views/404/index.vue b/src/views/404/index.vue new file mode 100644 index 0000000..c7a9600 --- /dev/null +++ b/src/views/404/index.vue @@ -0,0 +1,138 @@ + + + + + \ No newline at end of file diff --git a/src/views/layout/components/LayoutNav.vue b/src/views/layout/components/LayoutNav.vue index 0eb20b0..446d2e0 100644 --- a/src/views/layout/components/LayoutNav.vue +++ b/src/views/layout/components/LayoutNav.vue @@ -20,11 +20,13 @@ import { MenuOption, NIcon } from 'naive-ui'; import { useAppStore } from '@/store/app'; import { storeToRefs } from 'pinia'; import { RouterLink } from 'vue-router'; +import SvgIcon from '@/components/SvgIcon.vue'; +import type { MenuNode } from '@/api/menu'; + const appStore = useAppStore(); -const activeKey = ref('default'); +const activeKey = ref('Home'); const router = useRouter(); const { menuApp } = storeToRefs(appStore); -import SvgIcon from '@/components/SvgIcon.vue'; const expandIcon = () => { return h(NIcon, null, { default: () => h(CaretDownOutline) }) } @@ -32,12 +34,36 @@ const expandIcon = () => { function renderIcon(iconClass: string) { return () => h(SvgIcon, { iconClass, width: '16', height: '16' }) }; -watch(() => router.currentRoute.value, (newName) => { - if (newName) { - activeKey.value = newName.fullPath as string; +function renderLabel(item: MenuNode) { + return () => h( + RouterLink, + { + to: { + name: item.path.toUpperCase() + } + }, + { default: () => item.label } + ) +} +watch(() => router.currentRoute.value, (path) => { + if (path) { + activeKey.value = path.name as string; } -},{ immediate: true }); -// 后面改成动态的 +}, { immediate: true }); +const generatorMenuList = (menu: MenuNode | MenuNode[]): MenuOption[] => { + // Handle both array and single object input + const menuItems = Array.isArray(menu) ? menu : [menu]; + + return menuItems.map(item => { + const menuItem: MenuOption = { + label: item.component === 'view-router' ? item.label : renderLabel(item), + key: item.path.toUpperCase(), + icon: renderIcon(item.icon), + children: item.children && item.children.length > 0 ? generatorMenuList(item.children) : undefined + }; + return menuItem; + }); +} const menuOptions: MenuOption[] = [ { label: () => @@ -45,80 +71,15 @@ const menuOptions: MenuOption[] = [ RouterLink, { to: { - name: 'home' + name: 'HOME' } }, { default: () => '概览' } ), - key: '/layout', + key: 'HOME', icon: renderIcon('mainproject') }, - { - label: '角色管理', - key: '/role', - icon: renderIcon('mainproject'), - children: [ - { - label: () => h( - RouterLink, - { - to: { - name: 'roleAuth' - } - }, - { default: () => '权限分配' } - ), - key: '/layout/role', - icon: renderIcon('mainproject') - } - ] - }, - { - label: '系统配置', - key: '/system', - icon: renderIcon('mainproject'), - children: [ - { - label: () => h( - RouterLink, - { - to: { - name: 'menu' - } - }, - { default: () => '菜单管理' } - ), - key: '/layout/menu', - icon: renderIcon('mainproject') - }, - { - label: () => h( - RouterLink, - { - to: { - name: 'dict' - } - }, - { default: () => '字典配置' } - ), - key: '/layout/dict', - icon: renderIcon('mainproject') - }, - { - label: () => h( - RouterLink, - { - to: { - name: 'globalSys' - } - }, - { default: () => '全局参数' } - ), - key: '/layout/globalSys', - icon: renderIcon('mainproject') - } - ] - }, + ...generatorMenuList(menuApp.value.menuList) ];