From cb401eebe1dd7523411e6023142ab08af0a92bc0 Mon Sep 17 00:00:00 2001 From: wangys <3401275564@qq.com> Date: Fri, 14 Nov 2025 19:17:49 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B7=AF=E7=94=B1=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../.bin/mysql/sql/initMenuData.sql | 9 +-- schoolNewsWeb/public/img/admin/crontab.svg | 3 + schoolNewsWeb/src/utils/permission.ts | 6 +- schoolNewsWeb/src/utils/route-generator.ts | 9 ++- schoolNewsWeb/src/utils/routeUtils.ts | 59 +++++++++++-------- schoolNewsWeb/src/views/admin/AdminLayout.vue | 3 +- .../admin/manage/resource/DataRecordsView.vue | 56 ------------------ .../resource/ResourceManagementView.vue | 7 +-- 8 files changed, 54 insertions(+), 98 deletions(-) create mode 100644 schoolNewsWeb/public/img/admin/crontab.svg delete mode 100644 schoolNewsWeb/src/views/admin/manage/resource/DataRecordsView.vue diff --git a/schoolNewsServ/.bin/mysql/sql/initMenuData.sql b/schoolNewsServ/.bin/mysql/sql/initMenuData.sql index 24e0cc3..ed9e3ad 100644 --- a/schoolNewsServ/.bin/mysql/sql/initMenuData.sql +++ b/schoolNewsServ/.bin/mysql/sql/initMenuData.sql @@ -134,7 +134,7 @@ INSERT INTO `tb_sys_menu` VALUES -- 管理后台菜单 (1000-8999) ('1000', 'menu_admin_overview', '系统总览', NULL, '/admin/overview', 'admin/overview/SystemOverviewView', 'admin/overview.svg', 1, 0, 'SidebarLayout', '1', NULL, '2025-10-27 17:26:06', '2025-10-29 11:52:32', NULL, 0), ('2000', 'menu_sys_manage', '系统管理', NULL, '', '', 'admin/settings.svg', 2, 0, 'SidebarLayout', '1', NULL, '2025-10-27 17:26:06', '2025-10-29 11:52:35', NULL, 0), -('2001', 'menu_admin_user', '用户管理', 'menu_sys_manage', '/admin/manage/system/user', 'admin/manage/system/UserManageView', 'admin/usermange.svg', 1, 0, 'SidebarLayout', '1', NULL, '2025-10-27 17:26:06', '2025-10-29 11:52:38', NULL, 0), +('2001', 'menu_admin_user', '用户管理', 'menu_sys_manage', '/admin/manage/system/user', 'admin/manage/system/UserManageView', NULL, 1, 0, 'SidebarLayout', '1', NULL, '2025-10-27 17:26:06', '2025-10-29 11:52:38', NULL, 0), ('2002', 'menu_admin_dept', '部门管理', 'menu_sys_manage', '/admin/manage/system/dept', 'admin/manage/system/DeptManageView', NULL, 2, 0, 'SidebarLayout', '1', NULL, '2025-10-27 17:26:06', '2025-10-29 11:48:39', NULL, 0), ('2003', 'menu_admin_role', '角色管理', 'menu_sys_manage', '/admin/manage/system/role', 'admin/manage/system/RoleManageView', NULL, 3, 0, 'SidebarLayout', '1', NULL, '2025-10-27 17:26:06', '2025-10-29 11:48:39', NULL, 0), ('2005', 'menu_admin_menu', '菜单管理', 'menu_sys_manage', '/admin/manage/system/menu', 'admin/manage/system/MenuManageView', NULL, 4, 0, 'SidebarLayout', '1', NULL, '2025-10-27 17:26:06', '2025-10-29 11:48:39', NULL, 0), @@ -142,7 +142,6 @@ INSERT INTO `tb_sys_menu` VALUES ('3000', 'menu_admin_resource_manage', '资源管理', NULL, '', '', 'admin/resource.svg', 3, 0, 'SidebarLayout', '1', NULL, '2025-10-27 17:26:06', '2025-10-29 11:52:40', NULL, 0), ('3001', 'menu_admin_resource', '数据采集', 'menu_admin_resource_manage', '/admin/manage/resource/resource', 'admin/manage/resource/ResourceManagementView', NULL, 1, 0, 'SidebarLayout', '1', NULL, '2025-10-27 17:26:06', '2025-10-29 11:48:39', NULL, 0), ('3002', 'menu_admin_article', '文章管理', 'menu_admin_resource_manage', '/admin/manage/resource/article', 'admin/manage/resource/ArticleManagementView', NULL, 2, 0, 'SidebarLayout', '1', NULL, '2025-10-27 17:26:06', '2025-10-29 11:48:39', NULL, 0), -('3003', 'menu_admin_data_records', '数据记录', 'menu_admin_resource_manage', '/admin/manage/resource/data-records', 'admin/manage/resource/DataRecordsView', NULL, 3, 0, 'SidebarLayout', '1', NULL, '2025-10-27 17:26:06', '2025-10-29 11:48:39', NULL, 0), ('3010', 'menu_article_add', '文章添加', 'menu_admin_article', '/article/add', 'public/article/ArticleAddView', NULL, 1, 3, 'SidebarLayout', '1', NULL, '2025-10-27 17:26:06', '2025-10-29 11:48:39', NULL, 0), ('3011', 'menu_article_show', '文章展示', 'menu_admin_article', '/article/show', 'public/article/ArticleShowView', NULL, 2, 3, 'NavigationLayout', '1', NULL, '2025-10-27 17:26:06', '2025-10-29 11:48:39', NULL, 0), ('4000', 'menu_admin_content_manage', '运营管理', NULL, '', '', 'admin/maintain.svg', 4, 0, 'SidebarLayout', '1', NULL, '2025-10-27 17:26:06', '2025-10-29 11:52:42', NULL, 0), @@ -153,10 +152,9 @@ INSERT INTO `tb_sys_menu` VALUES ('5000', 'menu_admin_study_manage', '学习管理', NULL, '', '', 'admin/study.svg', 5, 0, 'SidebarLayout', '1', NULL, '2025-10-27 17:26:06', '2025-10-29 11:52:46', NULL, 0), ('5002', 'menu_admin_task_manage', '任务管理', 'menu_admin_study_manage', '/admin/manage/study/task-manage', 'admin/manage/study/TaskManageView', NULL, 2, 0, 'SidebarLayout', '1', NULL, '2025-10-27 17:26:06', '2025-10-29 11:48:39', NULL, 0), ('5003', 'menu_admin_study_records', '学习记录', 'menu_admin_study_manage', '/admin/manage/study/study-records', 'admin/manage/study/StudyRecordsView', NULL, 3, 0, 'SidebarLayout', '1', NULL, '2025-10-27 17:26:06', '2025-10-29 11:48:39', NULL, 0), -('5004', 'menu_admin_course_manage', '课程管理', 'menu_admin_study_manage', '/admin/manage/study/course', 'admin/manage/study/CourseManagementView', 'admin/course.svg', 4, 0, 'SidebarLayout', '1', NULL, '2025-10-27 17:26:06', '2025-10-29 11:52:48', NULL, 0), +('5004', 'menu_admin_course_manage', '课程管理', 'menu_admin_study_manage', '/admin/manage/study/course', 'admin/manage/study/CourseManagementView', NULL, 4, 0, 'SidebarLayout', '1', NULL, '2025-10-27 17:26:06', '2025-10-29 11:52:48', NULL, 0), ('5005', 'menu_admin_achievement_manage', '成就管理', 'menu_admin_study_manage', '/admin/manage/study/achievement', 'admin/manage/achievement/AchievementManagementView', NULL, 5, 0, 'SidebarLayout', '1', NULL, '2025-10-27 17:26:06', '2025-10-29 11:48:39', NULL, 0), ('6000', 'menu_admin_ai_manage', '智能体管理', NULL, '', '', 'admin/agent.svg', 6, 0, 'SidebarLayout', '1', NULL, '2025-10-27 17:26:06', '2025-10-29 11:52:50', NULL, 0), -('6001', 'menu_admin_ai', 'AI管理', 'menu_admin_ai_manage', '/admin/manage/ai/ai', 'admin/manage/ai/AIManagementView', NULL, 1, 0, 'SidebarLayout', '1', NULL, '2025-10-27 17:26:06', '2025-10-29 11:48:39', NULL, 0), ('6002', 'menu_admin_ai_config', 'AI配置', 'menu_admin_ai_manage', '/admin/manage/ai/config', 'admin/manage/ai/AIConfigView', NULL, 2, 0, 'SidebarLayout', '1', NULL, '2025-10-27 17:26:06', '2025-10-29 11:48:39', NULL, 0), ('6003', 'menu_admin_knowledge', '知识库管理', 'menu_admin_ai_manage', '/admin/manage/ai/knowledge', 'admin/manage/ai/KnowledgeManagementView', NULL, 3, 0, 'SidebarLayout', '1', NULL, '2025-10-27 17:26:06', '2025-10-29 11:48:39', NULL, 0), ('7000', 'menu_admin_logs_manage', '系统日志', NULL, '', '', 'admin/logs.svg', 7, 0, 'SidebarLayout', '1', NULL, '2025-10-27 17:26:06', '2025-10-29 11:52:53', NULL, 0), @@ -164,8 +162,7 @@ INSERT INTO `tb_sys_menu` VALUES ('7002', 'menu_admin_login_logs', '登录日志', 'menu_admin_logs_manage', '/admin/manage/logs/login', 'admin/manage/logs/LoginLogsView', NULL, 2, 0, 'SidebarLayout', '1', NULL, '2025-10-27 17:26:06', '2025-10-29 11:48:39', NULL, 0), -- ('7003', 'menu_admin_operation_logs', '操作日志', 'menu_admin_logs_manage', '/admin/manage/logs/operation', 'admin/manage/logs/OperationLogsView', NULL, 3, 0, 'SidebarLayout', '1', NULL, '2025-10-27 17:26:06', '2025-10-29 11:48:39', NULL, 0), -- ('7004', 'menu_admin_system_config', '系统配置', 'menu_admin_logs_manage', '/admin/manage/logs/config', 'admin/manage/logs/SystemConfigView', NULL, 4, 0, 'SidebarLayout', '1', NULL, '2025-10-27 17:26:06', '2025-10-29 11:48:39', NULL, 0), -('8000', 'menu_admin_crontab_manage', '定时任务管理', NULL, '', '', NULL, 8, 0, 'SidebarLayout', '1', NULL, '2025-10-27 17:26:06', '2025-10-29 11:48:39', NULL, 0), -('8001', 'menu_admin_crontab_task', '任务管理', 'menu_admin_crontab_manage', '/admin/manage/crontab/task', 'admin/manage/crontab/TaskManagementView', NULL, 1, 0, 'SidebarLayout', '1', NULL, '2025-10-27 17:26:06', '2025-10-29 11:48:39', NULL, 0), +('8000', 'menu_admin_crontab_manage', '定时任务管理', NULL, '', '', NULL, 8, 0, 'SidebarLayout', '1', '/admin/crontab.svg', '2025-10-27 17:26:06', '2025-10-29 11:48:39', NULL, 0), ('8002', 'menu_admin_crontab_log', '执行日志', 'menu_admin_crontab_manage', '/admin/manage/crontab/log', 'admin/manage/crontab/LogManagementView', NULL, 2, 0, 'SidebarLayout', '1', NULL, '2025-10-27 17:26:06', '2025-10-29 11:48:39', NULL, 0), ('8003', 'menu_admin_news_crawler', '新闻爬虫配置', 'menu_admin_crontab_manage', '/admin/manage/crontab/news-crawler', 'admin/manage/crontab/NewsCrawlerView', NULL, 3, 0, 'SidebarLayout', '1', NULL, '2025-10-27 17:26:06', '2025-10-29 11:48:39', NULL, 0), -- 消息通知模块菜单 (9000-9999) diff --git a/schoolNewsWeb/public/img/admin/crontab.svg b/schoolNewsWeb/public/img/admin/crontab.svg new file mode 100644 index 0000000..4fb2164 --- /dev/null +++ b/schoolNewsWeb/public/img/admin/crontab.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/schoolNewsWeb/src/utils/permission.ts b/schoolNewsWeb/src/utils/permission.ts index 999809f..ddd0795 100644 --- a/schoolNewsWeb/src/utils/permission.ts +++ b/schoolNewsWeb/src/utils/permission.ts @@ -8,6 +8,7 @@ import type { Router, NavigationGuardNext, RouteLocationNormalized } from 'vue-r import type { Store } from 'vuex'; import { AuthState } from '@/store/modules/auth'; import { systemOverviewApi } from '@/apis/system/overview'; +import { routes as staticRoutes } from '@/router'; /** * 白名单路由 - 无需登录即可访问 @@ -50,8 +51,9 @@ export function setupRouterGuards(router: Router, store: Store) { // 设置页面标题 setPageTitle(to.meta?.title as string); - // 统计PV:对path以"/"开头的路由进行统计 - if (to.path.startsWith('/')) { + // 统计PV:对path以"/"开头的路由进行统计 非静态路由 + const isStaticRoute = staticRoutes.some(route => route.path === to.matched[0]?.path); + if (!isStaticRoute && to.path.startsWith('/')) { systemOverviewApi.trackVisit().catch(() => { // 统计失败不影响正常页面使用 }); diff --git a/schoolNewsWeb/src/utils/route-generator.ts b/schoolNewsWeb/src/utils/route-generator.ts index 50e36a2..5dd34c9 100644 --- a/schoolNewsWeb/src/utils/route-generator.ts +++ b/schoolNewsWeb/src/utils/route-generator.ts @@ -186,9 +186,12 @@ function generateRouteFromMenu(menu: SysMenu, isTopLevel = true): RouteRecordRaw } }); - // 当前菜单指定了页面组件时,即使存在子菜单也应当渲染该页面 - // 但如果 component 是布局组件,则不应该创建 path: '' 的子路由(因为布局组件已经是父路由的组件了) - if (menu.component && !isComponentLayout) { + // 当前菜单指定了页面组件时,如果存在“普通子菜单”(非 PAGE 类型) + // 则需要创建一个默认子路由来承载当前菜单的页面组件, + // 这样父级既能作为分组,又能渲染自己的页面。 + // 如果只有 PAGE 类型子菜单,则直接使用当前路由组件,而不再包一层 `_page`, + // 避免多出一层嵌套导致 matched 结构过深。 + if (menu.component && !isComponentLayout && normalChildren.length > 0) { route.children!.push({ path: '', name: `${menu.menuID}_page`, diff --git a/schoolNewsWeb/src/utils/routeUtils.ts b/schoolNewsWeb/src/utils/routeUtils.ts index 2088c3d..0c2fe77 100644 --- a/schoolNewsWeb/src/utils/routeUtils.ts +++ b/schoolNewsWeb/src/utils/routeUtils.ts @@ -1,33 +1,40 @@ import { RouteRecordRaw, RouteLocationNormalized } from 'vue-router'; export function getParentChildrenRoutes(route: RouteLocationNormalized): RouteRecordRaw[] { - // 判断是否有父节点(至少需要2个匹配的路由) - if (route.matched.length < 2) { + // 没有任何匹配路由,直接返回空 + if (!route.matched || route.matched.length === 0) { return []; } - - // 获取倒数第二个匹配的路由(父路由) - const parentRoute = route.matched[route.matched.length - 2]; - - // 检查父路由是否有子路由 - if (!parentRoute?.children || parentRoute.children.length === 0) { - return []; + + // 从当前路由向上查找,找到第一个“有可见子路由”的父级 + for (let i = route.matched.length - 2; i >= 0; i--) { + const parentRoute = route.matched[i]; + const children = parentRoute?.children || []; + + if (!children || children.length === 0) { + continue; + } + + const visibleChildren = children.filter((child: RouteRecordRaw) => { + // 必须有 title + if (!child.meta?.title) { + return false; + } + // 排除 path 为空字符串的子路由(通常是默认子路由) + if (child.path === '' || child.path === undefined) { + return false; + } + // 排除 name 以 _page 结尾的子路由(父路由的默认子路由) + if (typeof child.name === 'string' && child.name.endsWith('_page')) { + return false; + } + return true; + }); + + if (visibleChildren.length > 0) { + return visibleChildren; + } } - - // 返回有 title 的子路由,但排除父路由本身(path 为空字符串或 name 以 _page 结尾的子路由) - return parentRoute.children.filter((child: RouteRecordRaw) => { - // 必须有 title - if (!child.meta?.title) { - return false; - } - // 排除 path 为空字符串的子路由(代表父路由本身) - if (child.path === '' || child.path === undefined) { - return false; - } - // 排除 name 以 _page 结尾的子路由(父路由的默认子路由) - if (typeof child.name === 'string' && child.name.endsWith('_page')) { - return false; - } - return true; - }); + + return []; } \ No newline at end of file diff --git a/schoolNewsWeb/src/views/admin/AdminLayout.vue b/schoolNewsWeb/src/views/admin/AdminLayout.vue index 300c099..828073a 100644 --- a/schoolNewsWeb/src/views/admin/AdminLayout.vue +++ b/schoolNewsWeb/src/views/admin/AdminLayout.vue @@ -49,11 +49,12 @@ defineProps<{ }>(); const route = useRoute(); - +console.log(route.path); // 获取兄弟路由(计算属性,确保响应式更新) const menus = computed(() => { return getParentChildrenRoutes(route); }); +console.log(menus.value); // 获取完整路径 function getFullPath(menu: RouteRecordRaw): string { diff --git a/schoolNewsWeb/src/views/admin/manage/resource/DataRecordsView.vue b/schoolNewsWeb/src/views/admin/manage/resource/DataRecordsView.vue deleted file mode 100644 index ab46df8..0000000 --- a/schoolNewsWeb/src/views/admin/manage/resource/DataRecordsView.vue +++ /dev/null @@ -1,56 +0,0 @@ - - - - - - diff --git a/schoolNewsWeb/src/views/admin/manage/resource/ResourceManagementView.vue b/schoolNewsWeb/src/views/admin/manage/resource/ResourceManagementView.vue index 0ed85c1..7e39d1b 100644 --- a/schoolNewsWeb/src/views/admin/manage/resource/ResourceManagementView.vue +++ b/schoolNewsWeb/src/views/admin/manage/resource/ResourceManagementView.vue @@ -1,11 +1,10 @@