Compare commits
32 Commits
Author | SHA1 | Date | |
---|---|---|---|
4c9c67927b | |||
6f42d2e821 | |||
07cc5dfa51 | |||
22881ccb59 | |||
c44c280b21 | |||
452da5caeb | |||
c78758e32d | |||
4b7e9152c6 | |||
e8e149719a | |||
d2730a187e | |||
068483ac6a | |||
e597cdead4 | |||
25340da2e2 | |||
02375cbe7d | |||
5587d39d42 | |||
ae8f069cbc | |||
d6f7423d59 | |||
2a3981268a | |||
40263f9549 | |||
be8cb965e3 | |||
8a92dc8257 | |||
2cd634a8de | |||
a23af96034 | |||
78abc63c06 | |||
ba9b483472 | |||
a21b875402 | |||
366459e8f3 | |||
7414626137 | |||
9ff9eb30aa | |||
4d6ff66187 | |||
0bc9bd2cfb | |||
7cd98d6dd0 |
48
pom.xml
48
pom.xml
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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")
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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));
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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',
|
||||
|
@ -2,7 +2,7 @@
|
||||
* @update zhixin wen <wenzhixin2010@gmail.com>
|
||||
*/
|
||||
|
||||
const Utils = $.fn.bootstrapTable.utils
|
||||
var Utils = $.fn.bootstrapTable.utils
|
||||
|
||||
function printPageBuilderDefault (table) {
|
||||
return `
|
||||
|
@ -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])$/;
|
||||
|
@ -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 {
|
||||
|
@ -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>
|
||||
|
@ -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树插件 -->
|
||||
|
@ -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>
|
||||
|
@ -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">
|
||||
|
@ -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 = [[@{/}]];
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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"];
|
||||
|
@ -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);
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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()
|
||||
{
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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注入风险");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
27
ruoyi-common/src/main/java/com/ruoyi/common/xss/Xss.java
Normal file
27
ruoyi-common/src/main/java/com/ruoyi/common/xss/Xss.java
Normal 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 {};
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -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>
|
||||
|
||||
|
@ -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>
|
||||
|
||||
<!-- 通用工具-->
|
||||
|
@ -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() + "]");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 预览代码
|
||||
|
@ -72,7 +72,7 @@ public interface IGenTableService
|
||||
* @param sql 创建表语句
|
||||
* @return 结果
|
||||
*/
|
||||
public int createTable(String sql);
|
||||
public boolean createTable(String sql);
|
||||
|
||||
/**
|
||||
* 导入表结构
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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()">
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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})
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
||||
|
@ -7,7 +7,7 @@ import javax.sql.DataSource;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* 定时任务配置
|
||||
* 定时任务配置(单机部署建议删除此类和qrtz数据库表,默认走内存会最高效)
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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";
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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()
|
||||
|
@ -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++;
|
||||
|
Reference in New Issue
Block a user