From 92b3b1ca2da9d6ad9bef61f5cfb70020a522df4b Mon Sep 17 00:00:00 2001 From: "Ray.Hao" <1490493387@qq.com> Date: Mon, 29 Jun 2026 22:33:54 +0800 Subject: [PATCH] =?UTF-8?q?refactor(menu):=20=E5=A4=96=E9=93=BE/=E5=86=85?= =?UTF-8?q?=E5=B5=8C=E6=94=B9=E4=B8=BA=20type=3DE+component=20=E7=BB=9F?= =?UTF-8?q?=E4=B8=80=E5=88=A4=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/youlai/boot/common/enums/EnvEnum.java | 4 +- .../youlai/boot/common/enums/StatusEnum.java | 7 ++- .../mybatis/config/MybatisConfig.java | 6 +-- .../handler/AutoFillMetaObjectHandler.java | 11 +--- .../system/service/impl/MenuServiceImpl.java | 51 +++++++++++-------- 5 files changed, 41 insertions(+), 38 deletions(-) diff --git a/src/main/java/com/youlai/boot/common/enums/EnvEnum.java b/src/main/java/com/youlai/boot/common/enums/EnvEnum.java index 9f502fab..64936d58 100644 --- a/src/main/java/com/youlai/boot/common/enums/EnvEnum.java +++ b/src/main/java/com/youlai/boot/common/enums/EnvEnum.java @@ -6,8 +6,8 @@ import lombok.Getter; /** * 环境枚举 * - * @author Ray - * @since 4.0.0 + * @author Ray.Hao + * @since 3.5.1 */ @Getter public enum EnvEnum implements IBaseEnum { diff --git a/src/main/java/com/youlai/boot/common/enums/StatusEnum.java b/src/main/java/com/youlai/boot/common/enums/StatusEnum.java index 229086fa..eadca183 100644 --- a/src/main/java/com/youlai/boot/common/enums/StatusEnum.java +++ b/src/main/java/com/youlai/boot/common/enums/StatusEnum.java @@ -6,18 +6,17 @@ import lombok.Getter; /** * 状态枚举 * - * @author haoxr - * @since 2022/10/14 + * @author Ray.Hao + * @since 3.5.1 */ @Getter public enum StatusEnum implements IBaseEnum { ENABLE(1, "启用"), - DISABLE (0, "禁用"); + DISABLE(0, "禁用"); private final Integer value; - private final String label; StatusEnum(Integer value, String label) { diff --git a/src/main/java/com/youlai/boot/framework/mybatis/config/MybatisConfig.java b/src/main/java/com/youlai/boot/framework/mybatis/config/MybatisConfig.java index 2da50bd3..bf8e5728 100644 --- a/src/main/java/com/youlai/boot/framework/mybatis/config/MybatisConfig.java +++ b/src/main/java/com/youlai/boot/framework/mybatis/config/MybatisConfig.java @@ -12,10 +12,10 @@ import org.springframework.context.annotation.Configuration; import org.springframework.transaction.annotation.EnableTransactionManagement; /** - * mybatis-plus 配置类 + * MyBatis-Plus 配置类 * * @author Ray.Hao - * @since 2022/7/2 + * @since 3.5.1 */ @Configuration @EnableTransactionManagement @@ -38,7 +38,7 @@ public class MybatisConfig { } /** - * 自动填充数据库创建人、创建时间、更新人、更新时间 + * 自动填充创建时间和更新时间 */ @Bean public GlobalConfig globalConfig() { diff --git a/src/main/java/com/youlai/boot/framework/mybatis/handler/AutoFillMetaObjectHandler.java b/src/main/java/com/youlai/boot/framework/mybatis/handler/AutoFillMetaObjectHandler.java index 0a24cd86..631d29a8 100644 --- a/src/main/java/com/youlai/boot/framework/mybatis/handler/AutoFillMetaObjectHandler.java +++ b/src/main/java/com/youlai/boot/framework/mybatis/handler/AutoFillMetaObjectHandler.java @@ -1,23 +1,16 @@ package com.youlai.boot.framework.mybatis.handler; import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; -import lombok.RequiredArgsConstructor; import org.apache.ibatis.reflection.MetaObject; -import org.springframework.stereotype.Component; import java.time.LocalDateTime; /** - * mybatis-plus 字段自动填充 - *

- * 支持自动填充创建时间、更新时间 - *

+ * MyBatis-Plus 字段自动填充 * * @author Ray.Hao - * @since 2022/10/14 + * @since 3.5.1 */ -@Component -@RequiredArgsConstructor public class AutoFillMetaObjectHandler implements MetaObjectHandler { /** diff --git a/src/main/java/com/youlai/boot/system/service/impl/MenuServiceImpl.java b/src/main/java/com/youlai/boot/system/service/impl/MenuServiceImpl.java index 088ae04a..21329319 100644 --- a/src/main/java/com/youlai/boot/system/service/impl/MenuServiceImpl.java +++ b/src/main/java/com/youlai/boot/system/service/impl/MenuServiceImpl.java @@ -227,36 +227,46 @@ public class MenuServiceImpl extends ServiceImpl implements Me private RouteVO toRouteVo(Menu menu) { RouteVO routeVo = new RouteVO(); String routePath = menu.getRoutePath(); - boolean externalLink = StrUtil.startWithAny(routePath, "http://", "https://"); + String externalUrl = menu.getExternalUrl(); + + boolean isExternal = MenuTypeEnum.EXTERNAL.getValue().equals(menu.getType()); + boolean isEmbedded = isExternal && "iframe".equals(menu.getComponent()); + + String path = isExternal && !isEmbedded && StrUtil.isNotBlank(externalUrl) + ? externalUrl + : routePath; + routeVo.setPath(path); - // 获取路由名称 String routeName = menu.getRouteName(); - if (StrUtil.isBlank(routeName)) { - // 外链不做驼峰转换,使用唯一占位,避免 http:// 被解析异常 - routeName = externalLink - ? "ext-" + menu.getId() - : StringUtils.capitalize(StrUtil.toCamelCase(routePath, '-')); + if (StrUtil.isBlank(routeName) && !isExternal) { + routeName = StringUtils.capitalize(StrUtil.toCamelCase(path, '-')); } - // 根据name路由跳转 this.$router.push({name:xxx}) routeVo.setName(routeName); - // 根据path路由跳转 this.$router.push({path:xxx}) - routeVo.setPath(routePath); routeVo.setRedirect(menu.getRedirect()); - // 外链无组件 - routeVo.setComponent(externalLink ? null : menu.getComponent()); + + if (isEmbedded) { + routeVo.setComponent("iframe"); + } else if (isExternal) { + routeVo.setComponent(null); + } else { + routeVo.setComponent(menu.getComponent()); + } RouteVO.Meta meta = new RouteVO.Meta(); meta.setTitle(menu.getName()); meta.setIcon(menu.getIcon()); meta.setHidden(StatusEnum.DISABLE.getValue().equals(menu.getVisible())); - // 【菜单】是否开启页面缓存 - if (MenuTypeEnum.MENU.getValue().equals(menu.getType()) + if ((MenuTypeEnum.MENU.getValue().equals(menu.getType()) || isEmbedded) && ObjectUtil.equals(menu.getKeepAlive(), 1)) { meta.setKeepAlive(true); } meta.setAlwaysShow(ObjectUtil.equals(menu.getAlwaysShow(), 1)); + if (isEmbedded && StrUtil.isNotBlank(externalUrl)) { + meta.setExternalUrl(externalUrl); + } + Map paramsMap = menu.getParams(); if (paramsMap != null && !paramsMap.isEmpty()) { Map paramMap = paramsMap.entrySet().stream() @@ -275,8 +285,8 @@ public class MenuServiceImpl extends ServiceImpl implements Me public boolean saveMenu(MenuForm menuForm) { String menuType = menuForm.getType(); - boolean isExternalLink = MenuTypeEnum.MENU.getValue().equals(menuType) - && StrUtil.startWithAny(menuForm.getRoutePath(), "http://", "https://"); + boolean isExternal = MenuTypeEnum.EXTERNAL.getValue().equals(menuType); + boolean isEmbedded = isExternal && "iframe".equals(menuForm.getComponent()); if (MenuTypeEnum.CATALOG.getValue().equals(menuType)) { // 如果是目录 String path = menuForm.getRoutePath(); @@ -284,8 +294,8 @@ public class MenuServiceImpl extends ServiceImpl implements Me menuForm.setRoutePath("/" + path); // 一级目录需以 / 开头 } menuForm.setComponent("Layout"); - } else if (isExternalLink) { - // 外链菜单组件设置为 null,通过 routePath 判断外链 + } else if (isExternal && !isEmbedded) { + // 外链新标签页:component 留空 menuForm.setComponent(null); } if (Objects.equals(menuForm.getParentId(), menuForm.getId())) { @@ -302,8 +312,9 @@ public class MenuServiceImpl extends ServiceImpl implements Me } else { entity.setParams(null); } - // 新增类型为菜单时候 路由名称唯一 - if (MenuTypeEnum.MENU.getValue().equals(menuType) && !isExternalLink) { + // 菜单(M)和内嵌外链(E+iframe)需要路由名称唯一 + boolean needsRouteName = MenuTypeEnum.MENU.getValue().equals(menuType) || isEmbedded; + if (needsRouteName) { Assert.isFalse(this.exists(new LambdaQueryWrapper() .eq(Menu::getRouteName, entity.getRouteName()) .ne(menuForm.getId() != null, Menu::getId, menuForm.getId())