From edcdc9f996568a07d1f500c4d316bd8997aa32d5 Mon Sep 17 00:00:00 2001 From: fengshuonan Date: Thu, 15 Jun 2023 10:15:25 +0800 Subject: [PATCH] =?UTF-8?q?=E3=80=907.6.0=E3=80=91=E3=80=90sys=E3=80=91?= =?UTF-8?q?=E3=80=90menu=E3=80=91=E6=9B=B4=E6=96=B0=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E8=8F=9C=E5=8D=95=E7=9A=84=E6=A0=A1=E9=AA=8C=E5=92=8Cpids?= =?UTF-8?q?=E5=A1=AB=E5=85=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kernel/sys/api/enums/MenuTypeEnum.java | 92 +++++++++++++++++++ .../menu/enums/SysMenuExceptionEnum.java | 22 ++++- .../menu/factory/MenuValidateFactory.java | 66 +++++++++++-- .../menu/service/impl/SysMenuServiceImpl.java | 28 ++++++ 4 files changed, 198 insertions(+), 10 deletions(-) create mode 100644 kernel-s-sys/sys-api/src/main/java/cn/stylefeng/roses/kernel/sys/api/enums/MenuTypeEnum.java diff --git a/kernel-s-sys/sys-api/src/main/java/cn/stylefeng/roses/kernel/sys/api/enums/MenuTypeEnum.java b/kernel-s-sys/sys-api/src/main/java/cn/stylefeng/roses/kernel/sys/api/enums/MenuTypeEnum.java new file mode 100644 index 000000000..5eca6afe8 --- /dev/null +++ b/kernel-s-sys/sys-api/src/main/java/cn/stylefeng/roses/kernel/sys/api/enums/MenuTypeEnum.java @@ -0,0 +1,92 @@ +/* + * Copyright [2020-2030] [https://www.stylefeng.cn] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Guns采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + * + * 1.请不要删除和修改根目录下的LICENSE文件。 + * 2.请不要删除和修改Guns源码头部的版权声明。 + * 3.请保留源码和相关描述文件的项目出处,作者声明等。 + * 4.分发源码时候,请注明软件出处 https://gitee.com/stylefeng/guns + * 5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/stylefeng/guns + * 6.若您的项目无法满足以上几点,可申请商业授权 + */ +package cn.stylefeng.roses.kernel.sys.api.enums; + +import cn.hutool.core.convert.Convert; +import cn.hutool.core.util.ObjectUtil; +import cn.stylefeng.roses.kernel.rule.base.ReadableEnum; +import lombok.Getter; + +/** + * 菜单类型:10-后台菜单,20-纯前台路由界面,30-内部链接,40-外部链接 + * + * @author fengshuonan + * @since 2023/6/15 9:45 + */ +@Getter +public enum MenuTypeEnum implements ReadableEnum { + + /** + * 后台菜单 + */ + BACKEND_MENU(10, "后台菜单"), + + /** + * 纯前台路由界面 + */ + FRONT_VUE(20, "纯前台路由界面"), + + /** + * 内部链接 + */ + INNER_URL(30, "内部链接"), + + /** + * 外部链接 + */ + OUT_URL(40, "外部链接"); + + private final Integer code; + + private final String message; + + MenuTypeEnum(Integer code, String message) { + this.code = code; + this.message = message; + } + + @Override + public Object getKey() { + return this.code; + } + + @Override + public Object getName() { + return this.message; + } + + @Override + public MenuTypeEnum parseToEnum(String originValue) { + if (ObjectUtil.isEmpty(originValue)) { + return null; + } + for (MenuTypeEnum value : MenuTypeEnum.values()) { + if (value.code.equals(Convert.toInt(originValue))) { + return value; + } + } + return null; + } +} diff --git a/kernel-s-sys/sys-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/menu/enums/SysMenuExceptionEnum.java b/kernel-s-sys/sys-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/menu/enums/SysMenuExceptionEnum.java index 5a20e9865..50d9909db 100644 --- a/kernel-s-sys/sys-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/menu/enums/SysMenuExceptionEnum.java +++ b/kernel-s-sys/sys-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/menu/enums/SysMenuExceptionEnum.java @@ -21,7 +21,27 @@ public enum SysMenuExceptionEnum implements AbstractExceptionEnum { /** * 当前应用下菜单编码存在重复,请更换编码 */ - MENU_CODE_REPEAT(RuleConstants.USER_OPERATION_ERROR_TYPE_CODE + "10002", "当前应用下菜单编码存在重复,请更换编码"); + MENU_CODE_REPEAT(RuleConstants.USER_OPERATION_ERROR_TYPE_CODE + "10002", "当前应用下菜单编码存在重复,请更换编码"), + + /** + * 路由地址不能为空 + */ + URL_CANT_EMPTY(RuleConstants.USER_OPERATION_ERROR_TYPE_CODE + "10003", "路由地址不能为空"), + + /** + * 组件代码路径不能为空 + */ + COMPONENT_PATH_CANT_EMPTY(RuleConstants.USER_OPERATION_ERROR_TYPE_CODE + "10004", "组件代码路径不能为空"), + + /** + * 是否隐藏不能为空 + */ + HIDDEN_FLAG_CANT_EMPTY(RuleConstants.USER_OPERATION_ERROR_TYPE_CODE + "10005", "是否隐藏不能为空"), + + /** + * 链接地址不能为空 + */ + LINK_URL_CANT_EMPTY(RuleConstants.USER_OPERATION_ERROR_TYPE_CODE + "10006", "链接地址不能为空"); /** * 错误编码 diff --git a/kernel-s-sys/sys-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/menu/factory/MenuValidateFactory.java b/kernel-s-sys/sys-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/menu/factory/MenuValidateFactory.java index d1a91ce79..ab3722e6a 100644 --- a/kernel-s-sys/sys-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/menu/factory/MenuValidateFactory.java +++ b/kernel-s-sys/sys-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/menu/factory/MenuValidateFactory.java @@ -1,7 +1,9 @@ package cn.stylefeng.roses.kernel.sys.modular.menu.factory; +import cn.hutool.core.util.ObjectUtil; import cn.hutool.extra.spring.SpringUtil; import cn.stylefeng.roses.kernel.rule.exception.base.ServiceException; +import cn.stylefeng.roses.kernel.sys.api.enums.MenuTypeEnum; import cn.stylefeng.roses.kernel.sys.modular.menu.entity.SysMenu; import cn.stylefeng.roses.kernel.sys.modular.menu.enums.SysMenuExceptionEnum; import cn.stylefeng.roses.kernel.sys.modular.menu.pojo.request.SysMenuRequest; @@ -26,21 +28,67 @@ public class MenuValidateFactory { SysMenuService sysMenuService = SpringUtil.getBean(SysMenuService.class); - // 同应用下菜单编码不能重复 + // 1. 校验同应用下菜单编码不能重复 Long menuId = sysMenuRequest.getMenuId(); - // 如果是新增菜单 - if (menuId == null) { - String menuCode = sysMenuRequest.getMenuCode(); - LambdaQueryWrapper sysMenuLambdaQueryWrapper = new LambdaQueryWrapper<>(); - sysMenuLambdaQueryWrapper.eq(SysMenu::getMenuCode, menuCode); - long alreadyCount = sysMenuService.count(sysMenuLambdaQueryWrapper); - if (alreadyCount > 0) { - throw new ServiceException(SysMenuExceptionEnum.MENU_CODE_REPEAT); + String menuCode = sysMenuRequest.getMenuCode(); + + LambdaQueryWrapper sysMenuLambdaQueryWrapper = new LambdaQueryWrapper<>(); + sysMenuLambdaQueryWrapper.eq(SysMenu::getMenuCode, menuCode); + sysMenuLambdaQueryWrapper.eq(SysMenu::getAppId, sysMenuRequest.getAppId()); + + // 如果是编辑菜单,则排除当前这个菜单的查询 + if (menuId != null) { + sysMenuLambdaQueryWrapper.ne(SysMenu::getMenuId, menuId); + } + + long alreadyCount = sysMenuService.count(sysMenuLambdaQueryWrapper); + if (alreadyCount > 0) { + throw new ServiceException(SysMenuExceptionEnum.MENU_CODE_REPEAT); + } + + // 2. 校验vue组件相关的配置是否必填 + Integer menuType = sysMenuRequest.getMenuType(); + + // 2.1 如果是后台菜单,校验路由地址、组件代码路径、是否隐藏参数 + if (MenuTypeEnum.BACKEND_MENU.getKey().equals(menuType)) { + if (ObjectUtil.isEmpty(sysMenuRequest.getAntdvRouter())) { + throw new ServiceException(SysMenuExceptionEnum.URL_CANT_EMPTY); + } + if (ObjectUtil.isEmpty(sysMenuRequest.getAntdvComponent())) { + throw new ServiceException(SysMenuExceptionEnum.COMPONENT_PATH_CANT_EMPTY); + } + if (ObjectUtil.isEmpty(sysMenuRequest.getAntdvVisible())) { + throw new ServiceException(SysMenuExceptionEnum.HIDDEN_FLAG_CANT_EMPTY); } } + // 2.2 如果是纯前端路由,则判断路由地址和组件代码路径 + else if (MenuTypeEnum.FRONT_VUE.getKey().equals(menuType)) { + if (ObjectUtil.isEmpty(sysMenuRequest.getAntdvRouter())) { + throw new ServiceException(SysMenuExceptionEnum.URL_CANT_EMPTY); + } + if (ObjectUtil.isEmpty(sysMenuRequest.getAntdvComponent())) { + throw new ServiceException(SysMenuExceptionEnum.COMPONENT_PATH_CANT_EMPTY); + } + } + // 2.3 如果是内部链接,判断路由地址和连接地址 + else if (MenuTypeEnum.INNER_URL.getKey().equals(menuType)) { + if (ObjectUtil.isEmpty(sysMenuRequest.getAntdvRouter())) { + throw new ServiceException(SysMenuExceptionEnum.URL_CANT_EMPTY); + } + if (ObjectUtil.isEmpty(sysMenuRequest.getAntdvLinkUrl())) { + throw new ServiceException(SysMenuExceptionEnum.LINK_URL_CANT_EMPTY); + } + } + + // 2.4 如果是外部链接,则判断外部链接地址 + else if (MenuTypeEnum.OUT_URL.getKey().equals(menuType)) { + if (ObjectUtil.isEmpty(sysMenuRequest.getAntdvComponent())) { + throw new ServiceException(SysMenuExceptionEnum.COMPONENT_PATH_CANT_EMPTY); + } + } } } diff --git a/kernel-s-sys/sys-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/menu/service/impl/SysMenuServiceImpl.java b/kernel-s-sys/sys-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/menu/service/impl/SysMenuServiceImpl.java index 10d6fe671..f8bed6c03 100644 --- a/kernel-s-sys/sys-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/menu/service/impl/SysMenuServiceImpl.java +++ b/kernel-s-sys/sys-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/menu/service/impl/SysMenuServiceImpl.java @@ -3,6 +3,8 @@ package cn.stylefeng.roses.kernel.sys.modular.menu.service.impl; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; +import cn.stylefeng.roses.kernel.rule.constants.SymbolConstant; +import cn.stylefeng.roses.kernel.rule.constants.TreeConstants; import cn.stylefeng.roses.kernel.rule.exception.base.ServiceException; import cn.stylefeng.roses.kernel.sys.modular.app.service.SysAppService; import cn.stylefeng.roses.kernel.sys.modular.menu.entity.SysMenu; @@ -45,6 +47,8 @@ public class SysMenuServiceImpl extends ServiceImpl impl BeanUtil.copyProperties(sysMenuRequest, sysMenu); // 组装pids集合 + String pids = this.createPids(sysMenuRequest.getMenuParentId()); + sysMenu.setMenuPids(pids); this.save(sysMenu); } @@ -177,4 +181,28 @@ public class SysMenuServiceImpl extends ServiceImpl impl return queryWrapper; } + /** + * 创建pids的值 + *

+ * 如果pid是顶级节点,pids = 【[-1],】 + *

+ * 如果pid不是顶级节点,pids = 【父菜单的pids,[pid],】 + * + * @author fengshuonan + * @since 2023/6/15 10:09 + */ + private String createPids(Long pid) { + if (pid.equals(TreeConstants.DEFAULT_PARENT_ID)) { + return SymbolConstant.LEFT_SQUARE_BRACKETS + TreeConstants.DEFAULT_PARENT_ID + SymbolConstant.RIGHT_SQUARE_BRACKETS + SymbolConstant.COMMA; + } else { + //获取父菜单 + SysMenuRequest sysMenuRequest = new SysMenuRequest(); + sysMenuRequest.setMenuId(pid); + SysMenu parentMenu = this.querySysMenu(sysMenuRequest); + + // 组装pids + return parentMenu.getMenuPids() + SymbolConstant.LEFT_SQUARE_BRACKETS + pid + SymbolConstant.RIGHT_SQUARE_BRACKETS + SymbolConstant.COMMA; + } + } + } \ No newline at end of file