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>
<artifactId>ruoyi</artifactId>
<version>4.7.1</version>
<version>4.7.2</version>
<name>ruoyi</name>
<url>http://www.ruoyi.vip</url>
<description>若依管理系统</description>
<properties>
<ruoyi.version>4.7.1</ruoyi.version>
<ruoyi.version>4.7.2</ruoyi.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<maven-jar-plugin.version>3.1.1</maven-jar-plugin.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>
<druid.version>1.2.8</druid.version>
<bitwalker.version>1.21</bitwalker.version>
@ -25,13 +26,14 @@
<swagger.version>3.0.0</swagger.version>
<mybatis-spring-boot.version>2.2.0</mybatis-spring-boot.version>
<pagehelper.boot.version>1.4.0</pagehelper.boot.version>
<fastjson.version>1.2.78</fastjson.version>
<oshi.version>5.8.2</oshi.version>
<jna.version>5.9.0</jna.version>
<fastjson.version>1.2.79</fastjson.version>
<oshi.version>5.8.6</oshi.version>
<jna.version>5.10.0</jna.version>
<commons.io.version>2.11.0</commons.io.version>
<commons.fileupload.version>1.4</commons.fileupload.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>
<!-- 依赖声明 -->
@ -82,6 +84,19 @@
<version>${shiro.version}</version>
</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框架的整合 -->
<dependency>
<groupId>com.github.theborakompanioni</groupId>
@ -166,14 +181,8 @@
<!-- velocity代码生成使用模板 -->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity</artifactId>
<artifactId>velocity-engine-core</artifactId>
<version>${velocity.version}</version>
<exclusions>
<exclusion>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- 阿里JSON解析器 -->
@ -183,6 +192,19 @@
<version>${fastjson.version}</version>
</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>
<groupId>com.ruoyi</groupId>

View File

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

View File

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

View File

@ -95,6 +95,7 @@ public class SysConfigController extends BaseController
/**
* 修改参数配置
*/
@RequiresPermissions("system:config:edit")
@GetMapping("/edit/{configId}")
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}")
public String edit(@PathVariable("deptId") Long deptId, ModelMap mmap)
{
@ -100,7 +101,7 @@ public class SysDeptController extends BaseController
}
/**
* 保存
* 修改保存部门
*/
@Log(title = "部门管理", businessType = BusinessType.UPDATE)
@RequiresPermissions("system:dept:edit")

View File

