32 Commits

Author SHA1 Message Date
4c9c67927b 若依 v4.7.2 2021-12-23 08:39:07 +08:00
6f42d2e821 升级oshi到最新版本v5.8.6 2021-12-22 09:57:26 +08:00
07cc5dfa51 升级thymeleaf到最新版3.0.14 阻止远程代码执行漏洞 2021-12-22 09:27:15 +08:00
22881ccb59 工具类异常使用UtilException 2021-12-21 13:55:55 +08:00
c44c280b21 升级fastjson到最新版1.2.79 2021-12-21 13:21:16 +08:00
452da5caeb 代码生成创建表检查关键字,防止注入风险 2021-12-21 13:21:03 +08:00
c78758e32d 升级log4j2到安全版本,防止漏洞风险 2021-12-19 19:59:32 +08:00
4b7e9152c6 请求分页方法设置成通用方便灵活调用 2021-12-18 10:00:52 +08:00
e8e149719a 代码生成创建按钮添加超级管理员权限 2021-12-18 10:00:43 +08:00
d2730a187e !356 前端添加单独的二代身份证校验
Merge pull request !356 from 网游之鱼/N/A
2021-12-18 01:38:24 +00:00
068483ac6a 前端添加单独的二代身份证校验 2021-12-16 08:40:12 +00:00
e597cdead4 优化日期类型错误提示与图标重叠问题 2021-12-16 10:21:33 +08:00
25340da2e2 !355 update ruoyi-admin/src/main/resources/static/ruoyi/css/ry-ui.css.
Merge pull request !355 from 风晓/N/A
2021-12-16 02:18:43 +00:00
02375cbe7d update ruoyi-admin/src/main/resources/static/ruoyi/css/ry-ui.css.
日期类型后面会有一个日历的图标,3px的偏移量太小了,错误提示信息会与那个图标重叠。设置为40px可以避开那个日历小图标
2021-12-15 10:46:09 +00:00
5587d39d42 自定义xss校验注解实现 2021-12-15 10:44:40 +08:00
ae8f069cbc 升级log4j2到安全版本,防止漏洞风险 2021-12-14 12:09:49 +08:00
d6f7423d59 升级log4j2到安全版本,防止漏洞风险 2021-12-14 10:18:11 +08:00
2a3981268a 优化查询用户的角色组&岗位组代码 2021-12-10 21:28:36 +08:00
40263f9549 !350 修复多参数逗号分隔的问题
Merge pull request !350 from 网游之鱼/N/A
2021-12-10 13:27:26 +00:00
be8cb965e3 修复插件一起使用出现的已声明报错问题 2021-12-05 11:34:35 +08:00
8a92dc8257 tomcat update 2021-12-02 16:40:39 +08:00
2cd634a8de 代码生成主子表优化 2021-11-29 09:23:07 +08:00
a23af96034 修复多参数逗号分隔的问题 2021-11-26 07:45:50 +00:00
78abc63c06 升级velocity到最新版本2.3(语法升级) 2021-11-25 17:24:24 +08:00
ba9b483472 进入修改页面方法添加权限标识 2021-11-24 13:55:22 +08:00
a21b875402 优化修改/授权角色实时生效 2021-11-24 13:22:54 +08:00
366459e8f3 优化新增部门时验证用户所属部门 2021-11-24 11:45:11 +08:00
7414626137 升级velocity到最新版本2.3 2021-11-24 11:15:17 +08:00
9ff9eb30aa 添加新群号:264355400 2021-11-20 12:01:36 +08:00
4d6ff66187 添加新群号:298522656 2021-11-19 18:40:23 +08:00
0bc9bd2cfb 代码生成主子表模板删除方法缺少事务 2021-11-18 17:58:20 +08:00
7cd98d6dd0 任务参数忽略双引号中的逗号 2021-11-16 11:51:59 +08:00
60 changed files with 383 additions and 153 deletions

48
pom.xml
View File

@ -5,19 +5,20 @@
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi</artifactId> <artifactId>ruoyi</artifactId>
<version>4.7.1</version> <version>4.7.2</version>
<name>ruoyi</name> <name>ruoyi</name>
<url>http://www.ruoyi.vip</url> <url>http://www.ruoyi.vip</url>
<description>若依管理系统</description> <description>若依管理系统</description>
<properties> <properties>
<ruoyi.version>4.7.1</ruoyi.version> <ruoyi.version>4.7.2</ruoyi.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version> <java.version>1.8</java.version>
<maven-jar-plugin.version>3.1.1</maven-jar-plugin.version> <maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
<shiro.version>1.8.0</shiro.version> <shiro.version>1.8.0</shiro.version>
<thymeleaf.version>3.0.14.RELEASE</thymeleaf.version>
<thymeleaf.extras.shiro.version>2.1.0</thymeleaf.extras.shiro.version> <thymeleaf.extras.shiro.version>2.1.0</thymeleaf.extras.shiro.version>
<druid.version>1.2.8</druid.version> <druid.version>1.2.8</druid.version>
<bitwalker.version>1.21</bitwalker.version> <bitwalker.version>1.21</bitwalker.version>
@ -25,13 +26,14 @@
<swagger.version>3.0.0</swagger.version> <swagger.version>3.0.0</swagger.version>
<mybatis-spring-boot.version>2.2.0</mybatis-spring-boot.version> <mybatis-spring-boot.version>2.2.0</mybatis-spring-boot.version>
<pagehelper.boot.version>1.4.0</pagehelper.boot.version> <pagehelper.boot.version>1.4.0</pagehelper.boot.version>
<fastjson.version>1.2.78</fastjson.version> <fastjson.version>1.2.79</fastjson.version>
<oshi.version>5.8.2</oshi.version> <oshi.version>5.8.6</oshi.version>
<jna.version>5.9.0</jna.version> <jna.version>5.10.0</jna.version>
<commons.io.version>2.11.0</commons.io.version> <commons.io.version>2.11.0</commons.io.version>
<commons.fileupload.version>1.4</commons.fileupload.version> <commons.fileupload.version>1.4</commons.fileupload.version>
<poi.version>4.1.2</poi.version> <poi.version>4.1.2</poi.version>
<velocity.version>1.7</velocity.version> <velocity.version>2.3</velocity.version>
<log4j2.version>2.17.0</log4j2.version>
</properties> </properties>
<!-- 依赖声明 --> <!-- 依赖声明 -->
@ -82,6 +84,19 @@
<version>${shiro.version}</version> <version>${shiro.version}</version>
</dependency> </dependency>
<!-- thymeleaf模板引擎和spring框架的整合 -->
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring5</artifactId>
<version>${thymeleaf.version}</version>
</dependency>
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf</artifactId>
<version>${thymeleaf.version}</version>
</dependency>
<!-- thymeleaf模板引擎和shiro框架的整合 --> <!-- thymeleaf模板引擎和shiro框架的整合 -->
<dependency> <dependency>
<groupId>com.github.theborakompanioni</groupId> <groupId>com.github.theborakompanioni</groupId>
@ -166,14 +181,8 @@
<!-- velocity代码生成使用模板 --> <!-- velocity代码生成使用模板 -->
<dependency> <dependency>
<groupId>org.apache.velocity</groupId> <groupId>org.apache.velocity</groupId>
<artifactId>velocity</artifactId> <artifactId>velocity-engine-core</artifactId>
<version>${velocity.version}</version> <version>${velocity.version}</version>
<exclusions>
<exclusion>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
</exclusion>
</exclusions>
</dependency> </dependency>
<!-- 阿里JSON解析器 --> <!-- 阿里JSON解析器 -->
@ -183,6 +192,19 @@
<version>${fastjson.version}</version> <version>${fastjson.version}</version>
</dependency> </dependency>
<!-- log4j日志组件 -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>${log4j2.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-to-slf4j</artifactId>
<version>${log4j2.version}</version>
</dependency>
<!-- 定时任务--> <!-- 定时任务-->
<dependency> <dependency>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>ruoyi</artifactId> <artifactId>ruoyi</artifactId>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<version>4.7.1</version> <version>4.7.2</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging> <packaging>jar</packaging>

View File

@ -1,5 +1,6 @@
package com.ruoyi.web.controller.monitor; package com.ruoyi.web.controller.monitor;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap; import org.springframework.ui.ModelMap;
@ -25,6 +26,7 @@ public class CacheController extends BaseController
@Autowired @Autowired
private CacheService cacheService; private CacheService cacheService;
@RequiresPermissions("monitor:cache:view")
@GetMapping() @GetMapping()
public String cache(ModelMap mmap) public String cache(ModelMap mmap)
{ {
@ -32,6 +34,7 @@ public class CacheController extends BaseController
return prefix + "/cache"; return prefix + "/cache";
} }
@RequiresPermissions("monitor:cache:view")
@PostMapping("/getNames") @PostMapping("/getNames")
public String getCacheNames(String fragment, ModelMap mmap) public String getCacheNames(String fragment, ModelMap mmap)
{ {
@ -39,6 +42,7 @@ public class CacheController extends BaseController
return prefix + "/cache::" + fragment; return prefix + "/cache::" + fragment;
} }
@RequiresPermissions("monitor:cache:view")
@PostMapping("/getKeys") @PostMapping("/getKeys")
public String getCacheKeys(String fragment, String cacheName, ModelMap mmap) public String getCacheKeys(String fragment, String cacheName, ModelMap mmap)
{ {
@ -47,6 +51,7 @@ public class CacheController extends BaseController
return prefix + "/cache::" + fragment; return prefix + "/cache::" + fragment;
} }
@RequiresPermissions("monitor:cache:view")
@PostMapping("/getValue") @PostMapping("/getValue")
public String getCacheValue(String fragment, String cacheName, String cacheKey, ModelMap mmap) public String getCacheValue(String fragment, String cacheName, String cacheKey, ModelMap mmap)
{ {
@ -56,6 +61,7 @@ public class CacheController extends BaseController
return prefix + "/cache::" + fragment; return prefix + "/cache::" + fragment;
} }
@RequiresPermissions("monitor:cache:view")
@PostMapping("/clearCacheName") @PostMapping("/clearCacheName")
@ResponseBody @ResponseBody
public AjaxResult clearCacheName(String cacheName, ModelMap mmap) public AjaxResult clearCacheName(String cacheName, ModelMap mmap)
@ -64,6 +70,7 @@ public class CacheController extends BaseController
return AjaxResult.success(); return AjaxResult.success();
} }
@RequiresPermissions("monitor:cache:view")
@PostMapping("/clearCacheKey") @PostMapping("/clearCacheKey")
@ResponseBody @ResponseBody
public AjaxResult clearCacheKey(String cacheName, String cacheKey, ModelMap mmap) public AjaxResult clearCacheKey(String cacheName, String cacheKey, ModelMap mmap)
@ -72,6 +79,7 @@ public class CacheController extends BaseController
return AjaxResult.success(); return AjaxResult.success();
} }
@RequiresPermissions("monitor:cache:view")
@GetMapping("/clearAll") @GetMapping("/clearAll")
@ResponseBody @ResponseBody
public AjaxResult clearAll(ModelMap mmap) public AjaxResult clearAll(ModelMap mmap)

