Переглянути джерело

Merge remote-tracking branch 'origin/master'

cain 5 роки тому
батько
коміт
d1c5ec58df
26 змінених файлів з 302 додано та 78 видалено
  1. 2 2
      README.md
  2. 0 8
      pom.xml
  3. 3 0
      ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysRoleController.java
  4. 4 6
      ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java
  5. 0 0
      ruoyi-admin/src/main/resources/static/ajax/libs/bootstrap-table/bootstrap-table.min.js
  6. 21 12
      ruoyi-admin/src/main/resources/static/ruoyi/js/ry-ui.js
  7. 2 2
      ruoyi-admin/src/main/resources/templates/demo/form/autocomplete.html
  8. 2 2
      ruoyi-admin/src/main/resources/templates/demo/form/datetime.html
  9. 5 0
      ruoyi-admin/src/main/resources/templates/demo/form/duallistbox.html
  10. 2 2
      ruoyi-admin/src/main/resources/templates/demo/form/jasny.html
  11. 2 2
      ruoyi-admin/src/main/resources/templates/demo/form/select.html
  12. 1 1
      ruoyi-admin/src/main/resources/templates/demo/form/upload.html
  13. 1 1
      ruoyi-admin/src/main/resources/templates/demo/form/validate.html
  14. 2 1
      ruoyi-admin/src/main/resources/templates/demo/table/remember.html
  15. 1 1
      ruoyi-admin/src/main/resources/templates/index.html
  16. 0 6
      ruoyi-common/pom.xml
  17. 152 0
      ruoyi-common/src/main/java/com/ruoyi/common/utils/html/EscapeUtil.java
  18. 2 3
      ruoyi-common/src/main/java/com/ruoyi/common/xss/XssHttpServletRequestWrapper.java
  19. 26 19
      ruoyi-framework/src/main/java/com/ruoyi/framework/config/MyBatisConfig.java
  20. 0 1
      ruoyi-framework/src/main/java/com/ruoyi/framework/shiro/realm/UserRealm.java
  21. 20 0
      ruoyi-system/src/main/java/com/ruoyi/system/domain/SysRole.java
  22. 10 0
      ruoyi-system/src/main/java/com/ruoyi/system/domain/SysUser.java
  23. 9 1
      ruoyi-system/src/main/java/com/ruoyi/system/service/ISysRoleService.java
  24. 7 0
      ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserService.java
  25. 14 0
      ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysRoleServiceImpl.java
  26. 14 8
      ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java

+ 2 - 2
README.md

@@ -6,7 +6,7 @@
 
 若依参考后台模板。有需要可自行到群内下载。
 