@ -88,6 +88,7 @@ public class SysDictDataController extends BaseController
/**
* 修改字典类型
*/
@RequiresPermissions("system:dict:edit")
@GetMapping("/edit/{dictCode}")
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}")
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}")
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.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
@ -68,7 +69,7 @@ public class SysNoticeController extends BaseController
@Log(title = "通知公告", businessType = BusinessType.INSERT)
@PostMapping("/add")
@ResponseBody
public AjaxResult addSave(SysNotice notice)
public AjaxResult addSave(@Validated SysNotice notice)
{
notice.setCreateBy(getLoginName());
return toAjax(noticeService.insertNotice(notice));
@ -77,6 +78,7 @@ public class SysNoticeController extends BaseController
/**
* 修改公告
*/
@RequiresPermissions("system:notice:edit")
@GetMapping("/edit/{noticeId}")
public String edit(@PathVariable("noticeId") Long noticeId, ModelMap mmap)
{
@ -91,7 +93,7 @@ public class SysNoticeController extends BaseController
@Log(title = "通知公告", businessType = BusinessType.UPDATE)
@PostMapping("/edit")
@ResponseBody
public AjaxResult editSave(SysNotice notice)
public AjaxResult editSave(@Validated SysNotice notice)
{
notice.setUpdateBy(getLoginName());
return toAjax(noticeService.updateNotice(notice));

View File

@ -112,6 +112,7 @@ public class SysPostController extends BaseController
/**
* 修改岗位
*/
@RequiresPermissions("system:post:edit")
@GetMapping("/edit/{postId}")
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}")
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.poi.ExcelUtil;
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.ISysRoleService;
import com.ruoyi.system.service.ISysUserService;
@ -146,6 +147,7 @@ public class SysUserController extends BaseController
/**
* 修改用户
*/
@RequiresPermissions("system:user:edit")
@GetMapping("/edit/{userId}")
public String edit(@PathVariable("userId") Long userId, ModelMap mmap)
{
@ -178,6 +180,7 @@ public class SysUserController extends BaseController
return error("修改用户'" + user.getLoginName() + "'失败,邮箱账号已存在");
}
user.setUpdateBy(getLoginName());
AuthorizationUtils.clearAllCachedAuthorizationInfo();
return toAjax(userService.updateUser(user));
}
@ -233,6 +236,7 @@ public class SysUserController extends BaseController
public AjaxResult insertAuthRole(Long userId, Long[] roleIds)
{
userService.insertUserAuth(userId, roleIds);
AuthorizationUtils.clearAllCachedAuthorizationInfo();
return success();
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -8,7 +8,7 @@ $(document).ready(function(){
//手机号码验证身份证正则合并:(^\d{15}$)|(^\d{17}([0-9]|X)$)
jQuery.validator.addMethod("isPhone",function(value,element){
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));
},"请填写正确的11位手机号");
//电话号码验证
@ -31,7 +31,12 @@ $(document).ready(function(){
jQuery.validator.addMethod("isIdentity",function(value,element){
var id= /^(\d{15}$|^\d{18}$|^\d{17}(\d|X))$/;
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){
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 {
z-index:99;
right: 3px
right: 42px
}
.Validform_error,input.error,textarea.error,select.error {

View File

@ -17,7 +17,7 @@
<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>
<b>当前版本:</b>v4.7.1
<b>当前版本:</b>v4.7.2
</p>
<p>
<span class="label label-warning">免费开源</span>
@ -56,7 +56,7 @@
<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>
<b>当前版本:</b>v4.7.1
<b>当前版本:</b>v4.7.2
</p>
<p>
<span class="label label-warning">开源免费</span>

View File

@ -7,12 +7,12 @@
<meta name="description" content="">
<title th:text="${title}"></title>
<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 表格插件样式 -->
<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/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>
<!-- 通用JS -->
@ -36,8 +36,8 @@
<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/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/ry-ui.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.2}"></script>
</div>
<!-- ztree树插件 -->

View File

@ -14,7 +14,7 @@
<link th:href="@{/css/animate.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="@{/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>
<body class="fixed-sidebar full-height-layout gray-bg" th:classappend="${isMobile} ? 'canvas-menu'" style="overflow: hidden">
<div id="wrapper">
@ -315,8 +315,8 @@
<script th:src="@{/js/jquery.contextMenu.min.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="@{/ruoyi/js/ry-ui.js?v=4.7.1}"></script>
<script th:src="@{/ruoyi/js/common.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.2}"></script>
<script th:src="@{/ruoyi/index.js?v=20201208}"></script>
<script th:src="@{/ajax/libs/fullscreen/jquery.fullscreen.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/style.min.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>
<body class="fixed-sidebar full-height-layout gray-bg" th:classappend="${isMobile} ? 'canvas-menu'" style="overflow: hidden">
<div id="wrapper">
@ -262,8 +262,8 @@
<script th:src="@{/js/jquery.contextMenu.min.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="@{/ruoyi/js/ry-ui.js?v=4.7.1}"></script>
<script th:src="@{/ruoyi/js/common.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.2}"></script>
<script th:src="@{/ruoyi/index.js?v=20201208}"></script>
<script th:src="@{/ajax/libs/fullscreen/jquery.fullscreen.js}"></script>
<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/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/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>
<script th:inline="javascript">
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/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/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浏览器急速模式 -->
<meta name="renderer" content="webkit">
<!-- 避免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/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/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>
</body>
</html>

View File

@ -96,13 +96,46 @@
<div class="ibox-content no-padding">
<div class="panel-body">
<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-heading">
<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>
</h5>
</div>
<div id="v471" class="panel-collapse collapse in">
<div id="v471" class="panel-collapse collapse">
<div class="panel-body">
<ol>
<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/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/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浏览器急速模式 -->
<meta name="renderer" content="webkit">
<!-- 避免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/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/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>
</body>
</html>

View File

@ -140,7 +140,7 @@
</ul>
</body>
<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">
//皮肤样式列表
var skins = ["skin-blue", "skin-green", "skin-purple", "skin-red", "skin-yellow"];

View File

@ -6,12 +6,12 @@
<body class="white-bg">
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
<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">
<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="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>
</div>
</div>
@ -108,10 +108,15 @@
/*部门管理-新增-选择父部门树*/
function selectDeptTree() {
var treeId = $("#treeId").val();
if ($.common.isEmpty(treeId)) {
$.modal.alertWarning("请先添加用户所属的部门!");
return;
}
var options = {
title: '部门选择',
width: "380",
url: prefix + "/selectDeptTree/" + $("#treeId").val(),
url: prefix + "/selectDeptTree/" + treeId,
callBack: doSubmit
};
$.modal.openOptions(options);

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>ruoyi</artifactId>
<groupId>com.ruoyi</groupId>
<version>4.7.1</version>
<version>4.7.2</version>
</parent>
<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.TableSupport;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.PageUtils;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.common.utils.StringUtils;
@ -55,14 +56,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());
PageHelper.startPage(pageNum, pageSize, orderBy);
}
PageUtils.startPage();
}
/**

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.Excels;
import com.ruoyi.common.core.domain.BaseEntity;
import com.ruoyi.common.xss.Xss;
/**
* 用户对象 sys_user
@ -160,6 +161,7 @@ public class SysUser extends BaseEntity
this.roleId = roleId;
}
@Xss(message = "登录账号不能包含脚本字符")
@NotBlank(message = "登录账号不能为空")
@Size(min = 0, max = 30, message = "登录账号长度不能超过30个字符")
public String getLoginName()
@ -172,6 +174,7 @@ public class SysUser extends BaseEntity
this.loginName = loginName;
}
@Xss(message = "用户昵称不能包含脚本字符")
@Size(min = 0, max = 30, message = "用户昵称长度不能超过30个字符")
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 sheetName 工作表的名称
* @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);
}
@ -444,14 +443,13 @@ public class ExcelUtil<T>
* @param sheetName 工作表的名称
* @param title 标题
* @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.setCharacterEncoding("utf-8");
this.init(list, sheetName, title, Type.EXPORT);
exportExcel(response.getOutputStream());
exportExcel(response);
}
/**
@ -484,7 +482,7 @@ public class ExcelUtil<T>
* @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 +494,12 @@ public class ExcelUtil<T>
* @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 +507,12 @@ public class ExcelUtil<T>
*
* @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 +521,6 @@ public class ExcelUtil<T>
finally
{
IOUtils.closeQuietly(wb);
IOUtils.closeQuietly(out);
}
}

View File

@ -1,6 +1,6 @@
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;
/**
@ -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 ";
/**
* 仅支持字母、数字、下划线、空格、逗号、小数点(支持多个字段排序)
*/
@ -22,7 +27,7 @@ public class SqlUtil
{
if (StringUtils.isNotEmpty(value) && !isValidOrderBySql(value))
{
throw new BaseException("参数不符合规范,不能进行查询");
throw new UtilException("参数不符合规范,不能进行查询");
}
return value;
}
@ -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注入风险");
}
}
}
}

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>
<artifactId>ruoyi</artifactId>
<groupId>com.ruoyi</groupId>
<version>4.7.1</version>
<version>4.7.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

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

View File

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

View File

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

View File

@ -157,9 +157,9 @@ public class GenTableServiceImpl implements IGenTableService
* @return 结果
*/
@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
{
// 加载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);
}

View File

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

View File

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

View File

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

View File

@ -126,6 +126,7 @@ public class ${ClassName}Controller extends BaseController
/**
* 修改${functionName}
*/
@RequiresPermissions("${permissionPrefix}:edit")
@GetMapping("/edit/{${pkColumn.javaField}}")
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}主键
* @return 结果
*/
#if($table.sub)
@Transactional
#end
@Override
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
<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>
<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}
where t.${pkColumn.columnName} = #{${pkColumn.javaField}}
#elseif($table.sub)
select#foreach($column in $columns) a.$column.columnName#if($velocityCount != $columns.size()),#end#end,
#foreach($column in $subTable.columns) b.$column.columnName as sub_$column.columnName#if($velocityCount != $subTable.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($foreach.count != $subTable.columns.size()),#end#end
from ${tableName} a
left join ${subTableName} b on b.${subTableFkName} = a.${pkColumn.columnName}
@ -137,9 +137,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</delete>
<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($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>
</insert>
#end

View File

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

View File

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

View File

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

View File

@ -110,30 +110,30 @@ public class JobInvokeUtil
{
return null;
}
String[] methodParams = methodStr.split(",");
String[] methodParams = methodStr.split(",(?=([^\"']*[\"'][^\"']*[\"'])*[^\"']*$)");
List<Object[]> classs = new LinkedList<>();
for (int i = 0; i < methodParams.length; i++)
{
String str = StringUtils.trimToEmpty(methodParams[i]);
// String字符串类型包含'
if (StringUtils.contains(str, "'"))
// String字符串类型以'或"开头
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
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 });
}
// long长整形包含L
else if (StringUtils.containsIgnoreCase(str, "L"))
// long长整形以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
else if (StringUtils.containsIgnoreCase(str, "D"))
// double浮点类型以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

View File

@ -1131,7 +1131,7 @@
<script th:src="@{/js/jquery.min.js}"></script>
<script th:src="@{/js/bootstrap.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:inline="javascript">
var prefix = [[@{/}]] + "monitor/job";

View File

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

View File

@ -1,9 +1,11 @@
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.ToStringStyle;
import com.ruoyi.common.core.domain.BaseEntity;
import com.ruoyi.common.xss.Xss;
/**
* 通知公告表 sys_notice
@ -44,6 +46,7 @@ public class SysNotice extends BaseEntity
this.noticeTitle = noticeTitle;
}
@Xss(message = "公告标题不能包含脚本字符")
@NotBlank(message = "公告标题不能为空")
@Size(min = 0, max = 50, message = "公告标题不能超过50个字符")
public String getNoticeTitle()

View File

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