Commit 646b2022ff5310e3876854b6207e4267b6da01ff
1 parent
2e27a424
增加演示模式
Showing
7 changed files
with
64 additions
and
0 deletions
ruoyi-ui/src/utils/request.js
| @@ -73,6 +73,18 @@ service.interceptors.response.use(res => { | @@ -73,6 +73,18 @@ service.interceptors.response.use(res => { | ||
| 73 | type: 'error' | 73 | type: 'error' |
| 74 | }) | 74 | }) |
| 75 | return Promise.reject(new Error(msg)) | 75 | return Promise.reject(new Error(msg)) |
| 76 | + } else if (code === 901) { | ||
| 77 | + Message({ | ||
| 78 | + type: 'error', | ||
| 79 | + duration: 0, | ||
| 80 | + dangerouslyUseHTMLString: true, | ||
| 81 | + message: '<div>演示模式,不发进行写操作</div>' | ||
| 82 | + + '<div> </div>' | ||
| 83 | + + '<div>参考 https://www.iocoder.cn/Yudao/build-debugger-environment 教程</div>' | ||
| 84 | + + '<div> </div>' | ||
| 85 | + + '<div>5 分钟搭建本地环境</div>', | ||
| 86 | + }) | ||
| 87 | + return Promise.reject(new Error(msg)) | ||
| 76 | } else if (code !== 200) { | 88 | } else if (code !== 200) { |
| 77 | Notification.error({ | 89 | Notification.error({ |
| 78 | title: msg | 90 | title: msg |
src/main/java/cn/iocoder/dashboard/common/exception/enums/GlobalErrorCodeConstants.java
| @@ -32,6 +32,7 @@ public interface GlobalErrorCodeConstants { | @@ -32,6 +32,7 @@ public interface GlobalErrorCodeConstants { | ||
| 32 | 32 | ||
| 33 | // ========== 自定义错误段 ========== | 33 | // ========== 自定义错误段 ========== |
| 34 | ErrorCode REPEATED_REQUESTS = new ErrorCode(900, "重复请求,请稍后重试"); // 重复请求 | 34 | ErrorCode REPEATED_REQUESTS = new ErrorCode(900, "重复请求,请稍后重试"); // 重复请求 |
| 35 | + ErrorCode DEMO_DENY = new ErrorCode(901, "演示模式,禁止写操作"); | ||
| 35 | 36 | ||
| 36 | ErrorCode UNKNOWN = new ErrorCode(999, "未知错误"); | 37 | ErrorCode UNKNOWN = new ErrorCode(999, "未知错误"); |
| 37 | 38 |
src/main/java/cn/iocoder/dashboard/framework/web/config/WebConfiguration.java
| @@ -2,7 +2,9 @@ package cn.iocoder.dashboard.framework.web.config; | @@ -2,7 +2,9 @@ package cn.iocoder.dashboard.framework.web.config; | ||
| 2 | 2 | ||
| 3 | import cn.iocoder.dashboard.framework.web.core.enums.FilterOrderEnum; | 3 | import cn.iocoder.dashboard.framework.web.core.enums.FilterOrderEnum; |
| 4 | import cn.iocoder.dashboard.framework.web.core.filter.CacheRequestBodyFilter; | 4 | import cn.iocoder.dashboard.framework.web.core.filter.CacheRequestBodyFilter; |
| 5 | +import cn.iocoder.dashboard.framework.web.core.filter.DemoFilter; | ||
| 5 | import cn.iocoder.dashboard.framework.web.core.filter.XssFilter; | 6 | import cn.iocoder.dashboard.framework.web.core.filter.XssFilter; |
| 7 | +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; | ||
| 6 | import org.springframework.boot.context.properties.EnableConfigurationProperties; | 8 | import org.springframework.boot.context.properties.EnableConfigurationProperties; |
| 7 | import org.springframework.boot.web.servlet.FilterRegistrationBean; | 9 | import org.springframework.boot.web.servlet.FilterRegistrationBean; |
| 8 | import org.springframework.context.annotation.Bean; | 10 | import org.springframework.context.annotation.Bean; |
| @@ -68,6 +70,15 @@ public class WebConfiguration implements WebMvcConfigurer { | @@ -68,6 +70,15 @@ public class WebConfiguration implements WebMvcConfigurer { | ||
| 68 | return createFilterBean(new XssFilter(properties, pathMatcher), FilterOrderEnum.XSS_FILTER); | 70 | return createFilterBean(new XssFilter(properties, pathMatcher), FilterOrderEnum.XSS_FILTER); |
| 69 | } | 71 | } |
| 70 | 72 | ||
| 73 | + /** | ||
| 74 | + * 创建 DemoFilter Bean,演示模式 | ||
| 75 | + */ | ||
| 76 | + @Bean | ||
| 77 | + @ConditionalOnProperty(value = "yudao.demo", havingValue = "true") | ||
| 78 | + public FilterRegistrationBean<DemoFilter> demoFilter() { | ||
| 79 | + return createFilterBean(new DemoFilter(), FilterOrderEnum.DEMO_FILTER); | ||
| 80 | + } | ||
| 81 | + | ||
| 71 | private static <T extends Filter> FilterRegistrationBean<T> createFilterBean(T filter, Integer order) { | 82 | private static <T extends Filter> FilterRegistrationBean<T> createFilterBean(T filter, Integer order) { |
| 72 | FilterRegistrationBean<T> bean = new FilterRegistrationBean<>(filter); | 83 | FilterRegistrationBean<T> bean = new FilterRegistrationBean<>(filter); |
| 73 | bean.setOrder(order); | 84 | bean.setOrder(order); |
src/main/java/cn/iocoder/dashboard/framework/web/core/enums/FilterOrderEnum.java
| @@ -9,6 +9,7 @@ public interface FilterOrderEnum { | @@ -9,6 +9,7 @@ public interface FilterOrderEnum { | ||
| 9 | 9 | ||
| 10 | int CORS_FILTER = Integer.MIN_VALUE; | 10 | int CORS_FILTER = Integer.MIN_VALUE; |
| 11 | 11 | ||
| 12 | + | ||
| 12 | int REQUEST_BODY_CACHE_FILTER = Integer.MIN_VALUE + 500; | 13 | int REQUEST_BODY_CACHE_FILTER = Integer.MIN_VALUE + 500; |
| 13 | 14 | ||
| 14 | // OrderedRequestContextFilter 默认为 -105,用于国际化上下文等等 | 15 | // OrderedRequestContextFilter 默认为 -105,用于国际化上下文等等 |
| @@ -19,4 +20,6 @@ public interface FilterOrderEnum { | @@ -19,4 +20,6 @@ public interface FilterOrderEnum { | ||
| 19 | 20 | ||
| 20 | // Spring Security Filter 默认为 -100,可见 SecurityProperties 配置属性类 | 21 | // Spring Security Filter 默认为 -100,可见 SecurityProperties 配置属性类 |
| 21 | 22 | ||
| 23 | + int DEMO_FILTER = Integer.MAX_VALUE; | ||
| 24 | + | ||
| 22 | } | 25 | } |
src/main/java/cn/iocoder/dashboard/framework/web/core/filter/DemoFilter.java
0 → 100644
| 1 | +package cn.iocoder.dashboard.framework.web.core.filter; | ||
| 2 | + | ||
| 3 | +import cn.hutool.core.util.StrUtil; | ||
| 4 | +import cn.iocoder.dashboard.common.pojo.CommonResult; | ||
| 5 | +import cn.iocoder.dashboard.framework.security.core.util.SecurityFrameworkUtils; | ||
| 6 | +import cn.iocoder.dashboard.util.servlet.ServletUtils; | ||
| 7 | +import org.springframework.web.filter.OncePerRequestFilter; | ||
| 8 | + | ||
| 9 | +import javax.servlet.FilterChain; | ||
| 10 | +import javax.servlet.http.HttpServletRequest; | ||
| 11 | +import javax.servlet.http.HttpServletResponse; | ||
| 12 | + | ||
| 13 | +import static cn.iocoder.dashboard.common.exception.enums.GlobalErrorCodeConstants.DEMO_DENY; | ||
| 14 | + | ||
| 15 | +/** | ||
| 16 | + * 演示 Filter,禁止用户发起写操作,避免影响测试数据 | ||
| 17 | + * | ||
| 18 | + * @author 芋道源码 | ||
| 19 | + */ | ||
| 20 | +public class DemoFilter extends OncePerRequestFilter { | ||
| 21 | + | ||
| 22 | + @Override | ||
| 23 | + protected boolean shouldNotFilter(HttpServletRequest request) { | ||
| 24 | + String method = request.getMethod(); | ||
| 25 | + return !StrUtil.equalsAnyIgnoreCase(method, "POST", "PUT", "DELETE") // 写操作时,不进行过滤率 | ||
| 26 | + || SecurityFrameworkUtils.getLoginUser() == null; // 非登陆用户时,不进行过滤 | ||
| 27 | + } | ||
| 28 | + | ||
| 29 | + @Override | ||
| 30 | + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) { | ||
| 31 | + // 直接返回 DEMO_DENY 的结果。即,请求不继续 | ||
| 32 | + ServletUtils.writeJSON(response, CommonResult.error(DEMO_DENY)); | ||
| 33 | + } | ||
| 34 | + | ||
| 35 | +} |
src/main/resources/application-dev.yaml
| @@ -161,3 +161,4 @@ yudao: | @@ -161,3 +161,4 @@ yudao: | ||
| 161 | exclude-urls: # 如下两个 url,仅仅是为了演示,去掉配置也没关系 | 161 | exclude-urls: # 如下两个 url,仅仅是为了演示,去掉配置也没关系 |
| 162 | - ${spring.boot.admin.context-path}/** # 不处理 Spring Boot Admin 的请求 | 162 | - ${spring.boot.admin.context-path}/** # 不处理 Spring Boot Admin 的请求 |
| 163 | - ${management.endpoints.web.base-path}/** # 不处理 Actuator 的请求 | 163 | - ${management.endpoints.web.base-path}/** # 不处理 Actuator 的请求 |
| 164 | + demo: true # 开启演示模式 |
src/main/resources/application-local.yaml
| @@ -161,3 +161,4 @@ yudao: | @@ -161,3 +161,4 @@ yudao: | ||
| 161 | exclude-urls: # 如下两个 url,仅仅是为了演示,去掉配置也没关系 | 161 | exclude-urls: # 如下两个 url,仅仅是为了演示,去掉配置也没关系 |
| 162 | - ${spring.boot.admin.context-path}/** # 不处理 Spring Boot Admin 的请求 | 162 | - ${spring.boot.admin.context-path}/** # 不处理 Spring Boot Admin 的请求 |
| 163 | - ${management.endpoints.web.base-path}/** # 不处理 Actuator 的请求 | 163 | - ${management.endpoints.web.base-path}/** # 不处理 Actuator 的请求 |
| 164 | + demo: false # 关闭演示模式 |