diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 000000000..fbcab775d
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1 @@
+custom: http://doc.ruoyi.vip/ruoyi-vue/other/donate.html
diff --git a/README.md b/README.md
index a8dbc22ef..5a34add02 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,16 @@
## 平台的简介
+
+
+
+RuoYi v3.8.1
+基于SpringBoot+Vue前后端分离的Java快速开发框架
+
+
+
+
+
+
+## 平台简介
若依是一套全部开源的快速开发平台,毫无保留给个人及企业免费使用。
@@ -7,6 +19,7 @@
* 权限认证使用Jwt,支持多终端认证系统。
* 支持加载动态权限菜单,多方式轻松权限控制。
* 高效率开发,使用代码生成器可以一键生成前后端代码。
+* 提供了技术栈([Vue3](https://v3.cn.vuejs.org) [Element Plus](https://element-plus.org/zh-CN) [Vite](https://cn.vitejs.dev))版本[RuoYi-Vue3](https://github.com/yangzongzhuan/RuoYi-Vue3),保持同步更新。
* 提供了单应用版本[RuoYi-Vue-fast](https://github.com/yangzongzhuan/RuoYi-Vue-fast),Oracle版本[RuoYi-Vue-Oracle](https://github.com/yangzongzhuan/RuoYi-Vue-Oracle),保持同步更新。
* 不分离版本,请移步[RuoYi](https://gitee.com/y_project/RuoYi),微服务版本,请移步[RuoYi-Cloud](https://gitee.com/y_project/RuoYi-Cloud)
* 特别鸣谢:[element](https://github.com/ElemeFE/element),[vue-element-admin](https://github.com/PanJiaChen/vue-element-admin),[eladmin-web](https://github.com/elunez/eladmin-web)。
@@ -82,4 +95,4 @@
## 若依前后端分离交流群
-QQ群: [](https://jq.qq.com/?_wv=1027&k=5bVB1og) [](https://jq.qq.com/?_wv=1027&k=5eiA4DH) [](https://jq.qq.com/?_wv=1027&k=5AxMKlC) [](https://jq.qq.com/?_wv=1027&k=51G72yr) [](https://jq.qq.com/?_wv=1027&k=VvjN2nvu) [](https://jq.qq.com/?_wv=1027&k=5vYAqA05) [](https://jq.qq.com/?_wv=1027&k=kOIINEb5) 点击按钮入群。
\ No newline at end of file
+QQ群: [](https://jq.qq.com/?_wv=1027&k=5bVB1og) [](https://jq.qq.com/?_wv=1027&k=5eiA4DH) [](https://jq.qq.com/?_wv=1027&k=5AxMKlC) [](https://jq.qq.com/?_wv=1027&k=51G72yr) [](https://jq.qq.com/?_wv=1027&k=VvjN2nvu) [](https://jq.qq.com/?_wv=1027&k=5vYAqA05) [](https://jq.qq.com/?_wv=1027&k=kOIINEb5) [](https://jq.qq.com/?_wv=1027&k=UKtX5jhs) [](https://jq.qq.com/?_wv=1027&k=EI9an8lJ) 点击按钮入群。
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 6feb0ee79..c024d33d7 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,14 +6,14 @@
com.ruoyi
ruoyi
- 3.7.0
+ 3.8.1
ruoyi
http://www.ruoyi.vip
若依管理系统
- 3.7.0
+ 3.8.1
UTF-8
UTF-8
1.8
@@ -24,14 +24,15 @@
2.3.2
2.2.0
1.4.0
- 1.2.78
- 5.8.2
- 5.9.0
+ 1.2.79
+ 5.8.6
+ 5.10.0
2.11.0
1.4
3.2.2
4.1.2
- 1.7
+ 2.3
+ 2.17.1
0.9.1
@@ -43,7 +44,7 @@
org.springframework.boot
spring-boot-dependencies
- 2.5.5
+ 2.5.8
pom
import
@@ -132,14 +133,8 @@
org.apache.velocity
- velocity
+ velocity-engine-core
${velocity.version}
-
-
- commons-collections
- commons-collections
-
-
@@ -156,6 +151,19 @@
${fastjson.version}
+
+
+ org.apache.logging.log4j
+ log4j-api
+ ${log4j2.version}
+
+
+
+ org.apache.logging.log4j
+ log4j-to-slf4j
+ ${log4j2.version}
+
+
io.jsonwebtoken
diff --git a/ruoyi-admin/pom.xml b/ruoyi-admin/pom.xml
index 1d1d687b4..14769e515 100644
--- a/ruoyi-admin/pom.xml
+++ b/ruoyi-admin/pom.xml
@@ -5,7 +5,7 @@
ruoyi
com.ruoyi
- 3.7.0
+ 3.8.1
4.0.0
jar
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java
index 649fd115e..955c78436 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java
@@ -6,8 +6,8 @@ import java.util.concurrent.TimeUnit;
import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
+import com.ruoyi.common.config.RuoYiConfig;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.FastByteArrayOutputStream;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@@ -36,10 +36,6 @@ public class CaptchaController
@Autowired
private RedisCache redisCache;
- // 验证码类型
- @Value("${ruoyi.captchaType}")
- private String captchaType;
-
@Autowired
private ISysConfigService configService;
/**
@@ -64,6 +60,7 @@ public class CaptchaController
BufferedImage image = null;
// 生成验证码
+ String captchaType = RuoYiConfig.getCaptchaType();
if ("math".equals(captchaType))
{
String capText = captchaProducerMath.createText();
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysLogininforController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysLogininforController.java
index 14f57fdaf..5bd40baed 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysLogininforController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysLogininforController.java
@@ -1,11 +1,13 @@
package com.ruoyi.web.controller.monitor;
import java.util.List;
+import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
@@ -40,12 +42,12 @@ public class SysLogininforController extends BaseController
@Log(title = "登录日志", businessType = BusinessType.EXPORT)
@PreAuthorize("@ss.hasPermi('monitor:logininfor:export')")
- @GetMapping("/export")
- public AjaxResult export(SysLogininfor logininfor)
+ @PostMapping("/export")
+ public void export(HttpServletResponse response, SysLogininfor logininfor)
{
List list = logininforService.selectLogininforList(logininfor);
ExcelUtil util = new ExcelUtil(SysLogininfor.class);
- return util.exportExcel(list, "登录日志");
+ util.exportExcel(response, list, "登录日志");
}
@PreAuthorize("@ss.hasPermi('monitor:logininfor:remove')")
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysOperlogController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysOperlogController.java
index 75bf12682..4ce126a54 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysOperlogController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysOperlogController.java
@@ -1,11 +1,13 @@
package com.ruoyi.web.controller.monitor;
import java.util.List;
+import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
@@ -40,12 +42,12 @@ public class SysOperlogController extends BaseController
@Log(title = "操作日志", businessType = BusinessType.EXPORT)
@PreAuthorize("@ss.hasPermi('monitor:operlog:export')")
- @GetMapping("/export")
- public AjaxResult export(SysOperLog operLog)
+ @PostMapping("/export")
+ public void export(HttpServletResponse response, SysOperLog operLog)
{
List list = operLogService.selectOperLogList(operLog);
ExcelUtil util = new ExcelUtil(SysOperLog.class);
- return util.exportExcel(list, "操作日志");
+ util.exportExcel(response, list, "操作日志");
}
@Log(title = "操作日志", businessType = BusinessType.DELETE)
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysConfigController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysConfigController.java
index dc2532fbc..04f71629a 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysConfigController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysConfigController.java
@@ -1,6 +1,7 @@
package com.ruoyi.web.controller.system;
import java.util.List;
+import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
@@ -13,7 +14,6 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
-import com.ruoyi.common.annotation.RepeatSubmit;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
@@ -49,12 +49,12 @@ public class SysConfigController extends BaseController
@Log(title = "参数管理", businessType = BusinessType.EXPORT)
@PreAuthorize("@ss.hasPermi('system:config:export')")
- @GetMapping("/export")
- public AjaxResult export(SysConfig config)
+ @PostMapping("/export")
+ public void export(HttpServletResponse response, SysConfig config)
{
List list = configService.selectConfigList(config);
ExcelUtil util = new ExcelUtil(SysConfig.class);
- return util.exportExcel(list, "参数数据");
+ util.exportExcel(response, list, "参数数据");
}
/**
@@ -82,7 +82,6 @@ public class SysConfigController extends BaseController
@PreAuthorize("@ss.hasPermi('system:config:add')")
@Log(title = "参数管理", businessType = BusinessType.INSERT)
@PostMapping
- @RepeatSubmit
public AjaxResult add(@Validated @RequestBody SysConfig config)
{
if (UserConstants.NOT_UNIQUE.equals(configService.checkConfigKeyUnique(config)))
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictDataController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictDataController.java
index b9e3dc3b1..eea89fd0d 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictDataController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictDataController.java
@@ -2,6 +2,7 @@ package com.ruoyi.web.controller.system;
import java.util.ArrayList;
import java.util.List;
+import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
@@ -50,12 +51,12 @@ public class SysDictDataController extends BaseController
@Log(title = "字典数据", businessType = BusinessType.EXPORT)
@PreAuthorize("@ss.hasPermi('system:dict:export')")
- @GetMapping("/export")
- public AjaxResult export(SysDictData dictData)
+ @PostMapping("/export")
+ public void export(HttpServletResponse response, SysDictData dictData)
{
List list = dictDataService.selectDictDataList(dictData);
ExcelUtil util = new ExcelUtil(SysDictData.class);
- return util.exportExcel(list, "字典数据");
+ util.exportExcel(response, list, "字典数据");
}
/**
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictTypeController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictTypeController.java
index acad00e26..0dd3474cf 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictTypeController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictTypeController.java
@@ -1,6 +1,7 @@
package com.ruoyi.web.controller.system;
import java.util.List;
+import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
@@ -45,12 +46,12 @@ public class SysDictTypeController extends BaseController
@Log(title = "字典类型", businessType = BusinessType.EXPORT)
@PreAuthorize("@ss.hasPermi('system:dict:export')")
- @GetMapping("/export")
- public AjaxResult export(SysDictType dictType)
+ @PostMapping("/export")
+ public void export(HttpServletResponse response, SysDictType dictType)
{
List list = dictTypeService.selectDictTypeList(dictType);
ExcelUtil util = new ExcelUtil(SysDictType.class);
- return util.exportExcel(list, "字典类型");
+ util.exportExcel(response, list, "字典类型");
}
/**
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysPostController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysPostController.java
index 30a87616c..1a2b408ed 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysPostController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysPostController.java
@@ -1,6 +1,7 @@
package com.ruoyi.web.controller.system;
import java.util.List;
+import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
@@ -48,12 +49,12 @@ public class SysPostController extends BaseController
@Log(title = "岗位管理", businessType = BusinessType.EXPORT)
@PreAuthorize("@ss.hasPermi('system:post:export')")
- @GetMapping("/export")
- public AjaxResult export(SysPost post)
+ @PostMapping("/export")
+ public void export(HttpServletResponse response, SysPost post)
{
List list = postService.selectPostList(post);
ExcelUtil util = new ExcelUtil(SysPost.class);
- return util.exportExcel(list, "岗位数据");
+ util.exportExcel(response, list, "岗位数据");
}
/**
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysProfileController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysProfileController.java
index 227ac872d..be515fd61 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysProfileController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysProfileController.java
@@ -60,6 +60,9 @@ public class SysProfileController extends BaseController
@PutMapping
public AjaxResult updateProfile(@RequestBody SysUser user)
{
+ LoginUser loginUser = getLoginUser();
+ SysUser sysUser = loginUser.getUser();
+ user.setUserName(sysUser.getUserName());
if (StringUtils.isNotEmpty(user.getPhonenumber())
&& UserConstants.NOT_UNIQUE.equals(userService.checkPhoneUnique(user)))
{
@@ -70,8 +73,6 @@ public class SysProfileController extends BaseController
{
return AjaxResult.error("修改用户'" + user.getUserName() + "'失败,邮箱账号已存在");
}
- LoginUser loginUser = getLoginUser();
- SysUser sysUser = loginUser.getUser();
user.setUserId(sysUser.getUserId());
user.setPassword(null);
if (userService.updateUserProfile(user) > 0)
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysRoleController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysRoleController.java
index d73749086..d70fa8158 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysRoleController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysRoleController.java
@@ -1,6 +1,7 @@
package com.ruoyi.web.controller.system;
import java.util.List;
+import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
@@ -61,12 +62,12 @@ public class SysRoleController extends BaseController
@Log(title = "角色管理", businessType = BusinessType.EXPORT)
@PreAuthorize("@ss.hasPermi('system:role:export')")
- @GetMapping("/export")
- public AjaxResult export(SysRole role)
+ @PostMapping("/export")
+ public void export(HttpServletResponse response, SysRole role)
{
List list = roleService.selectRoleList(role);
ExcelUtil util = new ExcelUtil(SysRole.class);
- return util.exportExcel(list, "角色数据");
+ util.exportExcel(response, list, "角色数据");
}
/**
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java
index 6cfbfb8d7..e9be25e04 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java
@@ -2,6 +2,7 @@ package com.ruoyi.web.controller.system;
import java.util.List;
import java.util.stream.Collectors;
+import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
@@ -62,12 +63,12 @@ public class SysUserController extends BaseController
@Log(title = "用户管理", businessType = BusinessType.EXPORT)
@PreAuthorize("@ss.hasPermi('system:user:export')")
- @GetMapping("/export")
- public AjaxResult export(SysUser user)
+ @PostMapping("/export")
+ public void export(HttpServletResponse response, SysUser user)
{
List list = userService.selectUserList(user);
ExcelUtil util = new ExcelUtil(SysUser.class);
- return util.exportExcel(list, "用户数据");
+ util.exportExcel(response, list, "用户数据");
}
@Log(title = "用户管理", businessType = BusinessType.IMPORT)
@@ -82,11 +83,11 @@ public class SysUserController extends BaseController
return AjaxResult.success(message);
}
- @GetMapping("/importTemplate")
- public AjaxResult importTemplate()
+ @PostMapping("/importTemplate")
+ public void importTemplate(HttpServletResponse response)
{
ExcelUtil util = new ExcelUtil(SysUser.class);
- return util.importTemplateExcel("用户数据");
+ util.importTemplateExcel(response, "用户数据");
}
/**
@@ -103,9 +104,10 @@ public class SysUserController extends BaseController
ajax.put("posts", postService.selectPostAll());
if (StringUtils.isNotNull(userId))
{
- ajax.put(AjaxResult.DATA_TAG, userService.selectUserById(userId));
+ SysUser sysUser = userService.selectUserById(userId);
+ ajax.put(AjaxResult.DATA_TAG, sysUser);
ajax.put("postIds", postService.selectPostListByUserId(userId));
- ajax.put("roleIds", roleService.selectRoleListByUserId(userId));
+ ajax.put("roleIds", sysUser.getRoles().stream().map(SysRole::getRoleId).collect(Collectors.toList()));
}
return ajax;
}
diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml
index ae0ffbc9e..ccef2502d 100644
--- a/ruoyi-admin/src/main/resources/application.yml
+++ b/ruoyi-admin/src/main/resources/application.yml
@@ -3,9 +3,9 @@ ruoyi:
# 名称
name: RuoYi
# 版本
- version: 3.7.0
+ version: 3.8.1
# 版权年份
- copyrightYear: 2021
+ copyrightYear: 2022
# 实例演示开关
demoEnabled: true
# 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
@@ -25,10 +25,13 @@ server:
tomcat:
# tomcat的URI编码
uri-encoding: UTF-8
- # tomcat最大线程数,默认为200
- max-threads: 800
- # Tomcat启动初始化的线程数,默认值25
- min-spare-threads: 30
+ # 连接数满后的排队数,默认为100
+ accept-count: 1000
+ threads:
+ # tomcat最大线程数,默认为200
+ max: 800
+ # Tomcat启动初始化的线程数,默认值10
+ min-spare: 100
# 日志配置
logging:
diff --git a/ruoyi-common/pom.xml b/ruoyi-common/pom.xml
index 486d39f8c..e18104ca1 100644
--- a/ruoyi-common/pom.xml
+++ b/ruoyi-common/pom.xml
@@ -5,7 +5,7 @@
ruoyi
com.ruoyi
- 3.7.0
+ 3.8.1
4.0.0
@@ -43,8 +43,8 @@
- javax.validation
- validation-api
+ org.springframework.boot
+ spring-boot-starter-validation
@@ -89,12 +89,18 @@
snakeyaml
-
+
io.jsonwebtoken
jjwt
+
+
+ javax.xml.bind
+ jaxb-api
+
+
org.springframework.boot
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/annotation/RepeatSubmit.java b/ruoyi-common/src/main/java/com/ruoyi/common/annotation/RepeatSubmit.java
index 408300525..1e2774350 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/annotation/RepeatSubmit.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/annotation/RepeatSubmit.java
@@ -27,5 +27,5 @@ public @interface RepeatSubmit
/**
* 提示消息
*/
- public String message() default "不允许重复提交,请稍后再试";
+ public String message() default "不允许重复提交,请稍候再试";
}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/config/RuoYiConfig.java b/ruoyi-common/src/main/java/com/ruoyi/common/config/RuoYiConfig.java
index 843b91912..84c0029db 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/config/RuoYiConfig.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/config/RuoYiConfig.java
@@ -30,6 +30,9 @@ public class RuoYiConfig
/** 获取地址开关 */
private static boolean addressEnabled;
+ /** 验证码类型 */
+ private static String captchaType;
+
public String getName()
{
return name;
@@ -90,6 +93,14 @@ public class RuoYiConfig
RuoYiConfig.addressEnabled = addressEnabled;
}
+ public static String getCaptchaType() {
+ return captchaType;
+ }
+
+ public void setCaptchaType(String captchaType) {
+ RuoYiConfig.captchaType = captchaType;
+ }
+
/**
* 获取导入上传路径
*/
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java b/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java
index 9f55771bf..6deff23bb 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java
@@ -142,10 +142,26 @@ public class Constants
/**
* RMI 远程方法调用
*/
- public static final String LOOKUP_RMI = "rmi://";
+ public static final String LOOKUP_RMI = "rmi:";
/**
* LDAP 远程方法调用
*/
- public static final String LOOKUP_LDAP = "ldap://";
+ public static final String LOOKUP_LDAP = "ldap:";
+
+ /**
+ * LDAPS 远程方法调用
+ */
+ public static final String LOOKUP_LDAPS = "ldaps:";
+
+ /**
+ * 定时任务白名单配置(仅允许访问的包名,如其他需要可以自行添加)
+ */
+ public static final String[] JOB_WHITELIST_STR = { "com.ruoyi" };
+
+ /**
+ * 定时任务违规的字符
+ */
+ public static final String[] JOB_ERROR_STR = { "java.net.URL", "javax.naming.InitialContext", "org.yaml.snakeyaml",
+ "org.springframework", "org.apache", "com.ruoyi.common.utils.file" };
}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/controller/BaseController.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/controller/BaseController.java
index 5b450cb87..2aeaf9bae 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/core/controller/BaseController.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/controller/BaseController.java
@@ -16,6 +16,7 @@ import com.ruoyi.common.core.page.PageDomain;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.page.TableSupport;
import com.ruoyi.common.utils.DateUtils;
+import com.ruoyi.common.utils.PageUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.sql.SqlUtil;
@@ -51,15 +52,7 @@ public class BaseController
*/
protected void startPage()
{
- PageDomain pageDomain = TableSupport.buildPageRequest();
- Integer pageNum = pageDomain.getPageNum();
- Integer pageSize = pageDomain.getPageSize();
- if (StringUtils.isNotNull(pageNum) && StringUtils.isNotNull(pageSize))
- {
- String orderBy = SqlUtil.escapeOrderBySql(pageDomain.getOrderBy());
- Boolean reasonable = pageDomain.getReasonable();
- PageHelper.startPage(pageNum, pageSize, orderBy).setReasonable(reasonable);
- }
+ PageUtils.startPage();
}
/**
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/AjaxResult.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/AjaxResult.java
index b26e066ab..8ca1b9b11 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/AjaxResult.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/AjaxResult.java
@@ -145,4 +145,18 @@ public class AjaxResult extends HashMap
{
return new AjaxResult(code, msg, null);
}
+
+ /**
+ * 方便链式调用
+ *
+ * @param key 键
+ * @param value 值
+ * @return 数据对象
+ */
+ @Override
+ public AjaxResult put(String key, Object value)
+ {
+ super.put(key, value);
+ return this;
+ }
}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysMenu.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysMenu.java
index 8c7c494bc..229f41803 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysMenu.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysMenu.java
@@ -3,6 +3,7 @@ package com.ruoyi.common.core.domain.entity;
import java.util.ArrayList;
import java.util.List;
import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
@@ -30,7 +31,7 @@ public class SysMenu extends BaseEntity
private Long parentId;
/** 显示顺序 */
- private String orderNum;
+ private Integer orderNum;
/** 路由地址 */
private String path;
@@ -107,13 +108,13 @@ public class SysMenu extends BaseEntity
this.parentId = parentId;
}
- @NotBlank(message = "显示顺序不能为空")
- public String getOrderNum()
+ @NotNull(message = "显示顺序不能为空")
+ public Integer getOrderNum()
{
return orderNum;
}
- public void setOrderNum(String orderNum)
+ public void setOrderNum(Integer orderNum)
{
this.orderNum = orderNum;
}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysUser.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysUser.java
index 08cf15142..4aa1d2b2d 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysUser.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysUser.java
@@ -2,9 +2,7 @@ package com.ruoyi.common.core.domain.entity;
import java.util.Date;
import java.util.List;
-import javax.validation.constraints.Email;
-import javax.validation.constraints.NotBlank;
-import javax.validation.constraints.Size;
+import javax.validation.constraints.*;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.fasterxml.jackson.annotation.JsonIgnore;
@@ -14,6 +12,7 @@ import com.ruoyi.common.annotation.Excel.ColumnType;
import com.ruoyi.common.annotation.Excel.Type;
import com.ruoyi.common.annotation.Excels;
import com.ruoyi.common.core.domain.BaseEntity;
+import com.ruoyi.common.xss.Xss;
/**
* 用户对象 sys_user
@@ -135,6 +134,7 @@ public class SysUser extends BaseEntity
this.deptId = deptId;
}
+ @Xss(message = "用户昵称不能包含脚本字符")
@Size(min = 0, max = 30, message = "用户昵称长度不能超过30个字符")
public String getNickName()
{
@@ -146,6 +146,7 @@ public class SysUser extends BaseEntity
this.nickName = nickName;
}
+ @Xss(message = "用户账号不能包含脚本字符")
@NotBlank(message = "用户账号不能为空")
@Size(min = 0, max = 30, message = "用户账号长度不能超过30个字符")
public String getUserName()
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisCache.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisCache.java
index 238753359..3246b7731 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisCache.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisCache.java
@@ -209,6 +209,18 @@ public class RedisCache
return opsForHash.get(key, hKey);
}
+ /**
+ * 删除Hash中的数据
+ *
+ * @param key
+ * @param mapkey
+ */
+ public void delCacheMapValue(final String key, final String hkey)
+ {
+ HashOperations hashOperations = redisTemplate.opsForHash();
+ hashOperations.delete(key, hkey);
+ }
+
/**
* 获取多个Hash中的数据
*
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/PageUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/PageUtils.java
new file mode 100644
index 000000000..7db37a2fe
--- /dev/null
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/PageUtils.java
@@ -0,0 +1,30 @@
+package com.ruoyi.common.utils;
+
+import com.github.pagehelper.PageHelper;
+import com.ruoyi.common.core.page.PageDomain;
+import com.ruoyi.common.core.page.TableSupport;
+import com.ruoyi.common.utils.sql.SqlUtil;
+
+/**
+ * 分页工具类
+ *
+ * @author ruoyi
+ */
+public class PageUtils extends PageHelper
+{
+ /**
+ * 设置请求分页数据
+ */
+ public static void startPage()
+ {
+ PageDomain pageDomain = TableSupport.buildPageRequest();
+ Integer pageNum = pageDomain.getPageNum();
+ Integer pageSize = pageDomain.getPageSize();
+ if (StringUtils.isNotNull(pageNum) && StringUtils.isNotNull(pageSize))
+ {
+ String orderBy = SqlUtil.escapeOrderBySql(pageDomain.getOrderBy());
+ Boolean reasonable = pageDomain.getReasonable();
+ PageHelper.startPage(pageNum, pageSize, orderBy).setReasonable(reasonable);
+ }
+ }
+}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/Threads.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/Threads.java
index 395920a24..f34935284 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/Threads.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/Threads.java
@@ -36,7 +36,7 @@ public class Threads
* 停止线程池
* 先使用shutdown, 停止接收新任务并尝试完成所有已存在任务.
* 如果超时, 则调用shutdownNow, 取消在workQueue中Pending的任务,并中断所有阻塞函数.
- * 如果仍人超時,則強制退出.
+ * 如果仍然超時,則強制退出.
* 另对在shutdown时线程本身被调用中断做了处理.
*/
public static void shutdownAndAwaitTermination(ExecutorService pool)
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/bean/BeanValidators.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/bean/BeanValidators.java
new file mode 100644
index 000000000..d9821e0ec
--- /dev/null
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/bean/BeanValidators.java
@@ -0,0 +1,24 @@
+package com.ruoyi.common.utils.bean;
+
+import java.util.Set;
+import javax.validation.ConstraintViolation;
+import javax.validation.ConstraintViolationException;
+import javax.validation.Validator;
+
+/**
+ * bean对象属性验证
+ *
+ * @author ruoyi
+ */
+public class BeanValidators
+{
+ public static void validateWithException(Validator validator, Object object, Class>... groups)
+ throws ConstraintViolationException
+ {
+ Set> constraintViolations = validator.validate(object, groups);
+ if (!constraintViolations.isEmpty())
+ {
+ throw new ConstraintViolationException(constraintViolations);
+ }
+ }
+}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/FileUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/FileUtils.java
index 8d8f5a6a3..dd1bcc46f 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/FileUtils.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/FileUtils.java
@@ -210,6 +210,8 @@ public class FileUtils
.append("utf-8''")
.append(percentEncodedFileName);
+ response.addHeader("Access-Control-Allow-Origin", "*");
+ response.addHeader("Access-Control-Expose-Headers", "Content-Disposition,download-filename");
response.setHeader("Content-disposition", contentDispositionValue.toString());
response.setHeader("download-filename", percentEncodedFileName);
}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/html/EscapeUtil.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/html/EscapeUtil.java
index 65fd7920f..dda96c32f 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/html/EscapeUtil.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/html/EscapeUtil.java
@@ -69,26 +69,37 @@ public class EscapeUtil
*/
private static String encode(String text)
{
- int len;
- if ((text == null) || ((len = text.length()) == 0))
+ if (StringUtils.isEmpty(text))
{
return StringUtils.EMPTY;
}
- StringBuilder buffer = new StringBuilder(len + (len >> 2));
+
+ final StringBuilder tmp = new StringBuilder(text.length() * 6);
char c;
- for (int i = 0; i < len; i++)
+ for (int i = 0; i < text.length(); i++)
{
c = text.charAt(i);
- if (c < 64)
+ if (c < 256)
{
- buffer.append(TEXT[c]);
+ tmp.append("%");
+ if (c < 16)
+ {
+ tmp.append("0");
+ }
+ tmp.append(Integer.toString(c, 16));
}
else
{
- buffer.append(c);
+ tmp.append("%u");
+ if (c <= 0xfff)
+ {
+ // issue#I49JU8@Gitee
+ tmp.append("0");
+ }
+ tmp.append(Integer.toString(c, 16));
}
}
- return buffer.toString();
+ return tmp.toString();
}
/**
@@ -145,11 +156,12 @@ public class EscapeUtil
public static void main(String[] args)
{
String html = "";
+ String escape = EscapeUtil.escape(html);
// String html = "ipt>alert(\"XSS\")ipt>";
// String html = "<123";
// String html = "123>";
- System.out.println(EscapeUtil.clean(html));
- System.out.println(EscapeUtil.escape(html));
- System.out.println(EscapeUtil.unescape(html));
+ System.out.println("clean: " + EscapeUtil.clean(html));
+ System.out.println("escape: " + escape);
+ System.out.println("unescape: " + EscapeUtil.unescape(escape));
}
}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/html/HTMLFilter.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/html/HTMLFilter.java
index 415acbab2..d3b211a48 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/html/HTMLFilter.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/html/HTMLFilter.java
@@ -332,7 +332,7 @@ public final class HTMLFilter
final String name = m.group(1).toLowerCase();
if (allowed(name))
{
- if (false == inArray(name, vSelfClosingTags))
+ if (!inArray(name, vSelfClosingTags))
{
if (vTagCounts.containsKey(name))
{
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/http/HttpUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/http/HttpUtils.java
index c920f5b12..f57baf0fc 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/http/HttpUtils.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/http/HttpUtils.java
@@ -30,6 +30,17 @@ public class HttpUtils
{
private static final Logger log = LoggerFactory.getLogger(HttpUtils.class);
+ /**
+ * 向指定 URL 发送GET方法的请求
+ *
+ * @param url 发送请求的 URL
+ * @return 所代表远程资源的响应结果
+ */
+ public static String sendGet(String url)
+ {
+ return sendGet(url, StringUtils.EMPTY);
+ }
+
/**
* 向指定 URL 发送GET方法的请求
*
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java
index 4169360a1..93a19e870 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java
@@ -431,7 +431,7 @@ public class ExcelUtil
* @return 结果
* @throws IOException
*/
- public void exportExcel(HttpServletResponse response, List list, String sheetName)throws IOException
+ public void exportExcel(HttpServletResponse response, List list, String sheetName)
{
exportExcel(response, list, sheetName, StringUtils.EMPTY);
}
@@ -446,12 +446,12 @@ public class ExcelUtil
* @return 结果
* @throws IOException
*/
- public void exportExcel(HttpServletResponse response, List list, String sheetName, String title) throws IOException
+ public void exportExcel(HttpServletResponse response, List list, String sheetName, String title)
{
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setCharacterEncoding("utf-8");
this.init(list, sheetName, title, Type.EXPORT);
- exportExcel(response.getOutputStream());
+ exportExcel(response);
}
/**
@@ -484,7 +484,7 @@ public class ExcelUtil
* @param sheetName 工作表的名称
* @return 结果
*/
- public void importTemplateExcel(HttpServletResponse response, String sheetName) throws IOException
+ public void importTemplateExcel(HttpServletResponse response, String sheetName)
{
importTemplateExcel(response, sheetName, StringUtils.EMPTY);
}
@@ -496,12 +496,12 @@ public class ExcelUtil
* @param title 标题
* @return 结果
*/
- public void importTemplateExcel(HttpServletResponse response, String sheetName, String title) throws IOException
+ public void importTemplateExcel(HttpServletResponse response, String sheetName, String title)
{
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setCharacterEncoding("utf-8");
this.init(null, sheetName, title, Type.IMPORT);
- exportExcel(response.getOutputStream());
+ exportExcel(response);
}
/**
@@ -509,12 +509,12 @@ public class ExcelUtil
*
* @return 结果
*/
- public void exportExcel(OutputStream out)
+ public void exportExcel(HttpServletResponse response)
{
try
{
writeSheet();
- wb.write(out);
+ wb.write(response.getOutputStream());
}
catch (Exception e)
{
@@ -523,7 +523,6 @@ public class ExcelUtil
finally
{
IOUtils.closeQuietly(wb);
- IOUtils.closeQuietly(out);
}
}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/sql/SqlUtil.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/sql/SqlUtil.java
index ceff84132..71a7ae10f 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/sql/SqlUtil.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/sql/SqlUtil.java
@@ -10,6 +10,11 @@ import com.ruoyi.common.utils.StringUtils;
*/
public class SqlUtil
{
+ /**
+ * 定义常用的 sql关键字
+ */
+ public static String SQL_REGEX = "select |insert |delete |update |drop |count |exec |chr |mid |master |truncate |char |and |declare ";
+
/**
* 仅支持字母、数字、下划线、空格、逗号、小数点(支持多个字段排序)
*/
@@ -34,4 +39,23 @@ public class SqlUtil
{
return value.matches(SQL_PATTERN);
}
+
+ /**
+ * SQL关键字检查
+ */
+ public static void filterKeyword(String value)
+ {
+ if (StringUtils.isEmpty(value))
+ {
+ return;
+ }
+ String[] sqlKeywords = StringUtils.split(SQL_REGEX, "\\|");
+ for (int i = 0; i < sqlKeywords.length; i++)
+ {
+ if (StringUtils.indexOfIgnoreCase(value, sqlKeywords[i]) > -1)
+ {
+ throw new UtilException("参数存在SQL注入风险");
+ }
+ }
+ }
}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/uuid/UUID.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/uuid/UUID.java
index eef72ee0b..c0c18af01 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/uuid/UUID.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/uuid/UUID.java
@@ -343,25 +343,25 @@ public final class UUID implements java.io.Serializable, Comparable
final StringBuilder builder = new StringBuilder(isSimple ? 32 : 36);
// time_low
builder.append(digits(mostSigBits >> 32, 8));
- if (false == isSimple)
+ if (!isSimple)
{
builder.append('-');
}
// time_mid
builder.append(digits(mostSigBits >> 16, 4));
- if (false == isSimple)
+ if (!isSimple)
{
builder.append('-');
}
// time_high_and_version
builder.append(digits(mostSigBits, 4));
- if (false == isSimple)
+ if (!isSimple)
{
builder.append('-');
}
// variant_and_sequence
builder.append(digits(leastSigBits >> 48, 4));
- if (false == isSimple)
+ if (!isSimple)
{
builder.append('-');
}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/xss/Xss.java b/ruoyi-common/src/main/java/com/ruoyi/common/xss/Xss.java
new file mode 100644
index 000000000..14e43dc55
--- /dev/null
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/xss/Xss.java
@@ -0,0 +1,27 @@
+package com.ruoyi.common.xss;
+
+import javax.validation.Constraint;
+import javax.validation.Payload;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 自定义xss校验注解
+ *
+ * @author ruoyi
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(value = { ElementType.METHOD, ElementType.FIELD, ElementType.CONSTRUCTOR, ElementType.PARAMETER })
+@Constraint(validatedBy = { XssValidator.class })
+public @interface Xss
+{
+ String message()
+
+ default "不允许任何脚本运行";
+
+ Class>[] groups() default {};
+
+ Class extends Payload>[] payload() default {};
+}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/xss/XssValidator.java b/ruoyi-common/src/main/java/com/ruoyi/common/xss/XssValidator.java
new file mode 100644
index 000000000..43163721d
--- /dev/null
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/xss/XssValidator.java
@@ -0,0 +1,29 @@
+package com.ruoyi.common.xss;
+
+import javax.validation.ConstraintValidator;
+import javax.validation.ConstraintValidatorContext;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * 自定义xss校验注解实现
+ *
+ * @author ruoyi
+ */
+public class XssValidator implements ConstraintValidator
+{
+ private final String HTML_PATTERN = "<(\\S*?)[^>]*>.*?|<.*? />";
+
+ @Override
+ public boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext)
+ {
+ return !containsHtml(value);
+ }
+
+ public boolean containsHtml(String value)
+ {
+ Pattern pattern = Pattern.compile(HTML_PATTERN);
+ Matcher matcher = pattern.matcher(value);
+ return matcher.matches();
+ }
+}
\ No newline at end of file
diff --git a/ruoyi-framework/pom.xml b/ruoyi-framework/pom.xml
index 0eea3ce11..f1b68c7c5 100644
--- a/ruoyi-framework/pom.xml
+++ b/ruoyi-framework/pom.xml
@@ -5,7 +5,7 @@
ruoyi
com.ruoyi
- 3.7.0
+ 3.8.1
4.0.0
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/RateLimiterAspect.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/RateLimiterAspect.java
index 5020d000b..7b8ccf1d3 100644
--- a/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/RateLimiterAspect.java
+++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/RateLimiterAspect.java
@@ -61,7 +61,7 @@ public class RateLimiterAspect
Long number = redisTemplate.execute(limitScript, keys, count, time);
if (StringUtils.isNull(number) || number.intValue() > count)
{
- throw new ServiceException("访问过于频繁,请稍后再试");
+ throw new ServiceException("访问过于频繁,请稍候再试");
}
log.info("限制请求'{}',当前请求'{}',缓存key'{}'", count, number.intValue(), key);
}
@@ -71,7 +71,7 @@ public class RateLimiterAspect
}
catch (Exception e)
{
- throw new RuntimeException("服务器限流异常,请稍后再试");
+ throw new RuntimeException("服务器限流异常,请稍候再试");
}
}
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/FilterConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/FilterConfig.java
index ab12e4164..610807a86 100644
--- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/FilterConfig.java
+++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/FilterConfig.java
@@ -18,7 +18,6 @@ import com.ruoyi.common.utils.StringUtils;
* @author ruoyi
*/
@Configuration
-@ConditionalOnProperty(value = "xss.enabled", havingValue = "true")
public class FilterConfig
{
@Value("${xss.excludes}")
@@ -29,6 +28,7 @@ public class FilterConfig
@SuppressWarnings({ "rawtypes", "unchecked" })
@Bean
+ @ConditionalOnProperty(value = "xss.enabled", havingValue = "true")
public FilterRegistrationBean xssFilterRegistration()
{
FilterRegistrationBean registration = new FilterRegistrationBean();
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ThreadPoolConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ThreadPoolConfig.java
index 618a925dc..63739f9c0 100644
--- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ThreadPoolConfig.java
+++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ThreadPoolConfig.java
@@ -1,13 +1,13 @@
package com.ruoyi.framework.config;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ScheduledThreadPoolExecutor;
-import java.util.concurrent.ThreadPoolExecutor;
+import com.ruoyi.common.utils.Threads;
import org.apache.commons.lang3.concurrent.BasicThreadFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
-import com.ruoyi.common.utils.Threads;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.ThreadPoolExecutor;
/**
* 线程池配置
@@ -49,7 +49,8 @@ public class ThreadPoolConfig
protected ScheduledExecutorService scheduledExecutorService()
{
return new ScheduledThreadPoolExecutor(corePoolSize,
- new BasicThreadFactory.Builder().namingPattern("schedule-pool-%d").daemon(true).build())
+ new BasicThreadFactory.Builder().namingPattern("schedule-pool-%d").daemon(true).build(),
+ new ThreadPoolExecutor.CallerRunsPolicy())
{
@Override
protected void afterExecute(Runnable r, Throwable t)
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/interceptor/impl/SameUrlDataInterceptor.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/interceptor/impl/SameUrlDataInterceptor.java
index 33c9c876b..b956b3f25 100644
--- a/ruoyi-framework/src/main/java/com/ruoyi/framework/interceptor/impl/SameUrlDataInterceptor.java
+++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/interceptor/impl/SameUrlDataInterceptor.java
@@ -60,14 +60,10 @@ public class SameUrlDataInterceptor extends RepeatSubmitInterceptor
String url = request.getRequestURI();
// 唯一值(没有消息头则使用请求地址)
- String submitKey = request.getHeader(header);
- if (StringUtils.isEmpty(submitKey))
- {
- submitKey = url;
- }
+ String submitKey = StringUtils.trimToEmpty(request.getHeader(header));
- // 唯一标识(指定key + 消息头)
- String cacheRepeatKey = Constants.REPEAT_SUBMIT_KEY + submitKey;
+ // 唯一标识(指定key + url + 消息头)
+ String cacheRepeatKey = Constants.REPEAT_SUBMIT_KEY + url + submitKey;
Object sessionObj = redisCache.getCacheObject(cacheRepeatKey);
if (sessionObj != null)
diff --git a/ruoyi-generator/pom.xml b/ruoyi-generator/pom.xml
index f68bbe984..b80b938cf 100644
--- a/ruoyi-generator/pom.xml
+++ b/ruoyi-generator/pom.xml
@@ -5,7 +5,7 @@
ruoyi
com.ruoyi
- 3.7.0
+ 3.8.1
4.0.0
@@ -20,7 +20,7 @@
org.apache.velocity
- velocity
+ velocity-engine-core
diff --git a/ruoyi-generator/src/main/java/com/ruoyi/generator/service/GenTableServiceImpl.java b/ruoyi-generator/src/main/java/com/ruoyi/generator/service/GenTableServiceImpl.java
index f2ffbe951..68bba7bed 100644
--- a/ruoyi-generator/src/main/java/com/ruoyi/generator/service/GenTableServiceImpl.java
+++ b/ruoyi-generator/src/main/java/com/ruoyi/generator/service/GenTableServiceImpl.java
@@ -7,6 +7,7 @@ import java.io.StringWriter;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
+import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
@@ -286,7 +287,7 @@ public class GenTableServiceImpl implements IGenTableService
{
GenTable table = genTableMapper.selectGenTableByName(tableName);
List tableColumns = table.getColumns();
- List tableColumnNames = tableColumns.stream().map(GenTableColumn::getColumnName).collect(Collectors.toList());
+ Map tableColumnMap = tableColumns.stream().collect(Collectors.toMap(GenTableColumn::getColumnName, Function.identity()));
List dbTableColumns = genTableColumnMapper.selectDbTableColumnsByName(tableName);
if (StringUtils.isEmpty(dbTableColumns))
@@ -296,9 +297,20 @@ public class GenTableServiceImpl implements IGenTableService
List dbTableColumnNames = dbTableColumns.stream().map(GenTableColumn::getColumnName).collect(Collectors.toList());
dbTableColumns.forEach(column -> {
- if (!tableColumnNames.contains(column.getColumnName()))
+ GenUtils.initColumnField(column, table);
+ if (tableColumnMap.containsKey(column.getColumnName()))
+ {
+ GenTableColumn prevColumn = tableColumnMap.get(column.getColumnName());
+ column.setColumnId(prevColumn.getColumnId());
+ if (column.isList())
+ {
+ // 如果是列表,继续保留字典类型
+ column.setDictType(prevColumn.getDictType());
+ }
+ genTableColumnMapper.updateGenTableColumn(column);
+ }
+ else
{
- GenUtils.initColumnField(column, table);
genTableColumnMapper.insertGenTableColumn(column);
}
});
@@ -359,7 +371,7 @@ public class GenTableServiceImpl implements IGenTableService
zip.putNextEntry(new ZipEntry(VelocityUtils.getFileName(template, table)));
IOUtils.write(sw.toString(), zip, Constants.UTF8);
IOUtils.closeQuietly(sw);
- zip.flush();
+ zip.flush();
zip.closeEntry();
}
catch (IOException e)
@@ -472,7 +484,7 @@ public class GenTableServiceImpl implements IGenTableService
String treeName = paramsObj.getString(GenConstants.TREE_NAME);
String parentMenuId = paramsObj.getString(GenConstants.PARENT_MENU_ID);
String parentMenuName = paramsObj.getString(GenConstants.PARENT_MENU_NAME);
-
+
genTable.setTreeCode(treeCode);
genTable.setTreeParentCode(treeParentCode);
genTable.setTreeName(treeName);
diff --git a/ruoyi-generator/src/main/java/com/ruoyi/generator/util/VelocityInitializer.java b/ruoyi-generator/src/main/java/com/ruoyi/generator/util/VelocityInitializer.java
index 4be1eecbb..26456335e 100644
--- a/ruoyi-generator/src/main/java/com/ruoyi/generator/util/VelocityInitializer.java
+++ b/ruoyi-generator/src/main/java/com/ruoyi/generator/util/VelocityInitializer.java
@@ -20,10 +20,9 @@ public class VelocityInitializer
try
{
// 加载classpath目录下的vm文件
- p.setProperty("file.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
+ p.setProperty("resource.loader.file.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
// 定义字符集
p.setProperty(Velocity.INPUT_ENCODING, Constants.UTF8);
- p.setProperty(Velocity.OUTPUT_ENCODING, Constants.UTF8);
// 初始化Velocity引擎,指定配置Properties
Velocity.init(p);
}
diff --git a/ruoyi-generator/src/main/java/com/ruoyi/generator/util/VelocityUtils.java b/ruoyi-generator/src/main/java/com/ruoyi/generator/util/VelocityUtils.java
index 2683ec8fd..2ae6802e3 100644
--- a/ruoyi-generator/src/main/java/com/ruoyi/generator/util/VelocityUtils.java
+++ b/ruoyi-generator/src/main/java/com/ruoyi/generator/util/VelocityUtils.java
@@ -3,6 +3,7 @@ package com.ruoyi.generator.util;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
+import java.util.Set;
import org.apache.velocity.VelocityContext;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.constant.GenConstants;
@@ -270,11 +271,12 @@ public class VelocityUtils
public static String getDicts(GenTable genTable)
{
List columns = genTable.getColumns();
- List dicts = new ArrayList();
+ Set dicts = new HashSet();
for (GenTableColumn column : columns)
{
if (!column.isSuperColumn() && StringUtils.isNotEmpty(column.getDictType()) && StringUtils.equalsAny(
- column.getHtmlType(), new String[] { GenConstants.HTML_SELECT, GenConstants.HTML_RADIO }))
+ column.getHtmlType(),
+ new String[] { GenConstants.HTML_SELECT, GenConstants.HTML_RADIO, GenConstants.HTML_CHECKBOX }))
{
dicts.add("'" + column.getDictType() + "'");
}
diff --git a/ruoyi-generator/src/main/resources/vm/java/controller.java.vm b/ruoyi-generator/src/main/resources/vm/java/controller.java.vm
index 56ff5e66a..ab19cf51f 100644
--- a/ruoyi-generator/src/main/resources/vm/java/controller.java.vm
+++ b/ruoyi-generator/src/main/resources/vm/java/controller.java.vm
@@ -1,6 +1,7 @@
package ${packageName}.controller;
import java.util.List;
+import javax.servlet.http.HttpServletResponse;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
@@ -61,12 +62,12 @@ public class ${ClassName}Controller extends BaseController
*/
@PreAuthorize("@ss.hasPermi('${permissionPrefix}:export')")
@Log(title = "${functionName}", businessType = BusinessType.EXPORT)
- @GetMapping("/export")
- public AjaxResult export(${ClassName} ${className})
+ @PostMapping("/export")
+ public void export(HttpServletResponse response, ${ClassName} ${className})
{
List<${ClassName}> list = ${className}Service.select${ClassName}List(${className});
ExcelUtil<${ClassName}> util = new ExcelUtil<${ClassName}>(${ClassName}.class);
- return util.exportExcel(list, "${functionName}数据");
+ util.exportExcel(response, list, "${functionName}数据");
}
/**
diff --git a/ruoyi-generator/src/main/resources/vm/java/serviceImpl.java.vm b/ruoyi-generator/src/main/resources/vm/java/serviceImpl.java.vm
index 2fc79492e..116f6c544 100644
--- a/ruoyi-generator/src/main/resources/vm/java/serviceImpl.java.vm
+++ b/ruoyi-generator/src/main/resources/vm/java/serviceImpl.java.vm
@@ -129,6 +129,9 @@ public class ${ClassName}ServiceImpl implements I${ClassName}Service
* @param ${pkColumn.javaField} ${functionName}主键
* @return 结果
*/
+#if($table.sub)
+ @Transactional
+#end
@Override
public int delete${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField})
{
diff --git a/ruoyi-generator/src/main/resources/vm/js/api.js.vm b/ruoyi-generator/src/main/resources/vm/js/api.js.vm
index cd2403cc6..d78cd2f64 100644
--- a/ruoyi-generator/src/main/resources/vm/js/api.js.vm
+++ b/ruoyi-generator/src/main/resources/vm/js/api.js.vm
@@ -42,12 +42,3 @@ export function del${BusinessName}(${pkColumn.javaField}) {
method: 'delete'
})
}
-
-// 导出${functionName}
-export function export${BusinessName}(query) {
- return request({
- url: '/${moduleName}/${businessName}/export',
- method: 'get',
- params: query
- })
-}
\ No newline at end of file
diff --git a/ruoyi-generator/src/main/resources/vm/vue/index-tree.vue.vm b/ruoyi-generator/src/main/resources/vm/vue/index-tree.vue.vm
index 19802cee8..adba807b4 100644
--- a/ruoyi-generator/src/main/resources/vm/vue/index-tree.vue.vm
+++ b/ruoyi-generator/src/main/resources/vm/vue/index-tree.vue.vm
@@ -105,10 +105,20 @@
{{ parseTime(scope.row.${javaField}, '{y}-{m}-{d}') }}
+#elseif($column.list && $column.htmlType == "imageUpload")
+
+
+
+
+
#elseif($column.list && "" != $column.dictType)
+#if($column.htmlType == "checkbox")
+
+#else
+#end
#elseif($column.list && "" != $javaField)
@@ -170,11 +180,11 @@
#elseif($column.htmlType == "imageUpload")
-
+
#elseif($column.htmlType == "fileUpload")
-
+
#elseif($column.htmlType == "editor")
@@ -259,7 +269,7 @@
diff --git a/ruoyi-generator/src/main/resources/vm/vue/v3/index.vue.vm b/ruoyi-generator/src/main/resources/vm/vue/v3/index.vue.vm
new file mode 100644
index 000000000..08bb07110
--- /dev/null
+++ b/ruoyi-generator/src/main/resources/vm/vue/v3/index.vue.vm
@@ -0,0 +1,564 @@
+
+
+
+#foreach($column in $columns)
+#if($column.query)
+#set($dictType=$column.dictType)
+#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
+#set($parentheseIndex=$column.columnComment.indexOf("("))
+#if($parentheseIndex != -1)
+#set($comment=$column.columnComment.substring(0, $parentheseIndex))
+#else
+#set($comment=$column.columnComment)
+#end
+#if($column.htmlType == "input")
+
+
+
+#elseif(($column.htmlType == "select" || $column.htmlType == "radio") && "" != $dictType)
+
+
+
+
+
+#elseif(($column.htmlType == "select" || $column.htmlType == "radio") && $dictType)
+
+
+
+
+
+#elseif($column.htmlType == "datetime" && $column.queryType != "BETWEEN")
+
+
+
+
+#elseif($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
+
+
+
+#end
+#end
+#end
+
+ 搜索
+ 重置
+
+
+
+
+
+ 新增
+
+
+ 修改
+
+
+ 删除
+
+
+ 导出
+
+
+
+
+
+
+#foreach($column in $columns)
+#set($javaField=$column.javaField)
+#set($parentheseIndex=$column.columnComment.indexOf("("))
+#if($parentheseIndex != -1)
+#set($comment=$column.columnComment.substring(0, $parentheseIndex))
+#else
+#set($comment=$column.columnComment)
+#end
+#if($column.pk)
+
+#elseif($column.list && $column.htmlType == "datetime")
+
+
+ {{ parseTime(scope.row.${javaField}, '{y}-{m}-{d}') }}
+
+
+#elseif($column.list && $column.htmlType == "imageUpload")
+
+
+
+
+
+#elseif($column.list && "" != $column.dictType)
+
+
+#if($column.htmlType == "checkbox")
+
+#else
+
+#end
+
+
+#elseif($column.list && "" != $javaField)
+
+#end
+#end
+
+
+ 修改
+ 删除
+
+
+
+
+
+
+
+
+
+#foreach($column in $columns)
+#set($field=$column.javaField)
+#if($column.insert && !$column.pk)
+#if(($column.usableColumn) || (!$column.superColumn))
+#set($parentheseIndex=$column.columnComment.indexOf("("))
+#if($parentheseIndex != -1)
+#set($comment=$column.columnComment.substring(0, $parentheseIndex))
+#else
+#set($comment=$column.columnComment)
+#end
+#set($dictType=$column.dictType)
+#if($column.htmlType == "input")
+
+
+
+#elseif($column.htmlType == "imageUpload")
+
+
+
+#elseif($column.htmlType == "fileUpload")
+
+
+
+#elseif($column.htmlType == "editor")
+
+
+
+#elseif($column.htmlType == "select" && "" != $dictType)
+
+
+
+
+
+#elseif($column.htmlType == "select" && $dictType)
+
+
+
+
+
+#elseif($column.htmlType == "checkbox" && "" != $dictType)
+
+
+
+ {{dict.label}}
+
+
+
+#elseif($column.htmlType == "checkbox" && $dictType)
+
+
+ 请选择字典生成
+
+
+#elseif($column.htmlType == "radio" && "" != $dictType)
+
+
+ {{dict.label}}
+
+
+#elseif($column.htmlType == "radio" && $dictType)
+
+
+ 请选择字典生成
+
+
+#elseif($column.htmlType == "datetime")
+
+
+
+
+#elseif($column.htmlType == "textarea")
+
+
+
+#end
+#end
+#end
+#end
+#if($table.sub)
+ ${subTable.functionName}信息
+
+
+ 添加
+
+
+ 删除
+
+
+
+
+
+#foreach($column in $subTable.columns)
+#set($javaField=$column.javaField)
+#set($parentheseIndex=$column.columnComment.indexOf("("))
+#if($parentheseIndex != -1)
+#set($comment=$column.columnComment.substring(0, $parentheseIndex))
+#else
+#set($comment=$column.columnComment)
+#end
+#if($column.pk || $javaField == ${subTableFkclassName})
+#elseif($column.list && "" != $javaField)
+
+
+
+
+
+#end
+#end
+
+#end
+
+
+
+
+
+
+
+
+
diff --git a/ruoyi-generator/src/main/resources/vm/vue/v3/readme.txt b/ruoyi-generator/src/main/resources/vm/vue/v3/readme.txt
new file mode 100644
index 000000000..99239bb53
--- /dev/null
+++ b/ruoyi-generator/src/main/resources/vm/vue/v3/readme.txt
@@ -0,0 +1 @@
+ʹõRuoYi-Vue3ǰˣôҪһ´Ŀ¼ģindex.vue.vmindex-tree.vue.vmļϼvueĿ¼
\ No newline at end of file
diff --git a/ruoyi-generator/src/main/resources/vm/xml/mapper.xml.vm b/ruoyi-generator/src/main/resources/vm/xml/mapper.xml.vm
index 0c681d9cd..5b704e737 100644
--- a/ruoyi-generator/src/main/resources/vm/xml/mapper.xml.vm
+++ b/ruoyi-generator/src/main/resources/vm/xml/mapper.xml.vm
@@ -23,7 +23,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
#end
- select#foreach($column in $columns) $column.columnName#if($velocityCount != $columns.size()),#end#end from ${tableName}
+ select#foreach($column in $columns) $column.columnName#if($foreach.count != $columns.size()),#end#end from ${tableName}
-
-
+
立即执行
执行一次
@@ -295,7 +294,7 @@