View File

@ -95,6 +95,7 @@ public class SysConfigController extends BaseController
/** /**
* 修改参数配置 * 修改参数配置
*/ */
@RequiresPermissions("system:config:edit")
@GetMapping("/edit/{configId}") @GetMapping("/edit/{configId}")
public String edit(@PathVariable("configId") Long configId, ModelMap mmap) public String edit(@PathVariable("configId") Long configId, ModelMap mmap)
{ {

View File

@ -84,8 +84,9 @@ public class SysDeptController extends BaseController
} }
/** /**
* 修改 * 修改部门
*/ */
@RequiresPermissions("system:dept:edit")
@GetMapping("/edit/{deptId}") @GetMapping("/edit/{deptId}")
public String edit(@PathVariable("deptId") Long deptId, ModelMap mmap) public String edit(@PathVariable("deptId") Long deptId, ModelMap mmap)
{ {
@ -100,7 +101,7 @@ public class SysDeptController extends BaseController
} }
/** /**
* 保存 * 修改保存部门
*/ */
@Log(title = "部门管理", businessType = BusinessType.UPDATE) @Log(title = "部门管理", businessType = BusinessType.UPDATE)
@RequiresPermissions("system:dept:edit") @RequiresPermissions("system:dept:edit")

View File

@ -88,6 +88,7 @@ public class SysDictDataController extends BaseController
/** /**
* 修改字典类型 * 修改字典类型
*/ */
@RequiresPermissions("system:dict:edit")
@GetMapping("/edit/{dictCode}") @GetMapping("/edit/{dictCode}")
public String edit(@PathVariable("dictCode") Long dictCode, ModelMap mmap) public String edit(@PathVariable("dictCode") Long dictCode, ModelMap mmap)
{ {

View File

@ -94,6 +94,7 @@ public class SysDictTypeController extends BaseController
/** /**
* 修改字典类型 * 修改字典类型
*/ */
@RequiresPermissions("system:dict:edit")
@GetMapping("/edit/{dictId}") @GetMapping("/edit/{dictId}")
public String edit(@PathVariable("dictId") Long dictId, ModelMap mmap) public String edit(@PathVariable("dictId") Long dictId, ModelMap mmap)
{ {

View File

@ -117,6 +117,7 @@ public class SysMenuController extends BaseController
/** /**
* 修改菜单 * 修改菜单
*/ */
@RequiresPermissions("system:menu:edit")
@GetMapping("/edit/{menuId}") @GetMapping("/edit/{menuId}")
public String edit(@PathVariable("menuId") Long menuId, ModelMap mmap) public String edit(@PathVariable("menuId") Long menuId, ModelMap mmap)
{ {

View File

@ -5,6 +5,7 @@ import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap; import org.springframework.ui.ModelMap;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
@ -68,7 +69,7 @@ public class SysNoticeController extends BaseController
@Log(title = "通知公告", businessType = BusinessType.INSERT) @Log(title = "通知公告", businessType = BusinessType.INSERT)
@PostMapping("/add") @PostMapping("/add")
@ResponseBody @ResponseBody
public AjaxResult addSave(SysNotice notice) public AjaxResult addSave(@Validated SysNotice notice)
{ {
notice.setCreateBy(getLoginName()); notice.setCreateBy(getLoginName());
return toAjax(noticeService.insertNotice(notice)); return toAjax(noticeService.insertNotice(notice));
@ -77,6 +78,7 @@ public class SysNoticeController extends BaseController
/** /**
* 修改公告 * 修改公告
*/ */
@RequiresPermissions("system:notice:edit")
@GetMapping("/edit/{noticeId}") @GetMapping("/edit/{noticeId}")
public String edit(@PathVariable("noticeId") Long noticeId, ModelMap mmap) public String edit(@PathVariable("noticeId") Long noticeId, ModelMap mmap)
{ {
@ -91,7 +93,7 @@ public class SysNoticeController extends BaseController
@Log(title = "通知公告", businessType = BusinessType.UPDATE) @Log(title = "通知公告", businessType = BusinessType.UPDATE)
@PostMapping("/edit") @PostMapping("/edit")
@ResponseBody @ResponseBody
public AjaxResult editSave(SysNotice notice) public AjaxResult editSave(@Validated SysNotice notice)
{ {
notice.setUpdateBy(getLoginName()); notice.setUpdateBy(getLoginName());
return toAjax(noticeService.updateNotice(notice)); return toAjax(noticeService.updateNotice(notice));

View File

@ -112,6 +112,7 @@ public class SysPostController extends BaseController
/** /**
* 修改岗位 * 修改岗位
*/ */
@RequiresPermissions("system:post:edit")
@GetMapping("/edit/{postId}") @GetMapping("/edit/{postId}")
public String edit(@PathVariable("postId") Long postId, ModelMap mmap) public String edit(@PathVariable("postId") Long postId, ModelMap mmap)
{ {

View File

@ -105,6 +105,7 @@ public class SysRoleController extends BaseController
/** /**
* 修改角色 * 修改角色
*/ */
@RequiresPermissions("system:role:edit")
@GetMapping("/edit/{roleId}") @GetMapping("/edit/{roleId}")
public String edit(@PathVariable("roleId") Long roleId, ModelMap mmap) public String edit(@PathVariable("roleId") Long roleId, ModelMap mmap)
{ {

View File

@ -27,6 +27,7 @@ import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.shiro.service.SysPasswordService; import com.ruoyi.framework.shiro.service.SysPasswordService;
import com.ruoyi.framework.shiro.util.AuthorizationUtils;
import com.ruoyi.system.service.ISysPostService; import com.ruoyi.system.service.ISysPostService;
import com.ruoyi.system.service.ISysRoleService; import com.ruoyi.system.service.ISysRoleService;
import com.ruoyi.system.service.ISysUserService; import com.ruoyi.system.service.ISysUserService;
@ -146,6 +147,7 @@ public class SysUserController extends BaseController
/** /**
* 修改用户 * 修改用户
*/ */
@RequiresPermissions("system:user:edit")
@GetMapping("/edit/{userId}") @GetMapping("/edit/{userId}")
public String edit(@PathVariable("userId") Long userId, ModelMap mmap) public String edit(@PathVariable("userId") Long userId, ModelMap mmap)
{ {
@ -178,6 +180,7 @@ public class SysUserController extends BaseController
return error("修改用户'" + user.getLoginName() + "'失败,邮箱账号已存在"); return error("修改用户'" + user.getLoginName() + "'失败,邮箱账号已存在");
} }
user.setUpdateBy(getLoginName()); user.setUpdateBy(getLoginName());
AuthorizationUtils.clearAllCachedAuthorizationInfo();
return toAjax(userService.updateUser(user)); return toAjax(userService.updateUser(user));
} }
@ -233,6 +236,7 @@ public class SysUserController extends BaseController
public AjaxResult insertAuthRole(Long userId, Long[] roleIds) public AjaxResult insertAuthRole(Long userId, Long[] roleIds)
{ {
userService.insertUserAuth(userId, roleIds); userService.insertUserAuth(userId, roleIds);
AuthorizationUtils.clearAllCachedAuthorizationInfo();
return success(); return success();
} }

View File

@ -3,7 +3,7 @@ ruoyi:
# 名称 # 名称
name: RuoYi name: RuoYi
# 版本 # 版本
version: 4.7.1 version: 4.7.2
# 版权年份 # 版权年份
copyrightYear: 2021 copyrightYear: 2021
# 实例演示开关 # 实例演示开关
@ -23,10 +23,13 @@ server:
tomcat: tomcat:
# tomcat的URI编码 # tomcat的URI编码
uri-encoding: UTF-8 uri-encoding: UTF-8
# tomcat最大线程数,默认为200 # 连接数满后的排队数,默认为100
max-threads: 800 accept-count: 1000
# Tomcat启动初始化的线程数默认值25 threads:
min-spare-threads: 30 # tomcat最大线程数默认为200
max: 800
# Tomcat启动初始化的线程数默认值10
min-spare: 100
# 日志配置 # 日志配置
logging: logging:

View File

@ -4,7 +4,7 @@
* @update: zhixin wen <wenzhixin2010@gmail.com> * @update: zhixin wen <wenzhixin2010@gmail.com>
*/ */
const Utils = $.fn.bootstrapTable.utils var Utils = $.fn.bootstrapTable.utils
$.extend($.fn.bootstrapTable.defaults, { $.extend($.fn.bootstrapTable.defaults, {
autoRefresh: false, autoRefresh: false,

View File

@ -2,7 +2,7 @@
* @author zhixin wen <wenzhixin2010@gmail.com> * @author zhixin wen <wenzhixin2010@gmail.com>
*/ */
const Utils = $.fn.bootstrapTable.utils var Utils = $.fn.bootstrapTable.utils
// Reasonable defaults // Reasonable defaults
const PIXEL_STEP = 10 const PIXEL_STEP = 10

View File

@ -2,7 +2,7 @@
* @author zhixin wen <wenzhixin2010@gmail.com> * @author zhixin wen <wenzhixin2010@gmail.com>
*/ */
const Utils = $.fn.bootstrapTable.utils var Utils = $.fn.bootstrapTable.utils
$.extend($.fn.bootstrapTable.defaults, { $.extend($.fn.bootstrapTable.defaults, {
customView: false, customView: false,

View File

@ -4,7 +4,7 @@
* extensions: https://github.com/vitalets/x-editable * extensions: https://github.com/vitalets/x-editable
*/ */
const Utils = $.fn.bootstrapTable.utils var Utils = $.fn.bootstrapTable.utils
$.extend($.fn.bootstrapTable.defaults, { $.extend($.fn.bootstrapTable.defaults, {
editable: true, editable: true,

View File

@ -3,7 +3,7 @@
* extensions: https://github.com/hhurz/tableExport.jquery.plugin * extensions: https://github.com/hhurz/tableExport.jquery.plugin
*/ */
const Utils = $.fn.bootstrapTable.utils var Utils = $.fn.bootstrapTable.utils
const TYPE_NAME = { const TYPE_NAME = {
json: 'JSON', json: 'JSON',

View File

@ -2,7 +2,7 @@
* @update zhixin wen <wenzhixin2010@gmail.com> * @update zhixin wen <wenzhixin2010@gmail.com>
*/ */
const Utils = $.fn.bootstrapTable.utils var Utils = $.fn.bootstrapTable.utils
function printPageBuilderDefault (table) { function printPageBuilderDefault (table) {
return ` return `

View File

@ -8,7 +8,7 @@ $(document).ready(function(){
//手机号码验证身份证正则合并:(^\d{15}$)|(^\d{17}([0-9]|X)$) //手机号码验证身份证正则合并:(^\d{15}$)|(^\d{17}([0-9]|X)$)
jQuery.validator.addMethod("isPhone",function(value,element){ jQuery.validator.addMethod("isPhone",function(value,element){
var length = value.length; var length = value.length;
var phone=/^1[3|4|5|6|7|8|9][0-9]\d{8}$/; var phone=/^1[3-9]\d{9}$/;
return this.optional(element)||(length == 11 && phone.test(value)); return this.optional(element)||(length == 11 && phone.test(value));
},"请填写正确的11位手机号"); },"请填写正确的11位手机号");
//电话号码验证 //电话号码验证
@ -31,7 +31,12 @@ $(document).ready(function(){
jQuery.validator.addMethod("isIdentity",function(value,element){ jQuery.validator.addMethod("isIdentity",function(value,element){
var id= /^(\d{15}$|^\d{18}$|^\d{17}(\d|X))$/; var id= /^(\d{15}$|^\d{18}$|^\d{17}(\d|X))$/;
return this.optional(element) || (id.test(value)); return this.optional(element) || (id.test(value));
},"请输入正确的15或18位身份证号,末尾大写X"); },"请输入正确的15或18位身份证号,末尾若为X请大写");
//校验二代身份证
jQuery.validator.addMethod("isIdentity18",function(value,element){
var id= /^(^\d{17}(\d|X))$/;
return this.optional(element) || (id.test(value));
},"请输入正确的18位身份证号末尾若为X请大写");
//校验出生日期 //校验出生日期
jQuery.validator.addMethod("isBirth",function(value,element){ jQuery.validator.addMethod("isBirth",function(value,element){
var birth = /^(19|20)\d{2}-(1[0-2]|0?[1-9])-(0?[1-9]|[1-2][0-9]|3[0-1])$/; var birth = /^(19|20)\d{2}-(1[0-2]|0?[1-9])-(0?[1-9]|[1-2][0-9]|3[0-1])$/;

View File

@ -347,7 +347,7 @@ label.error {
.input-group.date label.error { .input-group.date label.error {
z-index:99; z-index:99;
right: 3px right: 42px
} }
.Validform_error,input.error,textarea.error,select.error { .Validform_error,input.error,textarea.error,select.error {

View File

@ -17,7 +17,7 @@
<h2>若依后台管理系统</h2> <h2>若依后台管理系统</h2>
<p>ruoyi是一个完全响应式基于Bootstrap3.3.7最新版本开发的扁平化主题她采用了主流的左右两栏式布局使用了Html5+CSS3等现代技术她提供了诸多的强大的可以重新组合的UI组件并集成了最新的jQuery版本(v2.1.1)当然也集成了很多功能强大用途广泛的就jQuery插件她可以用于所有的Web应用程序<b>网站管理后台</b><b>网站会员中心</b><b>CMS</b><b>CRM</b><b>OA</b>等等,当然,您也可以对她进行深度定制,以做出更强系统。</p> <p>ruoyi是一个完全响应式基于Bootstrap3.3.7最新版本开发的扁平化主题她采用了主流的左右两栏式布局使用了Html5+CSS3等现代技术她提供了诸多的强大的可以重新组合的UI组件并集成了最新的jQuery版本(v2.1.1)当然也集成了很多功能强大用途广泛的就jQuery插件她可以用于所有的Web应用程序<b>网站管理后台</b><b>网站会员中心</b><b>CMS</b><b>CRM</b><b>OA</b>等等,当然,您也可以对她进行深度定制,以做出更强系统。</p>
<p> <p>
<b>当前版本:</b>v4.7.1 <b>当前版本:</b>v4.7.2
</p> </p>
<p> <p>
<span class="label label-warning">免费开源</span> <span class="label label-warning">免费开源</span>
@ -56,7 +56,7 @@
<h3>你好,若依 </h3> <h3>你好,若依 </h3>
<p>H+是一个完全响应式基于Bootstrap3.3.7最新版本开发的扁平化主题她采用了主流的左右两栏式布局使用了Html5+CSS3等现代技术她提供了诸多的强大的可以重新组合的UI组件并集成了最新的jQuery版本(v2.1.1)当然也集成了很多功能强大用途广泛的就jQuery插件她可以用于所有的Web应用程序<b>网站管理后台</b><b>网站会员中心</b><b>CMS</b><b>CRM</b><b>OA</b>等等,当然,您也可以对她进行深度定制,以做出更强系统。</p> <p>H+是一个完全响应式基于Bootstrap3.3.7最新版本开发的扁平化主题她采用了主流的左右两栏式布局使用了Html5+CSS3等现代技术她提供了诸多的强大的可以重新组合的UI组件并集成了最新的jQuery版本(v2.1.1)当然也集成了很多功能强大用途广泛的就jQuery插件她可以用于所有的Web应用程序<b>网站管理后台</b><b>网站会员中心</b><b>CMS</b><b>CRM</b><b>OA</b>等等,当然,您也可以对她进行深度定制,以做出更强系统。</p>
<p> <p>
<b>当前版本:</b>v4.7.1 <b>当前版本:</b>v4.7.2
</p> </p>
<p> <p>
<span class="label label-warning">开源免费</span> <span class="label label-warning">开源免费</span>

View File

@ -7,12 +7,12 @@
<meta name="description" content=""> <meta name="description" content="">
<title th:text="${title}"></title> <title th:text="${title}"></title>
<link th:href="@{/css/bootstrap.min.css?v=3.3.7}" rel="stylesheet"/> <link th:href="@{/css/bootstrap.min.css?v=3.3.7}" rel="stylesheet"/>
<link th:href="@{/css/font-awesome.min.css?v=4.7.1}" rel="stylesheet"/> <link th:href="@{/css/font-awesome.min.css?v=4.7.2}" rel="stylesheet"/>
<!-- bootstrap-table 表格插件样式 --> <!-- bootstrap-table 表格插件样式 -->
<link th:href="@{/ajax/libs/bootstrap-table/bootstrap-table.min.css?v=1.18.3}" rel="stylesheet"/> <link th:href="@{/ajax/libs/bootstrap-table/bootstrap-table.min.css?v=1.18.3}" rel="stylesheet"/>
<link th:href="@{/css/animate.min.css?v=20210831}" rel="stylesheet"/> <link th:href="@{/css/animate.min.css?v=20210831}" rel="stylesheet"/>
<link th:href="@{/css/style.min.css?v=20210831}" rel="stylesheet"/> <link th:href="@{/css/style.min.css?v=20210831}" rel="stylesheet"/>
<link th:href="@{/ruoyi/css/ry-ui.css?v=4.7.1}" rel="stylesheet"/> <link th:href="@{/ruoyi/css/ry-ui.css?v=4.7.2}" rel="stylesheet"/>
</head> </head>
<!-- 通用JS --> <!-- 通用JS -->
@ -36,8 +36,8 @@
<script th:src="@{/ajax/libs/iCheck/icheck.min.js?v=1.0.3}"></script> <script th:src="@{/ajax/libs/iCheck/icheck.min.js?v=1.0.3}"></script>
<script th:src="@{/ajax/libs/layer/layer.min.js?v=3.5.1}"></script> <script th:src="@{/ajax/libs/layer/layer.min.js?v=3.5.1}"></script>
<script th:src="@{/ajax/libs/layui/layui.min.js?v=2.6.8}"></script> <script th:src="@{/ajax/libs/layui/layui.min.js?v=2.6.8}"></script>
<script th:src="@{/ruoyi/js/common.js?v=4.7.1}"></script> <script th:src="@{/ruoyi/js/common.js?v=4.7.2}"></script>
<script th:src="@{/ruoyi/js/ry-ui.js?v=4.7.1}"></script> <script th:src="@{/ruoyi/js/ry-ui.js?v=4.7.2}"></script>
</div> </div>
<!-- ztree树插件 --> <!-- ztree树插件 -->

View File

@ -14,7 +14,7 @@
<link th:href="@{/css/animate.min.css}" rel="stylesheet"/> <link th:href="@{/css/animate.min.css}" rel="stylesheet"/>
<link th:href="@{/css/style.min.css}" rel="stylesheet"/> <link th:href="@{/css/style.min.css}" rel="stylesheet"/>
<link th:href="@{/css/skins.css?v=20200902}" rel="stylesheet"/> <link th:href="@{/css/skins.css?v=20200902}" rel="stylesheet"/>
<link th:href="@{/ruoyi/css/ry-ui.css?v=4.7.1}" rel="stylesheet"/> <link th:href="@{/ruoyi/css/ry-ui.css?v=4.7.2}" rel="stylesheet"/>
</head> </head>
<body class="fixed-sidebar full-height-layout gray-bg" th:classappend="${isMobile} ? 'canvas-menu'" style="overflow: hidden"> <body class="fixed-sidebar full-height-layout gray-bg" th:classappend="${isMobile} ? 'canvas-menu'" style="overflow: hidden">
<div id="wrapper"> <div id="wrapper">
@ -315,8 +315,8 @@
<script th:src="@{/js/jquery.contextMenu.min.js}"></script> <script th:src="@{/js/jquery.contextMenu.min.js}"></script>
<script th:src="@{/ajax/libs/blockUI/jquery.blockUI.js}"></script> <script th:src="@{/ajax/libs/blockUI/jquery.blockUI.js}"></script>
<script th:src="@{/ajax/libs/layer/layer.min.js}"></script> <script th:src="@{/ajax/libs/layer/layer.min.js}"></script>
<script th:src="@{/ruoyi/js/ry-ui.js?v=4.7.1}"></script> <script th:src="@{/ruoyi/js/ry-ui.js?v=4.7.2}"></script>
<script th:src="@{/ruoyi/js/common.js?v=4.7.1}"></script> <script th:src="@{/ruoyi/js/common.js?v=4.7.2}"></script>
<script th:src="@{/ruoyi/index.js?v=20201208}"></script> <script th:src="@{/ruoyi/index.js?v=20201208}"></script>
<script th:src="@{/ajax/libs/fullscreen/jquery.fullscreen.js}"></script> <script th:src="@{/ajax/libs/fullscreen/jquery.fullscreen.js}"></script>
<script th:src="@{/js/resize-tabs.js}"></script> <script th:src="@{/js/resize-tabs.js}"></script>

View File

@ -14,7 +14,7 @@
<link th:href="@{/css/animate.min.css}" rel="stylesheet"/> <link th:href="@{/css/animate.min.css}" rel="stylesheet"/>
<link th:href="@{/css/style.min.css}" rel="stylesheet"/> <link th:href="@{/css/style.min.css}" rel="stylesheet"/>
<link th:href="@{/css/skins.css}" rel="stylesheet"/> <link th:href="@{/css/skins.css}" rel="stylesheet"/>
<link th:href="@{/ruoyi/css/ry-ui.css?v=4.7.1}" rel="stylesheet"/> <link th:href="@{/ruoyi/css/ry-ui.css?v=4.7.2}" rel="stylesheet"/>
</head> </head>
<body class="fixed-sidebar full-height-layout gray-bg" th:classappend="${isMobile} ? 'canvas-menu'" style="overflow: hidden"> <body class="fixed-sidebar full-height-layout gray-bg" th:classappend="${isMobile} ? 'canvas-menu'" style="overflow: hidden">
<div id="wrapper"> <div id="wrapper">
@ -262,8 +262,8 @@
<script th:src="@{/js/jquery.contextMenu.min.js}"></script> <script th:src="@{/js/jquery.contextMenu.min.js}"></script>
<script th:src="@{/ajax/libs/blockUI/jquery.blockUI.js}"></script> <script th:src="@{/ajax/libs/blockUI/jquery.blockUI.js}"></script>
<script th:src="@{/ajax/libs/layer/layer.min.js}"></script> <script th:src="@{/ajax/libs/layer/layer.min.js}"></script>
<script th:src="@{/ruoyi/js/ry-ui.js?v=4.7.1}"></script> <script th:src="@{/ruoyi/js/ry-ui.js?v=4.7.2}"></script>
<script th:src="@{/ruoyi/js/common.js?v=4.7.1}"></script> <script th:src="@{/ruoyi/js/common.js?v=4.7.2}"></script>
<script th:src="@{/ruoyi/index.js?v=20201208}"></script> <script th:src="@{/ruoyi/index.js?v=20201208}"></script>
<script th:src="@{/ajax/libs/fullscreen/jquery.fullscreen.js}"></script> <script th:src="@{/ajax/libs/fullscreen/jquery.fullscreen.js}"></script>
<script th:inline="javascript"> <script th:inline="javascript">

View File

@ -38,7 +38,7 @@
<script src="../static/js/bootstrap.min.js" th:src="@{/js/bootstrap.min.js}"></script> <script src="../static/js/bootstrap.min.js" th:src="@{/js/bootstrap.min.js}"></script>
<script src="../static/js/three.min.js" th:src="@{/js/three.min.js}"></script> <script src="../static/js/three.min.js" th:src="@{/js/three.min.js}"></script>
<script src="../static/ajax/libs/layer/layer.min.js" th:src="@{/ajax/libs/layer/layer.min.js}"></script> <script src="../static/ajax/libs/layer/layer.min.js" th:src="@{/ajax/libs/layer/layer.min.js}"></script>
<script src="../static/ruoyi/js/ry-ui.js" th:src="@{/ruoyi/js/ry-ui.js?v=4.7.1}"></script> <script src="../static/ruoyi/js/ry-ui.js" th:src="@{/ruoyi/js/ry-ui.js?v=4.7.2}"></script>
</body> </body>
<script th:inline="javascript"> <script th:inline="javascript">
var ctx = [[@{/}]]; var ctx = [[@{/}]];

View File

@ -9,7 +9,7 @@
<link href="../static/css/font-awesome.min.css" th:href="@{/css/font-awesome.min.css}" rel="stylesheet"/> <link href="../static/css/font-awesome.min.css" th:href="@{/css/font-awesome.min.css}" rel="stylesheet"/>
<link href="../static/css/style.min.css" th:href="@{/css/style.min.css}" rel="stylesheet"/> <link href="../static/css/style.min.css" th:href="@{/css/style.min.css}" rel="stylesheet"/>
<link href="../static/css/login.min.css" th:href="@{/css/login.min.css}" rel="stylesheet"/> <link href="../static/css/login.min.css" th:href="@{/css/login.min.css}" rel="stylesheet"/>
<link href="../static/ruoyi/css/ry-ui.css" th:href="@{/ruoyi/css/ry-ui.css?v=4.7.1}" rel="stylesheet"/> <link href="../static/ruoyi/css/ry-ui.css" th:href="@{/ruoyi/css/ry-ui.css?v=4.7.2}" rel="stylesheet"/>
<!-- 360浏览器急速模式 --> <!-- 360浏览器急速模式 -->
<meta name="renderer" content="webkit"> <meta name="renderer" content="webkit">
<!-- 避免IE使用兼容模式 --> <!-- 避免IE使用兼容模式 -->
@ -76,7 +76,7 @@
<script src="../static/ajax/libs/validate/jquery.validate.min.js" th:src="@{/ajax/libs/validate/jquery.validate.min.js}"></script> <script src="../static/ajax/libs/validate/jquery.validate.min.js" th:src="@{/ajax/libs/validate/jquery.validate.min.js}"></script>
<script src="../static/ajax/libs/layer/layer.min.js" th:src="@{/ajax/libs/layer/layer.min.js}"></script> <script src="../static/ajax/libs/layer/layer.min.js" th:src="@{/ajax/libs/layer/layer.min.js}"></script>
<script src="../static/ajax/libs/blockUI/jquery.blockUI.js" th:src="@{/ajax/libs/blockUI/jquery.blockUI.js}"></script> <script src="../static/ajax/libs/blockUI/jquery.blockUI.js" th:src="@{/ajax/libs/blockUI/jquery.blockUI.js}"></script>
<script src="../static/ruoyi/js/ry-ui.js" th:src="@{/ruoyi/js/ry-ui.js?v=4.7.1}"></script> <script src="../static/ruoyi/js/ry-ui.js" th:src="@{/ruoyi/js/ry-ui.js?v=4.7.2}"></script>
<script src="../static/ruoyi/login.js" th:src="@{/ruoyi/login.js}"></script> <script src="../static/ruoyi/login.js" th:src="@{/ruoyi/login.js}"></script>
</body> </body>
</html> </html>

View File

@ -96,13 +96,46 @@
<div class="ibox-content no-padding"> <div class="ibox-content no-padding">
<div class="panel-body"> <div class="panel-body">
<div class="panel-group" id="version"> <div class="panel-group" id="version">
<div class="panel panel-default">
<div class="panel-heading">
<h5 class="panel-title">
<a data-toggle="collapse" data-parent="#version" href="#v472">v4.7.2</a><code class="pull-right">2021.12.23</code>
</h5>
</div>
<div id="v472" class="panel-collapse collapse in">
<div class="panel-body">
<ol>
<li>自定义xss校验注解实现</li>
<li>进入修改页面方法添加权限标识</li>
<li>代码生成创建按钮添加超级管理员权限</li>
<li>代码生成创建表检查关键字,防止注入风险</li>
<li>修复定时任务多参数逗号分隔的问题</li>
<li>修复表格插件一起使用出现的声明报错问题</li>
<li>修复代码生成主子表模板删除方法缺少事务</li>
<li>升级oshi到最新版本v5.8.6</li>
<li>升级velocity到最新版本2.3</li>
<li>升级fastjson到最新版1.2.79</li>
<li>升级log4j2到最新版2.17.0 防止漏洞风险</li>
<li>升级thymeleaf到最新版3.0.14 阻止远程代码执行漏洞</li>
<li>优化修改/授权角色实时生效</li>
<li>修整tomcat配置参数已过期问题</li>
<li>前端添加单独的二代身份证校验</li>
<li>优化新增部门时验证用户所属部门</li>
<li>优化查询用户的角色组&岗位组代码</li>
<li>请求分页方法设置成通用方便灵活调用</li>
<li>优化日期类型错误提示与图标重叠问题</li>
<li>其他细节优化</li>
</ol>
</div>
</div>
</div>
<div class="panel panel-default"> <div class="panel panel-default">
<div class="panel-heading"> <div class="panel-heading">
<h5 class="panel-title"> <h5 class="panel-title">
<a data-toggle="collapse" data-parent="#version" href="#v471">v4.7.1</a><code class="pull-right">2021.11.10</code> <a data-toggle="collapse" data-parent="#version" href="#v471">v4.7.1</a><code class="pull-right">2021.11.10</code>
</h5> </h5>
</div> </div>
<div id="v471" class="panel-collapse collapse in"> <div id="v471" class="panel-collapse collapse">
<div class="panel-body"> <div class="panel-body">
<ol> <ol>
<li>新增是否开启页签功能</li> <li>新增是否开启页签功能</li>

View File

@ -9,7 +9,7 @@
<link href="../static/css/font-awesome.min.css" th:href="@{/css/font-awesome.min.css}" rel="stylesheet"/> <link href="../static/css/font-awesome.min.css" th:href="@{/css/font-awesome.min.css}" rel="stylesheet"/>
<link href="../static/css/style.min.css" th:href="@{/css/style.min.css}" rel="stylesheet"/> <link href="../static/css/style.min.css" th:href="@{/css/style.min.css}" rel="stylesheet"/>
<link href="../static/css/login.min.css" th:href="@{/css/login.min.css}" rel="stylesheet"/> <link href="../static/css/login.min.css" th:href="@{/css/login.min.css}" rel="stylesheet"/>
<link href="../static/ruoyi/css/ry-ui.css" th:href="@{/ruoyi/css/ry-ui.css?v=4.7.1}" rel="stylesheet"/> <link href="../static/ruoyi/css/ry-ui.css" th:href="@{/ruoyi/css/ry-ui.css?v=4.7.2}" rel="stylesheet"/>
<!-- 360浏览器急速模式 --> <!-- 360浏览器急速模式 -->
<meta name="renderer" content="webkit"> <meta name="renderer" content="webkit">
<!-- 避免IE使用兼容模式 --> <!-- 避免IE使用兼容模式 -->
@ -74,7 +74,7 @@
<script src="../static/ajax/libs/validate/jquery.validate.min.js" th:src="@{/ajax/libs/validate/jquery.validate.min.js}"></script> <script src="../static/ajax/libs/validate/jquery.validate.min.js" th:src="@{/ajax/libs/validate/jquery.validate.min.js}"></script>
<script src="../static/ajax/libs/layer/layer.min.js" th:src="@{/ajax/libs/layer/layer.min.js}"></script> <script src="../static/ajax/libs/layer/layer.min.js" th:src="@{/ajax/libs/layer/layer.min.js}"></script>
<script src="../static/ajax/libs/blockUI/jquery.blockUI.js" th:src="@{/ajax/libs/blockUI/jquery.blockUI.js}"></script> <script src="../static/ajax/libs/blockUI/jquery.blockUI.js" th:src="@{/ajax/libs/blockUI/jquery.blockUI.js}"></script>
<script src="../static/ruoyi/js/ry-ui.js" th:src="@{/ruoyi/js/ry-ui.js?v=4.7.1}"></script> <script src="../static/ruoyi/js/ry-ui.js" th:src="@{/ruoyi/js/ry-ui.js?v=4.7.2}"></script>
<script src="../static/ruoyi/register.js" th:src="@{/ruoyi/register.js}"></script> <script src="../static/ruoyi/register.js" th:src="@{/ruoyi/register.js}"></script>
</body> </body>
</html> </html>

View File

@ -140,7 +140,7 @@
</ul> </ul>
</body> </body>
<script th:src="@{/js/jquery.min.js}"></script> <script th:src="@{/js/jquery.min.js}"></script>
<script th:src="@{/ruoyi/js/common.js?v=4.7.1}"></script> <script th:src="@{/ruoyi/js/common.js?v=4.7.2}"></script>
<script type="text/javascript"> <script type="text/javascript">
//皮肤样式列表 //皮肤样式列表
var skins = ["skin-blue", "skin-green", "skin-purple", "skin-red", "skin-yellow"]; var skins = ["skin-blue", "skin-green", "skin-purple", "skin-red", "skin-yellow"];

View File

@ -6,12 +6,12 @@
<body class="white-bg"> <body class="white-bg">
<div class="wrapper wrapper-content animated fadeInRight ibox-content"> <div class="wrapper wrapper-content animated fadeInRight ibox-content">
<form class="form-horizontal m" id="form-dept-add"> <form class="form-horizontal m" id="form-dept-add">
<input id="treeId" name="parentId" type="hidden" th:value="${dept.deptId}" /> <input id="treeId" name="parentId" type="hidden" th:value="${dept?.deptId}" />
<div class="form-group"> <div class="form-group">
<label class="col-sm-3 control-label">上级部门:</label> <label class="col-sm-3 control-label is-required">上级部门:</label>
<div class="col-sm-8"> <div class="col-sm-8">
<div class="input-group"> <div class="input-group">
<input class="form-control" type="text" onclick="selectDeptTree()" id="treeName" readonly="true" th:value="${dept.deptName}"> <input class="form-control" type="text" onclick="selectDeptTree()" id="treeName" readonly="true" th:value="${dept?.deptName}" required>
<span class="input-group-addon"><i class="fa fa-search"></i></span> <span class="input-group-addon"><i class="fa fa-search"></i></span>
</div> </div>
</div> </div>
@ -108,10 +108,15 @@
/*部门管理-新增-选择父部门树*/ /*部门管理-新增-选择父部门树*/
function selectDeptTree() { function selectDeptTree() {
var treeId = $("#treeId").val();
if ($.common.isEmpty(treeId)) {
$.modal.alertWarning("请先添加用户所属的部门!");
return;
}
var options = { var options = {
title: '部门选择', title: '部门选择',
width: "380", width: "380",
url: prefix + "/selectDeptTree/" + $("#treeId").val(), url: prefix + "/selectDeptTree/" + treeId,
callBack: doSubmit callBack: doSubmit
}; };
$.modal.openOptions(options); $.modal.openOptions(options);

View File

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>ruoyi</artifactId> <artifactId>ruoyi</artifactId>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<version>4.7.1</version> <version>4.7.2</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@ -19,6 +19,7 @@ import com.ruoyi.common.core.page.PageDomain;
import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.page.TableSupport; import com.ruoyi.common.core.page.TableSupport;
import com.ruoyi.common.utils.DateUtils; import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.PageUtils;
import com.ruoyi.common.utils.ServletUtils; import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.ShiroUtils; import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
@ -55,14 +56,7 @@ public class BaseController
*/ */
protected void startPage() protected void startPage()
{ {
PageDomain pageDomain = TableSupport.buildPageRequest(); PageUtils.startPage();
Integer pageNum = pageDomain.getPageNum();
Integer pageSize = pageDomain.getPageSize();
if (StringUtils.isNotNull(pageNum) && StringUtils.isNotNull(pageSize))
{
String orderBy = SqlUtil.escapeOrderBySql(pageDomain.getOrderBy());
PageHelper.startPage(pageNum, pageSize, orderBy);
}
} }
/** /**

View File

@ -11,6 +11,7 @@ import com.ruoyi.common.annotation.Excel.ColumnType;
import com.ruoyi.common.annotation.Excel.Type; import com.ruoyi.common.annotation.Excel.Type;
import com.ruoyi.common.annotation.Excels; import com.ruoyi.common.annotation.Excels;
import com.ruoyi.common.core.domain.BaseEntity; import com.ruoyi.common.core.domain.BaseEntity;
import com.ruoyi.common.xss.Xss;
/** /**
* 用户对象 sys_user * 用户对象 sys_user
@ -160,6 +161,7 @@ public class SysUser extends BaseEntity
this.roleId = roleId; this.roleId = roleId;
} }
@Xss(message = "登录账号不能包含脚本字符")
@NotBlank(message = "登录账号不能为空") @NotBlank(message = "登录账号不能为空")
@Size(min = 0, max = 30, message = "登录账号长度不能超过30个字符") @Size(min = 0, max = 30, message = "登录账号长度不能超过30个字符")
public String getLoginName() public String getLoginName()
@ -172,6 +174,7 @@ public class SysUser extends BaseEntity
this.loginName = loginName; this.loginName = loginName;
} }
@Xss(message = "用户昵称不能包含脚本字符")
@Size(min = 0, max = 30, message = "用户昵称长度不能超过30个字符") @Size(min = 0, max = 30, message = "用户昵称长度不能超过30个字符")
public String getUserName() public String getUserName()
{ {

View File

@ -0,0 +1,29 @@
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());
PageHelper.startPage(pageNum, pageSize, orderBy);
}
}
}

View File

@ -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<ConstraintViolation<Object>> constraintViolations = validator.validate(object, groups);
if (!constraintViolations.isEmpty())
{
throw new ConstraintViolationException(constraintViolations);
}
}
}

View File

@ -429,9 +429,8 @@ public class ExcelUtil<T>
* @param list 导出数据集合 * @param list 导出数据集合
* @param sheetName 工作表的名称 * @param sheetName 工作表的名称
* @return 结果 * @return 结果
* @throws IOException
*/ */
public void exportExcel(HttpServletResponse response, List<T> list, String sheetName)throws IOException public void exportExcel(HttpServletResponse response, List<T> list, String sheetName)
{ {
exportExcel(response, list, sheetName, StringUtils.EMPTY); exportExcel(response, list, sheetName, StringUtils.EMPTY);
} }
@ -444,14 +443,13 @@ public class ExcelUtil<T>
* @param sheetName 工作表的名称 * @param sheetName 工作表的名称
* @param title 标题 * @param title 标题
* @return 结果 * @return 结果
* @throws IOException
*/ */
public void exportExcel(HttpServletResponse response, List<T> list, String sheetName, String title) throws IOException public void exportExcel(HttpServletResponse response, List<T> list, String sheetName, String title)
{ {
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setCharacterEncoding("utf-8"); response.setCharacterEncoding("utf-8");
this.init(list, sheetName, title, Type.EXPORT); this.init(list, sheetName, title, Type.EXPORT);
exportExcel(response.getOutputStream()); exportExcel(response);
} }
/** /**
@ -484,7 +482,7 @@ public class ExcelUtil<T>
* @param sheetName 工作表的名称 * @param sheetName 工作表的名称
* @return 结果 * @return 结果
*/ */
public void importTemplateExcel(HttpServletResponse response, String sheetName) throws IOException public void importTemplateExcel(HttpServletResponse response, String sheetName)
{ {
importTemplateExcel(response, sheetName, StringUtils.EMPTY); importTemplateExcel(response, sheetName, StringUtils.EMPTY);
} }
@ -496,12 +494,12 @@ public class ExcelUtil<T>
* @param title 标题 * @param title 标题
* @return 结果 * @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.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setCharacterEncoding("utf-8"); response.setCharacterEncoding("utf-8");
this.init(null, sheetName, title, Type.IMPORT); this.init(null, sheetName, title, Type.IMPORT);
exportExcel(response.getOutputStream()); exportExcel(response);
} }
/** /**
@ -509,12 +507,12 @@ public class ExcelUtil<T>
* *
* @return 结果 * @return 结果
*/ */
public void exportExcel(OutputStream out) public void exportExcel(HttpServletResponse response)
{ {
try try
{ {
writeSheet(); writeSheet();
wb.write(out); wb.write(response.getOutputStream());
} }
catch (Exception e) catch (Exception e)
{ {
@ -523,7 +521,6 @@ public class ExcelUtil<T>
finally finally
{ {
IOUtils.closeQuietly(wb); IOUtils.closeQuietly(wb);
IOUtils.closeQuietly(out);
} }
} }

View File

@ -1,6 +1,6 @@
package com.ruoyi.common.utils.sql; package com.ruoyi.common.utils.sql;
import com.ruoyi.common.exception.base.BaseException; import com.ruoyi.common.exception.UtilException;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
/** /**
@ -10,6 +10,11 @@ import com.ruoyi.common.utils.StringUtils;
*/ */
public class SqlUtil public class SqlUtil
{ {
/**
* 定义常用的 sql关键字
*/
public static String SQL_REGEX = "select |insert |delete |update |drop |count |exec |chr |mid |master |truncate |char |and |declare ";
/** /**
* 仅支持字母、数字、下划线、空格、逗号、小数点(支持多个字段排序) * 仅支持字母、数字、下划线、空格、逗号、小数点(支持多个字段排序)
*/ */
@ -22,7 +27,7 @@ public class SqlUtil
{ {
if (StringUtils.isNotEmpty(value) && !isValidOrderBySql(value)) if (StringUtils.isNotEmpty(value) && !isValidOrderBySql(value))
{ {
throw new BaseException("参数不符合规范,不能进行查询"); throw new UtilException("参数不符合规范,不能进行查询");
} }
return value; return value;
} }
@ -34,4 +39,23 @@ public class SqlUtil
{ {
return value.matches(SQL_PATTERN); 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注入风险");
}
}
}
} }

View File

@ -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 {};
}

View File

@ -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<Xss, String>
{
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();
}
}

View File

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>ruoyi</artifactId> <artifactId>ruoyi</artifactId>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<version>4.7.1</version> <version>4.7.2</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>ruoyi</artifactId> <artifactId>ruoyi</artifactId>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<version>4.7.1</version> <version>4.7.2</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
@ -20,7 +20,7 @@
<!--velocity代码生成使用模板 --> <!--velocity代码生成使用模板 -->
<dependency> <dependency>
<groupId>org.apache.velocity</groupId> <groupId>org.apache.velocity</groupId>
<artifactId>velocity</artifactId> <artifactId>velocity-engine-core</artifactId>
</dependency> </dependency>
<!-- 通用工具--> <!-- 通用工具-->

View File

@ -31,6 +31,7 @@ import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.enums.BusinessType; import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.security.PermissionUtils; import com.ruoyi.common.utils.security.PermissionUtils;
import com.ruoyi.common.utils.sql.SqlUtil;
import com.ruoyi.generator.domain.GenTable; import com.ruoyi.generator.domain.GenTable;
import com.ruoyi.generator.domain.GenTableColumn; import com.ruoyi.generator.domain.GenTableColumn;
import com.ruoyi.generator.service.IGenTableColumnService; import com.ruoyi.generator.service.IGenTableColumnService;
@ -140,6 +141,7 @@ public class GenController extends BaseController
/** /**
* 修改代码生成业务 * 修改代码生成业务
*/ */
@RequiresPermissions("tool:gen:edit")
@GetMapping("/edit/{tableId}") @GetMapping("/edit/{tableId}")
public String edit(@PathVariable("tableId") Long tableId, ModelMap mmap) public String edit(@PathVariable("tableId") Long tableId, ModelMap mmap)
{ {
@ -195,31 +197,33 @@ public class GenController extends BaseController
@ResponseBody @ResponseBody
public AjaxResult create(String sql) public AjaxResult create(String sql)
{ {
List<SQLStatement> sqlStatements = SQLUtils.parseStatements(sql, DbType.mysql); try
List<String> tableNames = new ArrayList<>();
for (SQLStatement sqlStatement : sqlStatements)
{ {
if (sqlStatement instanceof MySqlCreateTableStatement) SqlUtil.filterKeyword(sql);
List<SQLStatement> sqlStatements = SQLUtils.parseStatements(sql, DbType.mysql);
List<String> tableNames = new ArrayList<>();
for (SQLStatement sqlStatement : sqlStatements)
{ {
MySqlCreateTableStatement createTableStatement = (MySqlCreateTableStatement) sqlStatement; if (sqlStatement instanceof MySqlCreateTableStatement)
String tableName = createTableStatement.getTableName();
tableName = tableName.replaceAll("`", "");
int msg = genTableService.createTable(createTableStatement.toString());
if (msg == 0)
{ {
tableNames.add(tableName); MySqlCreateTableStatement createTableStatement = (MySqlCreateTableStatement) sqlStatement;
if (genTableService.createTable(createTableStatement.toString()))
{
String tableName = createTableStatement.getTableName().replaceAll("`", "");
tableNames.add(tableName);
}
} }
} }
else List<GenTable> tableList = genTableService.selectDbTableListByNames(tableNames.toArray(new String[tableNames.size()]));
{ String operName = Convert.toStr(PermissionUtils.getPrincipalProperty("loginName"));
return AjaxResult.error("请输入建表语句"); genTableService.importGenTable(tableList, operName);
} return AjaxResult.success();
}
catch (Exception e)
{
logger.error(e.getMessage(), e);
return AjaxResult.error("创建表结构异常[" + e.getMessage() + "]");
} }
List<GenTable> tableList = genTableService.selectDbTableListByNames((tableNames.toArray(new String[tableNames.size()])));
String operName = Convert.toStr(PermissionUtils.getPrincipalProperty("loginName"));
genTableService.importGenTable(tableList, operName);
return AjaxResult.success();
} }
/** /**

View File

@ -72,7 +72,7 @@ public interface IGenTableService
* @param sql 创建表语句 * @param sql 创建表语句
* @return 结果 * @return 结果
*/ */
public int createTable(String sql); public boolean createTable(String sql);
/** /**
* 导入表结构 * 导入表结构

View File

@ -157,9 +157,9 @@ public class GenTableServiceImpl implements IGenTableService
* @return 结果 * @return 结果
*/ */
@Override @Override
public int createTable(String sql) public boolean createTable(String sql)
{ {
return genTableMapper.createTable(sql); return genTableMapper.createTable(sql) == 0;
} }
/** /**

View File

@ -20,10 +20,9 @@ public class VelocityInitializer
try try
{ {
// 加载classpath目录下的vm文件 // 加载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.INPUT_ENCODING, Constants.UTF8);
p.setProperty(Velocity.OUTPUT_ENCODING, Constants.UTF8);
// 初始化Velocity引擎指定配置Properties // 初始化Velocity引擎指定配置Properties
Velocity.init(p); Velocity.init(p);
} }

View File

@ -35,7 +35,7 @@
<a class="btn btn-success multiple disabled" onclick="javascript:batchGenCode()" shiro:hasPermission="tool:gen:code"> <a class="btn btn-success multiple disabled" onclick="javascript:batchGenCode()" shiro:hasPermission="tool:gen:code">
<i class="fa fa-download"></i> 生成 <i class="fa fa-download"></i> 生成
</a> </a>
<a class="btn btn-success" onclick="createTable()"> <a class="btn btn-success" onclick="createTable()" shiro:hasRole="admin">
<i class="fa fa-plus"></i> 创建 <i class="fa fa-plus"></i> 创建
</a> </a>
<a class="btn btn-info" onclick="importTable()"> <a class="btn btn-info" onclick="importTable()">

View File

@ -334,8 +334,9 @@
var name = $.common.sprintf("${subclassName}List[%s].${javaField}", index); var name = $.common.sprintf("${subclassName}List[%s].${javaField}", index);
return $.common.dictToSelect(${javaField}Datas, value, name); return $.common.dictToSelect(${javaField}Datas, value, name);
} }
#if($velocityCount != $subTable.columns.size())},#end #if($foreach.count != $subTable.columns.size())
},
#end
#else #else
{ {
field: '${javaField}', field: '${javaField}',
@ -345,8 +346,9 @@
var html = $.common.sprintf("<input class='form-control' type='text' name='${subclassName}List[%s].${javaField}' value='%s'>", index, value); var html = $.common.sprintf("<input class='form-control' type='text' name='${subclassName}List[%s].${javaField}' value='%s'>", index, value);
return html; return html;
} }
#if($velocityCount != $subTable.columns.size())},#end #if($foreach.count != $subTable.columns.size())
},
#end
#end #end
#end #end
}] }]
@ -366,7 +368,7 @@
#set($javaField=$column.javaField) #set($javaField=$column.javaField)
#if($column.pk || $javaField == ${subTableFkclassName}) #if($column.pk || $javaField == ${subTableFkclassName})
#else #else
${javaField}: ""#if($velocityCount != $subTable.columns.size()),#end ${javaField}: ""#if($foreach.count != $subTable.columns.size()),#end
#end #end
#end #end

View File

@ -345,8 +345,9 @@
var name = $.common.sprintf("${subclassName}List[%s].${javaField}", index); var name = $.common.sprintf("${subclassName}List[%s].${javaField}", index);
return $.common.dictToSelect(${javaField}Datas, value, name); return $.common.dictToSelect(${javaField}Datas, value, name);
} }
#if($velocityCount != $subTable.columns.size())},#end #if($foreach.count != $subTable.columns.size())
},
#end
#else #else
{ {
field: '${javaField}', field: '${javaField}',
@ -356,8 +357,9 @@
var html = $.common.sprintf("<input class='form-control' type='text' name='${subclassName}List[%s].${javaField}' value='%s'>", index, value); var html = $.common.sprintf("<input class='form-control' type='text' name='${subclassName}List[%s].${javaField}' value='%s'>", index, value);
return html; return html;
} }
#if($velocityCount != $subTable.columns.size())},#end #if($foreach.count != $subTable.columns.size())
},
#end
#end #end
#end #end
}] }]
@ -377,7 +379,7 @@
#set($javaField=$column.javaField) #set($javaField=$column.javaField)
#if($column.pk || $javaField == ${subTableFkclassName}) #if($column.pk || $javaField == ${subTableFkclassName})
#else #else
${javaField}: ""#if($velocityCount != $subTable.columns.size()),#end ${javaField}: ""#if($foreach.count != $subTable.columns.size()),#end
#end #end
#end #end

View File

@ -126,6 +126,7 @@ public class ${ClassName}Controller extends BaseController
/** /**
* 修改${functionName} * 修改${functionName}
*/ */
@RequiresPermissions("${permissionPrefix}:edit")
@GetMapping("/edit/{${pkColumn.javaField}}") @GetMapping("/edit/{${pkColumn.javaField}}")
public String edit(@PathVariable("${pkColumn.javaField}") ${pkColumn.javaType} ${pkColumn.javaField}, ModelMap mmap) public String edit(@PathVariable("${pkColumn.javaField}") ${pkColumn.javaType} ${pkColumn.javaField}, ModelMap mmap)
{ {

View File

@ -134,6 +134,9 @@ public class ${ClassName}ServiceImpl implements I${ClassName}Service
* @param ${pkColumn.javaField} ${functionName}主键 * @param ${pkColumn.javaField} ${functionName}主键
* @return 结果 * @return 结果
*/ */
#if($table.sub)
@Transactional
#end
@Override @Override
public int delete${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField}) public int delete${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField})
{ {

View File

@ -26,7 +26,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
#end #end
<sql id="select${ClassName}Vo"> <sql id="select${ClassName}Vo">
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}
</sql> </sql>
<select id="select${ClassName}List" parameterType="${ClassName}" resultMap="${ClassName}Result"> <select id="select${ClassName}List" parameterType="${ClassName}" resultMap="${ClassName}Result">
@ -74,8 +74,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
left join ${tableName} p on p.${pkColumn.columnName} = t.${tree_parent_code} left join ${tableName} p on p.${pkColumn.columnName} = t.${tree_parent_code}
where t.${pkColumn.columnName} = #{${pkColumn.javaField}} where t.${pkColumn.columnName} = #{${pkColumn.javaField}}
#elseif($table.sub) #elseif($table.sub)
select#foreach($column in $columns) a.$column.columnName#if($velocityCount != $columns.size()),#end#end, select#foreach($column in $columns) a.$column.columnName#if($foreach.count != $columns.size()),#end#end,
#foreach($column in $subTable.columns) b.$column.columnName as sub_$column.columnName#if($velocityCount != $subTable.columns.size()),#end#end #foreach($column in $subTable.columns) b.$column.columnName as sub_$column.columnName#if($foreach.count != $subTable.columns.size()),#end#end
from ${tableName} a from ${tableName} a
left join ${subTableName} b on b.${subTableFkName} = a.${pkColumn.columnName} left join ${subTableName} b on b.${subTableFkName} = a.${pkColumn.columnName}
@ -137,9 +137,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</delete> </delete>
<insert id="batch${subClassName}"> <insert id="batch${subClassName}">
insert into ${subTableName}(#foreach($column in $subTable.columns) $column.columnName#if($velocityCount != $subTable.columns.size()),#end#end) values insert into ${subTableName}(#foreach($column in $subTable.columns) $column.columnName#if($foreach.count != $subTable.columns.size()),#end#end) values
<foreach item="item" index="index" collection="list" separator=","> <foreach item="item" index="index" collection="list" separator=",">
(#foreach($column in $subTable.columns) #{item.$column.javaField}#if($velocityCount != $subTable.columns.size()),#end#end) (#foreach($column in $subTable.columns) #{item.$column.javaField}#if($foreach.count != $subTable.columns.size()),#end#end)
</foreach> </foreach>
</insert> </insert>
#end #end

View File

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>ruoyi</artifactId> <artifactId>ruoyi</artifactId>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<version>4.7.1</version> <version>4.7.2</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@ -7,7 +7,7 @@ import javax.sql.DataSource;
import java.util.Properties; import java.util.Properties;
/** /**
* 定时任务配置 * 定时任务配置单机部署建议删除此类和qrtz数据库表默认走内存会最高效
* *
* @author ruoyi * @author ruoyi
*/ */

View File

@ -159,6 +159,7 @@ public class SysJobController extends BaseController
/** /**
* 修改调度 * 修改调度
*/ */
@RequiresPermissions("monitor:job:edit")
@GetMapping("/edit/{jobId}") @GetMapping("/edit/{jobId}")
public String edit(@PathVariable("jobId") Long jobId, ModelMap mmap) public String edit(@PathVariable("jobId") Long jobId, ModelMap mmap)
{ {

View File

@ -110,30 +110,30 @@ public class JobInvokeUtil
{ {
return null; return null;
} }
String[] methodParams = methodStr.split(","); String[] methodParams = methodStr.split(",(?=([^\"']*[\"'][^\"']*[\"'])*[^\"']*$)");
List<Object[]> classs = new LinkedList<>(); List<Object[]> classs = new LinkedList<>();
for (int i = 0; i < methodParams.length; i++) for (int i = 0; i < methodParams.length; i++)
{ {
String str = StringUtils.trimToEmpty(methodParams[i]); String str = StringUtils.trimToEmpty(methodParams[i]);
// String字符串类型包含' // String字符串类型以'或"开头
if (StringUtils.contains(str, "'")) if (StringUtils.startsWithAny(str, "'", "\""))
{ {
classs.add(new Object[] { StringUtils.replace(str, "'", ""), String.class }); classs.add(new Object[] { StringUtils.substring(str, 1, str.length() - 1), String.class });
} }
// boolean布尔类型等于true或者false // boolean布尔类型等于true或者false
else if (StringUtils.equals(str, "true") || StringUtils.equalsIgnoreCase(str, "false")) else if ("true".equalsIgnoreCase(str) || "false".equalsIgnoreCase(str))
{ {
classs.add(new Object[] { Boolean.valueOf(str), Boolean.class }); classs.add(new Object[] { Boolean.valueOf(str), Boolean.class });
} }
// long长整形包含L // long长整形以L结尾
else if (StringUtils.containsIgnoreCase(str, "L")) else if (StringUtils.endsWith(str, "L"))
{ {
classs.add(new Object[] { Long.valueOf(StringUtils.replaceIgnoreCase(str, "L", "")), Long.class }); classs.add(new Object[] { Long.valueOf(StringUtils.substring(str, 0, str.length() - 1)), Long.class });
} }
// double浮点类型包含D // double浮点类型以D结尾
else if (StringUtils.containsIgnoreCase(str, "D")) else if (StringUtils.endsWith(str, "D"))
{ {
classs.add(new Object[] { Double.valueOf(StringUtils.replaceIgnoreCase(str, "D", "")), Double.class }); classs.add(new Object[] { Double.valueOf(StringUtils.substring(str, 0, str.length() - 1)), Double.class });
} }
// 其他类型归类为整形 // 其他类型归类为整形
else else

View File

@ -1131,7 +1131,7 @@
<script th:src="@{/js/jquery.min.js}"></script> <script th:src="@{/js/jquery.min.js}"></script>
<script th:src="@{/js/bootstrap.min.js}"></script> <script th:src="@{/js/bootstrap.min.js}"></script>
<script th:src="@{/ajax/libs/layer/layer.min.js}"></script> <script th:src="@{/ajax/libs/layer/layer.min.js}"></script>
<script th:src="@{/ruoyi/js/ry-ui.js?v=4.7.1}"></script> <script th:src="@{/ruoyi/js/ry-ui.js?v=4.7.2}"></script>
<script th:src="@{/js/cron.js}"></script> <script th:src="@{/js/cron.js}"></script>
<script th:inline="javascript"> <script th:inline="javascript">
var prefix = [[@{/}]] + "monitor/job"; var prefix = [[@{/}]] + "monitor/job";

View File

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>ruoyi</artifactId> <artifactId>ruoyi</artifactId>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<version>4.7.1</version> <version>4.7.2</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@ -1,9 +1,11 @@
package com.ruoyi.system.domain; package com.ruoyi.system.domain;
import javax.validation.constraints.*; import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle; import org.apache.commons.lang3.builder.ToStringStyle;
import com.ruoyi.common.core.domain.BaseEntity; import com.ruoyi.common.core.domain.BaseEntity;
import com.ruoyi.common.xss.Xss;
/** /**
* 通知公告表 sys_notice * 通知公告表 sys_notice
@ -44,6 +46,7 @@ public class SysNotice extends BaseEntity
this.noticeTitle = noticeTitle; this.noticeTitle = noticeTitle;
} }
@Xss(message = "公告标题不能包含脚本字符")
@NotBlank(message = "公告标题不能为空") @NotBlank(message = "公告标题不能为空")
@Size(min = 0, max = 50, message = "公告标题不能超过50个字符") @Size(min = 0, max = 50, message = "公告标题不能超过50个字符")
public String getNoticeTitle() public String getNoticeTitle()

View File

@ -2,11 +2,14 @@ package com.ruoyi.system.service.impl;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
import javax.validation.Validator;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import com.ruoyi.common.annotation.DataScope; import com.ruoyi.common.annotation.DataScope;
import com.ruoyi.common.constant.UserConstants; import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.domain.entity.SysRole; import com.ruoyi.common.core.domain.entity.SysRole;
@ -15,6 +18,7 @@ import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.ShiroUtils; import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.bean.BeanValidators;
import com.ruoyi.common.utils.security.Md5Utils; import com.ruoyi.common.utils.security.Md5Utils;
import com.ruoyi.common.utils.spring.SpringUtils; import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.system.domain.SysPost; import com.ruoyi.system.domain.SysPost;
@ -56,6 +60,9 @@ public class SysUserServiceImpl implements ISysUserService
@Autowired @Autowired
private ISysConfigService configService; private ISysConfigService configService;
@Autowired
protected Validator validator;
/** /**
* 根据条件分页查询用户列表 * 根据条件分页查询用户列表
* *
@ -435,16 +442,11 @@ public class SysUserServiceImpl implements ISysUserService
public String selectUserRoleGroup(Long userId) public String selectUserRoleGroup(Long userId)
{ {
List<SysRole> list = roleMapper.selectRolesByUserId(userId); List<SysRole> list = roleMapper.selectRolesByUserId(userId);
StringBuffer idsStr = new StringBuffer(); if (CollectionUtils.isEmpty(list))
for (SysRole role : list)
{ {
idsStr.append(role.getRoleName()).append(","); return StringUtils.EMPTY;
} }
if (StringUtils.isNotEmpty(idsStr.toString())) return list.stream().map(SysRole::getRoleName).collect(Collectors.joining(","));
{
return idsStr.substring(0, idsStr.length() - 1);
}
return idsStr.toString();
} }
/** /**
@ -457,16 +459,11 @@ public class SysUserServiceImpl implements ISysUserService
public String selectUserPostGroup(Long userId) public String selectUserPostGroup(Long userId)
{ {
List<SysPost> list = postMapper.selectPostsByUserId(userId); List<SysPost> list = postMapper.selectPostsByUserId(userId);
StringBuffer idsStr = new StringBuffer(); if (CollectionUtils.isEmpty(list))
for (SysPost post : list)
{ {
idsStr.append(post.getPostName()).append(","); return StringUtils.EMPTY;
} }
if (StringUtils.isNotEmpty(idsStr.toString())) return list.stream().map(SysPost::getPostName).collect(Collectors.joining(","));
{
return idsStr.substring(0, idsStr.length() - 1);
}
return idsStr.toString();
} }
/** /**
@ -497,6 +494,7 @@ public class SysUserServiceImpl implements ISysUserService
SysUser u = userMapper.selectUserByLoginName(user.getLoginName()); SysUser u = userMapper.selectUserByLoginName(user.getLoginName());
if (StringUtils.isNull(u)) if (StringUtils.isNull(u))
{ {
BeanValidators.validateWithException(validator, user);
user.setPassword(Md5Utils.hash(user.getLoginName() + password)); user.setPassword(Md5Utils.hash(user.getLoginName() + password));
user.setCreateBy(operName); user.setCreateBy(operName);
this.insertUser(user); this.insertUser(user);
@ -505,6 +503,7 @@ public class SysUserServiceImpl implements ISysUserService
} }
else if (isUpdateSupport) else if (isUpdateSupport)
{ {
BeanValidators.validateWithException(validator, user);
user.setUpdateBy(operName); user.setUpdateBy(operName);
this.updateUser(user); this.updateUser(user);
successNum++; successNum++;