mirror of
https://gitcode.com/ageerle/ruoyi-ai.git
synced 2026-04-17 05:43:39 +00:00
feat: 增加演示模式
This commit is contained in:
@@ -17,8 +17,8 @@ spring:
|
|||||||
type: ${spring.datasource.type}
|
type: ${spring.datasource.type}
|
||||||
driverClassName: com.mysql.cj.jdbc.Driver
|
driverClassName: com.mysql.cj.jdbc.Driver
|
||||||
url: jdbc:mysql://127.0.0.1:3306/ruoyi-ai?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true
|
url: jdbc:mysql://127.0.0.1:3306/ruoyi-ai?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true
|
||||||
username: ruoyi-ai
|
username: root
|
||||||
password: ruoyi-ai
|
password: root
|
||||||
|
|
||||||
hikari:
|
hikari:
|
||||||
# 最大连接池数量
|
# 最大连接池数量
|
||||||
|
|||||||
@@ -2,15 +2,13 @@
|
|||||||
# 项目相关配置
|
# 项目相关配置
|
||||||
ruoyi:
|
ruoyi:
|
||||||
# 名称
|
# 名称
|
||||||
name: "ruoyi"
|
name: "ruoyi-ai"
|
||||||
# 版本
|
# 版本
|
||||||
version: ${revision}
|
version: ${revision}
|
||||||
# 版权年份
|
# 版权年份
|
||||||
copyrightYear: 2025
|
copyrightYear: 2025
|
||||||
# 实例演示开关
|
# 实例演示开关
|
||||||
demoEnabled: true
|
demoEnabled: false
|
||||||
# 获取ip地址开关
|
|
||||||
addressEnabled: false
|
|
||||||
|
|
||||||
captcha:
|
captcha:
|
||||||
enable: false
|
enable: false
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
package org.ruoyi.common.web.config;
|
package org.ruoyi.common.web.config;
|
||||||
|
|
||||||
|
|
||||||
|
import org.ruoyi.common.web.interceptor.DemoModeInterceptor;
|
||||||
import org.ruoyi.common.web.interceptor.PlusWebInvokeTimeInterceptor;
|
import org.ruoyi.common.web.interceptor.PlusWebInvokeTimeInterceptor;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.web.cors.CorsConfiguration;
|
import org.springframework.web.cors.CorsConfiguration;
|
||||||
@@ -18,10 +21,35 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
|||||||
@AutoConfiguration
|
@AutoConfiguration
|
||||||
public class ResourcesConfig implements WebMvcConfigurer {
|
public class ResourcesConfig implements WebMvcConfigurer {
|
||||||
|
|
||||||
|
@Autowired(required = false)
|
||||||
|
private DemoModeInterceptor demoModeInterceptor;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addInterceptors(InterceptorRegistry registry) {
|
public void addInterceptors(InterceptorRegistry registry) {
|
||||||
// 全局访问性能拦截
|
// 全局访问性能拦截
|
||||||
registry.addInterceptor(new PlusWebInvokeTimeInterceptor());
|
registry.addInterceptor(new PlusWebInvokeTimeInterceptor());
|
||||||
|
|
||||||
|
// 演示模式拦截器
|
||||||
|
if (demoModeInterceptor != null) {
|
||||||
|
registry.addInterceptor(demoModeInterceptor)
|
||||||
|
.addPathPatterns("/**") // 拦截所有路径
|
||||||
|
.excludePathPatterns(
|
||||||
|
// 排除静态资源
|
||||||
|
"/css/**",
|
||||||
|
"/js/**",
|
||||||
|
"/images/**",
|
||||||
|
"/fonts/**",
|
||||||
|
"/favicon.ico",
|
||||||
|
// 排除错误页面
|
||||||
|
"/error",
|
||||||
|
// 排除API文档
|
||||||
|
"/*/api-docs/**",
|
||||||
|
"/swagger-ui/**",
|
||||||
|
"/webjars/**",
|
||||||
|
// 排除监控端点
|
||||||
|
"/actuator/**"
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -0,0 +1,100 @@
|
|||||||
|
package org.ruoyi.common.web.interceptor;
|
||||||
|
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.ruoyi.common.core.config.RuoYiConfig;
|
||||||
|
import org.ruoyi.common.core.exception.DemoModeException;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.web.servlet.HandlerInterceptor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 演示模式拦截器
|
||||||
|
* 全局拦截所有编辑操作(POST、PUT、DELETE、PATCH)
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
public class DemoModeInterceptor implements HandlerInterceptor {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RuoYiConfig ruoYiConfig;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
||||||
|
// 如果演示模式未开启,直接放行
|
||||||
|
if (!ruoYiConfig.isDemoEnabled()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
String method = request.getMethod();
|
||||||
|
String requestURI = request.getRequestURI();
|
||||||
|
|
||||||
|
// 拦截所有编辑操作
|
||||||
|
if (isEditOperation(method)) {
|
||||||
|
// 排除一些特殊的只读操作
|
||||||
|
if (isExcludedPath(requestURI)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
log.warn("演示模式拦截: {} {}", method, requestURI);
|
||||||
|
throw new DemoModeException();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否为编辑操作
|
||||||
|
*/
|
||||||
|
private boolean isEditOperation(String method) {
|
||||||
|
return "POST".equalsIgnoreCase(method)
|
||||||
|
|| "PUT".equalsIgnoreCase(method)
|
||||||
|
|| "DELETE".equalsIgnoreCase(method)
|
||||||
|
|| "PATCH".equalsIgnoreCase(method);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否为排除的路径(这些路径即使是POST等方法也不拦截)
|
||||||
|
*/
|
||||||
|
private boolean isExcludedPath(String requestURI) {
|
||||||
|
// 排除登录相关
|
||||||
|
if (requestURI.contains("/auth/login") || requestURI.contains("/auth/logout")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 排除导出操作(虽然是POST但是只读操作)
|
||||||
|
if (requestURI.contains("/export")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 排除查询操作(一些复杂查询使用POST)
|
||||||
|
if (requestURI.contains("/list") || requestURI.contains("/query")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 排除聊天接口(核心功能)
|
||||||
|
if (requestURI.contains("/chat/send") || requestURI.contains("/chat/upload")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 排除文件上传预览等只读操作
|
||||||
|
if (requestURI.contains("/upload") || requestURI.contains("/preview")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 排除支付回调
|
||||||
|
if (requestURI.contains("/pay/returnUrl") || requestURI.contains("/pay/notifyUrl")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 排除重置密码(用户自己的操作)
|
||||||
|
if (requestURI.contains("/auth/reset/password")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user