From 9ee37ff42cb466c6b76964e0ba9992b58cc7675d Mon Sep 17 00:00:00 2001 From: "Ray.Hao" <1490493387@qq.com> Date: Wed, 24 Jun 2026 08:12:01 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E5=88=A0=E9=99=A4=E9=99=90?= =?UTF-8?q?=E6=B5=81Filter=20=E5=AE=9E=E4=BD=93=E7=BB=9F=E4=B8=80=20?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E5=BD=92=E4=BD=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sql/youlai_admin.sql | 1 + .../boot/common/constant/RedisConstants.java | 2 +- .../boot/common/constant/SystemConstants.java | 4 - .../mybatis/config/MybatisConfig.java | 4 +- ...er.java => AutoFillMetaObjectHandler.java} | 2 +- ...CountJob.java => OnlineUserCountTask.java} | 2 +- .../boot/system/enums/MenuTypeEnum.java | 14 +-- .../youlai/boot/system/model/entity/Menu.java | 33 +++---- .../boot/system/model/form/MenuForm.java | 3 + .../youlai/boot/system/model/vo/MenuVO.java | 3 + .../youlai/boot/system/model/vo/RouteVO.java | 3 + .../security/config/SecurityConfig.java | 3 - .../security/filter/RateLimiterFilter.java | 98 ------------------- .../boot/system/service/ConfigService.java | 7 -- .../service/impl/ConfigServiceImpl.java | 14 --- .../resources/mapper/system/MenuMapper.xml | 1 + 16 files changed, 31 insertions(+), 163 deletions(-) rename youlai-framework/src/main/java/com/youlai/boot/framework/mybatis/handler/{MyMetaObjectHandler.java => AutoFillMetaObjectHandler.java} (94%) rename youlai-message/src/main/java/com/youlai/boot/message/job/{OnlineUserCountJob.java => OnlineUserCountTask.java} (96%) delete mode 100644 youlai-system/src/main/java/com/youlai/boot/system/security/filter/RateLimiterFilter.java diff --git a/sql/youlai_admin.sql b/sql/youlai_admin.sql index 2bf42096..1abbcc7b 100644 --- a/sql/youlai_admin.sql +++ b/sql/youlai_admin.sql @@ -120,6 +120,7 @@ CREATE TABLE `sys_menu` ( `route_name` varchar(255) COMMENT '路由名称(Vue Router 中用于命名路由)', `route_path` varchar(128) COMMENT '路由路径(Vue Router 中定义的 URL 路径)', `component` varchar(128) COMMENT '组件路径(组件页面完整路径,相对于 src/views/,缺省后缀 .vue)', + `external_url` varchar(512) COMMENT '外链地址', `perm` varchar(128) COMMENT '【按钮】权限标识', `always_show` tinyint DEFAULT 0 COMMENT '【目录】只有一个子路由是否始终显示(1-是 0-否)', `keep_alive` tinyint DEFAULT 0 COMMENT '【菜单】是否开启页面缓存(1-是 0-否)', diff --git a/youlai-common/src/main/java/com/youlai/boot/common/constant/RedisConstants.java b/youlai-common/src/main/java/com/youlai/boot/common/constant/RedisConstants.java index b54c0455..7555337d 100644 --- a/youlai-common/src/main/java/com/youlai/boot/common/constant/RedisConstants.java +++ b/youlai-common/src/main/java/com/youlai/boot/common/constant/RedisConstants.java @@ -12,7 +12,7 @@ public interface RedisConstants { * 限流相关键 */ interface RateLimiter { - String IP = "rate_limiter:ip:{}"; // IP限流(示例:rate_limiter:ip:192.168.1.1) + String API = "{}rate_limit:{}:{}"; // 接口限流 } /** diff --git a/youlai-common/src/main/java/com/youlai/boot/common/constant/SystemConstants.java b/youlai-common/src/main/java/com/youlai/boot/common/constant/SystemConstants.java index 43489745..0e5edc2f 100644 --- a/youlai-common/src/main/java/com/youlai/boot/common/constant/SystemConstants.java +++ b/youlai-common/src/main/java/com/youlai/boot/common/constant/SystemConstants.java @@ -24,9 +24,5 @@ public interface SystemConstants { String ROOT_ROLE_CODE = "ROOT"; - /** - * 系统配置 IP的QPS限流的KEY - */ - String SYSTEM_CONFIG_IP_QPS_LIMIT_KEY = "IP_QPS_THRESHOLD_LIMIT"; } diff --git a/youlai-framework/src/main/java/com/youlai/boot/framework/mybatis/config/MybatisConfig.java b/youlai-framework/src/main/java/com/youlai/boot/framework/mybatis/config/MybatisConfig.java index 76ff4115..2da50bd3 100644 --- a/youlai-framework/src/main/java/com/youlai/boot/framework/mybatis/config/MybatisConfig.java +++ b/youlai-framework/src/main/java/com/youlai/boot/framework/mybatis/config/MybatisConfig.java @@ -5,7 +5,7 @@ import com.baomidou.mybatisplus.core.config.GlobalConfig; import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; import com.baomidou.mybatisplus.extension.plugins.inner.DataPermissionInterceptor; import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; -import com.youlai.boot.framework.mybatis.handler.MyMetaObjectHandler; +import com.youlai.boot.framework.mybatis.handler.AutoFillMetaObjectHandler; import com.youlai.boot.framework.mybatis.interceptor.MyDataPermissionHandler; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -43,7 +43,7 @@ public class MybatisConfig { @Bean public GlobalConfig globalConfig() { GlobalConfig globalConfig = new GlobalConfig(); - globalConfig.setMetaObjectHandler(new MyMetaObjectHandler()); + globalConfig.setMetaObjectHandler(new AutoFillMetaObjectHandler()); return globalConfig; } diff --git a/youlai-framework/src/main/java/com/youlai/boot/framework/mybatis/handler/MyMetaObjectHandler.java b/youlai-framework/src/main/java/com/youlai/boot/framework/mybatis/handler/AutoFillMetaObjectHandler.java similarity index 94% rename from youlai-framework/src/main/java/com/youlai/boot/framework/mybatis/handler/MyMetaObjectHandler.java rename to youlai-framework/src/main/java/com/youlai/boot/framework/mybatis/handler/AutoFillMetaObjectHandler.java index 75b6f41f..0a24cd86 100644 --- a/youlai-framework/src/main/java/com/youlai/boot/framework/mybatis/handler/MyMetaObjectHandler.java +++ b/youlai-framework/src/main/java/com/youlai/boot/framework/mybatis/handler/AutoFillMetaObjectHandler.java @@ -18,7 +18,7 @@ import java.time.LocalDateTime; */ @Component @RequiredArgsConstructor -public class MyMetaObjectHandler implements MetaObjectHandler { +public class AutoFillMetaObjectHandler implements MetaObjectHandler { /** * 新增填充创建时间、更新时间 diff --git a/youlai-message/src/main/java/com/youlai/boot/message/job/OnlineUserCountJob.java b/youlai-message/src/main/java/com/youlai/boot/message/job/OnlineUserCountTask.java similarity index 96% rename from youlai-message/src/main/java/com/youlai/boot/message/job/OnlineUserCountJob.java rename to youlai-message/src/main/java/com/youlai/boot/message/job/OnlineUserCountTask.java index 14ecb42e..96bad07a 100644 --- a/youlai-message/src/main/java/com/youlai/boot/message/job/OnlineUserCountJob.java +++ b/youlai-message/src/main/java/com/youlai/boot/message/job/OnlineUserCountTask.java @@ -15,7 +15,7 @@ import org.springframework.stereotype.Component; @Component @Slf4j @RequiredArgsConstructor -public class OnlineUserCountJob { +public class OnlineUserCountTask { private final SseSessionRegistry sessionRegistry; private final SseService sseService; diff --git a/youlai-system/src/main/java/com/youlai/boot/system/enums/MenuTypeEnum.java b/youlai-system/src/main/java/com/youlai/boot/system/enums/MenuTypeEnum.java index 8745ff7f..dde3a1bc 100644 --- a/youlai-system/src/main/java/com/youlai/boot/system/enums/MenuTypeEnum.java +++ b/youlai-system/src/main/java/com/youlai/boot/system/enums/MenuTypeEnum.java @@ -5,28 +5,22 @@ import com.youlai.boot.common.base.IBaseEnum; import lombok.Getter; /** - * 菜单类型枚举(char) + * 菜单类型枚举 * - * C:目录 - * M:菜单 - * B:按钮 + * @author Ray.Hao + * @since 0.0.1 */ @Getter public enum MenuTypeEnum implements IBaseEnum { CATALOG("C", "目录"), MENU("M", "菜单"), + EXTERNAL("E", "外链"), BUTTON("B", "按钮"); - /** - * 数据库存储值 - */ @EnumValue private final String value; - /** - * 友好名称 - */ private final String label; MenuTypeEnum(String value, String label) { diff --git a/youlai-system/src/main/java/com/youlai/boot/system/model/entity/Menu.java b/youlai-system/src/main/java/com/youlai/boot/system/model/entity/Menu.java index 475e966a..4839f40b 100644 --- a/youlai-system/src/main/java/com/youlai/boot/system/model/entity/Menu.java +++ b/youlai-system/src/main/java/com/youlai/boot/system/model/entity/Menu.java @@ -2,10 +2,10 @@ package com.youlai.boot.system.model.entity; import com.baomidou.mybatisplus.annotation.*; import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; -import lombok.Getter; -import lombok.Setter; +import com.youlai.boot.common.base.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; -import java.time.LocalDateTime; import java.util.Map; /** @@ -15,15 +15,9 @@ import java.util.Map; * @since 2023/3/6 */ @TableName(value = "sys_menu", autoResultMap = true) -@Getter -@Setter -public class Menu { - /** - * 菜单ID - */ - @TableId(type = IdType.AUTO) - private Long id; - +@Data +@EqualsAndHashCode(callSuper = true) +public class Menu extends BaseEntity { /** * 父菜单ID */ @@ -54,6 +48,11 @@ public class Menu { */ private String component; + /** + * 外链地址 + */ + private String externalUrl; + /** * 权限标识 */ @@ -100,14 +99,4 @@ public class Menu { @TableField(updateStrategy = FieldStrategy.ALWAYS, typeHandler = JacksonTypeHandler.class) private Map params; - - @TableField(fill = FieldFill.INSERT) - private LocalDateTime createTime; - - /** - * 更新时间 - */ - @TableField(fill = FieldFill.INSERT_UPDATE) - private LocalDateTime updateTime; - } diff --git a/youlai-system/src/main/java/com/youlai/boot/system/model/form/MenuForm.java b/youlai-system/src/main/java/com/youlai/boot/system/model/form/MenuForm.java index dabc73ce..41cda185 100644 --- a/youlai-system/src/main/java/com/youlai/boot/system/model/form/MenuForm.java +++ b/youlai-system/src/main/java/com/youlai/boot/system/model/form/MenuForm.java @@ -38,6 +38,9 @@ public class MenuForm { @Schema(description = "组件路径(vue页面完整路径,省略.vue后缀)") private String component; + @Schema(description = "外链地址") + private String externalUrl; + @Schema(description = "权限标识") private String perm; diff --git a/youlai-system/src/main/java/com/youlai/boot/system/model/vo/MenuVO.java b/youlai-system/src/main/java/com/youlai/boot/system/model/vo/MenuVO.java index 81010597..2353a18e 100644 --- a/youlai-system/src/main/java/com/youlai/boot/system/model/vo/MenuVO.java +++ b/youlai-system/src/main/java/com/youlai/boot/system/model/vo/MenuVO.java @@ -31,6 +31,9 @@ public class MenuVO { @Schema(description = "组件路径") private String component; + @Schema(description = "外链地址") + private String externalUrl; + @Schema(description = "菜单排序(数字越小排名越靠前)") private Integer sort; diff --git a/youlai-system/src/main/java/com/youlai/boot/system/model/vo/RouteVO.java b/youlai-system/src/main/java/com/youlai/boot/system/model/vo/RouteVO.java index a07ed419..49b6e663 100644 --- a/youlai-system/src/main/java/com/youlai/boot/system/model/vo/RouteVO.java +++ b/youlai-system/src/main/java/com/youlai/boot/system/model/vo/RouteVO.java @@ -56,6 +56,9 @@ public class RouteVO { @Schema(description = "路由参数") private Map params; + + @Schema(description = "外链地址") + private String externalUrl; } @Schema(description = "子路由列表") diff --git a/youlai-system/src/main/java/com/youlai/boot/system/security/config/SecurityConfig.java b/youlai-system/src/main/java/com/youlai/boot/system/security/config/SecurityConfig.java index 731fa3f4..a302a5fe 100644 --- a/youlai-system/src/main/java/com/youlai/boot/system/security/config/SecurityConfig.java +++ b/youlai-system/src/main/java/com/youlai/boot/system/security/config/SecurityConfig.java @@ -3,7 +3,6 @@ package com.youlai.boot.system.security.config; import cn.binarywang.wx.miniapp.api.WxMaService; import com.youlai.boot.framework.captcha.service.CaptchaService; import cn.hutool.core.util.ArrayUtil; -import com.youlai.boot.system.security.filter.RateLimiterFilter; import com.youlai.boot.framework.security.filter.CaptchaValidationFilter; import com.youlai.boot.framework.security.filter.TokenAuthenticationFilter; import com.youlai.boot.framework.security.handler.MyAccessDeniedHandler; @@ -86,8 +85,6 @@ public class SecurityConfig { .httpBasic(AbstractHttpConfigurer::disable) // 禁用 HTTP Basic 认证,避免弹窗式登录 // 禁用 X-Frame-Options 响应头,允许页面被嵌套到 iframe 中 .headers(headers -> headers.frameOptions(HeadersConfigurer.FrameOptionsConfig::disable)) - // 限流过滤器 - .addFilterBefore(new RateLimiterFilter(redisTemplate, configService), UsernamePasswordAuthenticationFilter.class) // 验证码校验过滤器 .addFilterBefore(new CaptchaValidationFilter(captchaService), UsernamePasswordAuthenticationFilter.class) // 验证和解析过滤器 diff --git a/youlai-system/src/main/java/com/youlai/boot/system/security/filter/RateLimiterFilter.java b/youlai-system/src/main/java/com/youlai/boot/system/security/filter/RateLimiterFilter.java deleted file mode 100644 index 4621214b..00000000 --- a/youlai-system/src/main/java/com/youlai/boot/system/security/filter/RateLimiterFilter.java +++ /dev/null @@ -1,98 +0,0 @@ -package com.youlai.boot.system.security.filter; - -import cn.hutool.core.convert.Convert; -import cn.hutool.core.util.StrUtil; -import com.youlai.boot.common.constant.RedisConstants; -import com.youlai.boot.common.constant.SystemConstants; -import com.youlai.boot.common.result.ResultCode; -import com.youlai.boot.common.util.IPUtils; -import com.youlai.boot.common.result.ResponseWriter; -import com.youlai.boot.system.service.ConfigService; -import jakarta.servlet.FilterChain; -import jakarta.servlet.ServletException; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import lombok.extern.slf4j.Slf4j; -import jakarta.validation.constraints.NotNull; -import org.springframework.data.redis.core.RedisTemplate; -import org.springframework.web.filter.OncePerRequestFilter; - -import java.io.IOException; -import java.util.concurrent.TimeUnit; - -/** - * IP 限流过滤器 - * - * @author Theo - * @since 2024/08/10 14:38 - */ -@Slf4j -public class RateLimiterFilter extends OncePerRequestFilter { - - private final RedisTemplate redisTemplate; - private final ConfigService configService; - - private static final long DEFAULT_IP_LIMIT = 10L; // 默认 IP 限流阈值 - - public RateLimiterFilter(RedisTemplate redisTemplate, ConfigService configService) { - this.redisTemplate = redisTemplate; - this.configService = configService; - } - - /** - * 判断 IP 是否触发限流 - * 默认限制同一 IP 每秒最多请求 10 次,可通过系统配置调整。 - * 如果系统未配置限流阈值,默认跳过限流。 - * - * @param ip IP 地址 - * @return 是否限流:true 表示限流;false 表示未限流 - */ - public boolean rateLimit(String ip) { - // 限流 Redis 键 - String key = StrUtil.format(RedisConstants.RateLimiter.IP, ip); - - // 自增请求计数 - Long count = redisTemplate.opsForValue().increment(key); - if (count == null || count == 1) { - // 第一次访问时设置过期时间为 1 秒 - redisTemplate.expire(key, 1, TimeUnit.SECONDS); - } - - // 获取系统配置的限流阈值 - Object systemConfig = configService.getSystemConfig(SystemConstants.SYSTEM_CONFIG_IP_QPS_LIMIT_KEY); - if (systemConfig == null) { - // 系统未配置限流,跳过限流逻辑 - log.warn("系统未配置限流阈值,跳过限流"); - return false; - } - - // 转换系统配置为限流值,默认为 10 - long limit = Convert.toLong(systemConfig, DEFAULT_IP_LIMIT); - return count != null && count > limit; - } - - /** - * 执行 IP 限流逻辑 - * 如果 IP 请求超出限制,直接返回限流响应;否则继续执行过滤器链。 - * - * @param request 请求体 - * @param response 响应体 - * @param filterChain 过滤器链 - */ - @Override - protected void doFilterInternal(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response, - @NotNull FilterChain filterChain) throws ServletException, IOException { - // 获取请求的 IP 地址 - String ip = IPUtils.getIpAddr(request); - - // 判断是否限流 - if (rateLimit(ip)) { - // 返回限流错误信息 - ResponseWriter.writeError(response, ResultCode.REQUEST_CONCURRENCY_LIMIT_EXCEEDED); - return; - } - - // 未触发限流,继续执行过滤器链 - filterChain.doFilter(request, response); - } -} diff --git a/youlai-system/src/main/java/com/youlai/boot/system/service/ConfigService.java b/youlai-system/src/main/java/com/youlai/boot/system/service/ConfigService.java index d663826f..76bd563a 100644 --- a/youlai-system/src/main/java/com/youlai/boot/system/service/ConfigService.java +++ b/youlai-system/src/main/java/com/youlai/boot/system/service/ConfigService.java @@ -58,11 +58,4 @@ public interface ConfigService extends IService { */ boolean refreshCache(); - /** - * 获取系统配置 - * @param key 配置键 - * @return 配置值 - */ - Object getSystemConfig(String key); - } diff --git a/youlai-system/src/main/java/com/youlai/boot/system/service/impl/ConfigServiceImpl.java b/youlai-system/src/main/java/com/youlai/boot/system/service/impl/ConfigServiceImpl.java index 711b90c2..6c38a372 100644 --- a/youlai-system/src/main/java/com/youlai/boot/system/service/impl/ConfigServiceImpl.java +++ b/youlai-system/src/main/java/com/youlai/boot/system/service/impl/ConfigServiceImpl.java @@ -142,18 +142,4 @@ public class ConfigServiceImpl extends ServiceImpl impleme return false; } - /** - * 获取系统配置 - * - * @param key 配置键 - * @return 配置值 - */ - @Override - public Object getSystemConfig(String key) { - if (StringUtils.isNotBlank(key)) { - return redisTemplate.opsForHash().get(RedisConstants.System.CONFIG, key); - } - return null; - } - } diff --git a/youlai-system/src/main/resources/mapper/system/MenuMapper.xml b/youlai-system/src/main/resources/mapper/system/MenuMapper.xml index 3914e720..2f5afaae 100644 --- a/youlai-system/src/main/resources/mapper/system/MenuMapper.xml +++ b/youlai-system/src/main/resources/mapper/system/MenuMapper.xml @@ -18,6 +18,7 @@ t1.route_name, t1.route_path, t1.component, + t1.external_url, t1.icon, t1.sort, t1.visible,