-> 如需单应用,请移步 [RuoYi-fast](https://gitee.com/y_project/RuoYi-fast)  `(保持同步更新)`,如需其他版本,请移步 [项目扩展](http://doc.ruoyi.vip/#/standard/xmkz)  `(不定时更新)`
+> 如需单应用,请移步 [RuoYi-fast](https://gitee.com/y_project/RuoYi-fast)  `(保持同步更新)`,如需其他版本,请移步 [项目扩展](http://doc.ruoyi.vip/ruoyi/document/xmkz.html)  `(不定时更新)`
 
 > 阿里云通用云产品1888优惠券 :[点我领取](https://promotion.aliyun.com/ntms/yunparter/invite.html?userCode=brki8iof)    腾讯云通用云产品2860优惠券 :[点我领取](https://cloud.tencent.com/redirect.php?redirect=1025&cps_key=198c8df2ed259157187173bc7f4f32fd&from=console)  `(仅限新用户)`
 
@@ -26,7 +26,7 @@
 10. 登录日志:系统登录日志记录查询包含登录异常。
 11. 在线用户:当前系统中活跃用户状态监控。
 12. 定时任务:在线(添加、修改、删除)任务调度包含执行结果日志。
-13. 代码生成:前后端代码的生成(java、html、xml、sql)支持CRUD下载 。
+13. 代码生成:前后端代码的生成(java、html、xml、sql支持CRUD下载 。
 14. 系统接口:根据业务代码自动生成相关的api接口文档。
 15. 服务监控:监视当前系统CPU、内存、磁盘、堆栈等相关信息。
 16. 在线构建器:拖动表单元素生成相应的HTML代码。

+ 0 - 8
pom.xml

@@ -29,7 +29,6 @@
 		<oshi.version>3.9.1</oshi.version>
 		<commons.io.version>2.5</commons.io.version>
 		<commons.fileupload.version>1.3.3</commons.fileupload.version>
-		<jsoup.version>1.11.3</jsoup.version>
 		<poi.version>3.17</poi.version>
 		<velocity.version>1.7</velocity.version>
 	</properties>
@@ -148,13 +147,6 @@
 				<version>${commons.fileupload.version}</version>
 			</dependency>
 			
-			<!-- HTML解析器 -->
-			<dependency>
-				<groupId>org.jsoup</groupId>
-				<artifactId>jsoup</artifactId>
-				<version>${jsoup.version}</version>
-			</dependency>
-			
 			<!-- excel工具 -->
 			<dependency>
 				<groupId>org.apache.poi</groupId>

+ 3 - 0
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysRoleController.java

@@ -121,6 +121,7 @@ public class SysRoleController extends BaseController
     @ResponseBody
     public AjaxResult editSave(@Validated SysRole role)
     {
+        roleService.checkRoleAllowed(role);
         if (UserConstants.ROLE_NAME_NOT_UNIQUE.equals(roleService.checkRoleNameUnique(role)))
         {
             return error("修改角色'" + role.getRoleName() + "'失败,角色名称已存在");
@@ -153,6 +154,7 @@ public class SysRoleController extends BaseController
     @ResponseBody
     public AjaxResult authDataScopeSave(SysRole role)
     {
+        roleService.checkRoleAllowed(role);
         role.setUpdateBy(ShiroUtils.getLoginName());
         if (roleService.authDataScope(role) > 0)
         {
@@ -216,6 +218,7 @@ public class SysRoleController extends BaseController
     @ResponseBody
     public AjaxResult changeStatus(SysRole role)
     {
+        roleService.checkRoleAllowed(role);
         return toAjax(roleService.changeStatus(role));
     }
 

+ 4 - 6
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java

@@ -18,7 +18,6 @@ import com.ruoyi.common.core.controller.BaseController;
 import com.ruoyi.common.core.domain.AjaxResult;
 import com.ruoyi.common.core.page.TableDataInfo;
 import com.ruoyi.common.enums.BusinessType;
-import com.ruoyi.common.utils.StringUtils;
 import com.ruoyi.common.utils.poi.ExcelUtil;
 import com.ruoyi.framework.shiro.service.SysPasswordService;
 import com.ruoyi.framework.util.ShiroUtils;
@@ -159,11 +158,8 @@ public class SysUserController extends BaseController
     @ResponseBody
     public AjaxResult editSave(@Validated SysUser user)
     {
-        if (StringUtils.isNotNull(user.getUserId()) && SysUser.isAdmin(user.getUserId()))
-        {
-            return error("不允许修改超级管理员用户");
-        }
-        else if (UserConstants.USER_PHONE_NOT_UNIQUE.equals(userService.checkPhoneUnique(user)))
+        userService.checkUserAllowed(user);
+        if (UserConstants.USER_PHONE_NOT_UNIQUE.equals(userService.checkPhoneUnique(user)))
         {
             return error("修改用户'" + user.getLoginName() + "'失败,手机号码已存在");
         }
@@ -190,6 +186,7 @@ public class SysUserController extends BaseController
     @ResponseBody
     public AjaxResult resetPwdSave(SysUser user)
     {
+        userService.checkUserAllowed(user);
         user.setSalt(ShiroUtils.randomSalt());
         user.setPassword(passwordService.encryptPassword(user.getLoginName(), user.getPassword(), user.getSalt()));
         if (userService.resetUserPwd(user) > 0)
@@ -258,6 +255,7 @@ public class SysUserController extends BaseController
     @ResponseBody
     public AjaxResult changeStatus(SysUser user)
     {
+        userService.checkUserAllowed(user);
         return toAjax(userService.changeStatus(user));
     }
 }

Різницю між файлами не показано, бо вона завелика
+ 0 - 0
ruoyi-admin/src/main/resources/static/ajax/libs/bootstrap-table/bootstrap-table.min.js


+ 21 - 12
ruoyi-admin/src/main/resources/static/ruoyi/js/ry-ui.js

@@ -139,15 +139,6 @@
             },
             // 初始化事件
             initEvent: function(data) {
-            	// 触发行点击事件 加载成功事件
-            	$.btTable.on("check.bs.table uncheck.bs.table check-all.bs.table uncheck-all.bs.table load-success.bs.table", function () {
-            		// 工具栏按钮控制
-            		var rows = $.common.isEmpty($.table._option.uniqueId) ? $.table.selectFirstColumns() : $.table.selectColumns($.table._option.uniqueId);
-            		// 非多个禁用
-            		$('#' + $.table._option.toolbar + ' .multiple').toggleClass('disabled', !rows.length);
-            		// 非单个禁用
-            		$('#' + $.table._option.toolbar + ' .single').toggleClass('disabled', rows.length!=1);
-            	});
             	// 绑定选中事件、取消事件、全部选中、全部取消
             	$.btTable.on("check.bs.table check-all.bs.table uncheck.bs.table uncheck-all.bs.table", function (e, rows) {
             		// 复选框分页保留保存选中数组
@@ -155,8 +146,18 @@
             		if ($.common.isNotEmpty($.table._option.rememberSelected) && $.table._option.rememberSelected) {
             			func = $.inArray(e.type, ['check', 'check-all']) > -1 ? 'union' : 'difference';
             			selectionIds = _[func](selectionIds, rowIds);
+            			selectionRows = _[func](selectionRows, rows);
             		}
             	});
+            	// 触发行点击事件 加载成功事件
+            	$.btTable.on("check.bs.table uncheck.bs.table check-all.bs.table uncheck-all.bs.table load-success.bs.table", function () {
+            		// 工具栏按钮控制
+            		var rows = $.common.isEmpty($.table._option.uniqueId) ? $.table.selectFirstColumns() : $.table.selectColumns($.table._option.uniqueId);
+            		// 非多个禁用
+            		$('#' + $.table._option.toolbar + ' .multiple').toggleClass('disabled', !rows.length);
+            		// 非单个禁用
+            		$('#' + $.table._option.toolbar + ' .single').toggleClass('disabled', rows.length!=1);
+            	});
             	// 图片预览事件
             	$.btTable.on('click', '.img-circle', function() {
     			    var src = $(this).attr('src');
@@ -365,7 +366,9 @@
         	        return row[column];
         	    });
             	if ($.common.isNotEmpty($.table._option.rememberSelected) && $.table._option.rememberSelected) {
-            		rows = rows.concat(selectionIds);
+            		rows = $.map(selectionRows, function (row) {
+                        return row[column];
+                    });
             	}
             	return $.common.uniqueFn(rows);
             },
@@ -388,7 +391,9 @@
         	        return row[$.table._option.columns[1].field];
         	    });
             	if ($.common.isNotEmpty($.table._option.rememberSelected) && $.table._option.rememberSelected) {
-            		rows = rows.concat(selectionIds);
+            		rows = $.map(selectionRows, function (row) {
+                        return row[$.table._option.columns[1].field];
+                    });
             	}
             	return $.common.uniqueFn(rows);
             },
@@ -1348,7 +1353,11 @@
             formToJSON: function(formId) {
             	 var json = {};
                  $.each($("#" + formId).serializeArray(), function(i, field) {
-                	 json[field.name] = field.value;
+                 	 if(json[field.name]) {
+                         json[field.name] += ("," + field.value);
+					 } else {
+                         json[field.name] = field.value;
+                     }
                  });
             	return json;
             }

+ 2 - 2
ruoyi-admin/src/main/resources/templates/demo/form/autocomplete.html

@@ -99,7 +99,7 @@
                         <hr>
                         <div class="form-group">
                             <label class="font-noraml">相关参数详细信息</label>
-                            <div><a href="http://doc.ruoyi.vip/#/standard/zjwd?id=bootstrap-suggest" target="_blank">http://doc.ruoyi.vip/#/standard/zjwd?id=bootstrap-suggest</a></div>
+                            <div><a href="http://doc.ruoyi.vip/ruoyi/document/zjwd.html#bootstrap-suggest" target="_blank">http://doc.ruoyi.vip/ruoyi/document/zjwd.html#bootstrap-suggest</a></div>
                         </div>
                     </div>
                 </div>
@@ -145,7 +145,7 @@
                         <hr>
                         <div class="form-group">
                             <label class="font-noraml">相关参数详细信息</label>
-                            <div><a href="http://doc.ruoyi.vip/#/standard/zjwd?id=bootstrap-typeahead" target="_blank">http://doc.ruoyi.vip/#/standard/zjwd?id=bootstrap-typeahead</a></div>
+                            <div><a href="http://doc.ruoyi.vip/ruoyi/document/zjwd.html#bootstrap-typeahead" target="_blank">http://doc.ruoyi.vip/ruoyi/document/zjwd.html#bootstrap-typeahead</a></div>
                         </div>
                     </div>
                 </div>

+ 2 - 2
ruoyi-admin/src/main/resources/templates/demo/form/datetime.html

@@ -57,7 +57,7 @@
                         <hr>
                         <div class="form-group">
                             <label class="font-noraml">相关参数详细信息</label>
-                            <div><a href="http://doc.ruoyi.vip/#/standard/zjwd?id=bootstrap-datetimepicker" target="_blank">http://doc.ruoyi.vip/#/standard/zjwd?id=bootstrap-datetimepicker</a></div>
+                            <div><a href="http://doc.ruoyi.vip/ruoyi/document/zjwd.html#bootstrap-datetimepicker" target="_blank">http://doc.ruoyi.vip/ruoyi/document/zjwd.html#bootstrap-datetimepicker</a></div>
                         </div>
                     </div>
                 </div>
@@ -111,7 +111,7 @@
                         <hr>
                         <div class="form-group">
                             <label class="font-noraml">相关参数详细信息</label>
-                            <div><a href="http://doc.ruoyi.vip/#/standard/zjwd?id=laydate" target="_blank">http://doc.ruoyi.vip/#/standard/zjwd?id=laydate</a></div>
+                            <div><a href="http://doc.ruoyi.vip/ruoyi/document/zjwd.html#laydate" target="_blank">http://doc.ruoyi.vip/ruoyi/document/zjwd.html#laydate</a></div>
                         </div>
                     </div>
                 </div>

+ 5 - 0
ruoyi-admin/src/main/resources/templates/demo/form/duallistbox.html

@@ -33,6 +33,11 @@
                                 <option value="12">若依12</option>
                             </select>
                         </form>
+                        <hr>
+                        <div class="form-group">
+                            <label class="font-noraml">相关参数详细信息</label>
+                            <div><a href="http://doc.ruoyi.vip/ruoyi/document/zjwd.html#bootstrap-duallistbox" target="_blank">http://doc.ruoyi.vip/ruoyi/document/zjwd.html#bootstrap-duallistbox</a></div>
+                        </div>
                     </div>
                 </div>
             </div>

+ 2 - 2
ruoyi-admin/src/main/resources/templates/demo/form/jasny.html

@@ -62,7 +62,7 @@
                         <hr>
                         <div class="form-group">
                             <label class="font-noraml">相关参数详细信息</label>
-                            <div><a href="http://doc.ruoyi.vip/#/standard/zjwd?id=jasny-bootstrap" target="_blank">http://doc.ruoyi.vip/#/standard/zjwd?id=jasny-bootstrap</a></div>
+                            <div><a href="http://doc.ruoyi.vip/ruoyi/document/zjwd.html#jasny-bootstrap" target="_blank">http://doc.ruoyi.vip/ruoyi/document/zjwd.html#jasny-bootstrap</a></div>
                         </div>
                     </div>
                 </div>
@@ -105,7 +105,7 @@
                         <hr>
                         <div class="form-group">
                             <label class="font-noraml">相关参数详细信息</label>
-                            <div><a href="http://doc.ruoyi.vip/#/standard/zjwd?id=jasny-bootstrap" target="_blank">http://doc.ruoyi.vip/#/standard/zjwd?id=jasny-bootstrap</a></div>
+                            <div><a href="http://doc.ruoyi.vip/ruoyi/document/zjwd.html#jasny-bootstrap" target="_blank">http://doc.ruoyi.vip/ruoyi/document/zjwd.html#jasny-bootstrap</a></div>
                         </div>
                     </div>
                 </div>

+ 2 - 2
ruoyi-admin/src/main/resources/templates/demo/form/select.html

@@ -69,7 +69,7 @@
                         <hr>
                         <div class="form-group">
                             <label class="font-noraml">相关参数详细信息</label>
-                            <div><a href="http://doc.ruoyi.vip/#/standard/zjwd?id=select2" target="_blank">http://doc.ruoyi.vip/#/standard/zjwd?id=select2</a></div>
+                            <div><a href="http://doc.ruoyi.vip/ruoyi/document/zjwd.html#select2" target="_blank">http://doc.ruoyi.vip/ruoyi/document/zjwd.html#select2</a></div>
                         </div>
                     </div>
                 </div>
@@ -133,7 +133,7 @@
                         <hr>
                         <div class="form-group">
                             <label class="font-noraml">相关参数详细信息</label>
-                            <div><a href="http://doc.ruoyi.vip/#/standard/zjwd?id=bootstrap-select" target="_blank">http://doc.ruoyi.vip/#/standard/zjwd?id=bootstrap-select</a></div>
+                            <div><a href="http://doc.ruoyi.vip/ruoyi/document/zjwd.html#bootstrap-select" target="_blank">http://doc.ruoyi.vip/ruoyi/document/zjwd.html#bootstrap-select</a></div>
                         </div>
                     </div>
                 </div>

+ 1 - 1
ruoyi-admin/src/main/resources/templates/demo/form/upload.html

@@ -29,7 +29,7 @@
                         <hr>
                         <div class="form-group">
                             <label class="font-noraml">相关参数详细信息</label>
-                            <div><a href="http://doc.ruoyi.vip/#/standard/zjwd?id=jasny-bootstrap" target="_blank">http://doc.ruoyi.vip/#/standard/zjwd?id=jasny-bootstrap</a></div>
+                            <div><a href="http://doc.ruoyi.vip/ruoyi/document/zjwd.html#bootstrap-fileinput" target="_blank">http://doc.ruoyi.vip/ruoyi/document/zjwd.html#bootstrap-fileinput</a></div>
                         </div>
                     </div>
                 </div>

+ 1 - 1
ruoyi-admin/src/main/resources/templates/demo/form/validate.html

@@ -71,7 +71,7 @@
                     <div class="ibox-content">
                         <p class="m-t">更多示例请访问官方示例页面:<a href="http://jqueryvalidation.org/files/demo/" target="_blank">查看</a>
                         </p>
-                        <p>中文API可参考:<a href="http://doc.ruoyi.vip/#/standard/zjwd?id=jquery-validate" target="_blank">http://doc.ruoyi.vip/#/standard/zjwd?id=jquery-validate</a>
+                        <p>中文API可参考:<a href="http://doc.ruoyi.vip/ruoyi/document/zjwd.html#jquery-validate" target="_blank">http://doc.ruoyi.vip/ruoyi/document/zjwd.html#jquery-validate</a>
                         </p>
                     </div>
                 </div>

+ 2 - 1
ruoyi-admin/src/main/resources/templates/demo/table/remember.html

@@ -81,7 +81,8 @@
         
         // 选中数据
         function checkItem(){
-        	var arrays = $.table.selectColumns("userId");
+        	// var arrays = $.table.selectColumns("userId");
+        	var arrays = $.table.selectColumns("userCode");
         	alert(arrays);
         }
     </script>

+ 1 - 1
ruoyi-admin/src/main/resources/templates/index.html

@@ -173,7 +173,7 @@
                     </a>
                 </div>
                 <ul class="nav navbar-top-links navbar-right welcome-message">
-				    <li><a title="视频教程" href="http://doc.ruoyi.vip/#/standard/spjc" target="_blank"><i class="fa fa-video-camera"></i> 视频教程</a></li>
+				    <li><a title="视频教程" href="http://doc.ruoyi.vip/ruoyi/document/spjc.html" target="_blank"><i class="fa fa-video-camera"></i> 视频教程</a></li>
                     <li><a title="开发文档" href="http://doc.ruoyi.vip" target="_blank"><i class="fa fa-question-circle"></i> 开发文档</a></li>
 	                <li><a title="全屏显示" href="javascript:void(0)" id="fullScreen"><i class="fa fa-arrows-alt"></i> 全屏显示</a></li>
                     <li class="dropdown user-menu">

+ 0 - 6
ruoyi-common/pom.xml

@@ -77,12 +77,6 @@
 			<artifactId>commons-fileupload</artifactId>
 		</dependency>
 		
-		<!-- HTML解析器 -->
-		<dependency>
-			<groupId>org.jsoup</groupId>
-			<artifactId>jsoup</artifactId>
-		</dependency>
-		
 		<!-- excel工具 -->
 		<dependency>
 			<groupId>org.apache.poi</groupId>

+ 152 - 0
ruoyi-common/src/main/java/com/ruoyi/common/utils/html/EscapeUtil.java

@@ -0,0 +1,152 @@
+package com.ruoyi.common.utils.html;
+
+import com.ruoyi.common.utils.StringUtils;
+
+/**
+ * 转义和反转义工具类
+ * 
+ * @author ruoyi
+ */
+public class EscapeUtil
+{
+    public static final String RE_HTML_MARK = "(<[^<]*?>)|(<[\\s]*?/[^<]*?>)|(<[^<]*?/[\\s]*?>)";
+
+    private static final char[][] TEXT = new char[64][];
+
+    static
+    {
+        for (int i = 0; i < 64; i++)
+        {
+            TEXT[i] = new char[] { (char) i };
+        }
+
+        // special HTML characters
+        TEXT['\''] = "&#039;".toCharArray(); // 单引号
+        TEXT['"'] = "&#34;".toCharArray(); // 单引号
+        TEXT['&'] = "&#38;".toCharArray(); // &符
+        TEXT['<'] = "&#60;".toCharArray(); // 小于号
+        TEXT['>'] = "&#62;".toCharArray(); // 大于号
+    }
+
+    /**
+     * 转义文本中的HTML字符为安全的字符
+     * 
+     * @param text 被转义的文本
+     * @return 转义后的文本
+     */
+    public static String escape(String text)
+    {
+        return encode(text);
+    }
+
+    /**
+     * 还原被转义的HTML特殊字符
+     * 
+     * @param content 包含转义符的HTML内容
+     * @return 转换后的字符串
+     */
+    public static String unescape(String content)
+    {
+        return decode(content);
+    }
+
+    /**
+     * 清除所有HTML标签,但是不删除标签内的内容
+     * 
+     * @param content 文本
+     * @return 清除标签后的文本
+     */
+    public static String clean(String content)
+    {
+        return content.replaceAll(RE_HTML_MARK, "");
+    }
+
+    /**
+     * Escape编码
+     * 
+     * @param text 被编码的文本
+     * @return 编码后的字符
+     */
+    private static String encode(String text)
+    {
+        int len;
+        if ((text == null) || ((len = text.length()) == 0))
+        {
+            return StringUtils.EMPTY;
+        }
+        StringBuilder buffer = new StringBuilder(len + (len >> 2));
+        char c;
+        for (int i = 0; i < len; i++)
+        {
+            c = text.charAt(i);
+            if (c < 64)
+            {
+                buffer.append(TEXT[c]);
+            }
+            else
+            {
+                buffer.append(c);
+            }
+        }
+        return buffer.toString();
+    }
+
+    /**
+     * Escape解码
+     * 
+     * @param content 被转义的内容
+     * @return 解码后的字符串
+     */
+    public static String decode(String content)
+    {
+        if (StringUtils.isEmpty(content))
+        {
+            return content;
+        }
+
+        StringBuilder tmp = new StringBuilder(content.length());
+        int lastPos = 0, pos = 0;
+        char ch;
+        while (lastPos < content.length())
+        {
+            pos = content.indexOf("%", lastPos);
+            if (pos == lastPos)
+            {
+                if (content.charAt(pos + 1) == 'u')
+                {
+                    ch = (char) Integer.parseInt(content.substring(pos + 2, pos + 6), 16);
+                    tmp.append(ch);
+                    lastPos = pos + 6;
+                }
+                else
+                {
+                    ch = (char) Integer.parseInt(content.substring(pos + 1, pos + 3), 16);
+                    tmp.append(ch);
+                    lastPos = pos + 3;
+                }
+            }
+            else
+            {
+                if (pos == -1)
+                {
+                    tmp.append(content.substring(lastPos));
+                    lastPos = content.length();
+                }
+                else
+                {
+                    tmp.append(content.substring(lastPos, pos));
+                    lastPos = pos;
+                }
+            }
+        }
+        return tmp.toString();
+    }
+
+    public static void main(String[] args)
+    {
+        String html = "<script>alert(1);</script>";
+        System.out.println(EscapeUtil.clean(html));
+        System.out.println(EscapeUtil.escape(html));
+        System.out.println(EscapeUtil.unescape(html));
+    }
+}

+ 2 - 3
ruoyi-common/src/main/java/com/ruoyi/common/xss/XssHttpServletRequestWrapper.java

@@ -2,8 +2,7 @@ package com.ruoyi.common.xss;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletRequestWrapper;
-import org.jsoup.Jsoup;
-import org.jsoup.safety.Whitelist;
+import com.ruoyi.common.utils.html.EscapeUtil;
 
 /**
  * XSS过滤处理
@@ -31,7 +30,7 @@ public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper
             for (int i = 0; i < length; i++)
             {
                 // 防xss攻击和过滤前后空格
-                escapseValues[i] = Jsoup.clean(values[i], Whitelist.relaxed()).trim();
+                escapseValues[i] = EscapeUtil.clean(values[i]).trim();
             }
             return escapseValues;
         }

+ 26 - 19
ruoyi-framework/src/main/java/com/ruoyi/framework/config/MyBatisConfig.java

@@ -38,36 +38,43 @@ public class MyBatisConfig
     {
         ResourcePatternResolver resolver = (ResourcePatternResolver) new PathMatchingResourcePatternResolver();
         MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(resolver);
-        typeAliasesPackage = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + ClassUtils.convertClassNameToResourcePath(typeAliasesPackage) + "/" + DEFAULT_RESOURCE_PATTERN;
+        List<String> allResult = new ArrayList<String>();
         try
         {
-            List<String> result = new ArrayList<String>();
-            Resource[] resources = resolver.getResources(typeAliasesPackage);
-            if (resources != null && resources.length > 0)
+            for (String aliasesPackage : typeAliasesPackage.split(","))
             {
-                MetadataReader metadataReader = null;
-                for (Resource resource : resources)
+                List<String> result = new ArrayList<String>();
+                aliasesPackage = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX
+                        + ClassUtils.convertClassNameToResourcePath(aliasesPackage.trim()) + "/" + DEFAULT_RESOURCE_PATTERN;
+                Resource[] resources = resolver.getResources(aliasesPackage);
+                if (resources != null && resources.length > 0)
                 {
-                    if (resource.isReadable())
+                    MetadataReader metadataReader = null;
+                    for (Resource resource : resources)
                     {
-                        metadataReader = metadataReaderFactory.getMetadataReader(resource);
-                        try
+                        if (resource.isReadable())
                         {
-                            result.add(Class.forName(metadataReader.getClassMetadata().getClassName()).getPackage().getName());
-                        }
-                        catch (ClassNotFoundException e)
-                        {
-                            e.printStackTrace();
+                            metadataReader = metadataReaderFactory.getMetadataReader(resource);
+                            try
+                            {
+                                result.add(Class.forName(metadataReader.getClassMetadata().getClassName()).getPackage().getName());
+                            }
+                            catch (ClassNotFoundException e)
+                            {
+                                e.printStackTrace();
+                            }
                         }
                     }
                 }
+                if (result.size() > 0)
+                {
+                    HashSet<String> hashResult = new HashSet<String>(result);
+                    allResult.addAll(hashResult);
+                }
             }
-            if (result.size() > 0)
+            if (allResult.size() > 0)
             {
-                HashSet<String> h = new HashSet<String>(result);
-                result.clear();
-                result.addAll(h);
-                typeAliasesPackage = String.join(",", (String[]) result.toArray(new String[0]));
+                typeAliasesPackage = String.join(",", (String[]) allResult.toArray(new String[0]));
             }
             else
             {

+ 0 - 1
ruoyi-framework/src/main/java/com/ruoyi/framework/shiro/realm/UserRealm.java

@@ -19,7 +19,6 @@ import org.apache.shiro.subject.PrincipalCollection;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
-
 import com.ruoyi.common.exception.user.CaptchaException;
 import com.ruoyi.common.exception.user.RoleBlockedException;
 import com.ruoyi.common.exception.user.UserBlockedException;

+ 20 - 0
ruoyi-system/src/main/java/com/ruoyi/system/domain/SysRole.java

@@ -52,6 +52,16 @@ public class SysRole extends BaseEntity
     /** 部门组(数据权限) */
     private Long[] deptIds;
 
+    public SysRole()
+    {
+
+    }
+
+    public SysRole(Long roleId)
+    {
+        this.roleId = roleId;
+    }
+
     public Long getRoleId()
     {
         return roleId;
@@ -62,6 +72,16 @@ public class SysRole extends BaseEntity
         this.roleId = roleId;
     }
 
+    public boolean isAdmin()
+    {
+        return isAdmin(this.roleId);
+    }
+
+    public static boolean isAdmin(Long roleId)
+    {
+        return roleId != null && 1L == roleId;
+    }
+
     public String getDataScope()
     {
         return dataScope;

+ 10 - 0
ruoyi-system/src/main/java/com/ruoyi/system/domain/SysUser.java

@@ -93,6 +93,16 @@ public class SysUser extends BaseEntity
     /** 岗位组 */
     private Long[] postIds;
 
+    public SysUser()
+    {
+
+    }
+
+    public SysUser(Long userId)
+    {
+        this.userId = userId;
+    }
+
     public Long getUserId()
     {
         return userId;

+ 9 - 1
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysRoleService.java

@@ -108,6 +108,13 @@ public interface ISysRoleService
      */
     public String checkRoleKeyUnique(SysRole role);
 
+    /**
+     * 校验角色是否允许操作
+     * 
+     * @param role 角色信息
+     */
+    public void checkRoleAllowed(SysRole role);
+
     /**
      * 通过角色ID查询角色使用数量
      * 
@@ -123,6 +130,7 @@ public interface ISysRoleService
      * @return 结果
      */
     public int changeStatus(SysRole role);
+
     /**
      * 取消授权用户角色
      * 
@@ -139,7 +147,7 @@ public interface ISysRoleService
      * @return 结果
      */
     public int deleteAuthUsers(Long roleId, String userIds);
-    
+
     /**
      * 批量选择授权用户角色
      * 

+ 7 - 0
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserService.java

@@ -139,6 +139,13 @@ public interface ISysUserService
      */
     public String checkEmailUnique(SysUser user);
 
+    /**
+     * 校验用户是否允许操作
+     * 
+     * @param user 用户信息
+     */
+    public void checkUserAllowed(SysUser user);
+
     /**
      * 根据用户ID查询用户所属角色组
      * 

+ 14 - 0
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysRoleServiceImpl.java

@@ -150,6 +150,7 @@ public class SysRoleServiceImpl implements ISysRoleService
         Long[] roleIds = Convert.toLongArray(ids);
         for (Long roleId : roleIds)
         {
+            checkRoleAllowed(new SysRole(roleId));
             SysRole role = selectRoleById(roleId);
             if (countUserRoleByRoleId(roleId) > 0)
             {
@@ -293,6 +294,19 @@ public class SysRoleServiceImpl implements ISysRoleService
         return UserConstants.ROLE_KEY_UNIQUE;
     }
 
+    /**
+     * 校验角色是否允许操作
+     * 
+     * @param role 角色信息
+     */
+    public void checkRoleAllowed(SysRole role)
+    {
+        if (StringUtils.isNotNull(role.getRoleId()) && role.isAdmin())
+        {
+            throw new BusinessException("不允许操作超级管理员角色");
+        }
+    }
+
     /**
      * 通过角色ID查询角色使用数量
      * 

+ 14 - 8
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java

@@ -167,10 +167,7 @@ public class SysUserServiceImpl implements ISysUserService
         Long[] userIds = Convert.toLongArray(ids);
         for (Long userId : userIds)
         {
-            if (SysUser.isAdmin(userId))
-            {
-                throw new BusinessException("不允许删除超级管理员用户");
-            }
+            checkUserAllowed(new SysUser(userId));
         }
         return userMapper.deleteUserByIds(userIds);
     }
@@ -345,6 +342,19 @@ public class SysUserServiceImpl implements ISysUserService
         return UserConstants.USER_EMAIL_UNIQUE;
     }
 
+    /**
+     * 校验用户是否允许操作
+     * 
+     * @param user 用户信息
+     */
+    public void checkUserAllowed(SysUser user)
+    {
+        if (StringUtils.isNotNull(user.getUserId()) && user.isAdmin())
+        {
+            throw new BusinessException("不允许操作超级管理员用户");
+        }
+    }
+
     /**
      * 查询用户所属角色组
      * 
@@ -465,10 +475,6 @@ public class SysUserServiceImpl implements ISysUserService
     @Override
     public int changeStatus(SysUser user)
     {
-        if (SysUser.isAdmin(user.getUserId()))
-        {
-            throw new BusinessException("不允许修改超级管理员用户");
-        }
         return userMapper.updateUser(user);
     }
 }

Деякі файли не було показано, через те що забагато файлів було змінено