From 5486f6e79d09a0813c69e8eef993ecbcffa52fcd Mon Sep 17 00:00:00 2001 From: liyongde <1419499670@qq.com> Date: Thu, 9 Jul 2026 13:52:53 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=88=A0=E9=99=A4=E8=8F=9C=E5=8D=95?= =?UTF-8?q?=E5=8C=85=E6=8B=AC=E5=AD=90=E7=BA=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- nl-dependencies/pom.xml | 2 +- .../src/main/resources/application-dev.yaml | 5 ++- .../src/main/resources/application.yaml | 2 +- .../admin/permission/MenuController.java | 5 +-- .../service/permission/MenuService.java | 5 +-- .../service/permission/MenuServiceImpl.java | 32 +++++++++++++++--- .../src/main/resources/application-dev.yaml | 3 ++ .../src/main/resources/application.yaml | 2 +- .../src/main/resources/application-dev.yaml | 4 +++ .../src/api/system/menu/index.ts | 4 +-- .../src/views/system/menu/index.vue | 33 +++++++++++++++---- 11 files changed, 75 insertions(+), 22 deletions(-) diff --git a/nl-dependencies/pom.xml b/nl-dependencies/pom.xml index 88efd25f..82657709 100644 --- a/nl-dependencies/pom.xml +++ b/nl-dependencies/pom.xml @@ -40,7 +40,7 @@ - 2.4.0 + 2.4.2 2.2.7 diff --git a/nl-module-infra/nl-module-infra-server/src/main/resources/application-dev.yaml b/nl-module-infra/nl-module-infra-server/src/main/resources/application-dev.yaml index 8a68ca23..6dabe13c 100644 --- a/nl-module-infra/nl-module-infra-server/src/main/resources/application-dev.yaml +++ b/nl-module-infra/nl-module-infra-server/src/main/resources/application-dev.yaml @@ -95,7 +95,10 @@ spring: xxl: job: admin: - addresses: http://127.0.0.1:9090/xxl-job-admin # 调度中心部署跟地址 + addresses: http://192.168.10.14:8080/xxl-job-admin # 调度中心部署跟地址 + executor: + ip: 192.168.10.14 + port: 9991 --- #################### 服务保障相关配置 #################### diff --git a/nl-module-infra/nl-module-infra-server/src/main/resources/application.yaml b/nl-module-infra/nl-module-infra-server/src/main/resources/application.yaml index 17979f30..36a7066f 100644 --- a/nl-module-infra/nl-module-infra-server/src/main/resources/application.yaml +++ b/nl-module-infra/nl-module-infra-server/src/main/resources/application.yaml @@ -124,7 +124,7 @@ xxl: executor: appname: ${spring.application.name} # 执行器 AppName logpath: ${user.home}/logs/xxl-job/${spring.application.name} # 执行器运行日志文件存储磁盘路径 - accessToken: default_token # 执行器通讯TOKEN + accessToken: 123456 # 执行器通讯TOKEN --- #################### 芋道相关配置 #################### diff --git a/nl-module-system/nl-module-system-server/src/main/java/cn/code/nl/module/system/controller/admin/permission/MenuController.java b/nl-module-system/nl-module-system-server/src/main/java/cn/code/nl/module/system/controller/admin/permission/MenuController.java index 8e223d8d..34fcec2a 100644 --- a/nl-module-system/nl-module-system-server/src/main/java/cn/code/nl/module/system/controller/admin/permission/MenuController.java +++ b/nl-module-system/nl-module-system-server/src/main/java/cn/code/nl/module/system/controller/admin/permission/MenuController.java @@ -52,8 +52,9 @@ public class MenuController { @Operation(summary = "删除菜单") @Parameter(name = "id", description = "菜单编号", required= true, example = "1024") @PreAuthorize("@ss.hasPermission('system:menu:delete')") - public CommonResult deleteMenu(@RequestParam("id") Long id) { - menuService.deleteMenu(id); + public CommonResult deleteMenu(@RequestParam("id") Long id, + @RequestParam(value = "cascade", defaultValue = "false") boolean cascade) { + menuService.deleteMenu(id, cascade); return success(true); } diff --git a/nl-module-system/nl-module-system-server/src/main/java/cn/code/nl/module/system/service/permission/MenuService.java b/nl-module-system/nl-module-system-server/src/main/java/cn/code/nl/module/system/service/permission/MenuService.java index b684c183..543c4c02 100644 --- a/nl-module-system/nl-module-system-server/src/main/java/cn/code/nl/module/system/service/permission/MenuService.java +++ b/nl-module-system/nl-module-system-server/src/main/java/cn/code/nl/module/system/service/permission/MenuService.java @@ -32,9 +32,10 @@ public interface MenuService { /** * 删除菜单 * - * @param id 菜单编号 + * @param id 菜单编号 + * @param cascade 是否级联删除子菜单 */ - void deleteMenu(Long id); + void deleteMenu(Long id, boolean cascade); /** * 批量删除菜单 diff --git a/nl-module-system/nl-module-system-server/src/main/java/cn/code/nl/module/system/service/permission/MenuServiceImpl.java b/nl-module-system/nl-module-system-server/src/main/java/cn/code/nl/module/system/service/permission/MenuServiceImpl.java index d3fc553a..70e22208 100644 --- a/nl-module-system/nl-module-system-server/src/main/java/cn/code/nl/module/system/service/permission/MenuServiceImpl.java +++ b/nl-module-system/nl-module-system-server/src/main/java/cn/code/nl/module/system/service/permission/MenuServiceImpl.java @@ -89,21 +89,43 @@ public class MenuServiceImpl implements MenuService { @Transactional(rollbackFor = Exception.class) @CacheEvict(value = RedisKeyConstants.PERMISSION_MENU_ID_LIST, allEntries = true) // allEntries 清空所有缓存,因为此时不知道 id 对应的 permission 是多少。直接清理,简单有效 - public void deleteMenu(Long id) { - // 校验是否还有子菜单 - if (menuMapper.selectCountByParentId(id) > 0) { - throw exception(MENU_EXISTS_CHILDREN); - } + public void deleteMenu(Long id, boolean cascade) { // 校验删除的菜单是否存在 if (menuMapper.selectById(id) == null) { throw exception(MENU_NOT_EXISTS); } + // 校验是否还有子菜单 + if (menuMapper.selectCountByParentId(id) > 0) { + if (!cascade) { + throw exception(MENU_EXISTS_CHILDREN); + } + // 级联删除:递归收集所有子菜单 ID + List childIds = new ArrayList<>(); + collectChildMenuIds(id, childIds); + // 先删除子菜单,再删父菜单 + menuMapper.deleteByIds(childIds); + childIds.forEach(childId -> permissionService.processMenuDeleted(childId)); + } // 标记删除 menuMapper.deleteById(id); // 删除授予给角色的权限 permissionService.processMenuDeleted(id); } + /** + * 递归收集所有子菜单 ID + * + * @param parentId 父菜单 ID + * @param result 收集结果 + */ + private void collectChildMenuIds(Long parentId, List result) { + List children = menuMapper.selectList(MenuDO::getParentId, parentId); + for (MenuDO child : children) { + result.add(child.getId()); + collectChildMenuIds(child.getId(), result); + } + } + @Override @Transactional(rollbackFor = Exception.class) @CacheEvict(value = RedisKeyConstants.PERMISSION_MENU_ID_LIST, diff --git a/nl-module-system/nl-module-system-server/src/main/resources/application-dev.yaml b/nl-module-system/nl-module-system-server/src/main/resources/application-dev.yaml index 55f25a3f..8f34648a 100644 --- a/nl-module-system/nl-module-system-server/src/main/resources/application-dev.yaml +++ b/nl-module-system/nl-module-system-server/src/main/resources/application-dev.yaml @@ -96,6 +96,9 @@ xxl: job: admin: addresses: http://192.168.10.14:8080/xxl-job-admin # 调度中心部署跟地址 + executor: + ip: 192.168.10.14 + port: 9992 --- #################### 服务保障相关配置 #################### diff --git a/nl-module-system/nl-module-system-server/src/main/resources/application.yaml b/nl-module-system/nl-module-system-server/src/main/resources/application.yaml index 32f1873e..2e123eff 100644 --- a/nl-module-system/nl-module-system-server/src/main/resources/application.yaml +++ b/nl-module-system/nl-module-system-server/src/main/resources/application.yaml @@ -124,7 +124,7 @@ xxl: executor: appname: ${spring.application.name} # 执行器 AppName logpath: ${user.home}/logs/xxl-job/${spring.application.name} # 执行器运行日志文件存储磁盘路径 - accessToken: default_token # 执行器通讯TOKEN + accessToken: 123456 # 执行器通讯TOKEN --- #################### 验证码相关配置 #################### diff --git a/nl-server/src/main/resources/application-dev.yaml b/nl-server/src/main/resources/application-dev.yaml index a7c2ca9d..94b6b146 100644 --- a/nl-server/src/main/resources/application-dev.yaml +++ b/nl-server/src/main/resources/application-dev.yaml @@ -71,6 +71,10 @@ xxl: enabled: false # 是否开启调度中心,默认为 true 开启 admin: addresses: http://192.168.10.14:8080/xxl-job-admin # 调度中心部署跟地址 + executor: + appname: nl-lms-server + ip: 192.168.10.14 + port: 9992 --- #################### 消息队列相关 #################### diff --git a/nl-ui/nl-ui-admin-vben/yudao-ui-admin-vben/apps/web-antdv-next/src/api/system/menu/index.ts b/nl-ui/nl-ui-admin-vben/yudao-ui-admin-vben/apps/web-antdv-next/src/api/system/menu/index.ts index b296d815..cb1d5c7c 100644 --- a/nl-ui/nl-ui-admin-vben/yudao-ui-admin-vben/apps/web-antdv-next/src/api/system/menu/index.ts +++ b/nl-ui/nl-ui-admin-vben/yudao-ui-admin-vben/apps/web-antdv-next/src/api/system/menu/index.ts @@ -49,8 +49,8 @@ export async function updateMenu(data: SystemMenuApi.Menu) { } /** 删除菜单 */ -export async function deleteMenu(id: number) { - return requestClient.delete(`/system/menu/delete?id=${id}`); +export async function deleteMenu(id: number, cascade?: boolean) { + return requestClient.delete(`/system/menu/delete?id=${id}&cascade=${cascade || false}`); } /** 批量删除菜单 */ diff --git a/nl-ui/nl-ui-admin-vben/yudao-ui-admin-vben/apps/web-antdv-next/src/views/system/menu/index.vue b/nl-ui/nl-ui-admin-vben/yudao-ui-admin-vben/apps/web-antdv-next/src/views/system/menu/index.vue index d01ec354..6395edc1 100644 --- a/nl-ui/nl-ui-admin-vben/yudao-ui-admin-vben/apps/web-antdv-next/src/views/system/menu/index.vue +++ b/nl-ui/nl-ui-admin-vben/yudao-ui-admin-vben/apps/web-antdv-next/src/views/system/menu/index.vue @@ -8,7 +8,7 @@ import { Page, useVbenModal } from '@vben/common-ui'; import { SystemMenuTypeEnum } from '@vben/constants'; import { IconifyIcon } from '@vben/icons'; -import { message } from 'antdv-next'; +import { message, Modal } from 'antdv-next'; import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table'; import { deleteMenu, getMenuList } from '#/api/system/menu'; @@ -43,13 +43,35 @@ function handleEdit(row: SystemMenuApi.Menu) { } /** 删除菜单 */ -async function handleDelete(row: SystemMenuApi.Menu) { +function handleDelete(row: SystemMenuApi.Menu) { + const hasChildren = (row as any).children?.length > 0; + if (hasChildren) { + Modal.confirm({ + title: '提示', + content: '该菜单存在子菜单,是否连子级一起删除?', + okText: '是', + cancelText: '否', + onOk: () => doDelete(row, true), + }); + } else { + Modal.confirm({ + title: '提示', + content: $t('ui.actionMessage.deleteConfirm', [row.name]), + okText: '确认', + cancelText: '取消', + onOk: () => doDelete(row, false), + }); + } +} + +/** 执行菜单删除 */ +async function doDelete(row: SystemMenuApi.Menu, cascade: boolean) { const hideLoading = message.loading({ content: $t('ui.actionMessage.deleting', [row.name]), duration: 0, }); try { - await deleteMenu(row.id!); + await deleteMenu(row.id!, cascade); message.success($t('ui.actionMessage.deleteSuccess', [row.name])); handleRefresh(); } finally { @@ -161,10 +183,7 @@ const [Grid, gridApi] = useVbenVxeGrid({ danger: true, icon: ACTION_ICON.DELETE, auth: ['system:menu:delete'], - popConfirm: { - title: $t('ui.actionMessage.deleteConfirm', [row.name]), - confirm: handleDelete.bind(null, row), - }, + onClick: handleDelete.bind(null, row), }, ]" />