From c12dc71ecea33d5c23e2ceb32bfc3db68e4198e3 Mon Sep 17 00:00:00 2001
From: 疯狂的狮子li <15040126243@163.com>
Date: 星期三, 23 六月 2021 09:44:04 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/dev'

---
 ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/AsyncService.java                     |   96 
 ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDeptMapper.java                               |    4 
 ruoyi-ui/src/views/demo/demo/index.vue                                                              |    8 
 ruoyi-demo/src/main/java/com/ruoyi/demo/service/impl/TestTreeServiceImpl.java                       |    5 
 ruoyi-common/src/main/java/com/ruoyi/common/utils/ip/AddressUtils.java                              |   83 
 ruoyi-generator/src/main/resources/vm/java/serviceImpl.java.vm                                      |    6 
 ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/impl/SysJobServiceImpl.java                     |  492 ++--
 ruoyi-common/src/main/java/com/ruoyi/common/utils/ServletUtils.java                                 |  208 -
 ruoyi-ui/src/views/system/dict/index.vue                                                            |   10 
 ruoyi-common/src/main/java/com/ruoyi/common/core/mybatisplus/core/BaseMapperPlus.java               |   18 
 ruoyi-ui/package.json                                                                               |    3 
 ruoyi-framework/src/main/java/com/ruoyi/framework/security/handle/AuthenticationEntryPointImpl.java |    6 
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDictDataServiceImpl.java                |    4 
 ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserMapper.java                               |    2 
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDictTypeServiceImpl.java                |    4 
 ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleMapper.java                               |    2 
 ry.sh                                                                                               |    2 
 ruoyi-framework/src/main/java/com/ruoyi/framework/interceptor/RepeatSubmitInterceptor.java          |  111 
 ruoyi-common/src/main/java/com/ruoyi/common/utils/JsonUtils.java                                    |  101 
 ruoyi-demo/src/main/java/com/ruoyi/demo/bo/TestDemoAddBo.java                                       |    6 
 ruoyi-demo/src/main/java/com/ruoyi/demo/domain/TestTree.java                                        |    6 
 ruoyi-framework/src/main/java/com/ruoyi/framework/config/FeignConfig.java                           |    8 
 ruoyi-generator/src/main/resources/vm/vue/index.vue.vm                                              |   14 
 ruoyi-admin/src/main/resources/application.yml                                                      |   22 
 ruoyi-framework/src/main/java/com/ruoyi/framework/config/JacksonConfig.java                         |   50 
 ruoyi-admin/src/main/resources/application-prod.yml                                                 |   36 
 ruoyi-common/src/main/java/com/ruoyi/common/filter/XssHttpServletRequestWrapper.java                |    8 
 ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/ISysJobLogService.java                          |  124 
 ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysConfigMapper.java                             |    2 
 ruoyi-ui/.env.development                                                                           |    3 
 ruoyi-generator/src/main/java/com/ruoyi/generator/service/IGenTableService.java                     |    2 
 ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/TokenService.java                     |    3 
 ruoyi-common/src/main/java/com/ruoyi/common/utils/reflect/ReflectUtils.java                         |  460 ---
 ruoyi-system/src/main/java/com/ruoyi/system/service/ISysNoticeService.java                          |    2 
 ruoyi-admin/src/main/resources/application-dev.yml                                                  |   34 
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysNoticeServiceImpl.java                  |    4 
 ruoyi-ui/src/components/Pagination/index.vue                                                        |    6 
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDeptServiceImpl.java                    |   60 
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CommonController.java                     |    6 
 ruoyi-ui/src/views/index.vue                                                                        |    2 
 ruoyi-common/src/main/java/com/ruoyi/common/utils/file/FileUtils.java                               |   90 
 ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/ISysJobService.java                             |  212 +-
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysLogininforServiceImpl.java              |    9 
 ruoyi-ui/src/layout/components/Settings/index.vue                                                   |   19 
 pom.xml                                                                                             |   71 
 ruoyi-system/src/main/java/com/ruoyi/system/service/ISysPostService.java                            |    2 
 ruoyi-demo/src/main/java/com/ruoyi/demo/service/ITestTreeService.java                               |    2 
 ruoyi-ui/src/views/tool/swagger/index.vue                                                           |   19 
 ruoyi-demo/src/main/java/com/ruoyi/demo/feign/FeignTestService.java                                 |   10 
 ruoyi-demo/src/main/java/com/ruoyi/demo/mapper/TestDemoMapper.java                                  |    5 
 ruoyi-generator/src/main/java/com/ruoyi/generator/service/GenTableServiceImpl.java                  |   41 
 ruoyi-system/src/main/java/com/ruoyi/system/service/ISysConfigService.java                          |    2 
 ruoyi-common/src/main/java/com/ruoyi/common/core/mybatisplus/core/ServicePlusImpl.java              |   90 
 ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java                                 |    5 
 ruoyi-framework/src/main/java/com/ruoyi/framework/config/DruidConfig.java                           |   74 
 ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestBatchController.java                         |   52 
 ruoyi-common/src/main/java/com/ruoyi/common/utils/PageUtils.java                                    |   19 
 ruoyi-framework/src/main/java/com/ruoyi/framework/manager/ShutdownManager.java                      |   54 
 ruoyi-ui/src/permission.js                                                                          |    1 
 ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysNoticeMapper.java                             |    2 
 ruoyi-ui/src/views/monitor/druid/index.vue                                                          |   19 
 ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDeptService.java                            |    2 
 ruoyi-common/src/main/java/com/ruoyi/common/enums/DataSourceType.java                               |   30 
 ruoyi-ui/src/components/DictTag/index.vue                                                           |   51 
 ruoyi-demo/src/main/java/com/ruoyi/demo/domain/TestDemo.java                                        |    8 
 ruoyi-demo/src/main/java/com/ruoyi/demo/vo/TestDemoVo.java                                          |   15 
 ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDictDataMapper.java                           |    2 
 ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserRoleMapper.java                           |   12 
 ruoyi-system/src/main/resources/mapper/system/SysRoleDeptMapper.xml                                 |    7 
 ruoyi-ui/src/assets/styles/ruoyi.scss                                                               |    9 
 ruoyi-ui/src/views/monitor/operlog/index.vue                                                        |   19 
 ruoyi-generator/src/main/resources/vm/java/mapper.java.vm                                           |    5 
 ruoyi-system/src/main/resources/mapper/system/SysRoleMenuMapper.xml                                 |    7 
 ruoyi-system/src/main/java/com/ruoyi/system/service/ISysRoleService.java                            |    2 
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java                    |    8 
 ruoyi-generator/src/main/resources/vm/vue/index-tree.vue.vm                                         | 1094 +++++-----
 ruoyi-demo/src/main/java/com/ruoyi/demo/vo/TestTreeVo.java                                          |    6 
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDeptController.java                    |    2 
 ruoyi-common/src/main/java/com/ruoyi/common/core/controller/BaseController.java                     |   23 
 ruoyi-system/src/main/java/com/ruoyi/system/service/ISysMenuService.java                            |    2 
 ruoyi-ui/src/views/tool/gen/genInfoForm.vue                                                         |    2 
 ruoyi-common/src/main/java/com/ruoyi/common/core/mybatisplus/core/IServicePlus.java                 |   21 
 ruoyi-common/src/main/java/com/ruoyi/common/core/domain/BaseEntity.java                             |    5 
 ruoyi-ui/src/views/system/user/index.vue                                                            |   16 
 ruoyi-generator/src/main/java/com/ruoyi/generator/service/GenTableColumnServiceImpl.java            |    4 
 ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/impl/SysJobLogServiceImpl.java                  |  228 +-
 ruoyi-generator/src/main/resources/vm/java/addBo.java.vm                                            |    4 
 ruoyi-framework/src/main/java/com/ruoyi/framework/config/MybatisPlusConfig.java                     |   21 
 ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java                                           |    5 
 ruoyi-common/src/main/java/com/ruoyi/common/core/mybatisplus/cache/MybatisPlusRedisCache.java       |    2 
 ruoyi-ui/.env.production                                                                            |    3 
 ruoyi-ui/.env.staging                                                                               |    3 
 ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDictTypeMapper.java                           |    2 
 ruoyi-ui/src/main.js                                                                                |    8 
 ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/DataSourceAspect.java                     |   79 
 ruoyi-framework/src/main/java/com/ruoyi/framework/config/AsyncConfig.java                           |   11 
 ruoyi-generator/src/main/java/com/ruoyi/generator/util/GenUtils.java                                |   22 
 ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysLogininforMapper.java                         |    2 
 ruoyi-ui/src/views/system/user/profile/userInfo.vue                                                 |    2 
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysConfigServiceImpl.java                  |    4 
 ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserPostMapper.java                           |   12 
 ruoyi-system/src/main/java/com/ruoyi/system/service/ISysLogininforService.java                      |    2 
 ruoyi-generator/src/main/resources/vm/java/service.java.vm                                          |    4 
 ruoyi-ui/vue.config.js                                                                              |    3 
 ruoyi-ui/src/components/iFrame/index.vue                                                            |   36 
 ruoyi-framework/src/main/java/com/ruoyi/framework/config/FilterConfig.java                          |    2 
 ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisLockController.java                         |   61 
 ruoyi-system/src/main/resources/mapper/system/SysUserRoleMapper.xml                                 |    7 
 ruoyi-quartz/src/main/java/com/ruoyi/quartz/mapper/SysJobLogMapper.java                             |   26 
 README.md                                                                                           |   14 
 ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysPostMapper.java                               |    2 
 ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java                        |   10 
 ruoyi-ui/src/layout/components/Sidebar/Logo.vue                                                     |    4 
 ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDictDataService.java                        |    2 
 ruoyi-generator/src/main/resources/vm/java/editBo.java.vm                                           |    4 
 ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysMenuMapper.java                               |    2 
 ruoyi-quartz/src/main/java/com/ruoyi/quartz/mapper/SysJobMapper.java                                |   26 
 ruoyi-generator/src/main/java/com/ruoyi/generator/mapper/GenTableMapper.java                        |    2 
 ruoyi-system/src/main/java/com/ruoyi/system/service/ISysOperLogService.java                         |    2 
 ruoyi-ui/src/store/modules/settings.js                                                              |   11 
 ruoyi-generator/src/main/resources/vm/java/queryBo.java.vm                                          |    3 
 ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java                  |   20 
 ruoyi-demo/src/main/java/com/ruoyi/demo/service/impl/TestDemoServiceImpl.java                       |    4 
 ruoyi-generator/src/main/java/com/ruoyi/generator/util/VelocityUtils.java                           |   40 
 ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDictTypeService.java                        |    2 
 ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserService.java                            |    2 
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysPostServiceImpl.java                    |    4 
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysOperLogServiceImpl.java                 |    9 
 ruoyi-system/src/main/resources/mapper/system/SysUserPostMapper.xml                                 |    7 
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysMenuServiceImpl.java                    |   56 
 ruoyi-demo/src/main/java/com/ruoyi/demo/service/ITestDemoService.java                               |    3 
 ruoyi-ui/src/views/monitor/logininfor/index.vue                                                     |   19 
 ruoyi-ui/src/views/system/dict/data.vue                                                             |   59 
 ruoyi-common/src/main/java/com/ruoyi/common/utils/spring/SpringUtils.java                           |  179 -
 ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleMenuMapper.java                           |   12 
 ruoyi-framework/src/main/java/com/ruoyi/framework/interceptor/impl/SameUrlDataInterceptor.java      |  259 +-
 ruoyi-generator/src/main/java/com/ruoyi/generator/mapper/GenTableColumnMapper.java                  |    2 
 ruoyi-generator/src/main/resources/vm/java/domain.java.vm                                           |    1 
 ruoyi-ui/src/settings.js                                                                            |    7 
 ruoyi-quartz/src/main/java/com/ruoyi/quartz/controller/SysJobController.java                        |  278 +-
 ruoyi-ui/src/App.vue                                                                                |   10 
 ruoyi-generator/src/main/java/com/ruoyi/generator/service/IGenTableColumnService.java               |    2 
 ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleDeptMapper.java                           |   12 
 ruoyi-common/pom.xml                                                                                |   17 
 /dev/null                                                                                           |  111 -
 ruoyi-demo/src/main/java/com/ruoyi/demo/feign/constant/FeignTestConstant.java                       |    9 
 ruoyi-framework/src/main/java/com/ruoyi/framework/config/ResourcesConfig.java                       |    5 
 ruoyi-framework/src/main/java/com/ruoyi/framework/security/handle/LogoutSuccessHandlerImpl.java     |   55 
 ruoyi-demo/src/main/java/com/ruoyi/demo/mapper/TestTreeMapper.java                                  |    6 
 ruoyi-common/src/main/java/com/ruoyi/common/filter/RepeatedlyRequestWrapper.java                    |  152 
 ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/LogAspect.java                            |   46 
 ruoyi-common/src/main/java/com/ruoyi/common/core/mybatisplus/methods/InsertAll.java                 |   52 
 ruoyi-generator/src/main/resources/vm/java/vo.java.vm                                               |    2 
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysRoleServiceImpl.java                    |    8 
 ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysOperLogMapper.java                            |    2 
 155 files changed, 3,129 insertions(+), 3,127 deletions(-)

diff --git a/README.md b/README.md
index 312f3e1..9c5dbd7 100644
--- a/README.md
+++ b/README.md
@@ -2,6 +2,8 @@
 [![鐮佷簯Gitee](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/badge/star.svg?theme=blue)](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus)
 [![License](https://img.shields.io/badge/License-MIT-blue.svg)](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/blob/master/LICENSE)
 [![浣跨敤IntelliJ IDEA寮�鍙戠淮鎶(https://img.shields.io/badge/IntelliJ%20IDEA-鎻愪緵鏀寔-blue.svg)](https://www.jetbrains.com/?from=RuoYi-Vue-Plus)
+[![JDK-8+](https://img.shields.io/badge/JDK-8-green.svg)]()
+[![JDK-11](https://img.shields.io/badge/JDK-11-green.svg)]()
 
 鍩轰簬 RuoYi-Vue 闆嗘垚 Mybatis-Plus Lombok Hutool 绛変究鎹峰紑鍙戝伐鍏� 閫傞厤閲嶅啓鐩稿叧涓氬姟 渚夸簬寮�鍙� 瀹氭湡涓� RuoYi-Vue 鍚屾
 * 鍓嶇寮�鍙戞鏋� Vue銆丒lement UI
@@ -16,9 +18,15 @@
 * 鐩戞帶妗嗘灦 spring-boot-admin 鍏ㄦ柟浣嶆湇鍔$洃鎺�
 * 鏍¢獙妗嗘灦 validation 澧炲己鎺ュ彛瀹夊叏鎬� 涓ヨ皑鎬�
 * 鏂囨。妗嗘灦 knife4j 缇庡寲鎺ュ彛鏂囨。
+* 搴忓垪鍖栨鏋� 缁熶竴浣跨敤 jackson 楂樻晥鍙潬
 * 浠g爜鐢熸垚鍣� 涓�閿敓鎴愬墠鍚庣浠g爜
+* 澶氭暟鎹簮妗嗘灦 dynamic-datasource 鏀寔涓讳粠涓庡绉嶇被鏁版嵁搴撳紓鏋�
+* Redis瀹㈡埛绔� 閲囩敤 Redisson 鎬ц兘鏇村己
+* 鍒嗗竷寮忛攣 Lock4j 娉ㄨВ閿併�佸伐鍏烽攣 澶氱澶氭牱
 
 ## 鍙傝�冩枃妗�
+
+浣跨敤妗嗘灦鍓嶈浠旂粏闃呰鏂囨。閲嶇偣娉ㄦ剰浜嬮」  
 [鍙傝�冩枃妗� Wiki](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/wikis/pages)
 
 ## 淇敼RuoYi鍔熻兘
@@ -34,7 +42,10 @@
 * 闆嗘垚 Feign 鎺ュ彛鍖栫鐞� Http 璇锋眰(濡備笁鏂硅姹� 鏀粯,鐭俊,鎺ㄩ�佺瓑)
 * 绉婚櫎 鑷甫鏈嶅姟鐩戞帶 鏀逛负 spring-boot-admin 鍏ㄦ柟浣嶇洃鎺�
 * 澧炲姞 demo 妯″潡绀轰緥(缁欎笉浼氬鍔犳ā鍧楃殑灏忎紮浼村仛鍙傝��)
-* 澧炲姞 redisson 鏀寔鍒嗗竷寮忛攣 鍔熻兘鏇村己澶�
+* 澧炲姞 redisson 楂樻�ц兘 Redis 瀹㈡埛绔�
+* 绉婚櫎 fastjson 缁熶竴浣跨敤 jackson 搴忓垪鍖�
+* 闆嗘垚 dynamic-datasource 澶氭暟鎹簮(榛樿鏀寔MySQL,鍏朵粬绉嶇被闇�鑷閫傞厤)
+* 闆嗘垚 Lock4j 瀹炵幇鍒嗗竷寮� 娉ㄨВ閿併�佸伐鍏烽攣 澶氱澶氭牱
 
 ### 浠g爜鏀瑰姩
 
@@ -46,6 +57,7 @@
 * 椤圭洰淇敼涓� maven澶氱幆澧冮厤缃�
 * 椤圭洰閰嶇疆淇敼涓� application.yml 缁熶竴绠$悊
 * 鏁版嵁鏉冮檺淇敼涓� 閫傞厤鏀寔鍗曡〃銆佸琛�
+* 浣跨敤 redisson 瀹炵幇鍒嗗竷寮忛攣娉ㄨВ涓庡伐鍏风被
 * 浣跨敤 redisson 瀹炵幇 spring-cache 鏁村悎
 * 澧炲姞 mybatis-plus 浜岀骇缂撳瓨 redis 瀛樺偍
 
diff --git a/pom.xml b/pom.xml
index 4a73f1e..5fe335a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -14,23 +14,24 @@
 
     <properties>
         <ruoyi-vue-plus.version>2.3.2</ruoyi-vue-plus.version>
-        <spring-boot.version>2.3.11.RELEASE</spring-boot.version>
+        <spring-boot.version>2.4.7</spring-boot.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>
         <druid.version>1.2.6</druid.version>
         <knife4j.version>3.0.2</knife4j.version>
-        <fastjson.version>1.2.76</fastjson.version>
         <poi.version>4.1.2</poi.version>
         <velocity.version>1.7</velocity.version>
         <jwt.version>0.9.1</jwt.version>
         <mybatis-plus.version>3.4.3</mybatis-plus.version>
-        <hutool.version>5.6.5</hutool.version>
-        <feign.version>2.2.6.RELEASE</feign.version>
+        <hutool.version>5.7.2</hutool.version>
+        <feign.version>3.0.3</feign.version>
         <feign-okhttp.version>11.0</feign-okhttp.version>
-        <spring-boot-admin.version>2.3.1</spring-boot-admin.version>
+        <spring-boot-admin.version>2.4.1</spring-boot-admin.version>
         <redisson.version>3.15.2</redisson.version>
+        <lock4j.version>2.2.1</lock4j.version>
+        <datasource.version>3.4.0</datasource.version>
     </properties>
 
     <!-- 渚濊禆澹版槑 -->
@@ -73,18 +74,18 @@
                 <version>${velocity.version}</version>
             </dependency>
 
-            <!-- 闃块噷JSON瑙f瀽鍣� -->
-            <dependency>
-                <groupId>com.alibaba</groupId>
-                <artifactId>fastjson</artifactId>
-                <version>${fastjson.version}</version>
-            </dependency>
-
             <!-- Token鐢熸垚涓庤В鏋�-->
             <dependency>
                 <groupId>io.jsonwebtoken</groupId>
                 <artifactId>jjwt</artifactId>
                 <version>${jwt.version}</version>
+            </dependency>
+
+            <!-- dynamic-datasource 澶氭暟鎹簮-->
+            <dependency>
+                <groupId>com.baomidou</groupId>
+                <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
+                <version>${datasource.version}</version>
             </dependency>
 
             <dependency>
@@ -97,6 +98,7 @@
                 <artifactId>mybatis-plus-extension</artifactId>
                 <version>${mybatis-plus.version}</version>
             </dependency>
+
             <dependency>
                 <groupId>cn.hutool</groupId>
                 <artifactId>hutool-all</artifactId>
@@ -132,7 +134,11 @@
                 <artifactId>redisson-spring-boot-starter</artifactId>
                 <version>${redisson.version}</version>
             </dependency>
-
+            <dependency>
+                <groupId>com.baomidou</groupId>
+                <artifactId>lock4j-redisson-spring-boot-starter</artifactId>
+                <version>${lock4j.version}</version>
+            </dependency>
             <!-- 瀹氭椂浠诲姟-->
             <dependency>
                 <groupId>com.ruoyi</groupId>
@@ -270,6 +276,45 @@
                 <logging.level>warn</logging.level>
             </properties>
         </profile>
+
+        <!-- jdk澶氱増鏈厤缃� -->
+        <profile>
+            <id>jdk8</id>
+            <activation>
+                <activeByDefault>true</activeByDefault>
+                <jdk>1.8</jdk>
+            </activation>
+            <properties>
+                <java.version>1.8</java.version>
+            </properties>
+        </profile>
+        <profile>
+            <id>jdk11</id>
+            <activation>
+                <jdk>11</jdk>
+            </activation>
+            <properties>
+                <java.version>11</java.version>
+                <jaxb.version>3.0.1</jaxb.version>
+            </properties>
+            <dependencyManagement>
+                <dependencies>
+                    <!-- jdk11 缂哄け渚濊禆 jaxb-->
+                    <dependency>
+                        <groupId>com.sun.xml.bind</groupId>
+                        <artifactId>jaxb-impl</artifactId>
+                        <version>${jaxb.version}</version>
+                    </dependency>
+                </dependencies>
+            </dependencyManagement>
+            <dependencies>
+                <!--jaxb-->
+                <dependency>
+                    <groupId>com.sun.xml.bind</groupId>
+                    <artifactId>jaxb-impl</artifactId>
+                </dependency>
+            </dependencies>
+        </profile>
     </profiles>
 
 </project>
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java b/ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java
index 5b55927..3a1a4ae 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java
@@ -2,15 +2,14 @@
 
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
 
 /**
  * 鍚姩绋嬪簭
- * 
+ *
  * @author ruoyi
  */
 
-@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
+@SpringBootApplication
 public class RuoYiApplication
 {
     public static void main(String[] args)
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CommonController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CommonController.java
index 7418a2c..38913f5 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CommonController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CommonController.java
@@ -54,10 +54,10 @@
 
             response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
             FileUtils.setAttachmentResponseHeader(response, realFileName);
-            FileUtils.writeBytes(filePath, response.getOutputStream());
+			FileUtils.writeToStream(filePath, response.getOutputStream());
             if (delete)
             {
-                FileUtils.deleteFile(filePath);
+				FileUtils.del(filePath);
             }
         }
         catch (Exception e)
@@ -111,7 +111,7 @@
             String downloadName = StrUtil.subAfter(downloadPath, "/",true);
             response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
             FileUtils.setAttachmentResponseHeader(response, downloadName);
-            FileUtils.writeBytes(downloadPath, response.getOutputStream());
+            FileUtils.writeToStream(downloadPath, response.getOutputStream());
         }
         catch (Exception e)
         {
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDeptController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDeptController.java
index c3fdf83..ab39319 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDeptController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDeptController.java
@@ -56,7 +56,7 @@
         {
             SysDept d = (SysDept) it.next();
             if (d.getDeptId().intValue() == deptId
-                    || ArrayUtils.contains(StrUtil.split(d.getAncestors(), ","), deptId + ""))
+                    || ArrayUtils.contains(StrUtil.splitToArray(d.getAncestors(), ","), deptId + ""))
             {
                 it.remove();
             }
diff --git a/ruoyi-admin/src/main/resources/application-dev.yml b/ruoyi-admin/src/main/resources/application-dev.yml
index eb54d9c..35901b5 100644
--- a/ruoyi-admin/src/main/resources/application-dev.yml
+++ b/ruoyi-admin/src/main/resources/application-dev.yml
@@ -1,21 +1,27 @@
 # 鏁版嵁婧愰厤缃�
 spring:
+  autoconfigure:
+    exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure
   datasource:
     type: com.alibaba.druid.pool.DruidDataSource
-    driverClassName: com.mysql.cj.jdbc.Driver
+    # 鍔ㄦ�佹暟鎹簮鏂囨。 https://www.kancloud.cn/tracy5546/dynamic-datasource/content
+    dynamic:
+      #璁剧疆榛樿鐨勬暟鎹簮鎴栬�呮暟鎹簮缁�,榛樿鍊煎嵆涓� master
+      primary: master
+      datasource:
+        # 涓诲簱鏁版嵁婧�
+        master:
+          driverClassName: com.mysql.cj.jdbc.Driver
+          url: jdbc:mysql://localhost:3306/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true
+          username: root
+          password: root
+        # 浠庡簱鏁版嵁婧�
+        slave:
+          driverClassName: com.mysql.cj.jdbc.Driver
+          url:
+          username:
+          password:
     druid:
-      # 涓诲簱鏁版嵁婧�
-      master:
-        url: jdbc:mysql://localhost:3306/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true
-        username: root
-        password: root
-      # 浠庡簱鏁版嵁婧�
-      slave:
-        # 浠庢暟鎹簮寮�鍏�/榛樿鍏抽棴
-        enabled: false
-        url:
-        username:
-        password:
       # 鍒濆杩炴帴鏁�
       initialSize: 5
       # 鏈�灏忚繛鎺ユ睜鏁伴噺
@@ -35,6 +41,8 @@
       testWhileIdle: true
       testOnBorrow: false
       testOnReturn: false
+      # 娉ㄦ剰杩欎釜鍊煎拰druid鍘熺敓涓嶄竴鑷达紝榛樿鍚姩浜唖tat
+      filters: stat
       webStatFilter:
         enabled: true
       statViewServlet:
diff --git a/ruoyi-admin/src/main/resources/application-prod.yml b/ruoyi-admin/src/main/resources/application-prod.yml
index 2ebdcbd..35901b5 100644
--- a/ruoyi-admin/src/main/resources/application-prod.yml
+++ b/ruoyi-admin/src/main/resources/application-prod.yml
@@ -1,21 +1,27 @@
 # 鏁版嵁婧愰厤缃�
 spring:
+  autoconfigure:
+    exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure
   datasource:
     type: com.alibaba.druid.pool.DruidDataSource
-    driverClassName: com.mysql.cj.jdbc.Driver
+    # 鍔ㄦ�佹暟鎹簮鏂囨。 https://www.kancloud.cn/tracy5546/dynamic-datasource/content
+    dynamic:
+      #璁剧疆榛樿鐨勬暟鎹簮鎴栬�呮暟鎹簮缁�,榛樿鍊煎嵆涓� master
+      primary: master
+      datasource:
+        # 涓诲簱鏁版嵁婧�
+        master:
+          driverClassName: com.mysql.cj.jdbc.Driver
+          url: jdbc:mysql://localhost:3306/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true
+          username: root
+          password: root
+        # 浠庡簱鏁版嵁婧�
+        slave:
+          driverClassName: com.mysql.cj.jdbc.Driver
+          url:
+          username:
+          password:
     druid:
-      # 涓诲簱鏁版嵁婧�
-      master:
-        url: jdbc:mysql://localhost:3306/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true
-        username: root
-        password: root
-      # 浠庡簱鏁版嵁婧�
-      slave:
-        # 浠庢暟鎹簮寮�鍏�/榛樿鍏抽棴
-        enabled: false
-        url:
-        username:
-        password:
       # 鍒濆杩炴帴鏁�
       initialSize: 5
       # 鏈�灏忚繛鎺ユ睜鏁伴噺
@@ -35,6 +41,8 @@
       testWhileIdle: true
       testOnBorrow: false
       testOnReturn: false
+      # 娉ㄦ剰杩欎釜鍊煎拰druid鍘熺敓涓嶄竴鑷达紝榛樿鍚姩浜唖tat
+      filters: stat
       webStatFilter:
         enabled: true
       statViewServlet:
@@ -58,7 +66,7 @@
   # redis 閰嶇疆
   redis:
     # 鍦板潃
-    host: 192.168.0.222
+    host: localhost
     # 绔彛锛岄粯璁や负6379
     port: 6379
     # 鏁版嵁搴撶储寮�
diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml
index 476a933..e153d19 100644
--- a/ruoyi-admin/src/main/resources/application.yml
+++ b/ruoyi-admin/src/main/resources/application.yml
@@ -11,7 +11,7 @@
   # 鏂囦欢璺緞
   profile: ./ruoyi/uploadPath
   # 鑾峰彇ip鍦板潃寮�鍏�
-  addressEnabled: false
+  addressEnabled: true
 
 captcha:
   # 楠岃瘉鐮佸紑鍏�
@@ -86,6 +86,17 @@
   thymeleaf:
     # 灏嗙郴缁熸ā鏉挎斁缃埌鏈�鍓嶉潰 鍚﹀垯浼氫笌 springboot-admin 椤甸潰鍐茬獊
     template-resolver-order: 1
+  jackson:
+    # 鏃ユ湡鏍煎紡鍖�
+    date-format: yyyy-MM-dd HH:mm:ss
+    serialization:
+      # 鏍煎紡鍖栬緭鍑�
+      indent_output: false
+      # 蹇界暐鏃犳硶杞崲鐨勫璞�
+      fail_on_empty_beans: false
+    deserialization:
+      # 鍏佽瀵硅薄蹇界暐json涓笉瀛樺湪鐨勫睘鎬�
+      fail_on_unknown_properties: false
 
 # token閰嶇疆
 token:
@@ -242,9 +253,16 @@
       enabled: true
   okhttp:
     enabled: true
-  hystrix:
+  circuitbreaker:
     enabled: true
 
+--- # 鍒嗗竷寮忛攣 lock4j 鍏ㄥ眬閰嶇疆
+lock4j:
+  # 鑾峰彇鍒嗗竷寮忛攣瓒呮椂鏃堕棿锛岄粯璁や负 3000 姣
+  acquire-timeout: 3000
+  # 鍒嗗竷寮忛攣鐨勮秴鏃舵椂闂达紝榛樿涓� 30 姣
+  expire: 30000
+
 --- # 瀹氭椂浠诲姟閰嶇疆
 spring:
   quartz:
diff --git a/ruoyi-common/pom.xml b/ruoyi-common/pom.xml
index c6275c2..e2cbd39 100644
--- a/ruoyi-common/pom.xml
+++ b/ruoyi-common/pom.xml
@@ -53,12 +53,6 @@
             <artifactId>jackson-databind</artifactId>
         </dependency>
 
-        <!-- 闃块噷JSON瑙f瀽鍣� -->
-        <dependency>
-            <groupId>com.alibaba</groupId>
-            <artifactId>fastjson</artifactId>
-        </dependency>
-
         <!-- excel宸ュ叿 -->
         <dependency>
             <groupId>org.apache.poi</groupId>
@@ -152,6 +146,17 @@
             <artifactId>redisson-spring-boot-starter</artifactId>
         </dependency>
 
+        <!-- dynamic-datasource 澶氭暟鎹簮-->
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>lock4j-redisson-spring-boot-starter</artifactId>
+        </dependency>
+
     </dependencies>
 
 </project>
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/annotation/RedisLock.java b/ruoyi-common/src/main/java/com/ruoyi/common/annotation/RedisLock.java
deleted file mode 100644
index 7b3c912..0000000
--- a/ruoyi-common/src/main/java/com/ruoyi/common/annotation/RedisLock.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package com.ruoyi.common.annotation;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * 鍒嗗竷寮忛攣锛堟敞瑙fā寮忥紝涓嶆帹鑽愪娇鐢紝鏈�濂界敤閿佺殑宸ュ叿绫伙級
- *
- * @author shenxinquan
- */
-
-@Target({ElementType.METHOD})
-@Retention(RetentionPolicy.RUNTIME)
-public @interface RedisLock {
-
-	/**
-	 * 閿佽繃鏈熸椂闂� 榛樿30绉�
-	 */
-	int expireTime() default 30;
-
-	/**
-	 * 閿乲ey鍊�
-	 */
-	String key() default "redisLockKey";
-}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java b/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java
index 137969a..a871178 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java
@@ -128,6 +128,11 @@
     public static final String RESOURCE_PREFIX = "/profile";
 
 	/**
+	 * RMI 杩滅▼鏂规硶璋冪敤
+	 */
+	public static final String LOOKUP_RMI = "rmi://";
+
+	/**
 	 * 璧勬簮鏄犲皠璺緞 鍓嶇紑
 	 */
 	public static final String REDIS_LOCK_KEY = "redis_lock:";
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/controller/BaseController.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/controller/BaseController.java
index 317b92e..632c0fb 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/core/controller/BaseController.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/controller/BaseController.java
@@ -2,14 +2,8 @@
 
 import cn.hutool.core.util.StrUtil;
 import com.ruoyi.common.core.domain.AjaxResult;
-import com.ruoyi.common.utils.DateUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.springframework.web.bind.WebDataBinder;
-import org.springframework.web.bind.annotation.InitBinder;
-
-import java.beans.PropertyEditorSupport;
-import java.util.Date;
 
 /**
  * web灞傞�氱敤鏁版嵁澶勭悊
@@ -19,23 +13,6 @@
 public class BaseController
 {
     protected final Logger logger = LoggerFactory.getLogger(this.getClass());
-
-    /**
-     * 灏嗗墠鍙颁紶閫掕繃鏉ョ殑鏃ユ湡鏍煎紡鐨勫瓧绗︿覆锛岃嚜鍔ㄨ浆鍖栦负Date绫诲瀷
-     */
-    @InitBinder
-    public void initBinder(WebDataBinder binder)
-    {
-        // Date 绫诲瀷杞崲
-        binder.registerCustomEditor(Date.class, new PropertyEditorSupport()
-        {
-            @Override
-            public void setAsText(String text)
-            {
-                setValue(DateUtils.parseDate(text));
-            }
-        });
-    }
 
     /**
      * 鍝嶅簲杩斿洖缁撴灉
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/BaseEntity.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/BaseEntity.java
index 55655bf..d66686b 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/BaseEntity.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/BaseEntity.java
@@ -1,6 +1,5 @@
 package com.ruoyi.common.core.domain;
 
-import com.fasterxml.jackson.annotation.JsonFormat;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 import lombok.experimental.Accessors;
@@ -12,7 +11,7 @@
 
 /**
  * Entity鍩虹被
- * 
+ *
  * @author ruoyi
  */
 
@@ -30,14 +29,12 @@
     private String createBy;
 
     /** 鍒涘缓鏃堕棿 */
-    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private Date createTime;
 
     /** 鏇存柊鑰� */
     private String updateBy;
 
     /** 鏇存柊鏃堕棿 */
-    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private Date updateTime;
 
     /** 澶囨敞 */
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/mybatisplus/MybatisPlusRedisCache.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/mybatisplus/cache/MybatisPlusRedisCache.java
similarity index 97%
rename from ruoyi-common/src/main/java/com/ruoyi/common/core/mybatisplus/MybatisPlusRedisCache.java
rename to ruoyi-common/src/main/java/com/ruoyi/common/core/mybatisplus/cache/MybatisPlusRedisCache.java
index 6ff6a98..0e21d70 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/core/mybatisplus/MybatisPlusRedisCache.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/mybatisplus/cache/MybatisPlusRedisCache.java
@@ -1,4 +1,4 @@
-package com.ruoyi.common.core.mybatisplus;
+package com.ruoyi.common.core.mybatisplus.cache;
 
 import cn.hutool.extra.spring.SpringUtil;
 import com.ruoyi.common.core.redis.RedisCache;
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/mybatisplus/core/BaseMapperPlus.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/mybatisplus/core/BaseMapperPlus.java
new file mode 100644
index 0000000..cf51c90
--- /dev/null
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/mybatisplus/core/BaseMapperPlus.java
@@ -0,0 +1,18 @@
+package com.ruoyi.common.core.mybatisplus.core;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.Collection;
+
+/**
+ * 鑷畾涔� Mapper 鎺ュ彛, 瀹炵幇 鑷畾涔夋墿灞�
+ *
+ * @author Lion Li
+ * @since 2021-05-13
+ */
+public interface BaseMapperPlus<T> extends BaseMapper<T> {
+
+	int insertAll(@Param("list") Collection<T> batchList);
+
+}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/page/IServicePlus.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/mybatisplus/core/IServicePlus.java
similarity index 92%
rename from ruoyi-common/src/main/java/com/ruoyi/common/core/page/IServicePlus.java
rename to ruoyi-common/src/main/java/com/ruoyi/common/core/mybatisplus/core/IServicePlus.java
index aeaee0b..21b0ecc 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/core/page/IServicePlus.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/mybatisplus/core/IServicePlus.java
@@ -1,9 +1,10 @@
-package com.ruoyi.common.core.page;
+package com.ruoyi.common.core.mybatisplus.core;
 
 import cn.hutool.core.bean.BeanUtil;
 import com.baomidou.mybatisplus.core.conditions.Wrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.service.IService;
+import com.ruoyi.common.core.page.PagePlus;
 
 import java.io.Serializable;
 import java.util.Collection;
@@ -182,7 +183,6 @@
      *
      * @param page         缈婚〉瀵硅薄
      * @param queryWrapper 瀹炰綋瀵硅薄灏佽鎿嶄綔绫�
-     * @param kClass       vo绫诲瀷
      */
     default <K> PagePlus<T, K> pageVo(PagePlus<T, K> page, Wrapper<T> queryWrapper, Class<K> kClass) {
         PagePlus<T, K> result = getBaseMapper().selectPage(page, queryWrapper);
@@ -210,7 +210,6 @@
      * 鏃犳潯浠剁炕椤垫煡璇�
      *
      * @param page   缈婚〉瀵硅薄
-     * @param kClass vo绫诲瀷
      */
     default <K> PagePlus<T, K> pageVo(PagePlus<T, K> page, Class<K> kClass) {
         return pageVo(page, Wrappers.emptyWrapper(), kClass);
@@ -226,5 +225,21 @@
         return pageVo(page, Wrappers.emptyWrapper(), convertor);
     }
 
+	@Override
+	default boolean saveBatch(Collection<T> entityList) {
+		return saveBatch(entityList, DEFAULT_BATCH_SIZE);
+	}
+
+	@Override
+	default boolean saveOrUpdateBatch(Collection<T> entityList) {
+		return saveOrUpdateBatch(entityList, DEFAULT_BATCH_SIZE);
+	}
+
+	@Override
+	default boolean updateBatchById(Collection<T> entityList) {
+		return updateBatchById(entityList, DEFAULT_BATCH_SIZE);
+	}
+
+	boolean saveAll(Collection<T> entityList);
 }
 
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/mybatisplus/core/ServicePlusImpl.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/mybatisplus/core/ServicePlusImpl.java
new file mode 100644
index 0000000..77b9c28
--- /dev/null
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/mybatisplus/core/ServicePlusImpl.java
@@ -0,0 +1,90 @@
+package com.ruoyi.common.core.mybatisplus.core;
+
+import com.baomidou.mybatisplus.core.toolkit.ClassUtils;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.ResolvableType;
+
+import java.util.Collection;
+
+/**
+ * IServicePlus 瀹炵幇绫�
+ *
+ * @author Lion Li
+ */
+@Slf4j
+@SuppressWarnings("unchecked")
+public class ServicePlusImpl<M extends BaseMapperPlus<T>, T> extends ServiceImpl<M, T> implements IServicePlus<T> {
+
+	@Autowired
+	protected M baseMapper;
+
+	@Override
+	public M getBaseMapper() {
+		return baseMapper;
+	}
+
+
+	protected Class<T> entityClass = currentModelClass();
+
+	@Override
+	public Class<T> getEntityClass() {
+		return entityClass;
+	}
+
+	protected Class<T> mapperClass = currentMapperClass();
+
+	@Override
+	protected Class<T> currentMapperClass() {
+		return (Class<T>) this.getResolvableType().as(ServicePlusImpl.class).getGeneric(0).getType();
+	}
+
+	@Override
+	protected Class<T> currentModelClass() {
+		return (Class<T>) this.getResolvableType().as(ServicePlusImpl.class).getGeneric(1).getType();
+	}
+
+	@Override
+	protected ResolvableType getResolvableType() {
+		return ResolvableType.forClass(ClassUtils.getUserClass(getClass()));
+	}
+
+	/**
+	 * 鍗曟潯鎵ц鎬ц兘宸�
+	 *
+	 * {@link #saveAll(Collection)}
+	 */
+	@Deprecated
+	@Override
+	public boolean saveBatch(Collection<T> entityList, int batchSize) {
+		return super.saveBatch(entityList, batchSize);
+	}
+
+	@Override
+	public boolean saveOrUpdate(T entity) {
+		return super.saveOrUpdate(entity);
+	}
+
+	/**
+	 * 鍗曟潯鎵ц鎬ц兘宸�
+	 *
+	 * {@link #saveAll(Collection)}
+	 */
+	@Deprecated
+	@Override
+	public boolean saveOrUpdateBatch(Collection<T> entityList, int batchSize) {
+		return super.saveOrUpdateBatch(entityList, batchSize);
+	}
+
+	@Override
+	public boolean updateBatchById(Collection<T> entityList, int batchSize) {
+		return super.updateBatchById(entityList, batchSize);
+	}
+
+	@Override
+	public boolean saveAll(Collection<T> entityList) {
+		return baseMapper.insertAll(entityList) == entityList.size();
+	}
+
+}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/mybatisplus/methods/InsertAll.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/mybatisplus/methods/InsertAll.java
new file mode 100644
index 0000000..9c8c0f7
--- /dev/null
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/mybatisplus/methods/InsertAll.java
@@ -0,0 +1,52 @@
+package com.ruoyi.common.core.mybatisplus.methods;
+
+import cn.hutool.core.util.StrUtil;
+import org.apache.ibatis.executor.keygen.NoKeyGenerator;
+import org.apache.ibatis.mapping.MappedStatement;
+import org.apache.ibatis.mapping.SqlSource;
+
+import com.baomidou.mybatisplus.core.injector.AbstractMethod;
+import com.baomidou.mybatisplus.core.metadata.TableInfo;
+
+/**
+ * 鍗晄ql鎵归噺鎻掑叆
+ *
+ * @author Lion Li
+ */
+public class InsertAll extends AbstractMethod {
+
+	@Override
+	public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
+		final String sql = "<script>insert into %s %s values %s</script>";
+		final String fieldSql = prepareFieldSql(tableInfo);
+		final String valueSql = prepareValuesSqlForMysqlBatch(tableInfo);
+		final String sqlResult = String.format(sql, tableInfo.getTableName(), fieldSql, valueSql);
+		SqlSource sqlSource = languageDriver.createSqlSource(configuration, sqlResult, modelClass);
+		return this.addInsertMappedStatement(mapperClass, modelClass, "insertAll", sqlSource, new NoKeyGenerator(), null, null);
+	}
+
+	private String prepareFieldSql(TableInfo tableInfo) {
+		StringBuilder fieldSql = new StringBuilder();
+		if (StrUtil.isNotBlank(tableInfo.getKeyColumn())) {
+			fieldSql.append(tableInfo.getKeyColumn()).append(",");
+		}
+		tableInfo.getFieldList().forEach(x -> fieldSql.append(x.getColumn()).append(","));
+		fieldSql.delete(fieldSql.length() - 1, fieldSql.length());
+		fieldSql.insert(0, "(");
+		fieldSql.append(")");
+		return fieldSql.toString();
+	}
+
+	private String prepareValuesSqlForMysqlBatch(TableInfo tableInfo) {
+		final StringBuilder valueSql = new StringBuilder();
+		valueSql.append("<foreach collection=\"list\" item=\"item\" index=\"index\" open=\"(\" separator=\"),(\" close=\")\">");
+		if (StrUtil.isNotBlank(tableInfo.getKeyColumn())) {
+			valueSql.append("#{item.").append(tableInfo.getKeyProperty()).append("},");
+		}
+		tableInfo.getFieldList().forEach(x -> valueSql.append("#{item.").append(x.getProperty()).append("},"));
+		valueSql.delete(valueSql.length() - 1, valueSql.length());
+		valueSql.append("</foreach>");
+		return valueSql.toString();
+	}
+}
+
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/page/BaseMapperPlus.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/page/BaseMapperPlus.java
deleted file mode 100644
index ebba1b7..0000000
--- a/ruoyi-common/src/main/java/com/ruoyi/common/core/page/BaseMapperPlus.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package com.ruoyi.common.core.page;
-
-import com.baomidou.mybatisplus.core.mapper.BaseMapper;
-
-/**
- * 鑷畾涔� Mapper 鎺ュ彛, 瀹炵幇 鑷畾涔夋墿灞�
- *
- * @author Lion Li
- * @since 2021-05-13
- */
-public interface BaseMapperPlus<T> extends BaseMapper<T> {
-}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisLockManager.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisLockManager.java
deleted file mode 100644
index 0688bb1..0000000
--- a/ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisLockManager.java
+++ /dev/null
@@ -1,170 +0,0 @@
-package com.ruoyi.common.core.redis;
-
-import cn.hutool.core.lang.Assert;
-import cn.hutool.core.lang.Validator;
-import cn.hutool.core.util.StrUtil;
-import org.redisson.api.RCountDownLatch;
-import org.redisson.api.RLock;
-import org.redisson.api.RedissonClient;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
-
-import java.util.concurrent.TimeUnit;
-
-/**
- * redis 閿佺鐞嗙被
- *
- * @author shenxinquan
- */
-@Component
-public class RedisLockManager {
-
-	@Autowired
-	private RedissonClient redissonClient;
-
-	/**
-	 * 閫氱敤閿�
-	 */
-	private final static Integer BASE_LOCK = 1;
-
-	/**
-	 * 鍏钩閿�
-	 */
-	private final static Integer FAIR_LOCK = 2;
-
-	/**
-	 * 瀛樻斁褰撳墠绾跨▼鑾峰彇閿佺殑绫诲瀷
-	 */
-	private final ThreadLocal<Integer> threadLocal = new ThreadLocal<>();
-
-	/**
-	 * 鑾峰彇閿�
-	 */
-	private RLock getLock(String key, Integer lockType) {
-		Assert.isTrue(StrUtil.isNotBlank(key), "key涓嶈兘涓虹┖");
-		threadLocal.set(lockType);
-		RLock lock;
-		if (BASE_LOCK.equals(lockType)) {
-			lock = redissonClient.getLock(key);
-		} else if (FAIR_LOCK.equals(lockType)) {
-			lock = redissonClient.getFairLock(key);
-		} else {
-			throw new RuntimeException("閿佷笉瀛樺湪!");
-		}
-		return lock;
-	}
-
-	/**
-	 * 鑾峰彇閿侊紙涓嶇敤璁剧疆瓒呮椂鏃堕棿锛屼竴鐩寸瓑寰咃級
-	 */
-	public boolean getLock(String key) {
-		RLock lock = getLock(key, BASE_LOCK);
-		return lock.tryLock();
-	}
-
-	/**
-	 * 璁剧疆杩囨湡鏃堕棿
-	 *
-	 * @param key
-	 * @param time       杩囨湡鏃堕棿
-	 * @param expireUnit 鏃堕棿鍗曚綅
-	 */
-	public boolean getLock(String key, long time, TimeUnit expireUnit) {
-		Assert.isTrue(time > 0, "杩囨湡鏃堕棿蹇呴』澶т簬0");
-		Assert.isTrue(Validator.isNotEmpty(expireUnit), "鏃堕棿鍗曚綅涓嶈兘涓虹┖");
-		RLock lock = getLock(key, BASE_LOCK);
-		try {
-			return lock.tryLock(time, expireUnit);
-		} catch (InterruptedException e) {
-			e.printStackTrace();
-			return false;
-		}
-	}
-
-	/**
-	 * 璁剧疆杩囨湡鏃堕棿
-	 *
-	 * @param key
-	 * @param waitTime   鑾峰彇閿佺瓑寰呮椂闂�
-	 * @param leaseTime  淇濈暀閿佺殑鏃堕棿
-	 * @param expireUnit 鏃堕棿鍗曚綅
-	 */
-	public boolean getLock(String key, long waitTime, long leaseTime, TimeUnit expireUnit) {
-		Assert.isTrue(waitTime > 0, "鑾峰彇閿佺瓑寰呮椂闂村繀椤诲ぇ浜�0");
-		Assert.isTrue(leaseTime > 0, "淇濈暀閿佺殑鏃堕棿蹇呴』澶т簬0");
-		Assert.isTrue(Validator.isNotEmpty(expireUnit), "鏃堕棿鍗曚綅涓嶈兘涓虹┖");
-		RLock lock = getLock(key, BASE_LOCK);
-		try {
-			return lock.tryLock(waitTime, leaseTime, expireUnit);
-		} catch (InterruptedException e) {
-			e.printStackTrace();
-			return false;
-		}
-	}
-
-
-	/**
-	 * 鑾峰彇璁℃暟鍣ㄩ攣
-	 *
-	 * @param key
-	 * @param count countDownLatch 鐨勬暟閲�
-	 */
-	public RCountDownLatch getCountDownLatch(String key, long count) {
-		Assert.isTrue(count >= 0, "count鏁伴噺蹇呴』澶т簬绛変簬0");
-		RCountDownLatch rCountDownLatch = redissonClient.getCountDownLatch(key);
-		rCountDownLatch.trySetCount(count);
-		return rCountDownLatch;
-	}
-
-	/**
-	 * 鑾峰彇鍏钩閿�
-	 *
-	 * @param key
-	 * @param waitTime   鑾峰彇閿佺瓑寰呮椂闂�
-	 * @param leaseTime  鎸佹湁閿佺殑鏃堕棿
-	 * @param expireUnit 鏃堕棿鍗曚綅
-	 * @return
-	 * @throws InterruptedException
-	 */
-	public boolean getFairLock(String key, long waitTime, long leaseTime, TimeUnit expireUnit) {
-		Assert.isTrue(waitTime > 0, "鑾峰彇閿佺瓑寰呮椂闂村繀椤诲ぇ浜�0");
-		Assert.isTrue(leaseTime > 0, "淇濈暀閿佺殑鏃堕棿蹇呴』澶т簬0");
-		Assert.isTrue(Validator.isNotEmpty(expireUnit), "鏃堕棿鍗曚綅涓嶈兘涓虹┖");
-		RLock lock = getLock(key, FAIR_LOCK);
-		try {
-			return lock.tryLock(waitTime, leaseTime, expireUnit);
-		} catch (InterruptedException e) {
-			e.printStackTrace();
-			return false;
-		}
-	}
-
-	/**
-	 * 鑾峰彇鍏钩閿�
-	 *
-	 * @param key
-	 * @param leaseTime  鎸佹湁閿佺殑鏃堕棿
-	 * @param expireUnit 鏃堕棿鍗曚綅
-	 */
-	public boolean getFairLock(String key, long leaseTime, TimeUnit expireUnit) {
-		Assert.isTrue(leaseTime > 0, "淇濈暀閿佺殑鏃堕棿蹇呴』澶т簬0");
-		Assert.isTrue(Validator.isNotEmpty(expireUnit), "鏃堕棿鍗曚綅涓嶈兘涓虹┖");
-		RLock lock = getLock(key, FAIR_LOCK);
-		try {
-			return lock.tryLock(leaseTime, expireUnit);
-		} catch (InterruptedException e) {
-			e.printStackTrace();
-			return false;
-		}
-	}
-
-	/**
-	 * 閲婃斁閿�(缁熶竴閲婃斁)
-	 */
-	public void unLock(String key) {
-		Integer lockType = threadLocal.get();
-		RLock lock = getLock(key, lockType);
-		lock.unlock();
-		threadLocal.remove();
-	}
-}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/enums/DataSourceType.java b/ruoyi-common/src/main/java/com/ruoyi/common/enums/DataSourceType.java
index 0d945be..d5f5465 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/enums/DataSourceType.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/enums/DataSourceType.java
@@ -1,19 +1,25 @@
 package com.ruoyi.common.enums;
 
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
 /**
  * 鏁版嵁婧�
- * 
- * @author ruoyi
+ *
+ * @author Lion Li
  */
-public enum DataSourceType
-{
-    /**
-     * 涓诲簱
-     */
-    MASTER,
+@AllArgsConstructor
+public enum DataSourceType {
+	/**
+	 * 涓诲簱
+	 */
+	MASTER("master"),
 
-    /**
-     * 浠庡簱
-     */
-    SLAVE
+	/**
+	 * 浠庡簱
+	 */
+	SLAVE("slave");
+
+	@Getter
+	private final String source;
 }
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/filter/RepeatedlyRequestWrapper.java b/ruoyi-common/src/main/java/com/ruoyi/common/filter/RepeatedlyRequestWrapper.java
index caacba6..74659bf 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/filter/RepeatedlyRequestWrapper.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/filter/RepeatedlyRequestWrapper.java
@@ -1,75 +1,77 @@
-package com.ruoyi.common.filter;
-
-import java.io.BufferedReader;
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import javax.servlet.ReadListener;
-import javax.servlet.ServletInputStream;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletRequestWrapper;
-import com.ruoyi.common.utils.http.HttpHelper;
-
-/**
- * 鏋勫缓鍙噸澶嶈鍙杋nputStream鐨剅equest
- * 
- * @author ruoyi
- */
-public class RepeatedlyRequestWrapper extends HttpServletRequestWrapper
-{
-    private final byte[] body;
-
-    public RepeatedlyRequestWrapper(HttpServletRequest request, ServletResponse response) throws IOException
-    {
-        super(request);
-        request.setCharacterEncoding("UTF-8");
-        response.setCharacterEncoding("UTF-8");
-
-        body = HttpHelper.getBodyString(request).getBytes("UTF-8");
-    }
-
-    @Override
-    public BufferedReader getReader() throws IOException
-    {
-        return new BufferedReader(new InputStreamReader(getInputStream()));
-    }
-
-    @Override
-    public ServletInputStream getInputStream() throws IOException
-    {
-        final ByteArrayInputStream bais = new ByteArrayInputStream(body);
-        return new ServletInputStream()
-        {
-            @Override
-            public int read() throws IOException
-            {
-                return bais.read();
-            }
-
-            @Override
-            public int available() throws IOException
-            {
-                return body.length;
-            }
-
-            @Override
-            public boolean isFinished()
-            {
-                return false;
-            }
-
-            @Override
-            public boolean isReady()
-            {
-                return false;
-            }
-
-            @Override
-            public void setReadListener(ReadListener readListener)
-            {
-
-            }
-        };
-    }
-}
+package com.ruoyi.common.filter;
+
+import cn.hutool.core.io.IoUtil;
+
+import javax.servlet.ReadListener;
+import javax.servlet.ServletInputStream;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+
+/**
+ * 鏋勫缓鍙噸澶嶈鍙杋nputStream鐨剅equest
+ *
+ * @author ruoyi
+ */
+public class RepeatedlyRequestWrapper extends HttpServletRequestWrapper
+{
+    private final byte[] body;
+
+    public RepeatedlyRequestWrapper(HttpServletRequest request, ServletResponse response) throws IOException
+    {
+        super(request);
+        request.setCharacterEncoding("UTF-8");
+        response.setCharacterEncoding("UTF-8");
+
+        body = IoUtil.readUtf8(request.getInputStream()).getBytes(StandardCharsets.UTF_8);
+    }
+
+    @Override
+    public BufferedReader getReader() throws IOException
+    {
+        return new BufferedReader(new InputStreamReader(getInputStream()));
+    }
+
+    @Override
+    public ServletInputStream getInputStream() throws IOException
+    {
+        final ByteArrayInputStream bais = new ByteArrayInputStream(body);
+        return new ServletInputStream()
+        {
+            @Override
+            public int read() throws IOException
+            {
+                return bais.read();
+            }
+
+            @Override
+            public int available() throws IOException
+            {
+                return body.length;
+            }
+
+            @Override
+            public boolean isFinished()
+            {
+                return false;
+            }
+
+            @Override
+            public boolean isReady()
+            {
+                return false;
+            }
+
+            @Override
+            public void setReadListener(ReadListener readListener)
+            {
+
+            }
+        };
+    }
+}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/filter/XssHttpServletRequestWrapper.java b/ruoyi-common/src/main/java/com/ruoyi/common/filter/XssHttpServletRequestWrapper.java
index 0170e1d..4d36a92 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/filter/XssHttpServletRequestWrapper.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/filter/XssHttpServletRequestWrapper.java
@@ -1,9 +1,9 @@
 package com.ruoyi.common.filter;
 
+import cn.hutool.core.io.IoUtil;
 import cn.hutool.core.lang.Validator;
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.http.HtmlUtil;
-import org.apache.commons.io.IOUtils;
 import org.springframework.http.HttpHeaders;
 import org.springframework.http.MediaType;
 
@@ -13,6 +13,7 @@
 import javax.servlet.http.HttpServletRequestWrapper;
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
+import java.nio.charset.StandardCharsets;
 
 /**
  * XSS杩囨护澶勭悊
@@ -57,7 +58,7 @@
         }
 
         // 涓虹┖锛岀洿鎺ヨ繑鍥�
-        String json = IOUtils.toString(super.getInputStream(), "utf-8");
+        String json = IoUtil.read(super.getInputStream(), StandardCharsets.UTF_8);
         if (Validator.isEmpty(json))
         {
             return super.getInputStream();
@@ -65,7 +66,8 @@
 
         // xss杩囨护
         json = HtmlUtil.cleanHtmlTag(json).trim();
-        final ByteArrayInputStream bis = new ByteArrayInputStream(json.getBytes("utf-8"));
+
+        final ByteArrayInputStream bis = IoUtil.toStream(json, StandardCharsets.UTF_8);
         return new ServletInputStream()
         {
             @Override
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/JsonUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/JsonUtils.java
new file mode 100644
index 0000000..ae6cc11
--- /dev/null
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/JsonUtils.java
@@ -0,0 +1,101 @@
+package com.ruoyi.common.utils;
+
+import cn.hutool.core.lang.Validator;
+import cn.hutool.core.util.ArrayUtil;
+import cn.hutool.core.util.StrUtil;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * JSON 宸ュ叿绫�
+ *
+ * @author 鑺嬮亾婧愮爜
+ */
+public class JsonUtils {
+
+    private static ObjectMapper objectMapper = new ObjectMapper();
+
+    /**
+     * 鍒濆鍖� objectMapper 灞炴��
+     * <p>
+     * 閫氳繃杩欐牱鐨勬柟寮忥紝浣跨敤 Spring 鍒涘缓鐨� ObjectMapper Bean
+     *
+     * @param objectMapper ObjectMapper 瀵硅薄
+     */
+    public static void init(ObjectMapper objectMapper) {
+        JsonUtils.objectMapper = objectMapper;
+    }
+
+    public static String toJsonString(Object object) {
+		if (Validator.isEmpty(object)) {
+			return null;
+		}
+        try {
+            return objectMapper.writeValueAsString(object);
+        } catch (JsonProcessingException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public static <T> T parseObject(String text, Class<T> clazz) {
+        if (StrUtil.isEmpty(text)) {
+            return null;
+        }
+        try {
+            return objectMapper.readValue(text, clazz);
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public static <T> T parseObject(byte[] bytes, Class<T> clazz) {
+        if (ArrayUtil.isEmpty(bytes)) {
+            return null;
+        }
+        try {
+            return objectMapper.readValue(bytes, clazz);
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public static <T> T parseObject(String text, TypeReference<T> typeReference) {
+		if (StrUtil.isBlank(text)) {
+			return null;
+		}
+        try {
+            return objectMapper.readValue(text, typeReference);
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+	public static <T> Map<String, T> parseMap(String text) {
+		if (StrUtil.isBlank(text)) {
+			return null;
+		}
+		try {
+			return objectMapper.readValue(text, new TypeReference<Map<String, T>>() {});
+		} catch (IOException e) {
+			throw new RuntimeException(e);
+		}
+	}
+
+    public static <T> List<T> parseArray(String text, Class<T> clazz) {
+        if (StrUtil.isEmpty(text)) {
+            return new ArrayList<>();
+        }
+        try {
+            return objectMapper.readValue(text, objectMapper.getTypeFactory().constructCollectionType(List.class, clazz));
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/PageUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/PageUtils.java
index d5b72f7..bb3d3e2 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/PageUtils.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/PageUtils.java
@@ -70,20 +70,31 @@
         return page;
     }
 
+	public static <T> Page<T> buildPage() {
+		return buildPage(null, null);
+	}
+
     /**
      * 鏋勫缓 MP 鏅�氬垎椤靛璞�
      * @param <T> domain 瀹炰綋
      * @return 鍒嗛〉瀵硅薄
      */
-    public static <T> Page<T> buildPage() {
+    public static <T> Page<T> buildPage(String defaultOrderByColumn, String defaultIsAsc) {
         Integer pageNum = ServletUtils.getParameterToInt(PAGE_NUM, DEFAULT_PAGE_NUM);
         Integer pageSize = ServletUtils.getParameterToInt(PAGE_SIZE, DEFAULT_PAGE_SIZE);
-        String orderByColumn = ServletUtils.getParameter(ORDER_BY_COLUMN);
-        String isAsc = ServletUtils.getParameter(IS_ASC);
+        String orderByColumn = ServletUtils.getParameter(ORDER_BY_COLUMN, defaultOrderByColumn);
+        String isAsc = ServletUtils.getParameter(IS_ASC, defaultIsAsc);
+		// 鍏煎鍓嶇鎺掑簭绫诲瀷
+		if ("ascending".equals(isAsc)) {
+			isAsc = "asc";
+		} else if ("descending".equals(isAsc)) {
+			isAsc = "desc";
+		}
         Page<T> page = new Page<>(pageNum, pageSize);
         if (StrUtil.isNotBlank(orderByColumn)) {
             String orderBy = SqlUtil.escapeOrderBySql(orderByColumn);
-            if ("asc".equals(isAsc)) {
+			orderBy = StrUtil.toUnderlineCase(orderBy);
+			if ("asc".equals(isAsc)) {
                 page.addOrder(OrderItem.asc(orderBy));
             } else if ("desc".equals(isAsc)) {
                 page.addOrder(OrderItem.desc(orderBy));
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/ServletUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/ServletUtils.java
index 0535cf2..1594291 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/ServletUtils.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/ServletUtils.java
@@ -2,6 +2,9 @@
 
 import cn.hutool.core.convert.Convert;
 import cn.hutool.core.util.StrUtil;
+import cn.hutool.extra.servlet.ServletUtil;
+import cn.hutool.http.HttpStatus;
+import org.springframework.http.MediaType;
 import org.springframework.web.context.request.RequestAttributes;
 import org.springframework.web.context.request.RequestContextHolder;
 import org.springframework.web.context.request.ServletRequestAttributes;
@@ -10,129 +13,118 @@
 import javax.servlet.http.HttpServletResponse;
 import javax.servlet.http.HttpSession;
 import java.io.IOException;
+import java.nio.charset.StandardCharsets;
 
 /**
  * 瀹㈡埛绔伐鍏风被
- * 
+ *
  * @author ruoyi
  */
-public class ServletUtils
-{
-    /**
-     * 鑾峰彇String鍙傛暟
-     */
-    public static String getParameter(String name)
-    {
-        return getRequest().getParameter(name);
-    }
+public class ServletUtils extends ServletUtil {
+	/**
+	 * 鑾峰彇String鍙傛暟
+	 */
+	public static String getParameter(String name) {
+		return getRequest().getParameter(name);
+	}
 
-    /**
-     * 鑾峰彇String鍙傛暟
-     */
-    public static String getParameter(String name, String defaultValue)
-    {
-        return Convert.toStr(getRequest().getParameter(name), defaultValue);
-    }
+	/**
+	 * 鑾峰彇String鍙傛暟
+	 */
+	public static String getParameter(String name, String defaultValue) {
+		return Convert.toStr(getRequest().getParameter(name), defaultValue);
+	}
 
-    /**
-     * 鑾峰彇Integer鍙傛暟
-     */
-    public static Integer getParameterToInt(String name)
-    {
-        return Convert.toInt(getRequest().getParameter(name));
-    }
+	/**
+	 * 鑾峰彇Integer鍙傛暟
+	 */
+	public static Integer getParameterToInt(String name) {
+		return Convert.toInt(getRequest().getParameter(name));
+	}
 
-    /**
-     * 鑾峰彇Integer鍙傛暟
-     */
-    public static Integer getParameterToInt(String name, Integer defaultValue)
-    {
-        return Convert.toInt(getRequest().getParameter(name), defaultValue);
-    }
+	/**
+	 * 鑾峰彇Integer鍙傛暟
+	 */
+	public static Integer getParameterToInt(String name, Integer defaultValue) {
+		return Convert.toInt(getRequest().getParameter(name), defaultValue);
+	}
 
-    /**
-     * 鑾峰彇request
-     */
-    public static HttpServletRequest getRequest()
-    {
-        return getRequestAttributes().getRequest();
-    }
+	/**
+	 * 鑾峰彇request
+	 */
+	public static HttpServletRequest getRequest() {
+		return getRequestAttributes().getRequest();
+	}
 
-    /**
-     * 鑾峰彇response
-     */
-    public static HttpServletResponse getResponse()
-    {
-        return getRequestAttributes().getResponse();
-    }
+	/**
+	 * 鑾峰彇response
+	 */
+	public static HttpServletResponse getResponse() {
+		return getRequestAttributes().getResponse();
+	}
 
-    /**
-     * 鑾峰彇session
-     */
-    public static HttpSession getSession()
-    {
-        return getRequest().getSession();
-    }
+	/**
+	 * 鑾峰彇session
+	 */
+	public static HttpSession getSession() {
+		return getRequest().getSession();
+	}
 
-    public static ServletRequestAttributes getRequestAttributes()
-    {
-        RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
-        return (ServletRequestAttributes) attributes;
-    }
+	public static ServletRequestAttributes getRequestAttributes() {
+		RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
+		return (ServletRequestAttributes) attributes;
+	}
 
-    /**
-     * 灏嗗瓧绗︿覆娓叉煋鍒板鎴风
-     * 
-     * @param response 娓叉煋瀵硅薄
-     * @param string 寰呮覆鏌撶殑瀛楃涓�
-     * @return null
-     */
-    public static String renderString(HttpServletResponse response, String string)
-    {
-        try
-        {
-            response.setStatus(200);
-            response.setContentType("application/json");
-            response.setCharacterEncoding("utf-8");
-            response.getWriter().print(string);
-        }
-        catch (IOException e)
-        {
-            e.printStackTrace();
-        }
-        return null;
-    }
+	/**
+	 * 灏嗗瓧绗︿覆娓叉煋鍒板鎴风
+	 *
+	 * @param response 娓叉煋瀵硅薄
+	 * @param string   寰呮覆鏌撶殑瀛楃涓�
+	 * @return null
+	 */
+	public static String renderString(HttpServletResponse response, String string) {
+		try {
+			response.setStatus(HttpStatus.HTTP_OK);
+			response.setContentType(MediaType.APPLICATION_JSON_VALUE);
+			response.setCharacterEncoding(StandardCharsets.UTF_8.toString());
+			response.getWriter().print(string);
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+		return null;
+	}
 
-    /**
-     * 鏄惁鏄疉jax寮傛璇锋眰
-     * 
-     * @param request
-     */
-    public static boolean isAjaxRequest(HttpServletRequest request)
-    {
-        String accept = request.getHeader("accept");
-        if (accept != null && accept.indexOf("application/json") != -1)
-        {
-            return true;
-        }
+	/**
+	 * 鏄惁鏄疉jax寮傛璇锋眰
+	 *
+	 * @param request
+	 */
+	public static boolean isAjaxRequest(HttpServletRequest request) {
 
-        String xRequestedWith = request.getHeader("X-Requested-With");
-        if (xRequestedWith != null && xRequestedWith.indexOf("XMLHttpRequest") != -1)
-        {
-            return true;
-        }
+		String accept = request.getHeader("accept");
+		if (accept != null && accept.indexOf("application/json") != -1) {
+			return true;
+		}
 
-        String uri = request.getRequestURI();
-        if (StrUtil.equalsAnyIgnoreCase(uri, ".json", ".xml"))
-        {
-            return true;
-        }
+		String xRequestedWith = request.getHeader("X-Requested-With");
+		if (xRequestedWith != null && xRequestedWith.indexOf("XMLHttpRequest") != -1) {
+			return true;
+		}
 
-        String ajax = request.getParameter("__ajax");
-        if (StrUtil.equalsAnyIgnoreCase(ajax, "json", "xml"))
-        {
-            return true;
-        }
-        return false;
-    }
+		String uri = request.getRequestURI();
+		if (StrUtil.equalsAnyIgnoreCase(uri, ".json", ".xml")) {
+			return true;
+		}
+
+		String ajax = request.getParameter("__ajax");
+		if (StrUtil.equalsAnyIgnoreCase(ajax, "json", "xml")) {
+			return true;
+		}
+		return false;
+	}
+
+	public static String getClientIP() {
+		return getClientIP(getRequest());
+	}
+
 }
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/FileUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/FileUtils.java
index 587b2bf..bc953de 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/FileUtils.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/FileUtils.java
@@ -1,5 +1,6 @@
 package com.ruoyi.common.utils.file;
 
+import cn.hutool.core.io.FileUtil;
 import cn.hutool.core.util.ArrayUtil;
 import cn.hutool.core.util.StrUtil;
 
@@ -11,91 +12,16 @@
 
 /**
  * 鏂囦欢澶勭悊宸ュ叿绫�
- * 
+ *
  * @author ruoyi
  */
-public class FileUtils extends org.apache.commons.io.FileUtils
+public class FileUtils extends FileUtil
 {
     public static String FILENAME_PATTERN = "[a-zA-Z0-9_\\-\\|\\.\\u4e00-\\u9fa5]+";
 
     /**
-     * 杈撳嚭鎸囧畾鏂囦欢鐨刡yte鏁扮粍
-     * 
-     * @param filePath 鏂囦欢璺緞
-     * @param os 杈撳嚭娴�
-     * @return
-     */
-    public static void writeBytes(String filePath, OutputStream os) throws IOException
-    {
-        FileInputStream fis = null;
-        try
-        {
-            File file = new File(filePath);
-            if (!file.exists())
-            {
-                throw new FileNotFoundException(filePath);
-            }
-            fis = new FileInputStream(file);
-            byte[] b = new byte[1024];
-            int length;
-            while ((length = fis.read(b)) > 0)
-            {
-                os.write(b, 0, length);
-            }
-        }
-        catch (IOException e)
-        {
-            throw e;
-        }
-        finally
-        {
-            if (os != null)
-            {
-                try
-                {
-                    os.close();
-                }
-                catch (IOException e1)
-                {
-                    e1.printStackTrace();
-                }
-            }
-            if (fis != null)
-            {
-                try
-                {
-                    fis.close();
-                }
-                catch (IOException e1)
-                {
-                    e1.printStackTrace();
-                }
-            }
-        }
-    }
-
-    /**
-     * 鍒犻櫎鏂囦欢
-     * 
-     * @param filePath 鏂囦欢
-     * @return
-     */
-    public static boolean deleteFile(String filePath)
-    {
-        boolean flag = false;
-        File file = new File(filePath);
-        // 璺緞涓烘枃浠朵笖涓嶄负绌哄垯杩涜鍒犻櫎
-        if (file.isFile() && file.exists())
-        {
-            file.delete();
-            flag = true;
-        }
-        return flag;
-    }
-
-    /**
      * 鏂囦欢鍚嶇О楠岃瘉
-     * 
+     *
      * @param filename 鏂囦欢鍚嶇О
      * @return true 姝e父 false 闈炴硶
      */
@@ -130,7 +56,7 @@
 
     /**
      * 涓嬭浇鏂囦欢鍚嶉噸鏂扮紪鐮�
-     * 
+     *
      * @param request 璇锋眰瀵硅薄
      * @param fileName 鏂囦欢鍚�
      * @return 缂栫爜鍚庣殑鏂囦欢鍚�
@@ -142,7 +68,7 @@
         if (agent.contains("MSIE"))
         {
             // IE娴忚鍣�
-            filename = URLEncoder.encode(filename, "utf-8");
+            filename = URLEncoder.encode(filename, StandardCharsets.UTF_8.toString());
             filename = filename.replace("+", " ");
         }
         else if (agent.contains("Firefox"))
@@ -153,12 +79,12 @@
         else if (agent.contains("Chrome"))
         {
             // google娴忚鍣�
-            filename = URLEncoder.encode(filename, "utf-8");
+            filename = URLEncoder.encode(filename, StandardCharsets.UTF_8.toString());
         }
         else
         {
             // 鍏跺畠娴忚鍣�
-            filename = URLEncoder.encode(filename, "utf-8");
+            filename = URLEncoder.encode(filename, StandardCharsets.UTF_8.toString());
         }
         return filename;
     }
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/http/HttpHelper.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/http/HttpHelper.java
deleted file mode 100644
index 430daf8..0000000
--- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/http/HttpHelper.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package com.ruoyi.common.utils.http;
-
-import cn.hutool.core.exceptions.ExceptionUtil;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.servlet.ServletRequest;
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.nio.charset.Charset;
-
-/**
- * 閫氱敤http宸ュ叿灏佽
- * 
- * @author ruoyi
- */
-public class HttpHelper
-{
-    private static final Logger LOGGER = LoggerFactory.getLogger(HttpHelper.class);
-
-    public static String getBodyString(ServletRequest request)
-    {
-        StringBuilder sb = new StringBuilder();
-        BufferedReader reader = null;
-        try (InputStream inputStream = request.getInputStream())
-        {
-            reader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("UTF-8")));
-            String line = "";
-            while ((line = reader.readLine()) != null)
-            {
-                sb.append(line);
-            }
-        }
-        catch (IOException e)
-        {
-            LOGGER.warn("getBodyString鍑虹幇闂锛�");
-        }
-        finally
-        {
-            if (reader != null)
-            {
-                try
-                {
-                    reader.close();
-                }
-                catch (IOException e)
-                {
-                    LOGGER.error(ExceptionUtil.getMessage(e));
-                }
-            }
-        }
-        return sb.toString();
-    }
-}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/http/HttpUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/http/HttpUtils.java
deleted file mode 100644
index 9aee92e..0000000
--- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/http/HttpUtils.java
+++ /dev/null
@@ -1,262 +0,0 @@
-package com.ruoyi.common.utils.http;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.PrintWriter;
-import java.net.ConnectException;
-import java.net.SocketTimeoutException;
-import java.net.URL;
-import java.net.URLConnection;
-import java.security.cert.X509Certificate;
-import javax.net.ssl.HostnameVerifier;
-import javax.net.ssl.HttpsURLConnection;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLSession;
-import javax.net.ssl.TrustManager;
-import javax.net.ssl.X509TrustManager;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import com.ruoyi.common.constant.Constants;
-
-/**
- * 閫氱敤http鍙戦�佹柟娉�
- * 
- * @author ruoyi
- */
-public class HttpUtils
-{
-    private static final Logger log = LoggerFactory.getLogger(HttpUtils.class);
-
-    /**
-     * 鍚戞寚瀹� URL 鍙戦�丟ET鏂规硶鐨勮姹�
-     *
-     * @param url 鍙戦�佽姹傜殑 URL
-     * @param param 璇锋眰鍙傛暟锛岃姹傚弬鏁板簲璇ユ槸 name1=value1&name2=value2 鐨勫舰寮忋��
-     * @return 鎵�浠h〃杩滅▼璧勬簮鐨勫搷搴旂粨鏋�
-     */
-    public static String sendGet(String url, String param)
-    {
-        return sendGet(url, param, Constants.UTF8);
-    }
-
-    /**
-     * 鍚戞寚瀹� URL 鍙戦�丟ET鏂规硶鐨勮姹�
-     *
-     * @param url 鍙戦�佽姹傜殑 URL
-     * @param param 璇锋眰鍙傛暟锛岃姹傚弬鏁板簲璇ユ槸 name1=value1&name2=value2 鐨勫舰寮忋��
-     * @param contentType 缂栫爜绫诲瀷
-     * @return 鎵�浠h〃杩滅▼璧勬簮鐨勫搷搴旂粨鏋�
-     */
-    public static String sendGet(String url, String param, String contentType)
-    {
-        StringBuilder result = new StringBuilder();
-        BufferedReader in = null;
-        try
-        {
-            String urlNameString = url + "?" + param;
-            log.info("sendGet - {}", urlNameString);
-            URL realUrl = new URL(urlNameString);
-            URLConnection connection = realUrl.openConnection();
-            connection.setRequestProperty("accept", "*/*");
-            connection.setRequestProperty("connection", "Keep-Alive");
-            connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
-            connection.connect();
-            in = new BufferedReader(new InputStreamReader(connection.getInputStream(), contentType));
-            String line;
-            while ((line = in.readLine()) != null)
-            {
-                result.append(line);
-            }
-            log.info("recv - {}", result);
-        }
-        catch (ConnectException e)
-        {
-            log.error("璋冪敤HttpUtils.sendGet ConnectException, url=" + url + ",param=" + param, e);
-        }
-        catch (SocketTimeoutException e)
-        {
-            log.error("璋冪敤HttpUtils.sendGet SocketTimeoutException, url=" + url + ",param=" + param, e);
-        }
-        catch (IOException e)
-        {
-            log.error("璋冪敤HttpUtils.sendGet IOException, url=" + url + ",param=" + param, e);
-        }
-        catch (Exception e)
-        {
-            log.error("璋冪敤HttpsUtil.sendGet Exception, url=" + url + ",param=" + param, e);
-        }
-        finally
-        {
-            try
-            {
-                if (in != null)
-                {
-                    in.close();
-                }
-            }
-            catch (Exception ex)
-            {
-                log.error("璋冪敤in.close Exception, url=" + url + ",param=" + param, ex);
-            }
-        }
-        return result.toString();
-    }
-
-    /**
-     * 鍚戞寚瀹� URL 鍙戦�丳OST鏂规硶鐨勮姹�
-     *
-     * @param url 鍙戦�佽姹傜殑 URL
-     * @param param 璇锋眰鍙傛暟锛岃姹傚弬鏁板簲璇ユ槸 name1=value1&name2=value2 鐨勫舰寮忋��
-     * @return 鎵�浠h〃杩滅▼璧勬簮鐨勫搷搴旂粨鏋�
-     */
-    public static String sendPost(String url, String param)
-    {
-        PrintWriter out = null;
-        BufferedReader in = null;
-        StringBuilder result = new StringBuilder();
-        try
-        {
-            String urlNameString = url;
-            log.info("sendPost - {}", urlNameString);
-            URL realUrl = new URL(urlNameString);
-            URLConnection conn = realUrl.openConnection();
-            conn.setRequestProperty("accept", "*/*");
-            conn.setRequestProperty("connection", "Keep-Alive");
-            conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
-            conn.setRequestProperty("Accept-Charset", "utf-8");
-            conn.setRequestProperty("contentType", "utf-8");
-            conn.setDoOutput(true);
-            conn.setDoInput(true);
-            out = new PrintWriter(conn.getOutputStream());
-            out.print(param);
-            out.flush();
-            in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"));
-            String line;
-            while ((line = in.readLine()) != null)
-            {
-                result.append(line);
-            }
-            log.info("recv - {}", result);
-        }
-        catch (ConnectException e)
-        {
-            log.error("璋冪敤HttpUtils.sendPost ConnectException, url=" + url + ",param=" + param, e);
-        }
-        catch (SocketTimeoutException e)
-        {
-            log.error("璋冪敤HttpUtils.sendPost SocketTimeoutException, url=" + url + ",param=" + param, e);
-        }
-        catch (IOException e)
-        {
-            log.error("璋冪敤HttpUtils.sendPost IOException, url=" + url + ",param=" + param, e);
-        }
-        catch (Exception e)
-        {
-            log.error("璋冪敤HttpsUtil.sendPost Exception, url=" + url + ",param=" + param, e);
-        }
-        finally
-        {
-            try
-            {
-                if (out != null)
-                {
-                    out.close();
-                }
-                if (in != null)
-                {
-                    in.close();
-                }
-            }
-            catch (IOException ex)
-            {
-                log.error("璋冪敤in.close Exception, url=" + url + ",param=" + param, ex);
-            }
-        }
-        return result.toString();
-    }
-
-    public static String sendSSLPost(String url, String param)
-    {
-        StringBuilder result = new StringBuilder();
-        String urlNameString = url + "?" + param;
-        try
-        {
-            log.info("sendSSLPost - {}", urlNameString);
-            SSLContext sc = SSLContext.getInstance("SSL");
-            sc.init(null, new TrustManager[] { new TrustAnyTrustManager() }, new java.security.SecureRandom());
-            URL console = new URL(urlNameString);
-            HttpsURLConnection conn = (HttpsURLConnection) console.openConnection();
-            conn.setRequestProperty("accept", "*/*");
-            conn.setRequestProperty("connection", "Keep-Alive");
-            conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
-            conn.setRequestProperty("Accept-Charset", "utf-8");
-            conn.setRequestProperty("contentType", "utf-8");
-            conn.setDoOutput(true);
-            conn.setDoInput(true);
-
-            conn.setSSLSocketFactory(sc.getSocketFactory());
-            conn.setHostnameVerifier(new TrustAnyHostnameVerifier());
-            conn.connect();
-            InputStream is = conn.getInputStream();
-            BufferedReader br = new BufferedReader(new InputStreamReader(is));
-            String ret = "";
-            while ((ret = br.readLine()) != null)
-            {
-                if (ret != null && !"".equals(ret.trim()))
-                {
-                    result.append(new String(ret.getBytes("ISO-8859-1"), "utf-8"));
-                }
-            }
-            log.info("recv - {}", result);
-            conn.disconnect();
-            br.close();
-        }
-        catch (ConnectException e)
-        {
-            log.error("璋冪敤HttpUtils.sendSSLPost ConnectException, url=" + url + ",param=" + param, e);
-        }
-        catch (SocketTimeoutException e)
-        {
-            log.error("璋冪敤HttpUtils.sendSSLPost SocketTimeoutException, url=" + url + ",param=" + param, e);
-        }
-        catch (IOException e)
-        {
-            log.error("璋冪敤HttpUtils.sendSSLPost IOException, url=" + url + ",param=" + param, e);
-        }
-        catch (Exception e)
-        {
-            log.error("璋冪敤HttpsUtil.sendSSLPost Exception, url=" + url + ",param=" + param, e);
-        }
-        return result.toString();
-    }
-
-    private static class TrustAnyTrustManager implements X509TrustManager
-    {
-        @Override
-        public void checkClientTrusted(X509Certificate[] chain, String authType)
-        {
-        }
-
-        @Override
-        public void checkServerTrusted(X509Certificate[] chain, String authType)
-        {
-        }
-
-        @Override
-        public X509Certificate[] getAcceptedIssuers()
-        {
-            return new X509Certificate[] {};
-        }
-    }
-
-    private static class TrustAnyHostnameVerifier implements HostnameVerifier
-    {
-        @Override
-        public boolean verify(String hostname, SSLSession session)
-        {
-            return true;
-        }
-    }
-}
\ No newline at end of file
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/ip/AddressUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/ip/AddressUtils.java
index 4805d25..d6c262a 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/ip/AddressUtils.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/ip/AddressUtils.java
@@ -1,56 +1,55 @@
 package com.ruoyi.common.utils.ip;
 
+import cn.hutool.core.net.NetUtil;
 import cn.hutool.core.util.StrUtil;
-import com.alibaba.fastjson.JSONObject;
+import cn.hutool.http.HtmlUtil;
+import cn.hutool.http.HttpUtil;
 import com.ruoyi.common.config.RuoYiConfig;
 import com.ruoyi.common.constant.Constants;
-import com.ruoyi.common.utils.http.HttpUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import com.ruoyi.common.utils.JsonUtils;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.Map;
 
 /**
  * 鑾峰彇鍦板潃绫�
- * 
+ *
  * @author ruoyi
  */
-public class AddressUtils
-{
-    private static final Logger log = LoggerFactory.getLogger(AddressUtils.class);
+@Slf4j
+public class AddressUtils {
 
-    // IP鍦板潃鏌ヨ
-    public static final String IP_URL = "http://whois.pconline.com.cn/ipJson.jsp";
+	// IP鍦板潃鏌ヨ
+	public static final String IP_URL = "http://whois.pconline.com.cn/ipJson.jsp";
 
-    // 鏈煡鍦板潃
-    public static final String UNKNOWN = "XX XX";
+	// 鏈煡鍦板潃
+	public static final String UNKNOWN = "XX XX";
 
-    public static String getRealAddressByIP(String ip)
-    {
-        String address = UNKNOWN;
-        // 鍐呯綉涓嶆煡璇�
-        if (IpUtils.internalIp(ip))
-        {
-            return "鍐呯綉IP";
-        }
-        if (RuoYiConfig.isAddressEnabled())
-        {
-            try
-            {
-                String rspStr = HttpUtils.sendGet(IP_URL, "ip=" + ip + "&json=true", Constants.GBK);
-                if (StrUtil.isEmpty(rspStr))
-                {
-                    log.error("鑾峰彇鍦扮悊浣嶇疆寮傚父 {}", ip);
-                    return UNKNOWN;
-                }
-                JSONObject obj = JSONObject.parseObject(rspStr);
-                String region = obj.getString("pro");
-                String city = obj.getString("city");
-                return String.format("%s %s", region, city);
-            }
-            catch (Exception e)
-            {
-                log.error("鑾峰彇鍦扮悊浣嶇疆寮傚父 {}", ip);
-            }
-        }
-        return address;
-    }
+	public static String getRealAddressByIP(String ip) {
+		String address = UNKNOWN;
+		// 鍐呯綉涓嶆煡璇�
+		ip = "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : HtmlUtil.cleanHtmlTag(ip);
+		if (NetUtil.isInnerIP(ip)) {
+			return "鍐呯綉IP";
+		}
+		if (RuoYiConfig.isAddressEnabled()) {
+			try {
+				String rspStr = HttpUtil.createGet(IP_URL)
+					.body("ip=" + ip + "&json=true", Constants.GBK)
+					.execute()
+					.body();
+				if (StrUtil.isEmpty(rspStr)) {
+					log.error("鑾峰彇鍦扮悊浣嶇疆寮傚父 {}", ip);
+					return UNKNOWN;
+				}
+				Map<String, String> obj = JsonUtils.parseMap(rspStr);
+				String region = obj.get("pro");
+				String city = obj.get("city");
+				return String.format("%s %s", region, city);
+			} catch (Exception e) {
+				log.error("鑾峰彇鍦扮悊浣嶇疆寮傚父 {}", ip);
+			}
+		}
+		return address;
+	}
 }
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/ip/IpUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/ip/IpUtils.java
deleted file mode 100644
index c46c69b..0000000
--- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/ip/IpUtils.java
+++ /dev/null
@@ -1,196 +0,0 @@
-package com.ruoyi.common.utils.ip;
-
-import cn.hutool.core.lang.Validator;
-import cn.hutool.http.HtmlUtil;
-
-import javax.servlet.http.HttpServletRequest;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-
-/**
- * 鑾峰彇IP鏂规硶
- * 
- * @author ruoyi
- */
-public class IpUtils
-{
-    public static String getIpAddr(HttpServletRequest request)
-    {
-        if (request == null)
-        {
-            return "unknown";
-        }
-        String ip = request.getHeader("x-forwarded-for");
-        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
-        {
-            ip = request.getHeader("Proxy-Client-IP");
-        }
-        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
-        {
-            ip = request.getHeader("X-Forwarded-For");
-        }
-        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
-        {
-            ip = request.getHeader("WL-Proxy-Client-IP");
-        }
-        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
-        {
-            ip = request.getHeader("X-Real-IP");
-        }
-
-        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
-        {
-            ip = request.getRemoteAddr();
-        }
-        return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : HtmlUtil.cleanHtmlTag(ip);
-    }
-
-    public static boolean internalIp(String ip)
-    {
-        byte[] addr = textToNumericFormatV4(ip);
-        return internalIp(addr) || "127.0.0.1".equals(ip);
-    }
-
-    private static boolean internalIp(byte[] addr)
-    {
-        if (Validator.isNull(addr) || addr.length < 2)
-        {
-            return true;
-        }
-        final byte b0 = addr[0];
-        final byte b1 = addr[1];
-        // 10.x.x.x/8
-        final byte SECTION_1 = 0x0A;
-        // 172.16.x.x/12
-        final byte SECTION_2 = (byte) 0xAC;
-        final byte SECTION_3 = (byte) 0x10;
-        final byte SECTION_4 = (byte) 0x1F;
-        // 192.168.x.x/16
-        final byte SECTION_5 = (byte) 0xC0;
-        final byte SECTION_6 = (byte) 0xA8;
-        switch (b0)
-        {
-            case SECTION_1:
-                return true;
-            case SECTION_2:
-                if (b1 >= SECTION_3 && b1 <= SECTION_4)
-                {
-                    return true;
-                }
-            case SECTION_5:
-                switch (b1)
-                {
-                    case SECTION_6:
-                        return true;
-                }
-            default:
-                return false;
-        }
-    }
-
-    /**
-     * 灏咺Pv4鍦板潃杞崲鎴愬瓧鑺�
-     * 
-     * @param text IPv4鍦板潃
-     * @return byte 瀛楄妭
-     */
-    public static byte[] textToNumericFormatV4(String text)
-    {
-        if (text.length() == 0)
-        {
-            return null;
-        }
-
-        byte[] bytes = new byte[4];
-        String[] elements = text.split("\\.", -1);
-        try
-        {
-            long l;
-            int i;
-            switch (elements.length)
-            {
-                case 1:
-                    l = Long.parseLong(elements[0]);
-                    if ((l < 0L) || (l > 4294967295L)) {
-                        return null;
-                    }
-                    bytes[0] = (byte) (int) (l >> 24 & 0xFF);
-                    bytes[1] = (byte) (int) ((l & 0xFFFFFF) >> 16 & 0xFF);
-                    bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF);
-                    bytes[3] = (byte) (int) (l & 0xFF);
-                    break;
-                case 2:
-                    l = Integer.parseInt(elements[0]);
-                    if ((l < 0L) || (l > 255L)) {
-                        return null;
-                    }
-                    bytes[0] = (byte) (int) (l & 0xFF);
-                    l = Integer.parseInt(elements[1]);
-                    if ((l < 0L) || (l > 16777215L)) {
-                        return null;
-                    }
-                    bytes[1] = (byte) (int) (l >> 16 & 0xFF);
-                    bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF);
-                    bytes[3] = (byte) (int) (l & 0xFF);
-                    break;
-                case 3:
-                    for (i = 0; i < 2; ++i)
-                    {
-                        l = Integer.parseInt(elements[i]);
-                        if ((l < 0L) || (l > 255L)) {
-                            return null;
-                        }
-                        bytes[i] = (byte) (int) (l & 0xFF);
-                    }
-                    l = Integer.parseInt(elements[2]);
-                    if ((l < 0L) || (l > 65535L)) {
-                        return null;
-                    }
-                    bytes[2] = (byte) (int) (l >> 8 & 0xFF);
-                    bytes[3] = (byte) (int) (l & 0xFF);
-                    break;
-                case 4:
-                    for (i = 0; i < 4; ++i)
-                    {
-                        l = Integer.parseInt(elements[i]);
-                        if ((l < 0L) || (l > 255L)) {
-                            return null;
-                        }
-                        bytes[i] = (byte) (int) (l & 0xFF);
-                    }
-                    break;
-                default:
-                    return null;
-            }
-        }
-        catch (NumberFormatException e)
-        {
-            return null;
-        }
-        return bytes;
-    }
-
-    public static String getHostIp()
-    {
-        try
-        {
-            return InetAddress.getLocalHost().getHostAddress();
-        }
-        catch (UnknownHostException e)
-        {
-        }
-        return "127.0.0.1";
-    }
-
-    public static String getHostName()
-    {
-        try
-        {
-            return InetAddress.getLocalHost().getHostName();
-        }
-        catch (UnknownHostException e)
-        {
-        }
-        return "鏈煡";
-    }
-}
\ No newline at end of file
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/reflect/ReflectUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/reflect/ReflectUtils.java
index a3b3a76..c5d17d8 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/reflect/ReflectUtils.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/reflect/ReflectUtils.java
@@ -1,406 +1,54 @@
-package com.ruoyi.common.utils.reflect;
-
-import cn.hutool.core.convert.Convert;
-import com.ruoyi.common.utils.DateUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.lang3.Validate;
-import org.apache.poi.ss.usermodel.DateUtil;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.lang.reflect.*;
-import java.util.Date;
-
-/**
- * 鍙嶅皠宸ュ叿绫�. 鎻愪緵璋冪敤getter/setter鏂规硶, 璁块棶绉佹湁鍙橀噺, 璋冪敤绉佹湁鏂规硶, 鑾峰彇娉涘瀷绫诲瀷Class, 琚獳OP杩囩殑鐪熷疄绫荤瓑宸ュ叿鍑芥暟.
- * 
- * @author ruoyi
- */
-@SuppressWarnings("rawtypes")
-public class ReflectUtils
-{
-    private static final String SETTER_PREFIX = "set";
-
-    private static final String GETTER_PREFIX = "get";
-
-    private static final String CGLIB_CLASS_SEPARATOR = "$$";
-
-    private static Logger logger = LoggerFactory.getLogger(ReflectUtils.class);
-
-    /**
-     * 璋冪敤Getter鏂规硶.
-     * 鏀寔澶氱骇锛屽锛氬璞″悕.瀵硅薄鍚�.鏂规硶
-     */
-    @SuppressWarnings("unchecked")
-    public static <E> E invokeGetter(Object obj, String propertyName)
-    {
-        Object object = obj;
-        for (String name : StringUtils.split(propertyName, "."))
-        {
-            String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(name);
-            object = invokeMethod(object, getterMethodName, new Class[] {}, new Object[] {});
-        }
-        return (E) object;
-    }
-
-    /**
-     * 璋冪敤Setter鏂规硶, 浠呭尮閰嶆柟娉曞悕銆�
-     * 鏀寔澶氱骇锛屽锛氬璞″悕.瀵硅薄鍚�.鏂规硶
-     */
-    public static <E> void invokeSetter(Object obj, String propertyName, E value)
-    {
-        Object object = obj;
-        String[] names = StringUtils.split(propertyName, ".");
-        for (int i = 0; i < names.length; i++)
-        {
-            if (i < names.length - 1)
-            {
-                String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(names[i]);
-                object = invokeMethod(object, getterMethodName, new Class[] {}, new Object[] {});
-            }
-            else
-            {
-                String setterMethodName = SETTER_PREFIX + StringUtils.capitalize(names[i]);
-                invokeMethodByName(object, setterMethodName, new Object[] { value });
-            }
-        }
-    }
-
-    /**
-     * 鐩存帴璇诲彇瀵硅薄灞炴�у��, 鏃犺private/protected淇グ绗�, 涓嶇粡杩噂etter鍑芥暟.
-     */
-    @SuppressWarnings("unchecked")
-    public static <E> E getFieldValue(final Object obj, final String fieldName)
-    {
-        Field field = getAccessibleField(obj, fieldName);
-        if (field == null)
-        {
-            logger.debug("鍦� [" + obj.getClass() + "] 涓紝娌℃湁鎵惧埌 [" + fieldName + "] 瀛楁 ");
-            return null;
-        }
-        E result = null;
-        try
-        {
-            result = (E) field.get(obj);
-        }
-        catch (IllegalAccessException e)
-        {
-            logger.error("涓嶅彲鑳芥姏鍑虹殑寮傚父{}", e.getMessage());
-        }
-        return result;
-    }
-
-    /**
-     * 鐩存帴璁剧疆瀵硅薄灞炴�у��, 鏃犺private/protected淇グ绗�, 涓嶇粡杩噑etter鍑芥暟.
-     */
-    public static <E> void setFieldValue(final Object obj, final String fieldName, final E value)
-    {
-        Field field = getAccessibleField(obj, fieldName);
-        if (field == null)
-        {
-            // throw new IllegalArgumentException("鍦� [" + obj.getClass() + "] 涓紝娌℃湁鎵惧埌 [" + fieldName + "] 瀛楁 ");
-            logger.debug("鍦� [" + obj.getClass() + "] 涓紝娌℃湁鎵惧埌 [" + fieldName + "] 瀛楁 ");
-            return;
-        }
-        try
-        {
-            field.set(obj, value);
-        }
-        catch (IllegalAccessException e)
-        {
-            logger.error("涓嶅彲鑳芥姏鍑虹殑寮傚父: {}", e.getMessage());
-        }
-    }
-
-    /**
-     * 鐩存帴璋冪敤瀵硅薄鏂规硶, 鏃犺private/protected淇グ绗�.
-     * 鐢ㄤ簬涓�娆℃�ц皟鐢ㄧ殑鎯呭喌锛屽惁鍒欏簲浣跨敤getAccessibleMethod()鍑芥暟鑾峰緱Method鍚庡弽澶嶈皟鐢�.
-     * 鍚屾椂鍖归厤鏂规硶鍚�+鍙傛暟绫诲瀷锛�
-     */
-    @SuppressWarnings("unchecked")
-    public static <E> E invokeMethod(final Object obj, final String methodName, final Class<?>[] parameterTypes,
-            final Object[] args)
-    {
-        if (obj == null || methodName == null)
-        {
-            return null;
-        }
-        Method method = getAccessibleMethod(obj, methodName, parameterTypes);
-        if (method == null)
-        {
-            logger.debug("鍦� [" + obj.getClass() + "] 涓紝娌℃湁鎵惧埌 [" + methodName + "] 鏂规硶 ");
-            return null;
-        }
-        try
-        {
-            return (E) method.invoke(obj, args);
-        }
-        catch (Exception e)
-        {
-            String msg = "method: " + method + ", obj: " + obj + ", args: " + args + "";
-            throw convertReflectionExceptionToUnchecked(msg, e);
-        }
-    }
-
-    /**
-     * 鐩存帴璋冪敤瀵硅薄鏂规硶, 鏃犺private/protected淇グ绗︼紝
-     * 鐢ㄤ簬涓�娆℃�ц皟鐢ㄧ殑鎯呭喌锛屽惁鍒欏簲浣跨敤getAccessibleMethodByName()鍑芥暟鑾峰緱Method鍚庡弽澶嶈皟鐢�.
-     * 鍙尮閰嶅嚱鏁板悕锛屽鏋滄湁澶氫釜鍚屽悕鍑芥暟璋冪敤绗竴涓��
-     */
-    @SuppressWarnings("unchecked")
-    public static <E> E invokeMethodByName(final Object obj, final String methodName, final Object[] args)
-    {
-        Method method = getAccessibleMethodByName(obj, methodName, args.length);
-        if (method == null)
-        {
-            // 濡傛灉涓虹┖涓嶆姤閿欙紝鐩存帴杩斿洖绌恒��
-            logger.debug("鍦� [" + obj.getClass() + "] 涓紝娌℃湁鎵惧埌 [" + methodName + "] 鏂规硶 ");
-            return null;
-        }
-        try
-        {
-            // 绫诲瀷杞崲锛堝皢鍙傛暟鏁版嵁绫诲瀷杞崲涓虹洰鏍囨柟娉曞弬鏁扮被鍨嬶級
-            Class<?>[] cs = method.getParameterTypes();
-            for (int i = 0; i < cs.length; i++)
-            {
-                if (args[i] != null && !args[i].getClass().equals(cs[i]))
-                {
-                    if (cs[i] == String.class)
-                    {
-                        args[i] = Convert.toStr(args[i]);
-                        if (StringUtils.endsWith((String) args[i], ".0"))
-                        {
-                            args[i] = StringUtils.substringBefore((String) args[i], ".0");
-                        }
-                    }
-                    else if (cs[i] == Integer.class)
-                    {
-                        args[i] = Convert.toInt(args[i]);
-                    }
-                    else if (cs[i] == Long.class)
-                    {
-                        args[i] = Convert.toLong(args[i]);
-                    }
-                    else if (cs[i] == Double.class)
-                    {
-                        args[i] = Convert.toDouble(args[i]);
-                    }
-                    else if (cs[i] == Float.class)
-                    {
-                        args[i] = Convert.toFloat(args[i]);
-                    }
-                    else if (cs[i] == Date.class)
-                    {
-                        if (args[i] instanceof String)
-                        {
-                            args[i] = DateUtils.parseDate(args[i]);
-                        }
-                        else
-                        {
-                            args[i] = DateUtil.getJavaDate((Double) args[i]);
-                        }
-                    }
-                    else if (cs[i] == boolean.class || cs[i] == Boolean.class)
-                    {
-                        args[i] = Convert.toBool(args[i]);
-                    }
-                }
-            }
-            return (E) method.invoke(obj, args);
-        }
-        catch (Exception e)
-        {
-            String msg = "method: " + method + ", obj: " + obj + ", args: " + args + "";
-            throw convertReflectionExceptionToUnchecked(msg, e);
-        }
-    }
-
-    /**
-     * 寰幆鍚戜笂杞瀷, 鑾峰彇瀵硅薄鐨凞eclaredField, 骞跺己鍒惰缃负鍙闂�.
-     * 濡傚悜涓婅浆鍨嬪埌Object浠嶆棤娉曟壘鍒�, 杩斿洖null.
-     */
-    public static Field getAccessibleField(final Object obj, final String fieldName)
-    {
-        // 涓虹┖涓嶆姤閿欍�傜洿鎺ヨ繑鍥� null
-        if (obj == null)
-        {
-            return null;
-        }
-        Validate.notBlank(fieldName, "fieldName can't be blank");
-        for (Class<?> superClass = obj.getClass(); superClass != Object.class; superClass = superClass.getSuperclass())
-        {
-            try
-            {
-                Field field = superClass.getDeclaredField(fieldName);
-                makeAccessible(field);
-                return field;
-            }
-            catch (NoSuchFieldException e)
-            {
-                continue;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * 寰幆鍚戜笂杞瀷, 鑾峰彇瀵硅薄鐨凞eclaredMethod,骞跺己鍒惰缃负鍙闂�.
-     * 濡傚悜涓婅浆鍨嬪埌Object浠嶆棤娉曟壘鍒�, 杩斿洖null.
-     * 鍖归厤鍑芥暟鍚�+鍙傛暟绫诲瀷銆�
-     * 鐢ㄤ簬鏂规硶闇�瑕佽澶氭璋冪敤鐨勬儏鍐�. 鍏堜娇鐢ㄦ湰鍑芥暟鍏堝彇寰桵ethod,鐒跺悗璋冪敤Method.invoke(Object obj, Object... args)
-     */
-    public static Method getAccessibleMethod(final Object obj, final String methodName,
-            final Class<?>... parameterTypes)
-    {
-        // 涓虹┖涓嶆姤閿欍�傜洿鎺ヨ繑鍥� null
-        if (obj == null)
-        {
-            return null;
-        }
-        Validate.notBlank(methodName, "methodName can't be blank");
-        for (Class<?> searchType = obj.getClass(); searchType != Object.class; searchType = searchType.getSuperclass())
-        {
-            try
-            {
-                Method method = searchType.getDeclaredMethod(methodName, parameterTypes);
-                makeAccessible(method);
-                return method;
-            }
-            catch (NoSuchMethodException e)
-            {
-                continue;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * 寰幆鍚戜笂杞瀷, 鑾峰彇瀵硅薄鐨凞eclaredMethod,骞跺己鍒惰缃负鍙闂�.
-     * 濡傚悜涓婅浆鍨嬪埌Object浠嶆棤娉曟壘鍒�, 杩斿洖null.
-     * 鍙尮閰嶅嚱鏁板悕銆�
-     * 鐢ㄤ簬鏂规硶闇�瑕佽澶氭璋冪敤鐨勬儏鍐�. 鍏堜娇鐢ㄦ湰鍑芥暟鍏堝彇寰桵ethod,鐒跺悗璋冪敤Method.invoke(Object obj, Object... args)
-     */
-    public static Method getAccessibleMethodByName(final Object obj, final String methodName, int argsNum)
-    {
-        // 涓虹┖涓嶆姤閿欍�傜洿鎺ヨ繑鍥� null
-        if (obj == null)
-        {
-            return null;
-        }
-        Validate.notBlank(methodName, "methodName can't be blank");
-        for (Class<?> searchType = obj.getClass(); searchType != Object.class; searchType = searchType.getSuperclass())
-        {
-            Method[] methods = searchType.getDeclaredMethods();
-            for (Method method : methods)
-            {
-                if (method.getName().equals(methodName) && method.getParameterTypes().length == argsNum)
-                {
-                    makeAccessible(method);
-                    return method;
-                }
-            }
-        }
-        return null;
-    }
-
-    /**
-     * 鏀瑰彉private/protected鐨勬柟娉曚负public锛屽敖閲忎笉璋冪敤瀹為檯鏀瑰姩鐨勮鍙ワ紝閬垮厤JDK鐨凷ecurityManager鎶辨�ㄣ��
-     */
-    public static void makeAccessible(Method method)
-    {
-        if ((!Modifier.isPublic(method.getModifiers()) || !Modifier.isPublic(method.getDeclaringClass().getModifiers()))
-                && !method.isAccessible())
-        {
-            method.setAccessible(true);
-        }
-    }
-
-    /**
-     * 鏀瑰彉private/protected鐨勬垚鍛樺彉閲忎负public锛屽敖閲忎笉璋冪敤瀹為檯鏀瑰姩鐨勮鍙ワ紝閬垮厤JDK鐨凷ecurityManager鎶辨�ㄣ��
-     */
-    public static void makeAccessible(Field field)
-    {
-        if ((!Modifier.isPublic(field.getModifiers()) || !Modifier.isPublic(field.getDeclaringClass().getModifiers())
-                || Modifier.isFinal(field.getModifiers())) && !field.isAccessible())
-        {
-            field.setAccessible(true);
-        }
-    }
-
-    /**
-     * 閫氳繃鍙嶅皠, 鑾峰緱Class瀹氫箟涓0鏄庣殑娉涘瀷鍙傛暟鐨勭被鍨�, 娉ㄦ剰娉涘瀷蹇呴』瀹氫箟鍦ㄧ埗绫诲
-     * 濡傛棤娉曟壘鍒�, 杩斿洖Object.class.
-     */
-    @SuppressWarnings("unchecked")
-    public static <T> Class<T> getClassGenricType(final Class clazz)
-    {
-        return getClassGenricType(clazz, 0);
-    }
-
-    /**
-     * 閫氳繃鍙嶅皠, 鑾峰緱Class瀹氫箟涓0鏄庣殑鐖剁被鐨勬硾鍨嬪弬鏁扮殑绫诲瀷.
-     * 濡傛棤娉曟壘鍒�, 杩斿洖Object.class.
-     */
-    public static Class getClassGenricType(final Class clazz, final int index)
-    {
-        Type genType = clazz.getGenericSuperclass();
-
-        if (!(genType instanceof ParameterizedType))
-        {
-            logger.debug(clazz.getSimpleName() + "'s superclass not ParameterizedType");
-            return Object.class;
-        }
-
-        Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
-
-        if (index >= params.length || index < 0)
-        {
-            logger.debug("Index: " + index + ", Size of " + clazz.getSimpleName() + "'s Parameterized Type: "
-                    + params.length);
-            return Object.class;
-        }
-        if (!(params[index] instanceof Class))
-        {
-            logger.debug(clazz.getSimpleName() + " not set the actual class on superclass generic parameter");
-            return Object.class;
-        }
-
-        return (Class) params[index];
-    }
-
-    public static Class<?> getUserClass(Object instance)
-    {
-        if (instance == null)
-        {
-            throw new RuntimeException("Instance must not be null");
-        }
-        Class clazz = instance.getClass();
-        if (clazz != null && clazz.getName().contains(CGLIB_CLASS_SEPARATOR))
-        {
-            Class<?> superClass = clazz.getSuperclass();
-            if (superClass != null && !Object.class.equals(superClass))
-            {
-                return superClass;
-            }
-        }
-        return clazz;
-
-    }
-
-    /**
-     * 灏嗗弽灏勬椂鐨刢hecked exception杞崲涓簎nchecked exception.
-     */
-    public static RuntimeException convertReflectionExceptionToUnchecked(String msg, Exception e)
-    {
-        if (e instanceof IllegalAccessException || e instanceof IllegalArgumentException
-                || e instanceof NoSuchMethodException)
-        {
-            return new IllegalArgumentException(msg, e);
-        }
-        else if (e instanceof InvocationTargetException)
-        {
-            return new RuntimeException(msg, ((InvocationTargetException) e).getTargetException());
-        }
-        return new RuntimeException(msg, e);
-    }
-}
+package com.ruoyi.common.utils.reflect;
+
+import cn.hutool.core.util.ReflectUtil;
+import cn.hutool.core.util.StrUtil;
+
+import java.lang.reflect.Method;
+import java.util.List;
+
+/**
+ * 鍙嶅皠宸ュ叿绫�. 鎻愪緵璋冪敤getter/setter鏂规硶, 璁块棶绉佹湁鍙橀噺, 璋冪敤绉佹湁鏂规硶, 鑾峰彇娉涘瀷绫诲瀷Class, 琚獳OP杩囩殑鐪熷疄绫荤瓑宸ュ叿鍑芥暟.
+ *
+ * @author Lion Li
+ */
+@SuppressWarnings("rawtypes")
+public class ReflectUtils extends ReflectUtil {
+
+	private static final String SETTER_PREFIX = "set";
+
+	private static final String GETTER_PREFIX = "get";
+
+	/**
+	 * 璋冪敤Getter鏂规硶.
+	 * 鏀寔澶氱骇锛屽锛氬璞″悕.瀵硅薄鍚�.鏂规硶
+	 */
+	@SuppressWarnings("unchecked")
+	public static <E> E invokeGetter(Object obj, String propertyName) {
+		Object object = obj;
+		for (String name : StrUtil.split(propertyName, ".")) {
+			String getterMethodName = GETTER_PREFIX + StrUtil.upperFirst(name);
+			object = invoke(object, getterMethodName);
+		}
+		return (E) object;
+	}
+
+	/**
+	 * 璋冪敤Setter鏂规硶, 浠呭尮閰嶆柟娉曞悕銆�
+	 * 鏀寔澶氱骇锛屽锛氬璞″悕.瀵硅薄鍚�.鏂规硶
+	 */
+	public static <E> void invokeSetter(Object obj, String propertyName, E value) {
+		Object object = obj;
+		List<String> names = StrUtil.split(propertyName, ".");
+		for (int i = 0; i < names.size(); i++) {
+			if (i < names.size() - 1) {
+				String getterMethodName = GETTER_PREFIX + StrUtil.upperFirst(names.get(i));
+				object = invoke(object, getterMethodName);
+			} else {
+				String setterMethodName = SETTER_PREFIX + StrUtil.upperFirst(names.get(i));
+				Method method = getMethodByName(object.getClass(), setterMethodName);
+				invoke(object, method, value);
+			}
+		}
+	}
+
+}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/spring/SpringUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/spring/SpringUtils.java
index 8e98c50..14ff8a4 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/spring/SpringUtils.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/spring/SpringUtils.java
@@ -1,146 +1,65 @@
 package com.ruoyi.common.utils.spring;
 
-import cn.hutool.core.lang.Validator;
+import cn.hutool.extra.spring.SpringUtil;
 import org.springframework.aop.framework.AopContext;
-import org.springframework.beans.BeansException;
 import org.springframework.beans.factory.NoSuchBeanDefinitionException;
-import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
-import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.ApplicationContextAware;
 import org.springframework.stereotype.Component;
 
 /**
- * spring宸ュ叿绫� 鏂逛究鍦ㄩ潪spring绠$悊鐜涓幏鍙朾ean
- * 
- * @author ruoyi
+ * spring宸ュ叿绫�
+ *
+ * @author Lion Li
  */
 @Component
-public final class SpringUtils implements BeanFactoryPostProcessor, ApplicationContextAware 
-{
-    /** Spring搴旂敤涓婁笅鏂囩幆澧� */
-    private static ConfigurableListableBeanFactory beanFactory;
+public final class SpringUtils extends SpringUtil {
 
-    private static ApplicationContext applicationContext;
+	/**
+	 * 濡傛灉BeanFactory鍖呭惈涓�涓笌鎵�缁欏悕绉板尮閰嶇殑bean瀹氫箟锛屽垯杩斿洖true
+	 *
+	 * @param name
+	 * @return boolean
+	 */
+	public static boolean containsBean(String name) {
+		return getBeanFactory().containsBean(name);
+	}
 
-    @Override
-    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException 
-    {
-        SpringUtils.beanFactory = beanFactory;
-    }
+	/**
+	 * 鍒ゆ柇浠ョ粰瀹氬悕瀛楁敞鍐岀殑bean瀹氫箟鏄竴涓猻ingleton杩樻槸涓�涓猵rototype銆�
+	 * 濡傛灉涓庣粰瀹氬悕瀛楃浉搴旂殑bean瀹氫箟娌℃湁琚壘鍒帮紝灏嗕細鎶涘嚭涓�涓紓甯革紙NoSuchBeanDefinitionException锛�
+	 *
+	 * @param name
+	 * @return boolean
+	 */
+	public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException {
+		return getBeanFactory().isSingleton(name);
+	}
 
-    @Override
-    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException 
-    {
-        SpringUtils.applicationContext = applicationContext;
-    }
+	/**
+	 * @param name
+	 * @return Class 娉ㄥ唽瀵硅薄鐨勭被鍨�
+	 */
+	public static Class<?> getType(String name) throws NoSuchBeanDefinitionException {
+		return getBeanFactory().getType(name);
+	}
 
-    /**
-     * 鑾峰彇瀵硅薄
-     *
-     * @param name
-     * @return Object 涓�涓互鎵�缁欏悕瀛楁敞鍐岀殑bean鐨勫疄渚�
-     * @throws org.springframework.beans.BeansException
-     *
-     */
-    @SuppressWarnings("unchecked")
-    public static <T> T getBean(String name) throws BeansException
-    {
-        return (T) beanFactory.getBean(name);
-    }
+	/**
+	 * 濡傛灉缁欏畾鐨刡ean鍚嶅瓧鍦╞ean瀹氫箟涓湁鍒悕锛屽垯杩斿洖杩欎簺鍒悕
+	 *
+	 * @param name
+	 */
+	public static String[] getAliases(String name) throws NoSuchBeanDefinitionException {
+		return getBeanFactory().getAliases(name);
+	}
 
-    /**
-     * 鑾峰彇绫诲瀷涓簉equiredType鐨勫璞�
-     *
-     * @param clz
-     * @return
-     * @throws org.springframework.beans.BeansException
-     *
-     */
-    public static <T> T getBean(Class<T> clz) throws BeansException
-    {
-        T result = (T) beanFactory.getBean(clz);
-        return result;
-    }
+	/**
+	 * 鑾峰彇aop浠g悊瀵硅薄
+	 *
+	 * @param invoker
+	 * @return
+	 */
+	@SuppressWarnings("unchecked")
+	public static <T> T getAopProxy(T invoker) {
+		return (T) AopContext.currentProxy();
+	}
 
-    /**
-     * 濡傛灉BeanFactory鍖呭惈涓�涓笌鎵�缁欏悕绉板尮閰嶇殑bean瀹氫箟锛屽垯杩斿洖true
-     *
-     * @param name
-     * @return boolean
-     */
-    public static boolean containsBean(String name)
-    {
-        return beanFactory.containsBean(name);
-    }
-
-    /**
-     * 鍒ゆ柇浠ョ粰瀹氬悕瀛楁敞鍐岀殑bean瀹氫箟鏄竴涓猻ingleton杩樻槸涓�涓猵rototype銆� 濡傛灉涓庣粰瀹氬悕瀛楃浉搴旂殑bean瀹氫箟娌℃湁琚壘鍒帮紝灏嗕細鎶涘嚭涓�涓紓甯革紙NoSuchBeanDefinitionException锛�
-     *
-     * @param name
-     * @return boolean
-     * @throws org.springframework.beans.factory.NoSuchBeanDefinitionException
-     *
-     */
-    public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException
-    {
-        return beanFactory.isSingleton(name);
-    }
-
-    /**
-     * @param name
-     * @return Class 娉ㄥ唽瀵硅薄鐨勭被鍨�
-     * @throws org.springframework.beans.factory.NoSuchBeanDefinitionException
-     *
-     */
-    public static Class<?> getType(String name) throws NoSuchBeanDefinitionException
-    {
-        return beanFactory.getType(name);
-    }
-
-    /**
-     * 濡傛灉缁欏畾鐨刡ean鍚嶅瓧鍦╞ean瀹氫箟涓湁鍒悕锛屽垯杩斿洖杩欎簺鍒悕
-     *
-     * @param name
-     * @return
-     * @throws org.springframework.beans.factory.NoSuchBeanDefinitionException
-     *
-     */
-    public static String[] getAliases(String name) throws NoSuchBeanDefinitionException
-    {
-        return beanFactory.getAliases(name);
-    }
-
-    /**
-     * 鑾峰彇aop浠g悊瀵硅薄
-     * 
-     * @param invoker
-     * @return
-     */
-    @SuppressWarnings("unchecked")
-    public static <T> T getAopProxy(T invoker)
-    {
-        return (T) AopContext.currentProxy();
-    }
-
-    /**
-     * 鑾峰彇褰撳墠鐨勭幆澧冮厤缃紝鏃犻厤缃繑鍥瀗ull
-     *
-     * @return 褰撳墠鐨勭幆澧冮厤缃�
-     */
-    public static String[] getActiveProfiles()
-    {
-        return applicationContext.getEnvironment().getActiveProfiles();
-    }
-
-    /**
-     * 鑾峰彇褰撳墠鐨勭幆澧冮厤缃紝褰撴湁澶氫釜鐜閰嶇疆鏃讹紝鍙幏鍙栫涓�涓�
-     *
-     * @return 褰撳墠鐨勭幆澧冮厤缃�
-     */
-    public static String getActiveProfile()
-    {
-        final String[] activeProfiles = getActiveProfiles();
-        return Validator.isNotEmpty(activeProfiles) ? activeProfiles[0] : null;
-    }
 }
diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/bo/TestDemoAddBo.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/bo/TestDemoAddBo.java
index a7e79f8..10520ae 100644
--- a/ruoyi-demo/src/main/java/com/ruoyi/demo/bo/TestDemoAddBo.java
+++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/bo/TestDemoAddBo.java
@@ -5,7 +5,7 @@
 import lombok.Data;
 
 import javax.validation.constraints.NotBlank;
-
+import java.util.Date;
 
 
 /**
@@ -40,4 +40,8 @@
     @NotBlank(message = "鍊间笉鑳戒负绌�")
     private String value;
 
+	/** 鍒涘缓鏃堕棿 */
+	@ApiModelProperty("鍒涘缓鏃堕棿")
+	private Date createTime;
+
 }
diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisLockController.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisLockController.java
index c3c71ef..f6649ed 100644
--- a/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisLockController.java
+++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisLockController.java
@@ -1,8 +1,10 @@
 package com.ruoyi.demo.controller;
 
-import com.ruoyi.common.annotation.RedisLock;
+import com.baomidou.lock.LockInfo;
+import com.baomidou.lock.LockTemplate;
+import com.baomidou.lock.annotation.Lock4j;
+import com.baomidou.lock.executor.RedissonLockExecutor;
 import com.ruoyi.common.core.domain.AjaxResult;
-import com.ruoyi.common.core.redis.RedisLockManager;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.cache.annotation.Cacheable;
@@ -10,7 +12,7 @@
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
-import java.util.concurrent.TimeUnit;
+import java.time.LocalTime;
 
 
 /**
@@ -24,44 +26,47 @@
 public class RedisLockController {
 
 	@Autowired
-	private RedisLockManager redisLockManager;
+	private LockTemplate lockTemplate;
 
 	/**
-	 * #p0 鏍囪瘑鍙栫涓�涓弬鏁颁负redis閿佺殑key
+	 * 娴嬭瘯lock4j 娉ㄨВ
 	 */
-	@GetMapping("/testLock1")
-	@RedisLock(expireTime = 10, key = "#p0")
-	public AjaxResult<String> testLock1(String key, String value) {
+	@Lock4j(keys = {"#key"})
+	@GetMapping("/testLock4j")
+	public  AjaxResult<String> testLock4j(String key,String value){
+		System.out.println("start:"+key+",time:"+ LocalTime.now().toString());
 		try {
-			// 鍚屾椂璇锋眰鎺掗槦
-//			Thread.sleep(5000);
-			// 閿佽秴鏃舵祴璇�
-			Thread.sleep(11000);
+			Thread.sleep(10000);
 		} catch (InterruptedException e) {
 			e.printStackTrace();
 		}
+		System.out.println("end :"+key+",time:"+LocalTime.now().toString());
 		return AjaxResult.success("鎿嶄綔鎴愬姛",value);
 	}
 
 	/**
-	 * 娴嬭瘯閿佸伐鍏风被
+	 * 娴嬭瘯lock4j 宸ュ叿
 	 */
-	@GetMapping("/testLock2")
-	public AjaxResult<Void> testLock(String key, Long time) {
-		try {
-			boolean flag = redisLockManager.getLock(key, time, TimeUnit.SECONDS);
-			if (flag) {
-				log.info("鑾峰彇閿佹垚鍔�: " + key);
-				Thread.sleep(3000);
-				redisLockManager.unLock(key);
-				log.info("閲婃斁閿佹垚鍔�: " + key);
-			} else {
-				log.error("鑾峰彇閿佸け璐�: " + key);
-			}
-		} catch (InterruptedException e) {
-			log.error(e.getMessage());
+	@GetMapping("/testLock4jLockTemaplate")
+	public  AjaxResult<String> testLock4jLockTemaplate(String key,String value){
+		final LockInfo lockInfo = lockTemplate.lock(key, 30000L, 5000L, RedissonLockExecutor.class);
+		if (null == lockInfo) {
+			throw new RuntimeException("涓氬姟澶勭悊涓�,璇风◢鍚庡啀璇�");
 		}
-		return AjaxResult.success();
+		// 鑾峰彇閿佹垚鍔燂紝澶勭悊涓氬姟
+		try {
+			try {
+				Thread.sleep(8000);
+			} catch (InterruptedException e) {
+				//
+			}
+			System.out.println("鎵ц绠�鍗曟柟娉�1 , 褰撳墠绾跨▼:" + Thread.currentThread().getName());
+		} finally {
+			//閲婃斁閿�
+			lockTemplate.releaseLock(lockInfo);
+		}
+		//缁撴潫
+		return AjaxResult.success("鎿嶄綔鎴愬姛",value);
 	}
 
 	/**
diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestBatchController.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestBatchController.java
new file mode 100644
index 0000000..499a5ad
--- /dev/null
+++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestBatchController.java
@@ -0,0 +1,52 @@
+package com.ruoyi.demo.controller;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.ruoyi.common.core.controller.BaseController;
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.demo.domain.TestDemo;
+import com.ruoyi.demo.service.ITestDemoService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 娴嬭瘯鎵归噺鏂规硶
+ *
+ * @author Lion Li
+ * @date 2021-05-30
+ */
+@RequiredArgsConstructor(onConstructor_ = @Autowired)
+@RestController
+@RequestMapping("/demo/batch")
+public class TestBatchController extends BaseController {
+
+    private final ITestDemoService iTestDemoService;
+
+    /**
+     * 鏂板鎵归噺鏂规硶
+     */
+    @PostMapping()
+    public AjaxResult<Void> add() {
+		List<TestDemo> list = new ArrayList<>();
+		for (int i = 0; i < 1000; i++) {
+			list.add(new TestDemo().setOrderNum(-1L).setTestKey("鎵归噺鏂板").setValue("娴嬭瘯鏂板"));
+		}
+        return toAjax(iTestDemoService.saveAll(list) ? 1 : 0);
+    }
+
+    /**
+     * 淇敼鎵归噺鏂规硶
+     */
+    @DeleteMapping()
+    public AjaxResult<Void> edit() {
+        return toAjax(iTestDemoService.remove(new LambdaQueryWrapper<TestDemo>()
+			.eq(TestDemo::getOrderNum, -1L)) ? 1 : 0);
+    }
+
+}
diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/domain/TestDemo.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/domain/TestDemo.java
index f038706..26f652a 100644
--- a/ruoyi-demo/src/main/java/com/ruoyi/demo/domain/TestDemo.java
+++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/domain/TestDemo.java
@@ -1,6 +1,8 @@
 package com.ruoyi.demo.domain;
 
 import com.baomidou.mybatisplus.annotation.*;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 import lombok.experimental.Accessors;
@@ -23,8 +25,11 @@
     private static final long serialVersionUID=1L;
 
 
-    /** 涓婚敭 */
+	/**
+	 * 涓婚敭
+	 */
     @TableId(value = "id")
+	@JsonSerialize(using = ToStringSerializer.class)
     private Long id;
 
     /** 閮ㄩ棬id */
@@ -64,7 +69,6 @@
     private String updateBy;
 
     /** 鍒犻櫎鏍囧織 */
-    @TableLogic
     private Long delFlag;
 
 }
diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/domain/TestTree.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/domain/TestTree.java
index 43d1efe..b9bd2ba 100644
--- a/ruoyi-demo/src/main/java/com/ruoyi/demo/domain/TestTree.java
+++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/domain/TestTree.java
@@ -1,13 +1,14 @@
 package com.ruoyi.demo.domain;
 
 import com.baomidou.mybatisplus.annotation.*;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 import lombok.experimental.Accessors;
+
 import java.io.Serializable;
 import java.util.Date;
-import java.math.BigDecimal;
-import com.ruoyi.common.annotation.Excel;
 
 /**
  * 娴嬭瘯鏍戣〃瀵硅薄 test_tree
@@ -26,6 +27,7 @@
 
     /** 涓婚敭 */
     @TableId(value = "id")
+	@JsonSerialize(using = ToStringSerializer.class)
     private Long id;
 
     /** 鐖秈d */
diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/feign/FeignTestService.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/feign/FeignTestService.java
index c20973a..5273a69 100644
--- a/ruoyi-demo/src/main/java/com/ruoyi/demo/feign/FeignTestService.java
+++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/feign/FeignTestService.java
@@ -1,5 +1,6 @@
 package com.ruoyi.demo.feign;
 
+import com.ruoyi.demo.feign.constant.FeignTestConstant;
 import com.ruoyi.demo.feign.fallback.FeignTestFallback;
 import org.springframework.cloud.openfeign.FeignClient;
 import org.springframework.web.bind.annotation.GetMapping;
@@ -7,10 +8,15 @@
 
 /**
  * feign娴嬭瘯service
- *
+ * 瑙勮寖鎺ュ彛 Service 鏃犳劅璋冪敤
+ * 甯搁噺绠$悊璇锋眰璺緞 鏇村姞瑙勮寖
+ * 鑷畾涔夊閿欏鐞� 瀹夊叏鍙潬
  * @author Lion Li
  */
-@FeignClient(name = "baidu",url = "http://www.baidu.com",fallback = FeignTestFallback.class)
+@FeignClient(
+	name = FeignTestConstant.BAIDU_NAME,
+	url = FeignTestConstant.BAIDU_URL,
+	fallback = FeignTestFallback.class)
 public interface FeignTestService {
 
     @GetMapping("/s")
diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/feign/constant/FeignTestConstant.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/feign/constant/FeignTestConstant.java
new file mode 100644
index 0000000..7a5b3fb
--- /dev/null
+++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/feign/constant/FeignTestConstant.java
@@ -0,0 +1,9 @@
+package com.ruoyi.demo.feign.constant;
+
+public class FeignTestConstant {
+
+	public static final String BAIDU_NAME = "baidu";
+
+	public static final String BAIDU_URL = "http://www.baidu.com";
+
+}
diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/mapper/TestDemoMapper.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/mapper/TestDemoMapper.java
index 5cfb9f6..aceaf6d 100644
--- a/ruoyi-demo/src/main/java/com/ruoyi/demo/mapper/TestDemoMapper.java
+++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/mapper/TestDemoMapper.java
@@ -1,7 +1,7 @@
 package com.ruoyi.demo.mapper;
 
-import com.ruoyi.common.core.mybatisplus.MybatisPlusRedisCache;
-import com.ruoyi.common.core.page.BaseMapperPlus;
+import com.ruoyi.common.core.mybatisplus.cache.MybatisPlusRedisCache;
+import com.ruoyi.common.core.mybatisplus.core.BaseMapperPlus;
 import com.ruoyi.demo.domain.TestDemo;
 import org.apache.ibatis.annotations.CacheNamespace;
 
@@ -11,6 +11,7 @@
  * @author Lion Li
  * @date 2021-05-30
  */
+// 濡備娇闇�鍒囨崲鏁版嵁婧� 璇峰嬁浣跨敤缂撳瓨 浼氶�犳垚鏁版嵁涓嶄竴鑷寸幇璞�
 @CacheNamespace(implementation = MybatisPlusRedisCache.class, eviction = MybatisPlusRedisCache.class)
 public interface TestDemoMapper extends BaseMapperPlus<TestDemo> {
 
diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/mapper/TestTreeMapper.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/mapper/TestTreeMapper.java
index 0635ebc..20a3e9b 100644
--- a/ruoyi-demo/src/main/java/com/ruoyi/demo/mapper/TestTreeMapper.java
+++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/mapper/TestTreeMapper.java
@@ -1,9 +1,7 @@
 package com.ruoyi.demo.mapper;
 
-import com.ruoyi.common.core.mybatisplus.MybatisPlusRedisCache;
-import com.ruoyi.common.core.page.BaseMapperPlus;
+import com.ruoyi.common.core.mybatisplus.core.BaseMapperPlus;
 import com.ruoyi.demo.domain.TestTree;
-import org.apache.ibatis.annotations.CacheNamespace;
 
 /**
  * 娴嬭瘯鏍戣〃Mapper鎺ュ彛
@@ -11,7 +9,7 @@
  * @author Lion Li
  * @date 2021-05-30
  */
-@CacheNamespace(implementation = MybatisPlusRedisCache.class, eviction = MybatisPlusRedisCache.class)
+//@CacheNamespace(implementation = MybatisPlusRedisCache.class, eviction = MybatisPlusRedisCache.class)
 public interface TestTreeMapper extends BaseMapperPlus<TestTree> {
 
 }
diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/service/ITestDemoService.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/service/ITestDemoService.java
index 7f08668..c011325 100644
--- a/ruoyi-demo/src/main/java/com/ruoyi/demo/service/ITestDemoService.java
+++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/service/ITestDemoService.java
@@ -5,7 +5,7 @@
 import com.ruoyi.demo.bo.TestDemoQueryBo;
 import com.ruoyi.demo.bo.TestDemoAddBo;
 import com.ruoyi.demo.bo.TestDemoEditBo;
-import com.ruoyi.common.core.page.IServicePlus;
+import com.ruoyi.common.core.mybatisplus.core.IServicePlus;
 import com.ruoyi.common.core.page.TableDataInfo;
 
 import java.util.Collection;
@@ -18,6 +18,7 @@
  * @date 2021-05-30
  */
 public interface ITestDemoService extends IServicePlus<TestDemo> {
+
 	/**
 	 * 鏌ヨ鍗曚釜
 	 * @return
diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/service/ITestTreeService.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/service/ITestTreeService.java
index 605b3df..6f7be37 100644
--- a/ruoyi-demo/src/main/java/com/ruoyi/demo/service/ITestTreeService.java
+++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/service/ITestTreeService.java
@@ -1,6 +1,6 @@
 package com.ruoyi.demo.service;
 
-import com.ruoyi.common.core.page.IServicePlus;
+import com.ruoyi.common.core.mybatisplus.core.IServicePlus;
 import com.ruoyi.demo.bo.TestTreeAddBo;
 import com.ruoyi.demo.bo.TestTreeEditBo;
 import com.ruoyi.demo.bo.TestTreeQueryBo;
diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/service/impl/TestDemoServiceImpl.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/service/impl/TestDemoServiceImpl.java
index d974762..4d35efe 100644
--- a/ruoyi-demo/src/main/java/com/ruoyi/demo/service/impl/TestDemoServiceImpl.java
+++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/service/impl/TestDemoServiceImpl.java
@@ -4,8 +4,8 @@
 import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.ruoyi.common.annotation.DataScope;
+import com.ruoyi.common.core.mybatisplus.core.ServicePlusImpl;
 import com.ruoyi.common.core.page.PagePlus;
 import com.ruoyi.common.core.page.TableDataInfo;
 import com.ruoyi.common.utils.PageUtils;
@@ -29,7 +29,7 @@
  * @date 2021-05-30
  */
 @Service
-public class TestDemoServiceImpl extends ServiceImpl<TestDemoMapper, TestDemo> implements ITestDemoService {
+public class TestDemoServiceImpl extends ServicePlusImpl<TestDemoMapper, TestDemo> implements ITestDemoService {
 
 	@Override
 	public TestDemoVo queryById(Long id) {
diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/service/impl/TestTreeServiceImpl.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/service/impl/TestTreeServiceImpl.java
index ae93ef3..36482f1 100644
--- a/ruoyi-demo/src/main/java/com/ruoyi/demo/service/impl/TestTreeServiceImpl.java
+++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/service/impl/TestTreeServiceImpl.java
@@ -4,8 +4,8 @@
 import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.ruoyi.common.annotation.DataScope;
+import com.ruoyi.common.core.mybatisplus.core.ServicePlusImpl;
 import com.ruoyi.demo.bo.TestTreeAddBo;
 import com.ruoyi.demo.bo.TestTreeEditBo;
 import com.ruoyi.demo.bo.TestTreeQueryBo;
@@ -26,13 +26,14 @@
  * @date 2021-05-30
  */
 @Service
-public class TestTreeServiceImpl extends ServiceImpl<TestTreeMapper, TestTree> implements ITestTreeService {
+public class TestTreeServiceImpl extends ServicePlusImpl<TestTreeMapper, TestTree> implements ITestTreeService {
 
 	@Override
 	public TestTreeVo queryById(Long id) {
 		return getVoById(id, TestTreeVo.class);
 	}
 
+//	@DataSource(DataSourceType.SLAVE) // 鍒囨崲浠庡簱鏌ヨ
 	@DataScope(isUser = true)
 	@Override
 	public List<TestTreeVo> queryList(TestTreeQueryBo bo) {
diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/vo/TestDemoVo.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/vo/TestDemoVo.java
index c51ed43..d1eb8bf 100644
--- a/ruoyi-demo/src/main/java/com/ruoyi/demo/vo/TestDemoVo.java
+++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/vo/TestDemoVo.java
@@ -1,10 +1,12 @@
 package com.ruoyi.demo.vo;
 
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
 import com.ruoyi.common.annotation.Excel;
-import com.fasterxml.jackson.annotation.JsonFormat;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
+
 import java.util.Date;
 
 
@@ -21,8 +23,13 @@
 
 	private static final long serialVersionUID = 1L;
 
-	/** 涓婚敭 */
+	/**
+	 * 涓婚敭
+	 * 濡傛灉鏄嚜瀹氫箟id 鎴栬�� 闆姳id
+	 * 闇�瑕佸鍔犲簭鍒楀寲涓哄瓧绗︿覆娉ㄨВ 鍥犱负Long鍒板墠绔細澶辩湡
+	 */
 	@ApiModelProperty("涓婚敭")
+	@JsonSerialize(using = ToStringSerializer.class)
 	private Long id;
 
 	/** 閮ㄩ棬id */
@@ -52,7 +59,7 @@
 
 	/** 鍒涘缓鏃堕棿 */
 	@Excel(name = "鍒涘缓鏃堕棿" , width = 30, dateFormat = "yyyy-MM-dd")
-	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+//	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
 	@ApiModelProperty("鍒涘缓鏃堕棿")
 	private Date createTime;
 
@@ -63,7 +70,7 @@
 
 	/** 鏇存柊鏃堕棿 */
 	@Excel(name = "鏇存柊鏃堕棿" , width = 30, dateFormat = "yyyy-MM-dd")
-	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+//	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
 	@ApiModelProperty("鏇存柊鏃堕棿")
 	private Date updateTime;
 
diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/vo/TestTreeVo.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/vo/TestTreeVo.java
index 44413b1..c6ea558 100644
--- a/ruoyi-demo/src/main/java/com/ruoyi/demo/vo/TestTreeVo.java
+++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/vo/TestTreeVo.java
@@ -1,10 +1,13 @@
 package com.ruoyi.demo.vo;
 
-import com.ruoyi.common.annotation.Excel;
 import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import com.ruoyi.common.annotation.Excel;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
+
 import java.util.Date;
 
 
@@ -23,6 +26,7 @@
 
 	/** 涓婚敭 */
 	@ApiModelProperty("涓婚敭")
+	@JsonSerialize(using = ToStringSerializer.class)
 	private Long id;
 
 	/** 鐖秈d */
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/DataSourceAspect.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/DataSourceAspect.java
index f92a964..f82b2ae 100644
--- a/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/DataSourceAspect.java
+++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/DataSourceAspect.java
@@ -1,15 +1,13 @@
 package com.ruoyi.framework.aspectj;
 
 import cn.hutool.core.lang.Validator;
+import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
 import com.ruoyi.common.annotation.DataSource;
-import com.ruoyi.framework.datasource.DynamicDataSourceContextHolder;
 import org.aspectj.lang.ProceedingJoinPoint;
 import org.aspectj.lang.annotation.Around;
 import org.aspectj.lang.annotation.Aspect;
 import org.aspectj.lang.annotation.Pointcut;
 import org.aspectj.lang.reflect.MethodSignature;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.springframework.core.annotation.AnnotationUtils;
 import org.springframework.core.annotation.Order;
 import org.springframework.stereotype.Component;
@@ -18,56 +16,47 @@
 
 /**
  * 澶氭暟鎹簮澶勭悊
- * 
+ *
  * @author ruoyi
  */
 @Aspect
-@Order(1)
+@Order(-500)
 @Component
-public class DataSourceAspect
-{
-    protected Logger logger = LoggerFactory.getLogger(getClass());
+public class DataSourceAspect {
 
-    @Pointcut("@annotation(com.ruoyi.common.annotation.DataSource)"
-            + "|| @within(com.ruoyi.common.annotation.DataSource)")
-    public void dsPointCut()
-    {
+	@Pointcut("@annotation(com.ruoyi.common.annotation.DataSource)"
+		+ "|| @within(com.ruoyi.common.annotation.DataSource)")
+	public void dsPointCut() {
+	}
 
-    }
+	@Around("dsPointCut()")
+	public Object around(ProceedingJoinPoint point) throws Throwable {
+		DataSource dataSource = getDataSource(point);
 
-    @Around("dsPointCut()")
-    public Object around(ProceedingJoinPoint point) throws Throwable
-    {
-        DataSource dataSource = getDataSource(point);
+		if (Validator.isNotNull(dataSource)) {
+			DynamicDataSourceContextHolder.poll();
+			String source = dataSource.value().getSource();
+			DynamicDataSourceContextHolder.push(source);
+		}
 
-        if (Validator.isNotNull(dataSource))
-        {
-            DynamicDataSourceContextHolder.setDataSourceType(dataSource.value().name());
-        }
+		try {
+			return point.proceed();
+		} finally {
+			// 閿�姣佹暟鎹簮 鍦ㄦ墽琛屾柟娉曚箣鍚�
+			DynamicDataSourceContextHolder.clear();
+		}
+	}
 
-        try
-        {
-            return point.proceed();
-        }
-        finally
-        {
-            // 閿�姣佹暟鎹簮 鍦ㄦ墽琛屾柟娉曚箣鍚�
-            DynamicDataSourceContextHolder.clearDataSourceType();
-        }
-    }
+	/**
+	 * 鑾峰彇闇�瑕佸垏鎹㈢殑鏁版嵁婧�
+	 */
+	public DataSource getDataSource(ProceedingJoinPoint point) {
+		MethodSignature signature = (MethodSignature) point.getSignature();
+		DataSource dataSource = AnnotationUtils.findAnnotation(signature.getMethod(), DataSource.class);
+		if (Objects.nonNull(dataSource)) {
+			return dataSource;
+		}
 
-    /**
-     * 鑾峰彇闇�瑕佸垏鎹㈢殑鏁版嵁婧�
-     */
-    public DataSource getDataSource(ProceedingJoinPoint point)
-    {
-        MethodSignature signature = (MethodSignature) point.getSignature();
-        DataSource dataSource = AnnotationUtils.findAnnotation(signature.getMethod(), DataSource.class);
-        if (Objects.nonNull(dataSource))
-        {
-            return dataSource;
-        }
-
-        return AnnotationUtils.findAnnotation(signature.getDeclaringType(), DataSource.class);
-    }
+		return AnnotationUtils.findAnnotation(signature.getDeclaringType(), DataSource.class);
+	}
 }
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/LogAspect.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/LogAspect.java
index 442d258..d5c0fe8 100644
--- a/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/LogAspect.java
+++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/LogAspect.java
@@ -2,16 +2,14 @@
 
 import cn.hutool.core.lang.Validator;
 import cn.hutool.core.util.StrUtil;
-import com.alibaba.fastjson.JSON;
 import com.ruoyi.common.annotation.Log;
 import com.ruoyi.common.core.domain.model.LoginUser;
 import com.ruoyi.common.enums.BusinessStatus;
 import com.ruoyi.common.enums.HttpMethod;
+import com.ruoyi.common.utils.JsonUtils;
 import com.ruoyi.common.utils.ServletUtils;
-import com.ruoyi.common.utils.ip.IpUtils;
 import com.ruoyi.common.utils.spring.SpringUtils;
-import com.ruoyi.framework.manager.AsyncManager;
-import com.ruoyi.framework.manager.factory.AsyncFactory;
+import com.ruoyi.framework.web.service.AsyncService;
 import com.ruoyi.framework.web.service.TokenService;
 import com.ruoyi.system.domain.SysOperLog;
 import org.aspectj.lang.JoinPoint;
@@ -32,7 +30,6 @@
 import javax.servlet.http.HttpServletResponse;
 import java.lang.reflect.Method;
 import java.util.Collection;
-import java.util.Iterator;
 import java.util.Map;
 
 /**
@@ -93,10 +90,10 @@
             SysOperLog operLog = new SysOperLog();
             operLog.setStatus(BusinessStatus.SUCCESS.ordinal());
             // 璇锋眰鐨勫湴鍧�
-            String ip = IpUtils.getIpAddr(ServletUtils.getRequest());
+            String ip = ServletUtils.getClientIP();
             operLog.setOperIp(ip);
             // 杩斿洖鍙傛暟
-            operLog.setJsonResult(JSON.toJSONString(jsonResult));
+            operLog.setJsonResult(JsonUtils.toJsonString(jsonResult));
 
             operLog.setOperUrl(ServletUtils.getRequest().getRequestURI());
             if (loginUser != null)
@@ -118,7 +115,7 @@
             // 澶勭悊璁剧疆娉ㄨВ涓婄殑鍙傛暟
             getControllerMethodDescription(joinPoint, controllerLog, operLog);
             // 淇濆瓨鏁版嵁搴�
-            AsyncManager.me().execute(AsyncFactory.recordOper(operLog));
+			SpringUtils.getBean(AsyncService.class).recordOper(operLog);
         }
         catch (Exception exp)
         {
@@ -194,19 +191,16 @@
      */
     private String argsArrayToString(Object[] paramsArray)
     {
-        String params = "";
+        StringBuilder params = new StringBuilder();
         if (paramsArray != null && paramsArray.length > 0)
         {
-            for (int i = 0; i < paramsArray.length; i++)
-            {
-                if (Validator.isNotNull(paramsArray[i]) && !isFilterObject(paramsArray[i]))
-                {
-                    Object jsonObj = JSON.toJSON(paramsArray[i]);
-                    params += jsonObj.toString() + " ";
-                }
-            }
+			for (Object o : paramsArray) {
+				if (Validator.isNotNull(o) && !isFilterObject(o)) {
+					params.append(JsonUtils.toJsonString(o)).append(" ");
+				}
+			}
         }
-        return params.trim();
+        return params.toString().trim();
     }
 
     /**
@@ -226,19 +220,17 @@
         else if (Collection.class.isAssignableFrom(clazz))
         {
             Collection collection = (Collection) o;
-            for (Iterator iter = collection.iterator(); iter.hasNext();)
-            {
-                return iter.next() instanceof MultipartFile;
-            }
+			for (Object value : collection) {
+				return value instanceof MultipartFile;
+			}
         }
         else if (Map.class.isAssignableFrom(clazz))
         {
             Map map = (Map) o;
-            for (Iterator iter = map.entrySet().iterator(); iter.hasNext();)
-            {
-                Map.Entry entry = (Map.Entry) iter.next();
-                return entry.getValue() instanceof MultipartFile;
-            }
+			for (Object value : map.entrySet()) {
+				Map.Entry entry = (Map.Entry) value;
+				return entry.getValue() instanceof MultipartFile;
+			}
         }
         return o instanceof MultipartFile || o instanceof HttpServletRequest || o instanceof HttpServletResponse
                 || o instanceof BindingResult;
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/RedisLockAspect.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/RedisLockAspect.java
deleted file mode 100644
index d81c3ca..0000000
--- a/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/RedisLockAspect.java
+++ /dev/null
@@ -1,139 +0,0 @@
-package com.ruoyi.framework.aspectj;
-
-
-import com.ruoyi.common.annotation.RedisLock;
-import com.ruoyi.common.constant.Constants;
-import com.ruoyi.common.core.redis.RedisLockManager;
-import lombok.extern.slf4j.Slf4j;
-import org.aspectj.lang.ProceedingJoinPoint;
-import org.aspectj.lang.annotation.Around;
-import org.aspectj.lang.annotation.Aspect;
-import org.aspectj.lang.annotation.Pointcut;
-import org.aspectj.lang.reflect.MethodSignature;
-import org.redisson.api.RLock;
-import org.redisson.api.RedissonClient;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.core.annotation.Order;
-import org.springframework.stereotype.Component;
-
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-
-/**
- * 鍒嗗竷寮忛攣锛堟敞瑙e疄鐜扮増鏈級
- *
- * @author shenxinquan
- */
-
-@Slf4j
-@Aspect
-@Order(9)
-@Component
-public class RedisLockAspect {
-
-	@Autowired
-	private RedisLockManager redisLockManager;
-
-	@Pointcut("@annotation(com.ruoyi.common.annotation.RedisLock)")
-	public void annotationPointcut() {
-	}
-
-	@Around("annotationPointcut()")
-	public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
-		// 鑾峰緱褰撳墠璁块棶鐨刢lass
-		Class<?> className = joinPoint.getTarget().getClass();
-		// 鑾峰緱璁块棶鐨勬柟娉曞悕
-		String methodName = joinPoint.getSignature().getName();
-		// 寰楀埌鏂规硶鐨勫弬鏁扮殑绫诲瀷
-		Class<?>[] argClass = ((MethodSignature) joinPoint.getSignature()).getParameterTypes();
-		Object[] args = joinPoint.getArgs();
-		String key = "";
-		// 榛樿30绉掕繃鏈熸椂闂�
-		int expireTime = 30;
-
-		try {
-			// 寰楀埌璁块棶鐨勬柟娉曞璞�
-			Method method = className.getMethod(methodName, argClass);
-			method.setAccessible(true);
-			// 鍒ゆ柇鏄惁瀛樺湪@RedisLock娉ㄨВ
-			if (method.isAnnotationPresent(RedisLock.class)) {
-				RedisLock annotation = method.getAnnotation(RedisLock.class);
-				key = getRedisKey(args, annotation.key());
-				expireTime = getExpireTime(annotation);
-			}
-		} catch (Exception e) {
-			throw new RuntimeException("redis鍒嗗竷寮忛攣娉ㄨВ鍙傛暟寮傚父", e);
-		}
-
-		// 澹版槑閿佸悕绉�
-		key = Constants.REDIS_LOCK_KEY + key;
-		Object res;
-		try {
-			if (redisLockManager.getLock(key, expireTime, TimeUnit.SECONDS)) {
-				log.info("lock => key : " + key + " , ThreadName : " + Thread.currentThread().getName());
-				try {
-					res = joinPoint.proceed();
-					return res;
-				} catch (Exception e) {
-					throw new RuntimeException(e);
-				} finally {
-					redisLockManager.unLock(key);
-					log.info("unlock => key : " + key + " , ThreadName : " + Thread.currentThread().getName());
-				}
-			} else {
-				throw new RuntimeException("redis鍒嗗竷寮忛攣娉ㄨВ鍙傛暟寮傚父");
-			}
-		} catch (IllegalMonitorStateException e) {
-			log.error("lock timeout => key : " + key + " , ThreadName : " + Thread.currentThread().getName());
-			throw new RuntimeException("lock timeout => key : " + key);
-		} catch (Exception e) {
-			throw new Exception("redis鍒嗗竷寮忔湭鐭ュ紓甯�", e);
-		}
-	}
-
-	private int getExpireTime(RedisLock annotation) {
-		return annotation.expireTime();
-	}
-
-	private String getRedisKey(Object[] args, String primalKey) {
-		if (args.length == 0) {
-			return primalKey;
-		}
-		// 鑾峰彇#p0...闆嗗悎
-		List<String> keyList = getKeyParsList(primalKey);
-		for (String keyName : keyList) {
-			int keyIndex = Integer.parseInt(keyName.toLowerCase().replace("#p", ""));
-			Object parValue = args[keyIndex];
-			primalKey = primalKey.replace(keyName, String.valueOf(parValue));
-		}
-		return primalKey.replace("+", "").replace("'", "");
-	}
-
-	/**
-	 * 鑾峰彇key涓�#p0涓殑鍙傛暟鍚嶇О
-	 */
-	private static List<String> getKeyParsList(String key) {
-		List<String> listPar = new ArrayList<>();
-		if (key.contains("#")) {
-			int plusIndex = key.substring(key.indexOf("#")).indexOf("+");
-			int indexNext = 0;
-			String parName;
-			int indexPre = key.indexOf("#");
-			if (plusIndex > 0) {
-				indexNext = key.indexOf("#") + plusIndex;
-				parName = key.substring(indexPre, indexNext);
-			} else {
-				parName = key.substring(indexPre);
-			}
-			listPar.add(parName.trim());
-			key = key.substring(indexNext + 1);
-			if (key.contains("#")) {
-				listPar.addAll(getKeyParsList(key));
-			}
-		}
-		return listPar;
-	}
-
-}
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/AsyncConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/AsyncConfig.java
index 5c11ae6..2eb4eb3 100644
--- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/AsyncConfig.java
+++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/AsyncConfig.java
@@ -2,6 +2,8 @@
 
 import com.ruoyi.common.exception.CustomException;
 import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.scheduling.annotation.AsyncConfigurerSupport;
 import org.springframework.scheduling.annotation.EnableAsync;
@@ -9,7 +11,7 @@
 
 import java.util.Arrays;
 import java.util.concurrent.Executor;
-import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
 
 /**
  * 寮傛閰嶇疆
@@ -20,13 +22,16 @@
 @Configuration
 public class AsyncConfig extends AsyncConfigurerSupport {
 
+	@Autowired
+	@Qualifier("scheduledExecutorService")
+	private ScheduledExecutorService scheduledExecutorService;
+
     /**
      * 寮傛鎵ц闇�瑕佷娇鐢ㄦ潈闄愭鏋惰嚜甯︾殑鍖呰绾跨▼姹�  淇濊瘉鏉冮檺淇℃伅鐨勪紶閫�
      */
     @Override
     public Executor getAsyncExecutor() {
-        return new DelegatingSecurityContextExecutorService(
-        	Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()));
+        return new DelegatingSecurityContextExecutorService(scheduledExecutorService);
     }
 
     /**
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/DruidConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/DruidConfig.java
index 3fab843..735f7e3 100644
--- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/DruidConfig.java
+++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/DruidConfig.java
@@ -1,82 +1,22 @@
 package com.ruoyi.framework.config;
 
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-import javax.servlet.Filter;
-import javax.servlet.FilterChain;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.sql.DataSource;
+import com.alibaba.druid.spring.boot.autoconfigure.properties.DruidStatProperties;
+import com.alibaba.druid.util.Utils;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
-import org.springframework.boot.context.properties.ConfigurationProperties;
 import org.springframework.boot.web.servlet.FilterRegistrationBean;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.Primary;
-import com.alibaba.druid.pool.DruidDataSource;
-import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
-import com.alibaba.druid.spring.boot.autoconfigure.properties.DruidStatProperties;
-import com.alibaba.druid.util.Utils;
-import com.ruoyi.common.enums.DataSourceType;
-import com.ruoyi.common.utils.spring.SpringUtils;
-import com.ruoyi.framework.config.properties.DruidProperties;
-import com.ruoyi.framework.datasource.DynamicDataSource;
+
+import javax.servlet.*;
+import java.io.IOException;
 
 /**
  * druid 閰嶇疆澶氭暟鎹簮
- * 
+ *
  * @author ruoyi
  */
 @Configuration
-public class DruidConfig
-{
-    @Bean
-    @ConfigurationProperties("spring.datasource.druid.master")
-    public DataSource masterDataSource(DruidProperties druidProperties)
-    {
-        DruidDataSource dataSource = DruidDataSourceBuilder.create().build();
-        return druidProperties.dataSource(dataSource);
-    }
-
-    @Bean
-    @ConfigurationProperties("spring.datasource.druid.slave")
-    @ConditionalOnProperty(prefix = "spring.datasource.druid.slave", name = "enabled", havingValue = "true")
-    public DataSource slaveDataSource(DruidProperties druidProperties)
-    {
-        DruidDataSource dataSource = DruidDataSourceBuilder.create().build();
-        return druidProperties.dataSource(dataSource);
-    }
-
-    @Bean(name = "dynamicDataSource")
-    @Primary
-    public DynamicDataSource dataSource(DataSource masterDataSource)
-    {
-        Map<Object, Object> targetDataSources = new HashMap<>();
-        targetDataSources.put(DataSourceType.MASTER.name(), masterDataSource);
-        setDataSource(targetDataSources, DataSourceType.SLAVE.name(), "slaveDataSource");
-        return new DynamicDataSource(masterDataSource, targetDataSources);
-    }
-    
-    /**
-     * 璁剧疆鏁版嵁婧�
-     * 
-     * @param targetDataSources 澶囬�夋暟鎹簮闆嗗悎
-     * @param sourceName 鏁版嵁婧愬悕绉�
-     * @param beanName bean鍚嶇О
-     */
-    public void setDataSource(Map<Object, Object> targetDataSources, String sourceName, String beanName)
-    {
-        try
-        {
-            DataSource dataSource = SpringUtils.getBean(beanName);
-            targetDataSources.put(sourceName, dataSource);
-        }
-        catch (Exception e)
-        {
-        }
-    }
+public class DruidConfig {
 
     /**
      * 鍘婚櫎鐩戞帶椤甸潰搴曢儴鐨勫箍鍛�
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/FeignConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/FeignConfig.java
index 478a450..f10769b 100644
--- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/FeignConfig.java
+++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/FeignConfig.java
@@ -1,7 +1,6 @@
 package com.ruoyi.framework.config;
 
 import feign.*;
-import feign.hystrix.HystrixFeign;
 import okhttp3.ConnectionPool;
 import okhttp3.OkHttpClient;
 import org.springframework.boot.autoconfigure.AutoConfigureBefore;
@@ -36,11 +35,6 @@
     }
 
     @Bean
-    public Feign.Builder feignBuilder() {
-        return HystrixFeign.builder();
-    }
-
-    @Bean
     public Contract feignContract() {
         return new SpringMvcContract();
     }
@@ -60,4 +54,4 @@
         return new Retryer.Default();
     }
 
-}
\ No newline at end of file
+}
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/FilterConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/FilterConfig.java
index 73f7f93..b09bc98 100644
--- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/FilterConfig.java
+++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/FilterConfig.java
@@ -30,7 +30,7 @@
         FilterRegistrationBean registration = new FilterRegistrationBean();
         registration.setDispatcherTypes(DispatcherType.REQUEST);
         registration.setFilter(new XssFilter());
-        registration.addUrlPatterns(StrUtil.split(xssProperties.getUrlPatterns(), ","));
+        registration.addUrlPatterns(StrUtil.splitToArray(xssProperties.getUrlPatterns(), ","));
         registration.setName("xssFilter");
         registration.setOrder(FilterRegistrationBean.HIGHEST_PRECEDENCE);
         Map<String, String> initParameters = new HashMap<String, String>();
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/JacksonConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/JacksonConfig.java
index b367100..8334b2a 100644
--- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/JacksonConfig.java
+++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/JacksonConfig.java
@@ -2,35 +2,47 @@
 
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.module.SimpleModule;
-import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
+import com.ruoyi.common.utils.JsonUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.config.BeanPostProcessor;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.Primary;
-import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
+
+import java.time.LocalDateTime;
+import java.util.TimeZone;
 
 /**
- * 褰揗ybatis plus璁剧疆涓洪洩鑺盜D鏃�
- * 浣跨敤姝ょ被锛屼細鎶婃墍鏈夋暟瀛楄繑鍥炲彉涓哄瓧绗︿覆杩斿洖閫傞厤鍓嶇Long鍨嬪け鐪熼棶棰�
+ * jackson 閰嶇疆
  *
- * @author Ming LI
+ * @author Lion Li
  */
+@Slf4j
 @Configuration
 public class JacksonConfig {
 
 	@Bean
-	@Primary
-	@ConditionalOnMissingBean(ObjectMapper.class)
-	@ConditionalOnProperty(value = "mybatis-plus.global-config.dbConfig.idType", havingValue = "ASSIGN_ID")
-	public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {
-		ObjectMapper objectMapper = builder.createXmlMapper(false).build();
-		// 鍏ㄥ眬閰嶇疆搴忓垪鍖栬繑鍥� JSON 澶勭悊
-		SimpleModule simpleModule = new SimpleModule();
-		//JSON Long ==> String
-		simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
-		objectMapper.registerModule(simpleModule);
-		return objectMapper;
+	public BeanPostProcessor objectMapperBeanPostProcessor() {
+		return new BeanPostProcessor() {
+			@Override
+			public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
+				if (!(bean instanceof ObjectMapper)) {
+					return bean;
+				}
+				ObjectMapper objectMapper = (ObjectMapper) bean;
+				// 鍏ㄥ眬閰嶇疆搴忓垪鍖栬繑鍥� JSON 澶勭悊
+				SimpleModule simpleModule = new SimpleModule();
+				simpleModule.addSerializer(LocalDateTime.class, LocalDateTimeSerializer.INSTANCE);
+				simpleModule.addDeserializer(LocalDateTime.class, LocalDateTimeDeserializer.INSTANCE);
+				objectMapper.registerModule(simpleModule);
+				objectMapper.setTimeZone(TimeZone.getDefault());
+				JsonUtils.init(objectMapper);
+				log.info("鍒濆鍖� jackson 閰嶇疆");
+				return bean;
+			}
+		};
 	}
 
 }
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/MybatisPlusConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/MybatisPlusConfig.java
index bce2150..1246a29 100644
--- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/MybatisPlusConfig.java
+++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/MybatisPlusConfig.java
@@ -2,14 +2,20 @@
 
 import com.baomidou.mybatisplus.annotation.DbType;
 import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
+import com.baomidou.mybatisplus.core.injector.AbstractMethod;
+import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector;
+import com.baomidou.mybatisplus.core.injector.ISqlInjector;
 import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
 import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
 import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
+import com.ruoyi.common.core.mybatisplus.methods.InsertAll;
 import com.ruoyi.framework.mybatisplus.CreateAndUpdateMetaObjectHandler;
 import org.mybatis.spring.annotation.MapperScan;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.transaction.annotation.EnableTransactionManagement;
+
+import java.util.List;
 
 /**
  * mybatis-plus閰嶇疆绫�
@@ -94,10 +100,17 @@
 	 * sql娉ㄥ叆鍣ㄩ厤缃�
 	 * https://baomidou.com/guide/sql-injector.html
 	 */
-//	@Bean
-//	public ISqlInjector sqlInjector() {
-//		return new DefaultSqlInjector();
-//	}
+	@Bean
+	public ISqlInjector sqlInjector() {
+		return new DefaultSqlInjector() {
+			@Override
+			public List<AbstractMethod> getMethodList(Class<?> mapperClass) {
+				List<AbstractMethod> methodList = super.getMethodList(mapperClass);
+				methodList.add(new InsertAll());
+				return methodList;
+			}
+		};
+	}
 
 	/**
 	 * TenantLineInnerInterceptor 澶氱鎴锋彃浠�
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ResourcesConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ResourcesConfig.java
index 005f032..c3cdc94 100644
--- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ResourcesConfig.java
+++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ResourcesConfig.java
@@ -29,9 +29,6 @@
     {
         /** 鏈湴鏂囦欢涓婁紶璺緞 */
         registry.addResourceHandler(Constants.RESOURCE_PREFIX + "/**").addResourceLocations("file:" + RuoYiConfig.getProfile() + "/");
-
-        /** swagger閰嶇疆 */
-        registry.addResourceHandler("/swagger-ui/**").addResourceLocations("classpath:/META-INF/resources/webjars/springfox-swagger-ui/");
     }
 
     /**
@@ -53,7 +50,7 @@
         CorsConfiguration config = new CorsConfiguration();
         config.setAllowCredentials(true);
         // 璁剧疆璁块棶婧愬湴鍧�
-        config.addAllowedOrigin("*");
+		config.addAllowedOriginPattern("*");
         // 璁剧疆璁块棶婧愯姹傚ご
         config.addAllowedHeader("*");
         // 璁剧疆璁块棶婧愯姹傛柟娉�
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java
index 4822c91..79ade78 100644
--- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java
+++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java
@@ -21,7 +21,7 @@
 
 /**
  * spring security閰嶇疆
- * 
+ *
  * @author ruoyi
  */
 @EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
@@ -32,7 +32,7 @@
      */
     @Autowired
     private UserDetailsService userDetailsService;
-    
+
     /**
      * 璁よ瘉澶辫触澶勭悊绫�
      */
@@ -59,7 +59,7 @@
 
     @Autowired
     private AdminServerProperties adminServerProperties;
-    
+
     /**
      * 瑙e喅 鏃犳硶鐩存帴娉ㄥ叆 AuthenticationManager
      *
@@ -112,7 +112,7 @@
                 .antMatchers("/profile/**").anonymous()
                 .antMatchers("/common/download**").anonymous()
                 .antMatchers("/common/download/resource**").anonymous()
-                .antMatchers("/swagger-ui.html").anonymous()
+                .antMatchers("/doc.html").anonymous()
                 .antMatchers("/swagger-resources/**").anonymous()
                 .antMatchers("/webjars/**").anonymous()
                 .antMatchers("/*/api-docs").anonymous()
@@ -135,7 +135,7 @@
         httpSecurity.addFilterBefore(corsFilter, LogoutFilter.class);
     }
 
-    
+
     /**
      * 寮烘暎鍒楀搱甯屽姞瀵嗗疄鐜�
      */
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/properties/DruidProperties.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/properties/DruidProperties.java
deleted file mode 100644
index 03ddc2c..0000000
--- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/properties/DruidProperties.java
+++ /dev/null
@@ -1,55 +0,0 @@
-package com.ruoyi.framework.config.properties;
-
-import com.alibaba.druid.pool.DruidDataSource;
-import lombok.Data;
-import org.springframework.boot.context.properties.ConfigurationProperties;
-import org.springframework.context.annotation.Configuration;
-
-/**
- * druid 閰嶇疆灞炴��
- *
- * @author Lion Li
- */
-@Data
-@Configuration
-@ConfigurationProperties(prefix = "spring.datasource.druid")
-public class DruidProperties {
-
-    /** 鍒濆杩炴帴鏁� */
-    private int initialSize;
-    /** 鏈�灏忚繛鎺ユ睜鏁伴噺 */
-    private int minIdle;
-    /** 鏈�澶ц繛鎺ユ睜鏁伴噺 */
-    private int maxActive;
-    /** 閰嶇疆鑾峰彇杩炴帴绛夊緟瓒呮椂鐨勬椂闂� */
-    private int maxWait;
-    /** 閰嶇疆闂撮殧澶氫箙鎵嶈繘琛屼竴娆℃娴嬶紝妫�娴嬮渶瑕佸叧闂殑绌洪棽杩炴帴锛屽崟浣嶆槸姣 */
-    private int timeBetweenEvictionRunsMillis;
-    /** 閰嶇疆涓�涓繛鎺ュ湪姹犱腑鏈�灏忕敓瀛樼殑鏃堕棿锛屽崟浣嶆槸姣 */
-    private int minEvictableIdleTimeMillis;
-    /** 閰嶇疆涓�涓繛鎺ュ湪姹犱腑鏈�澶х敓瀛樼殑鏃堕棿锛屽崟浣嶆槸姣 */
-    private int maxEvictableIdleTimeMillis;
-    /** 閰嶇疆妫�娴嬭繛鎺ユ槸鍚︽湁鏁� */
-    private String validationQuery;
-    /** 鍒濆杩炴帴鏁� */
-    private boolean testWhileIdle;
-    /** 鍒濆杩炴帴鏁� */
-    private boolean testOnBorrow;
-    /** 鍒濆杩炴帴鏁� */
-    private boolean testOnReturn;
-
-    public DruidDataSource dataSource(DruidDataSource datasource) {
-        datasource.setInitialSize(initialSize);
-        datasource.setMaxActive(maxActive);
-        datasource.setMinIdle(minIdle);
-        datasource.setMaxWait(maxWait);
-        datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
-        datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
-        datasource.setMaxEvictableIdleTimeMillis(maxEvictableIdleTimeMillis);
-        datasource.setValidationQuery(validationQuery);
-        datasource.setTestWhileIdle(testWhileIdle);
-        datasource.setTestOnBorrow(testOnBorrow);
-        datasource.setTestOnReturn(testOnReturn);
-        return datasource;
-    }
-}
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/datasource/DynamicDataSource.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/datasource/DynamicDataSource.java
deleted file mode 100644
index e70b8cf..0000000
--- a/ruoyi-framework/src/main/java/com/ruoyi/framework/datasource/DynamicDataSource.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package com.ruoyi.framework.datasource;
-
-import java.util.Map;
-import javax.sql.DataSource;
-import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
-
-/**
- * 鍔ㄦ�佹暟鎹簮
- * 
- * @author ruoyi
- */
-public class DynamicDataSource extends AbstractRoutingDataSource
-{
-    public DynamicDataSource(DataSource defaultTargetDataSource, Map<Object, Object> targetDataSources)
-    {
-        super.setDefaultTargetDataSource(defaultTargetDataSource);
-        super.setTargetDataSources(targetDataSources);
-        super.afterPropertiesSet();
-    }
-
-    @Override
-    protected Object determineCurrentLookupKey()
-    {
-        return DynamicDataSourceContextHolder.getDataSourceType();
-    }
-}
\ No newline at end of file
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/datasource/DynamicDataSourceContextHolder.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/datasource/DynamicDataSourceContextHolder.java
deleted file mode 100644
index 3572db9..0000000
--- a/ruoyi-framework/src/main/java/com/ruoyi/framework/datasource/DynamicDataSourceContextHolder.java
+++ /dev/null
@@ -1,45 +0,0 @@
-package com.ruoyi.framework.datasource;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * 鏁版嵁婧愬垏鎹㈠鐞�
- * 
- * @author ruoyi
- */
-public class DynamicDataSourceContextHolder
-{
-    public static final Logger log = LoggerFactory.getLogger(DynamicDataSourceContextHolder.class);
-
-    /**
-     * 浣跨敤ThreadLocal缁存姢鍙橀噺锛孴hreadLocal涓烘瘡涓娇鐢ㄨ鍙橀噺鐨勭嚎绋嬫彁渚涚嫭绔嬬殑鍙橀噺鍓湰锛�
-     *  鎵�浠ユ瘡涓�涓嚎绋嬮兘鍙互鐙珛鍦版敼鍙樿嚜宸辩殑鍓湰锛岃�屼笉浼氬奖鍝嶅叾瀹冪嚎绋嬫墍瀵瑰簲鐨勫壇鏈��
-     */
-    private static final ThreadLocal<String> CONTEXT_HOLDER = new ThreadLocal<>();
-
-    /**
-     * 璁剧疆鏁版嵁婧愮殑鍙橀噺
-     */
-    public static void setDataSourceType(String dsType)
-    {
-        log.info("鍒囨崲鍒皗}鏁版嵁婧�", dsType);
-        CONTEXT_HOLDER.set(dsType);
-    }
-
-    /**
-     * 鑾峰緱鏁版嵁婧愮殑鍙橀噺
-     */
-    public static String getDataSourceType()
-    {
-        return CONTEXT_HOLDER.get();
-    }
-
-    /**
-     * 娓呯┖鏁版嵁婧愬彉閲�
-     */
-    public static void clearDataSourceType()
-    {
-        CONTEXT_HOLDER.remove();
-    }
-}
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/interceptor/RepeatSubmitInterceptor.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/interceptor/RepeatSubmitInterceptor.java
index d310382..bd0e99e 100644
--- a/ruoyi-framework/src/main/java/com/ruoyi/framework/interceptor/RepeatSubmitInterceptor.java
+++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/interceptor/RepeatSubmitInterceptor.java
@@ -1,55 +1,56 @@
-package com.ruoyi.framework.interceptor;
-
-import java.lang.reflect.Method;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import org.springframework.stereotype.Component;
-import org.springframework.web.method.HandlerMethod;
-import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
-import com.alibaba.fastjson.JSONObject;
-import com.ruoyi.common.annotation.RepeatSubmit;
-import com.ruoyi.common.core.domain.AjaxResult;
-import com.ruoyi.common.utils.ServletUtils;
-
-/**
- * 闃叉閲嶅鎻愪氦鎷︽埅鍣�
- *
- * @author ruoyi
- */
-@Component
-public abstract class RepeatSubmitInterceptor extends HandlerInterceptorAdapter
-{
-    @Override
-    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception
-    {
-        if (handler instanceof HandlerMethod)
-        {
-            HandlerMethod handlerMethod = (HandlerMethod) handler;
-            Method method = handlerMethod.getMethod();
-            RepeatSubmit annotation = method.getAnnotation(RepeatSubmit.class);
-            if (annotation != null)
-            {
-                if (this.isRepeatSubmit(request))
-                {
-                    AjaxResult ajaxResult = AjaxResult.error("涓嶅厑璁搁噸澶嶆彁浜わ紝璇风◢鍚庡啀璇�");
-                    ServletUtils.renderString(response, JSONObject.toJSONString(ajaxResult));
-                    return false;
-                }
-            }
-            return true;
-        }
-        else
-        {
-            return super.preHandle(request, response, handler);
-        }
-    }
-
-    /**
-     * 楠岃瘉鏄惁閲嶅鎻愪氦鐢卞瓙绫诲疄鐜板叿浣撶殑闃查噸澶嶆彁浜ょ殑瑙勫垯
-     *
-     * @param request
-     * @return
-     * @throws Exception
-     */
-    public abstract boolean isRepeatSubmit(HttpServletRequest request);
-}
+package com.ruoyi.framework.interceptor;
+
+import com.ruoyi.common.annotation.RepeatSubmit;
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.utils.JsonUtils;
+import com.ruoyi.common.utils.ServletUtils;
+import org.springframework.stereotype.Component;
+import org.springframework.web.method.HandlerMethod;
+import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.lang.reflect.Method;
+
+/**
+ * 闃叉閲嶅鎻愪氦鎷︽埅鍣�
+ *
+ * @author ruoyi
+ */
+@Component
+public abstract class RepeatSubmitInterceptor extends HandlerInterceptorAdapter
+{
+    @Override
+    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception
+    {
+        if (handler instanceof HandlerMethod)
+        {
+            HandlerMethod handlerMethod = (HandlerMethod) handler;
+            Method method = handlerMethod.getMethod();
+            RepeatSubmit annotation = method.getAnnotation(RepeatSubmit.class);
+            if (annotation != null)
+            {
+                if (this.isRepeatSubmit(request))
+                {
+                    AjaxResult ajaxResult = AjaxResult.error("涓嶅厑璁搁噸澶嶆彁浜わ紝璇风◢鍚庡啀璇�");
+                    ServletUtils.renderString(response, JsonUtils.toJsonString(ajaxResult));
+                    return false;
+                }
+            }
+            return true;
+        }
+        else
+        {
+            return super.preHandle(request, response, handler);
+        }
+    }
+
+    /**
+     * 楠岃瘉鏄惁閲嶅鎻愪氦鐢卞瓙绫诲疄鐜板叿浣撶殑闃查噸澶嶆彁浜ょ殑瑙勫垯
+     *
+     * @param request
+     * @return
+     * @throws Exception
+     */
+    public abstract boolean isRepeatSubmit(HttpServletRequest request);
+}
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/interceptor/impl/SameUrlDataInterceptor.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/interceptor/impl/SameUrlDataInterceptor.java
index 60bbf7c..bc09231 100644
--- a/ruoyi-framework/src/main/java/com/ruoyi/framework/interceptor/impl/SameUrlDataInterceptor.java
+++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/interceptor/impl/SameUrlDataInterceptor.java
@@ -1,126 +1,133 @@
-package com.ruoyi.framework.interceptor.impl;
-
-import cn.hutool.core.lang.Validator;
-import com.alibaba.fastjson.JSONObject;
-import com.ruoyi.common.constant.Constants;
-import com.ruoyi.common.core.redis.RedisCache;
-import com.ruoyi.common.filter.RepeatedlyRequestWrapper;
-import com.ruoyi.common.utils.http.HttpHelper;
-import com.ruoyi.framework.interceptor.RepeatSubmitInterceptor;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.stereotype.Component;
-
-import javax.servlet.http.HttpServletRequest;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.TimeUnit;
-
-/**
- * 鍒ゆ柇璇锋眰url鍜屾暟鎹槸鍚﹀拰涓婁竴娆$浉鍚岋紝
- * 濡傛灉鍜屼笂娆$浉鍚岋紝鍒欐槸閲嶅鎻愪氦琛ㄥ崟銆� 鏈夋晥鏃堕棿涓�10绉掑唴銆�
- * 
- * @author ruoyi
- */
-@Component
-public class SameUrlDataInterceptor extends RepeatSubmitInterceptor
-{
-    public final String REPEAT_PARAMS = "repeatParams";
-
-    public final String REPEAT_TIME = "repeatTime";
-
-    // 浠ょ墝鑷畾涔夋爣璇�
-    @Value("${token.header}")
-    private String header;
-
-    @Autowired
-    private RedisCache redisCache;
-
-    /**
-     * 闂撮殧鏃堕棿锛屽崟浣�:绉� 榛樿10绉�
-     * 
-     * 涓ゆ鐩稿悓鍙傛暟鐨勮姹傦紝濡傛灉闂撮殧鏃堕棿澶т簬璇ュ弬鏁帮紝绯荤粺涓嶄細璁ゅ畾涓洪噸澶嶆彁浜ょ殑鏁版嵁
-     */
-    private int intervalTime = 10;
-
-    public void setIntervalTime(int intervalTime)
-    {
-        this.intervalTime = intervalTime;
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
-    public boolean isRepeatSubmit(HttpServletRequest request)
-    {
-        String nowParams = "";
-        if (request instanceof RepeatedlyRequestWrapper)
-        {
-            RepeatedlyRequestWrapper repeatedlyRequest = (RepeatedlyRequestWrapper) request;
-            nowParams = HttpHelper.getBodyString(repeatedlyRequest);
-        }
-
-        // body鍙傛暟涓虹┖锛岃幏鍙朠arameter鐨勬暟鎹�
-        if (Validator.isEmpty(nowParams))
-        {
-            nowParams = JSONObject.toJSONString(request.getParameterMap());
-        }
-        Map<String, Object> nowDataMap = new HashMap<String, Object>();
-        nowDataMap.put(REPEAT_PARAMS, nowParams);
-        nowDataMap.put(REPEAT_TIME, System.currentTimeMillis());
-
-        // 璇锋眰鍦板潃锛堜綔涓哄瓨鏀綾ache鐨刱ey鍊硷級
-        String url = request.getRequestURI();
-
-        // 鍞竴鍊硷紙娌℃湁娑堟伅澶村垯浣跨敤璇锋眰鍦板潃锛�
-        String submitKey = request.getHeader(header);
-        if (Validator.isEmpty(submitKey))
-        {
-            submitKey = url;
-        }
-
-        // 鍞竴鏍囪瘑锛堟寚瀹歬ey + 娑堟伅澶达級
-        String cacheRepeatKey = Constants.REPEAT_SUBMIT_KEY + submitKey;
-
-        Object sessionObj = redisCache.getCacheObject(cacheRepeatKey);
-        if (sessionObj != null)
-        {
-            Map<String, Object> sessionMap = (Map<String, Object>) sessionObj;
-            if (sessionMap.containsKey(url))
-            {
-                Map<String, Object> preDataMap = (Map<String, Object>) sessionMap.get(url);
-                if (compareParams(nowDataMap, preDataMap) && compareTime(nowDataMap, preDataMap))
-                {
-                    return true;
-                }
-            }
-        }
-        Map<String, Object> cacheMap = new HashMap<String, Object>();
-        cacheMap.put(url, nowDataMap);
-        redisCache.setCacheObject(cacheRepeatKey, cacheMap, intervalTime, TimeUnit.SECONDS);
-        return false;
-    }
-
-    /**
-     * 鍒ゆ柇鍙傛暟鏄惁鐩稿悓
-     */
-    private boolean compareParams(Map<String, Object> nowMap, Map<String, Object> preMap)
-    {
-        String nowParams = (String) nowMap.get(REPEAT_PARAMS);
-        String preParams = (String) preMap.get(REPEAT_PARAMS);
-        return nowParams.equals(preParams);
-    }
-
-    /**
-     * 鍒ゆ柇涓ゆ闂撮殧鏃堕棿
-     */
-    private boolean compareTime(Map<String, Object> nowMap, Map<String, Object> preMap)
-    {
-        long time1 = (Long) nowMap.get(REPEAT_TIME);
-        long time2 = (Long) preMap.get(REPEAT_TIME);
-        if ((time1 - time2) < (this.intervalTime * 1000))
-        {
-            return true;
-        }
-        return false;
-    }
-}
+package com.ruoyi.framework.interceptor.impl;
+
+import cn.hutool.core.io.IoUtil;
+import cn.hutool.core.lang.Validator;
+import com.ruoyi.common.constant.Constants;
+import com.ruoyi.common.core.redis.RedisCache;
+import com.ruoyi.common.filter.RepeatedlyRequestWrapper;
+import com.ruoyi.common.utils.JsonUtils;
+import com.ruoyi.framework.interceptor.RepeatSubmitInterceptor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import javax.servlet.http.HttpServletRequest;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * 鍒ゆ柇璇锋眰url鍜屾暟鎹槸鍚﹀拰涓婁竴娆$浉鍚岋紝
+ * 濡傛灉鍜屼笂娆$浉鍚岋紝鍒欐槸閲嶅鎻愪氦琛ㄥ崟銆� 鏈夋晥鏃堕棿涓�10绉掑唴銆�
+ *
+ * @author ruoyi
+ */
+@Slf4j
+@Component
+public class SameUrlDataInterceptor extends RepeatSubmitInterceptor
+{
+    public final String REPEAT_PARAMS = "repeatParams";
+
+    public final String REPEAT_TIME = "repeatTime";
+
+    // 浠ょ墝鑷畾涔夋爣璇�
+    @Value("${token.header}")
+    private String header;
+
+    @Autowired
+    private RedisCache redisCache;
+
+    /**
+     * 闂撮殧鏃堕棿锛屽崟浣�:绉� 榛樿10绉�
+     *
+     * 涓ゆ鐩稿悓鍙傛暟鐨勮姹傦紝濡傛灉闂撮殧鏃堕棿澶т簬璇ュ弬鏁帮紝绯荤粺涓嶄細璁ゅ畾涓洪噸澶嶆彁浜ょ殑鏁版嵁
+     */
+    private int intervalTime = 10;
+
+    public void setIntervalTime(int intervalTime)
+    {
+        this.intervalTime = intervalTime;
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public boolean isRepeatSubmit(HttpServletRequest request)
+    {
+        String nowParams = "";
+        if (request instanceof RepeatedlyRequestWrapper)
+        {
+            RepeatedlyRequestWrapper repeatedlyRequest = (RepeatedlyRequestWrapper) request;
+			try {
+				nowParams = IoUtil.readUtf8(repeatedlyRequest.getInputStream());
+			} catch (IOException e) {
+				log.warn("璇诲彇娴佸嚭鐜伴棶棰橈紒");
+			}
+		}
+
+        // body鍙傛暟涓虹┖锛岃幏鍙朠arameter鐨勬暟鎹�
+        if (Validator.isEmpty(nowParams))
+        {
+            nowParams = JsonUtils.toJsonString(request.getParameterMap());
+        }
+        Map<String, Object> nowDataMap = new HashMap<String, Object>();
+        nowDataMap.put(REPEAT_PARAMS, nowParams);
+        nowDataMap.put(REPEAT_TIME, System.currentTimeMillis());
+
+        // 璇锋眰鍦板潃锛堜綔涓哄瓨鏀綾ache鐨刱ey鍊硷級
+        String url = request.getRequestURI();
+
+        // 鍞竴鍊硷紙娌℃湁娑堟伅澶村垯浣跨敤璇锋眰鍦板潃锛�
+        String submitKey = request.getHeader(header);
+        if (Validator.isEmpty(submitKey))
+        {
+            submitKey = url;
+        }
+
+        // 鍞竴鏍囪瘑锛堟寚瀹歬ey + 娑堟伅澶达級
+        String cacheRepeatKey = Constants.REPEAT_SUBMIT_KEY + submitKey;
+
+        Object sessionObj = redisCache.getCacheObject(cacheRepeatKey);
+        if (sessionObj != null)
+        {
+            Map<String, Object> sessionMap = (Map<String, Object>) sessionObj;
+            if (sessionMap.containsKey(url))
+            {
+                Map<String, Object> preDataMap = (Map<String, Object>) sessionMap.get(url);
+                if (compareParams(nowDataMap, preDataMap) && compareTime(nowDataMap, preDataMap))
+                {
+                    return true;
+                }
+            }
+        }
+        Map<String, Object> cacheMap = new HashMap<String, Object>();
+        cacheMap.put(url, nowDataMap);
+        redisCache.setCacheObject(cacheRepeatKey, cacheMap, intervalTime, TimeUnit.SECONDS);
+        return false;
+    }
+
+    /**
+     * 鍒ゆ柇鍙傛暟鏄惁鐩稿悓
+     */
+    private boolean compareParams(Map<String, Object> nowMap, Map<String, Object> preMap)
+    {
+        String nowParams = (String) nowMap.get(REPEAT_PARAMS);
+        String preParams = (String) preMap.get(REPEAT_PARAMS);
+        return nowParams.equals(preParams);
+    }
+
+    /**
+     * 鍒ゆ柇涓ゆ闂撮殧鏃堕棿
+     */
+    private boolean compareTime(Map<String, Object> nowMap, Map<String, Object> preMap)
+    {
+        long time1 = (Long) nowMap.get(REPEAT_TIME);
+        long time2 = (Long) preMap.get(REPEAT_TIME);
+        if ((time1 - time2) < (this.intervalTime * 1000))
+        {
+            return true;
+        }
+        return false;
+    }
+}
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/manager/AsyncManager.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/manager/AsyncManager.java
deleted file mode 100644
index 7387a02..0000000
--- a/ruoyi-framework/src/main/java/com/ruoyi/framework/manager/AsyncManager.java
+++ /dev/null
@@ -1,55 +0,0 @@
-package com.ruoyi.framework.manager;
-
-import java.util.TimerTask;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-import com.ruoyi.common.utils.Threads;
-import com.ruoyi.common.utils.spring.SpringUtils;
-
-/**
- * 寮傛浠诲姟绠$悊鍣�
- * 
- * @author ruoyi
- */
-public class AsyncManager
-{
-    /**
-     * 鎿嶄綔寤惰繜10姣
-     */
-    private final int OPERATE_DELAY_TIME = 10;
-
-    /**
-     * 寮傛鎿嶄綔浠诲姟璋冨害绾跨▼姹�
-     */
-    private ScheduledExecutorService executor = SpringUtils.getBean("scheduledExecutorService");
-
-    /**
-     * 鍗曚緥妯″紡
-     */
-    private AsyncManager(){}
-
-    private static AsyncManager me = new AsyncManager();
-
-    public static AsyncManager me()
-    {
-        return me;
-    }
-
-    /**
-     * 鎵ц浠诲姟
-     * 
-     * @param task 浠诲姟
-     */
-    public void execute(TimerTask task)
-    {
-        executor.schedule(task, OPERATE_DELAY_TIME, TimeUnit.MILLISECONDS);
-    }
-
-    /**
-     * 鍋滄浠诲姟绾跨▼姹�
-     */
-    public void shutdown()
-    {
-        Threads.shutdownAndAwaitTermination(executor);
-    }
-}
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/manager/ShutdownManager.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/manager/ShutdownManager.java
index e36ca3c..4ed5366 100644
--- a/ruoyi-framework/src/main/java/com/ruoyi/framework/manager/ShutdownManager.java
+++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/manager/ShutdownManager.java
@@ -1,39 +1,41 @@
 package com.ruoyi.framework.manager;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import com.ruoyi.common.utils.Threads;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.stereotype.Component;
+
 import javax.annotation.PreDestroy;
+import java.util.concurrent.ScheduledExecutorService;
 
 /**
  * 纭繚搴旂敤閫�鍑烘椂鑳藉叧闂悗鍙扮嚎绋�
  *
- * @author ruoyi
+ * @author Lion Li
  */
+@Slf4j(topic = "sys-user")
 @Component
-public class ShutdownManager
-{
-    private static final Logger logger = LoggerFactory.getLogger("sys-user");
+public class ShutdownManager {
 
-    @PreDestroy
-    public void destroy()
-    {
-        shutdownAsyncManager();
-    }
+	@Autowired
+	@Qualifier("scheduledExecutorService")
+	private ScheduledExecutorService scheduledExecutorService;
 
-    /**
-     * 鍋滄寮傛鎵ц浠诲姟
-     */
-    private void shutdownAsyncManager()
-    {
-        try
-        {
-            logger.info("====鍏抽棴鍚庡彴浠诲姟浠诲姟绾跨▼姹�====");
-            AsyncManager.me().shutdown();
-        }
-        catch (Exception e)
-        {
-            logger.error(e.getMessage(), e);
-        }
-    }
+	@PreDestroy
+	public void destroy() {
+		shutdownAsyncManager();
+	}
+
+	/**
+	 * 鍋滄寮傛鎵ц浠诲姟
+	 */
+	private void shutdownAsyncManager() {
+		try {
+			log.info("====鍏抽棴鍚庡彴浠诲姟浠诲姟绾跨▼姹�====");
+			Threads.shutdownAndAwaitTermination(scheduledExecutorService);
+		} catch (Exception e) {
+			log.error(e.getMessage(), e);
+		}
+	}
 }
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/manager/factory/AsyncFactory.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/manager/factory/AsyncFactory.java
deleted file mode 100644
index d0147a2..0000000
--- a/ruoyi-framework/src/main/java/com/ruoyi/framework/manager/factory/AsyncFactory.java
+++ /dev/null
@@ -1,111 +0,0 @@
-package com.ruoyi.framework.manager.factory;
-
-import cn.hutool.http.useragent.UserAgent;
-import cn.hutool.http.useragent.UserAgentUtil;
-import com.ruoyi.common.constant.Constants;
-import com.ruoyi.common.utils.ServletUtils;
-import com.ruoyi.common.utils.ip.AddressUtils;
-import com.ruoyi.common.utils.ip.IpUtils;
-import com.ruoyi.common.utils.spring.SpringUtils;
-import com.ruoyi.system.domain.SysLogininfor;
-import com.ruoyi.system.domain.SysOperLog;
-import com.ruoyi.system.service.ISysLogininforService;
-import com.ruoyi.system.service.ISysOperLogService;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.TimerTask;
-
-/**
- * 寮傛宸ュ巶锛堜骇鐢熶换鍔$敤锛�
- * 
- * @author ruoyi
- */
-public class AsyncFactory
-{
-    private static final Logger sys_user_logger = LoggerFactory.getLogger("sys-user");
-
-    /**
-     * 璁板綍鐧诲綍淇℃伅
-     * 
-     * @param username 鐢ㄦ埛鍚�
-     * @param status 鐘舵��
-     * @param message 娑堟伅
-     * @param args 鍒楄〃
-     * @return 浠诲姟task
-     */
-    public static TimerTask recordLogininfor(final String username, final String status, final String message,
-            final Object... args)
-    {
-        final UserAgent userAgent = UserAgentUtil.parse(ServletUtils.getRequest().getHeader("User-Agent"));
-        final String ip = IpUtils.getIpAddr(ServletUtils.getRequest());
-        return new TimerTask()
-        {
-            @Override
-            public void run()
-            {
-                String address = AddressUtils.getRealAddressByIP(ip);
-                StringBuilder s = new StringBuilder();
-                s.append(getBlock(ip));
-                s.append(address);
-                s.append(getBlock(username));
-                s.append(getBlock(status));
-                s.append(getBlock(message));
-                // 鎵撳嵃淇℃伅鍒版棩蹇�
-                sys_user_logger.info(s.toString(), args);
-                // 鑾峰彇瀹㈡埛绔搷浣滅郴缁�
-                String os = userAgent.getOs().getName();
-                // 鑾峰彇瀹㈡埛绔祻瑙堝櫒
-                String browser = userAgent.getBrowser().getName();
-                // 灏佽瀵硅薄
-                SysLogininfor logininfor = new SysLogininfor();
-                logininfor.setUserName(username);
-                logininfor.setIpaddr(ip);
-                logininfor.setLoginLocation(address);
-                logininfor.setBrowser(browser);
-                logininfor.setOs(os);
-                logininfor.setMsg(message);
-                // 鏃ュ織鐘舵��
-                if (Constants.LOGIN_SUCCESS.equals(status) || Constants.LOGOUT.equals(status))
-                {
-                    logininfor.setStatus(Constants.SUCCESS);
-                }
-                else if (Constants.LOGIN_FAIL.equals(status))
-                {
-                    logininfor.setStatus(Constants.FAIL);
-                }
-                // 鎻掑叆鏁版嵁
-                SpringUtils.getBean(ISysLogininforService.class).insertLogininfor(logininfor);
-            }
-        };
-    }
-
-    /**
-     * 鎿嶄綔鏃ュ織璁板綍
-     * 
-     * @param operLog 鎿嶄綔鏃ュ織淇℃伅
-     * @return 浠诲姟task
-     */
-    public static TimerTask recordOper(final SysOperLog operLog)
-    {
-        return new TimerTask()
-        {
-            @Override
-            public void run()
-            {
-                // 杩滅▼鏌ヨ鎿嶄綔鍦扮偣
-                operLog.setOperLocation(AddressUtils.getRealAddressByIP(operLog.getOperIp()));
-                SpringUtils.getBean(ISysOperLogService.class).insertOperlog(operLog);
-            }
-        };
-    }
-
-    public static String getBlock(Object msg)
-    {
-        if (msg == null)
-        {
-            msg = "";
-        }
-        return "[" + msg.toString() + "]";
-    }
-}
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/security/handle/AuthenticationEntryPointImpl.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/security/handle/AuthenticationEntryPointImpl.java
index 0ff60e2..1cd8d60 100644
--- a/ruoyi-framework/src/main/java/com/ruoyi/framework/security/handle/AuthenticationEntryPointImpl.java
+++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/security/handle/AuthenticationEntryPointImpl.java
@@ -2,8 +2,8 @@
 
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.http.HttpStatus;
-import com.alibaba.fastjson.JSON;
 import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.utils.JsonUtils;
 import com.ruoyi.common.utils.ServletUtils;
 import org.springframework.security.core.AuthenticationException;
 import org.springframework.security.web.AuthenticationEntryPoint;
@@ -16,7 +16,7 @@
 
 /**
  * 璁よ瘉澶辫触澶勭悊绫� 杩斿洖鏈巿鏉�
- * 
+ *
  * @author ruoyi
  */
 @Component
@@ -30,6 +30,6 @@
     {
         int code = HttpStatus.HTTP_UNAUTHORIZED;
         String msg = StrUtil.format("璇锋眰璁块棶锛歿}锛岃璇佸け璐ワ紝鏃犳硶璁块棶绯荤粺璧勬簮", request.getRequestURI());
-        ServletUtils.renderString(response, JSON.toJSONString(AjaxResult.error(code, msg)));
+        ServletUtils.renderString(response, JsonUtils.toJsonString(AjaxResult.error(code, msg)));
     }
 }
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/security/handle/LogoutSuccessHandlerImpl.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/security/handle/LogoutSuccessHandlerImpl.java
index e79f468..2a12126 100644
--- a/ruoyi-framework/src/main/java/com/ruoyi/framework/security/handle/LogoutSuccessHandlerImpl.java
+++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/security/handle/LogoutSuccessHandlerImpl.java
@@ -2,13 +2,12 @@
 
 import cn.hutool.core.lang.Validator;
 import cn.hutool.http.HttpStatus;
-import com.alibaba.fastjson.JSON;
 import com.ruoyi.common.constant.Constants;
 import com.ruoyi.common.core.domain.AjaxResult;
 import com.ruoyi.common.core.domain.model.LoginUser;
+import com.ruoyi.common.utils.JsonUtils;
 import com.ruoyi.common.utils.ServletUtils;
-import com.ruoyi.framework.manager.AsyncManager;
-import com.ruoyi.framework.manager.factory.AsyncFactory;
+import com.ruoyi.framework.web.service.AsyncService;
 import com.ruoyi.framework.web.service.TokenService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Configuration;
@@ -22,33 +21,33 @@
 
 /**
  * 鑷畾涔夐��鍑哄鐞嗙被 杩斿洖鎴愬姛
- * 
+ *
  * @author ruoyi
  */
 @Configuration
-public class LogoutSuccessHandlerImpl implements LogoutSuccessHandler
-{
-    @Autowired
-    private TokenService tokenService;
+public class LogoutSuccessHandlerImpl implements LogoutSuccessHandler {
 
-    /**
-     * 閫�鍑哄鐞�
-     * 
-     * @return
-     */
-    @Override
-    public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
-            throws IOException, ServletException
-    {
-        LoginUser loginUser = tokenService.getLoginUser(request);
-        if (Validator.isNotNull(loginUser))
-        {
-            String userName = loginUser.getUsername();
-            // 鍒犻櫎鐢ㄦ埛缂撳瓨璁板綍
-            tokenService.delLoginUser(loginUser.getToken());
-            // 璁板綍鐢ㄦ埛閫�鍑烘棩蹇�
-            AsyncManager.me().execute(AsyncFactory.recordLogininfor(userName, Constants.LOGOUT, "閫�鍑烘垚鍔�"));
-        }
-        ServletUtils.renderString(response, JSON.toJSONString(AjaxResult.error(HttpStatus.HTTP_OK, "閫�鍑烘垚鍔�")));
-    }
+	@Autowired
+	private TokenService tokenService;
+
+	@Autowired
+	private AsyncService asyncService;
+
+	/**
+	 * 閫�鍑哄鐞�
+	 */
+	@Override
+	public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
+		throws IOException, ServletException {
+		LoginUser loginUser = tokenService.getLoginUser(request);
+		if (Validator.isNotNull(loginUser)) {
+			String userName = loginUser.getUsername();
+			// 鍒犻櫎鐢ㄦ埛缂撳瓨璁板綍
+			tokenService.delLoginUser(loginUser.getToken());
+			// 璁板綍鐢ㄦ埛閫�鍑烘棩蹇�
+			asyncService.recordLogininfor(userName, Constants.LOGOUT, "閫�鍑烘垚鍔�", request);
+		}
+		ServletUtils.renderString(response, JsonUtils.toJsonString(AjaxResult.error(HttpStatus.HTTP_OK, "閫�鍑烘垚鍔�")));
+	}
+
 }
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/AsyncService.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/AsyncService.java
new file mode 100644
index 0000000..e64fbc1
--- /dev/null
+++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/AsyncService.java
@@ -0,0 +1,96 @@
+package com.ruoyi.framework.web.service;
+
+import cn.hutool.http.useragent.UserAgent;
+import cn.hutool.http.useragent.UserAgentUtil;
+import com.ruoyi.common.constant.Constants;
+import com.ruoyi.common.utils.ServletUtils;
+import com.ruoyi.common.utils.ip.AddressUtils;
+import com.ruoyi.system.domain.SysLogininfor;
+import com.ruoyi.system.domain.SysOperLog;
+import com.ruoyi.system.service.ISysLogininforService;
+import com.ruoyi.system.service.ISysOperLogService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Component;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * 寮傛宸ュ巶锛堜骇鐢熶换鍔$敤锛�
+ *
+ * @author Lion Li
+ */
+@Slf4j(topic = "sys-user")
+@Async
+@Component
+public class AsyncService {
+
+	@Autowired
+	private ISysLogininforService iSysLogininforService;
+
+	@Autowired
+	private ISysOperLogService iSysOperLogService;
+
+	/**
+	 * 璁板綍鐧诲綍淇℃伅
+	 *
+	 * @param username 鐢ㄦ埛鍚�
+	 * @param status   鐘舵��
+	 * @param message  娑堟伅
+	 * @param args     鍒楄〃
+	 */
+	public void recordLogininfor(final String username, final String status, final String message,
+								 HttpServletRequest request, final Object... args) {
+		final UserAgent userAgent = UserAgentUtil.parse(request.getHeader("User-Agent"));
+		final String ip = ServletUtils.getClientIP(request);
+
+		String address = AddressUtils.getRealAddressByIP(ip);
+		StringBuilder s = new StringBuilder();
+		s.append(getBlock(ip));
+		s.append(address);
+		s.append(getBlock(username));
+		s.append(getBlock(status));
+		s.append(getBlock(message));
+		// 鎵撳嵃淇℃伅鍒版棩蹇�
+		log.info(s.toString(), args);
+		// 鑾峰彇瀹㈡埛绔搷浣滅郴缁�
+		String os = userAgent.getOs().getName();
+		// 鑾峰彇瀹㈡埛绔祻瑙堝櫒
+		String browser = userAgent.getBrowser().getName();
+		// 灏佽瀵硅薄
+		SysLogininfor logininfor = new SysLogininfor();
+		logininfor.setUserName(username);
+		logininfor.setIpaddr(ip);
+		logininfor.setLoginLocation(address);
+		logininfor.setBrowser(browser);
+		logininfor.setOs(os);
+		logininfor.setMsg(message);
+		// 鏃ュ織鐘舵��
+		if (Constants.LOGIN_SUCCESS.equals(status) || Constants.LOGOUT.equals(status)) {
+			logininfor.setStatus(Constants.SUCCESS);
+		} else if (Constants.LOGIN_FAIL.equals(status)) {
+			logininfor.setStatus(Constants.FAIL);
+		}
+		// 鎻掑叆鏁版嵁
+		iSysLogininforService.insertLogininfor(logininfor);
+	}
+
+	/**
+	 * 鎿嶄綔鏃ュ織璁板綍
+	 *
+	 * @param operLog 鎿嶄綔鏃ュ織淇℃伅
+	 */
+	public void recordOper(final SysOperLog operLog) {
+		// 杩滅▼鏌ヨ鎿嶄綔鍦扮偣
+		operLog.setOperLocation(AddressUtils.getRealAddressByIP(operLog.getOperIp()));
+		iSysOperLogService.insertOperlog(operLog);
+	}
+
+	private String getBlock(Object msg) {
+		if (msg == null) {
+			msg = "";
+		}
+		return "[" + msg.toString() + "]";
+	}
+}
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java
index bc22ca0..d0b9511 100644
--- a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java
+++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java
@@ -11,10 +11,7 @@
 import com.ruoyi.common.utils.DateUtils;
 import com.ruoyi.common.utils.MessageUtils;
 import com.ruoyi.common.utils.ServletUtils;
-import com.ruoyi.common.utils.ip.IpUtils;
 import com.ruoyi.framework.config.properties.CaptchaProperties;
-import com.ruoyi.framework.manager.AsyncManager;
-import com.ruoyi.framework.manager.factory.AsyncFactory;
 import com.ruoyi.system.service.ISysUserService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.authentication.AuthenticationManager;
@@ -24,6 +21,7 @@
 import org.springframework.stereotype.Component;
 
 import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
 
 /**
  * 鐧诲綍鏍¢獙鏂规硶
@@ -48,6 +46,9 @@
 	@Autowired
     private ISysUserService userService;
 
+	@Autowired
+	private AsyncService asyncService;
+
     /**
      * 鐧诲綍楠岃瘉
      *
@@ -59,16 +60,17 @@
      */
     public String login(String username, String password, String code, String uuid)
     {
+		HttpServletRequest request = ServletUtils.getRequest();
 		if(captchaProperties.getEnabled()) {
 			String verifyKey = Constants.CAPTCHA_CODE_KEY + uuid;
 			String captcha = redisCache.getCacheObject(verifyKey);
 			redisCache.deleteObject(verifyKey);
 			if (captcha == null) {
-				AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire")));
+				asyncService.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire"), request);
 				throw new CaptchaExpireException();
 			}
 			if (!code.equalsIgnoreCase(captcha)) {
-				AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error")));
+				asyncService.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error"), request);
 				throw new CaptchaException();
 			}
 		}
@@ -84,16 +86,16 @@
         {
             if (e instanceof BadCredentialsException)
             {
-                AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
+				asyncService.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match"), request);
                 throw new UserPasswordNotMatchException();
             }
             else
             {
-                AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, e.getMessage()));
+				asyncService.recordLogininfor(username, Constants.LOGIN_FAIL, e.getMessage(), request);
                 throw new CustomException(e.getMessage());
             }
         }
-        AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
+		asyncService.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"), request);
         LoginUser loginUser = (LoginUser) authentication.getPrincipal();
         recordLoginInfo(loginUser.getUser());
         // 鐢熸垚token
@@ -105,7 +107,7 @@
      */
     public void recordLoginInfo(SysUser user)
     {
-        user.setLoginIp(IpUtils.getIpAddr(ServletUtils.getRequest()));
+        user.setLoginIp(ServletUtils.getClientIP());
         user.setLoginDate(DateUtils.getNowDate());
 		user.setUpdateBy(user.getUserName());
         userService.updateUserProfile(user);
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/TokenService.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/TokenService.java
index 0db777b..f834570 100644
--- a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/TokenService.java
+++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/TokenService.java
@@ -9,7 +9,6 @@
 import com.ruoyi.common.core.redis.RedisCache;
 import com.ruoyi.common.utils.ServletUtils;
 import com.ruoyi.common.utils.ip.AddressUtils;
-import com.ruoyi.common.utils.ip.IpUtils;
 import com.ruoyi.framework.config.properties.TokenProperties;
 import io.jsonwebtoken.Claims;
 import io.jsonwebtoken.Jwts;
@@ -131,7 +130,7 @@
      */
     public void setUserAgent(LoginUser loginUser) {
         UserAgent userAgent = UserAgentUtil.parse(ServletUtils.getRequest().getHeader("User-Agent"));
-        String ip = IpUtils.getIpAddr(ServletUtils.getRequest());
+        String ip = ServletUtils.getClientIP();
         loginUser.setIpaddr(ip);
         loginUser.setLoginLocation(AddressUtils.getRealAddressByIP(ip));
         loginUser.setBrowser(userAgent.getBrowser().getName());
diff --git a/ruoyi-generator/src/main/java/com/ruoyi/generator/mapper/GenTableColumnMapper.java b/ruoyi-generator/src/main/java/com/ruoyi/generator/mapper/GenTableColumnMapper.java
index 5a2691a..dc51009 100644
--- a/ruoyi-generator/src/main/java/com/ruoyi/generator/mapper/GenTableColumnMapper.java
+++ b/ruoyi-generator/src/main/java/com/ruoyi/generator/mapper/GenTableColumnMapper.java
@@ -1,6 +1,6 @@
 package com.ruoyi.generator.mapper;
 
-import com.ruoyi.common.core.page.BaseMapperPlus;
+import com.ruoyi.common.core.mybatisplus.core.BaseMapperPlus;
 import com.ruoyi.generator.domain.GenTableColumn;
 
 import java.util.List;
diff --git a/ruoyi-generator/src/main/java/com/ruoyi/generator/mapper/GenTableMapper.java b/ruoyi-generator/src/main/java/com/ruoyi/generator/mapper/GenTableMapper.java
index 85da309..3d3e4b9 100644
--- a/ruoyi-generator/src/main/java/com/ruoyi/generator/mapper/GenTableMapper.java
+++ b/ruoyi-generator/src/main/java/com/ruoyi/generator/mapper/GenTableMapper.java
@@ -1,7 +1,7 @@
 package com.ruoyi.generator.mapper;
 
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.ruoyi.common.core.page.BaseMapperPlus;
+import com.ruoyi.common.core.mybatisplus.core.BaseMapperPlus;
 import com.ruoyi.generator.domain.GenTable;
 import org.apache.ibatis.annotations.Param;
 
diff --git a/ruoyi-generator/src/main/java/com/ruoyi/generator/service/GenTableColumnServiceImpl.java b/ruoyi-generator/src/main/java/com/ruoyi/generator/service/GenTableColumnServiceImpl.java
index 40f0738..44baf82 100644
--- a/ruoyi-generator/src/main/java/com/ruoyi/generator/service/GenTableColumnServiceImpl.java
+++ b/ruoyi-generator/src/main/java/com/ruoyi/generator/service/GenTableColumnServiceImpl.java
@@ -1,7 +1,7 @@
 package com.ruoyi.generator.service;
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.common.core.mybatisplus.core.ServicePlusImpl;
 import com.ruoyi.generator.domain.GenTableColumn;
 import com.ruoyi.generator.mapper.GenTableColumnMapper;
 import org.springframework.stereotype.Service;
@@ -15,7 +15,7 @@
  * @author ruoyi
  */
 @Service
-public class GenTableColumnServiceImpl extends ServiceImpl<GenTableColumnMapper, GenTableColumn> implements IGenTableColumnService {
+public class GenTableColumnServiceImpl extends ServicePlusImpl<GenTableColumnMapper, GenTableColumn> implements IGenTableColumnService {
 
     /**
      * 鏌ヨ涓氬姟瀛楁鍒楄〃
diff --git a/ruoyi-generator/src/main/java/com/ruoyi/generator/service/GenTableServiceImpl.java b/ruoyi-generator/src/main/java/com/ruoyi/generator/service/GenTableServiceImpl.java
index f156e4f..4da27e8 100644
--- a/ruoyi-generator/src/main/java/com/ruoyi/generator/service/GenTableServiceImpl.java
+++ b/ruoyi-generator/src/main/java/com/ruoyi/generator/service/GenTableServiceImpl.java
@@ -1,17 +1,17 @@
 package com.ruoyi.generator.service;
 
 import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.convert.Convert;
 import cn.hutool.core.lang.Validator;
 import cn.hutool.core.util.StrUtil;
-import com.alibaba.fastjson.JSON;
-import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.ruoyi.common.constant.Constants;
 import com.ruoyi.common.constant.GenConstants;
+import com.ruoyi.common.core.mybatisplus.core.ServicePlusImpl;
 import com.ruoyi.common.core.page.TableDataInfo;
 import com.ruoyi.common.exception.CustomException;
+import com.ruoyi.common.utils.JsonUtils;
 import com.ruoyi.common.utils.PageUtils;
 import com.ruoyi.common.utils.SecurityUtils;
 import com.ruoyi.common.utils.file.FileUtils;
@@ -50,7 +50,7 @@
  */
 @Slf4j
 @Service
-public class GenTableServiceImpl extends ServiceImpl<GenTableMapper, GenTable> implements IGenTableService {
+public class GenTableServiceImpl extends ServicePlusImpl<GenTableMapper, GenTable> implements IGenTableService {
 
     @Autowired
     private GenTableColumnMapper genTableColumnMapper;
@@ -130,7 +130,7 @@
     @Override
     @Transactional
     public void updateGenTable(GenTable genTable) {
-        String options = JSON.toJSONString(genTable.getParams());
+        String options = JsonUtils.toJsonString(genTable.getParams());
         genTable.setOptions(options);
         int row = baseMapper.updateById(genTable);
         if (row > 0) {
@@ -263,12 +263,8 @@
                 StringWriter sw = new StringWriter();
                 Template tpl = Velocity.getTemplate(template, Constants.UTF8);
                 tpl.merge(context, sw);
-                try {
-                    String path = getGenPath(table, template);
-                    FileUtils.writeStringToFile(new File(path), sw.toString(), Constants.UTF8);
-                } catch (IOException e) {
-                    throw new CustomException("娓叉煋妯℃澘澶辫触锛岃〃鍚嶏細" + table.getTableName());
-                }
+                String path = getGenPath(table, template);
+                FileUtils.writeUtf8String(sw.toString(), path);
             }
         }
     }
@@ -365,13 +361,12 @@
     @Override
     public void validateEdit(GenTable genTable) {
         if (GenConstants.TPL_TREE.equals(genTable.getTplCategory())) {
-            String options = JSON.toJSONString(genTable.getParams());
-            JSONObject paramsObj = JSONObject.parseObject(options);
-            if (Validator.isEmpty(paramsObj.getString(GenConstants.TREE_CODE))) {
+			Map<String, Object> paramsObj = genTable.getParams();
+            if (Validator.isEmpty(paramsObj.get(GenConstants.TREE_CODE))) {
                 throw new CustomException("鏍戠紪鐮佸瓧娈典笉鑳戒负绌�");
-            } else if (Validator.isEmpty(paramsObj.getString(GenConstants.TREE_PARENT_CODE))) {
+            } else if (Validator.isEmpty(paramsObj.get(GenConstants.TREE_PARENT_CODE))) {
                 throw new CustomException("鏍戠埗缂栫爜瀛楁涓嶈兘涓虹┖");
-            } else if (Validator.isEmpty(paramsObj.getString(GenConstants.TREE_NAME))) {
+            } else if (Validator.isEmpty(paramsObj.get(GenConstants.TREE_NAME))) {
                 throw new CustomException("鏍戝悕绉板瓧娈典笉鑳戒负绌�");
             } else if (GenConstants.TPL_SUB.equals(genTable.getTplCategory())) {
                 if (Validator.isEmpty(genTable.getSubTableName())) {
@@ -429,13 +424,13 @@
      * @param genTable 璁剧疆鍚庣殑鐢熸垚瀵硅薄
      */
     public void setTableFromOptions(GenTable genTable) {
-        JSONObject paramsObj = JSONObject.parseObject(genTable.getOptions());
+		Map<String, Object> paramsObj = JsonUtils.parseMap(genTable.getOptions());
         if (Validator.isNotNull(paramsObj)) {
-            String treeCode = paramsObj.getString(GenConstants.TREE_CODE);
-            String treeParentCode = paramsObj.getString(GenConstants.TREE_PARENT_CODE);
-            String treeName = paramsObj.getString(GenConstants.TREE_NAME);
-            String parentMenuId = paramsObj.getString(GenConstants.PARENT_MENU_ID);
-            String parentMenuName = paramsObj.getString(GenConstants.PARENT_MENU_NAME);
+            String treeCode = Convert.toStr(paramsObj.get(GenConstants.TREE_CODE));
+            String treeParentCode = Convert.toStr(paramsObj.get(GenConstants.TREE_PARENT_CODE));
+            String treeName = Convert.toStr(paramsObj.get(GenConstants.TREE_NAME));
+            String parentMenuId = Convert.toStr(paramsObj.get(GenConstants.PARENT_MENU_ID));
+            String parentMenuName = Convert.toStr(paramsObj.get(GenConstants.PARENT_MENU_NAME));
 
             genTable.setTreeCode(treeCode);
             genTable.setTreeParentCode(treeParentCode);
@@ -448,7 +443,7 @@
     /**
      * 鑾峰彇浠g爜鐢熸垚鍦板潃
      *
-     * @param table    涓氬姟琛ㄤ俊鎭�
+     * @param table 涓氬姟琛ㄤ俊鎭�
      * @param template 妯℃澘鏂囦欢璺緞
      * @return 鐢熸垚鍦板潃
      */
diff --git a/ruoyi-generator/src/main/java/com/ruoyi/generator/service/IGenTableColumnService.java b/ruoyi-generator/src/main/java/com/ruoyi/generator/service/IGenTableColumnService.java
index 22946f2..38d3854 100644
--- a/ruoyi-generator/src/main/java/com/ruoyi/generator/service/IGenTableColumnService.java
+++ b/ruoyi-generator/src/main/java/com/ruoyi/generator/service/IGenTableColumnService.java
@@ -1,6 +1,6 @@
 package com.ruoyi.generator.service;
 
-import com.ruoyi.common.core.page.IServicePlus;
+import com.ruoyi.common.core.mybatisplus.core.IServicePlus;
 import com.ruoyi.generator.domain.GenTableColumn;
 
 import java.util.List;
diff --git a/ruoyi-generator/src/main/java/com/ruoyi/generator/service/IGenTableService.java b/ruoyi-generator/src/main/java/com/ruoyi/generator/service/IGenTableService.java
index cbfeae4..a44dd5e 100644
--- a/ruoyi-generator/src/main/java/com/ruoyi/generator/service/IGenTableService.java
+++ b/ruoyi-generator/src/main/java/com/ruoyi/generator/service/IGenTableService.java
@@ -1,6 +1,6 @@
 package com.ruoyi.generator.service;
 
-import com.ruoyi.common.core.page.IServicePlus;
+import com.ruoyi.common.core.mybatisplus.core.IServicePlus;
 import com.ruoyi.common.core.page.TableDataInfo;
 import com.ruoyi.generator.domain.GenTable;
 
diff --git a/ruoyi-generator/src/main/java/com/ruoyi/generator/util/GenUtils.java b/ruoyi-generator/src/main/java/com/ruoyi/generator/util/GenUtils.java
index 283ba19..928a051 100644
--- a/ruoyi-generator/src/main/java/com/ruoyi/generator/util/GenUtils.java
+++ b/ruoyi-generator/src/main/java/com/ruoyi/generator/util/GenUtils.java
@@ -11,7 +11,7 @@
 
 /**
  * 浠g爜鐢熸垚鍣� 宸ュ叿绫�
- * 
+ *
  * @author ruoyi
  */
 public class GenUtils
@@ -61,7 +61,7 @@
             column.setHtmlType(GenConstants.HTML_INPUT);
 
             // 濡傛灉鏄诞鐐瑰瀷 缁熶竴鐢˙igDecimal
-            String[] str = StrUtil.split(StrUtil.subBetween(column.getColumnType(), "(", ")"), ",");
+            String[] str = StrUtil.splitToArray(StrUtil.subBetween(column.getColumnType(), "(", ")"), ",");
             if (str != null && str.length == 2 && Integer.parseInt(str[1]) > 0)
             {
                 column.setJavaType(GenConstants.TYPE_BIGDECIMAL);
@@ -132,7 +132,7 @@
 
     /**
      * 鏍¢獙鏁扮粍鏄惁鍖呭惈鎸囧畾鍊�
-     * 
+     *
      * @param arr 鏁扮粍
      * @param targetValue 鍊�
      * @return 鏄惁鍖呭惈
@@ -144,7 +144,7 @@
 
     /**
      * 鑾峰彇妯″潡鍚�
-     * 
+     *
      * @param packageName 鍖呭悕
      * @return 妯″潡鍚�
      */
@@ -158,7 +158,7 @@
 
     /**
      * 鑾峰彇涓氬姟鍚�
-     * 
+     *
      * @param tableName 琛ㄥ悕
      * @return 涓氬姟鍚�
      */
@@ -172,7 +172,7 @@
 
     /**
      * 琛ㄥ悕杞崲鎴怞ava绫诲悕
-     * 
+     *
      * @param tableName 琛ㄥ悕绉�
      * @return 绫诲悕
      */
@@ -182,7 +182,7 @@
         String tablePrefix = GenConfig.getTablePrefix();
         if (autoRemovePre && StrUtil.isNotEmpty(tablePrefix))
         {
-            String[] searchList = StrUtil.split(tablePrefix, ",");
+            String[] searchList = StrUtil.splitToArray(tablePrefix, ",");
             tableName = replaceFirst(tableName, searchList);
         }
         return StrUtil.upperFirst(StrUtil.toCamelCase(tableName));
@@ -190,7 +190,7 @@
 
     /**
      * 鎵归噺鏇挎崲鍓嶇紑
-     * 
+     *
      * @param replacementm 鏇挎崲鍊�
      * @param searchList 鏇挎崲鍒楄〃
      * @return
@@ -211,7 +211,7 @@
 
     /**
      * 鍏抽敭瀛楁浛鎹�
-     * 
+     *
      * @param text 闇�瑕佽鏇挎崲鐨勫悕瀛�
      * @return 鏇挎崲鍚庣殑鍚嶅瓧
      */
@@ -222,7 +222,7 @@
 
     /**
      * 鑾峰彇鏁版嵁搴撶被鍨嬪瓧娈�
-     * 
+     *
      * @param columnType 鍒楃被鍨�
      * @return 鎴彇鍚庣殑鍒楃被鍨�
      */
@@ -240,7 +240,7 @@
 
     /**
      * 鑾峰彇瀛楁闀垮害
-     * 
+     *
      * @param columnType 鍒楃被鍨�
      * @return 鎴彇鍚庣殑鍒楃被鍨�
      */
diff --git a/ruoyi-generator/src/main/java/com/ruoyi/generator/util/VelocityUtils.java b/ruoyi-generator/src/main/java/com/ruoyi/generator/util/VelocityUtils.java
index 69421cc..76073c7 100644
--- a/ruoyi-generator/src/main/java/com/ruoyi/generator/util/VelocityUtils.java
+++ b/ruoyi-generator/src/main/java/com/ruoyi/generator/util/VelocityUtils.java
@@ -1,10 +1,11 @@
 package com.ruoyi.generator.util;
 
+import cn.hutool.core.convert.Convert;
 import cn.hutool.core.lang.Validator;
 import cn.hutool.core.util.StrUtil;
-import com.alibaba.fastjson.JSONObject;
 import com.ruoyi.common.constant.GenConstants;
 import com.ruoyi.common.utils.DateUtils;
+import com.ruoyi.common.utils.JsonUtils;
 import com.ruoyi.generator.domain.GenTable;
 import com.ruoyi.generator.domain.GenTableColumn;
 import org.apache.velocity.VelocityContext;
@@ -12,10 +13,11 @@
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
 
 /**
  * 妯℃澘澶勭悊宸ュ叿绫�
- * 
+ *
  * @author ruoyi
  */
 public class VelocityUtils
@@ -75,7 +77,7 @@
     public static void setMenuVelocityContext(VelocityContext context, GenTable genTable)
     {
         String options = genTable.getOptions();
-        JSONObject paramsObj = JSONObject.parseObject(options);
+		Map<String, Object> paramsObj = JsonUtils.parseMap(options);
         String parentMenuId = getParentMenuId(paramsObj);
         context.put("parentMenuId", parentMenuId);
     }
@@ -83,7 +85,7 @@
     public static void setTreeVelocityContext(VelocityContext context, GenTable genTable)
     {
         String options = genTable.getOptions();
-        JSONObject paramsObj = JSONObject.parseObject(options);
+		Map<String, Object> paramsObj = JsonUtils.parseMap(options);
         String treeCode = getTreecode(paramsObj);
         String treeParentCode = getTreeParentCode(paramsObj);
         String treeName = getTreeName(paramsObj);
@@ -94,11 +96,11 @@
         context.put("expandColumn", getExpandColumn(genTable));
         if (paramsObj.containsKey(GenConstants.TREE_PARENT_CODE))
         {
-            context.put("tree_parent_code", paramsObj.getString(GenConstants.TREE_PARENT_CODE));
+            context.put("tree_parent_code", paramsObj.get(GenConstants.TREE_PARENT_CODE));
         }
         if (paramsObj.containsKey(GenConstants.TREE_NAME))
         {
-            context.put("tree_name", paramsObj.getString(GenConstants.TREE_NAME));
+            context.put("tree_name", paramsObj.get(GenConstants.TREE_NAME));
         }
     }
 
@@ -300,11 +302,11 @@
      * @param paramsObj 鐢熸垚鍏朵粬閫夐」
      * @return 涓婄骇鑿滃崟ID瀛楁
      */
-    public static String getParentMenuId(JSONObject paramsObj)
+    public static String getParentMenuId(Map<String, Object> paramsObj)
     {
         if (Validator.isNotEmpty(paramsObj) && paramsObj.containsKey(GenConstants.PARENT_MENU_ID))
         {
-            return paramsObj.getString(GenConstants.PARENT_MENU_ID);
+            return Convert.toStr(paramsObj.get(GenConstants.PARENT_MENU_ID));
         }
         return DEFAULT_PARENT_MENU_ID;
     }
@@ -315,11 +317,11 @@
      * @param paramsObj 鐢熸垚鍏朵粬閫夐」
      * @return 鏍戠紪鐮�
      */
-    public static String getTreecode(JSONObject paramsObj)
+    public static String getTreecode(Map<String, Object> paramsObj)
     {
-        if (paramsObj.containsKey(GenConstants.TREE_CODE))
+        if (Validator.isNotEmpty(paramsObj) && paramsObj.containsKey(GenConstants.TREE_CODE))
         {
-            return StrUtil.toCamelCase(paramsObj.getString(GenConstants.TREE_CODE));
+            return StrUtil.toCamelCase(Convert.toStr(paramsObj.get(GenConstants.TREE_CODE)));
         }
         return StrUtil.EMPTY;
     }
@@ -330,11 +332,11 @@
      * @param paramsObj 鐢熸垚鍏朵粬閫夐」
      * @return 鏍戠埗缂栫爜
      */
-    public static String getTreeParentCode(JSONObject paramsObj)
+    public static String getTreeParentCode(Map<String, Object> paramsObj)
     {
-        if (paramsObj.containsKey(GenConstants.TREE_PARENT_CODE))
+        if (Validator.isNotEmpty(paramsObj) && paramsObj.containsKey(GenConstants.TREE_PARENT_CODE))
         {
-            return StrUtil.toCamelCase(paramsObj.getString(GenConstants.TREE_PARENT_CODE));
+            return StrUtil.toCamelCase(Convert.toStr(paramsObj.get(GenConstants.TREE_PARENT_CODE)));
         }
         return StrUtil.EMPTY;
     }
@@ -345,11 +347,11 @@
      * @param paramsObj 鐢熸垚鍏朵粬閫夐」
      * @return 鏍戝悕绉�
      */
-    public static String getTreeName(JSONObject paramsObj)
+    public static String getTreeName(Map<String, Object> paramsObj)
     {
-        if (paramsObj.containsKey(GenConstants.TREE_NAME))
+        if (Validator.isNotEmpty(paramsObj) && paramsObj.containsKey(GenConstants.TREE_NAME))
         {
-            return StrUtil.toCamelCase(paramsObj.getString(GenConstants.TREE_NAME));
+            return StrUtil.toCamelCase(Convert.toStr(paramsObj.get(GenConstants.TREE_NAME)));
         }
         return StrUtil.EMPTY;
     }
@@ -363,8 +365,8 @@
     public static int getExpandColumn(GenTable genTable)
     {
         String options = genTable.getOptions();
-        JSONObject paramsObj = JSONObject.parseObject(options);
-        String treeName = paramsObj.getString(GenConstants.TREE_NAME);
+        Map<String, Object> paramsObj = JsonUtils.parseMap(options);
+        String treeName = Convert.toStr(paramsObj.get(GenConstants.TREE_NAME));
         int num = 0;
         for (GenTableColumn column : genTable.getColumns())
         {
diff --git a/ruoyi-generator/src/main/resources/vm/java/addBo.java.vm b/ruoyi-generator/src/main/resources/vm/java/addBo.java.vm
index e010d20..82d0862 100644
--- a/ruoyi-generator/src/main/resources/vm/java/addBo.java.vm
+++ b/ruoyi-generator/src/main/resources/vm/java/addBo.java.vm
@@ -2,7 +2,6 @@
 
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
-import com.fasterxml.jackson.annotation.JsonFormat;
 import lombok.Data;
 import java.util.Date;
 import javax.validation.constraints.*;
@@ -27,9 +26,6 @@
 
     /** $column.columnComment */
     @ApiModelProperty("$column.columnComment")
-#if($column.javaType == 'Date')
-    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
-#end
 #if($column.isRequired==1)
 #if($column.javaType == 'String')
     @NotBlank(message = "$column.columnComment涓嶈兘涓虹┖")
diff --git a/ruoyi-generator/src/main/resources/vm/java/domain.java.vm b/ruoyi-generator/src/main/resources/vm/java/domain.java.vm
index b6eca82..5832be6 100644
--- a/ruoyi-generator/src/main/resources/vm/java/domain.java.vm
+++ b/ruoyi-generator/src/main/resources/vm/java/domain.java.vm
@@ -7,7 +7,6 @@
 import java.io.Serializable;
 import java.util.Date;
 import java.math.BigDecimal;
-import com.ruoyi.common.annotation.Excel;
 
 /**
  * ${functionName}瀵硅薄 ${tableName}
diff --git a/ruoyi-generator/src/main/resources/vm/java/editBo.java.vm b/ruoyi-generator/src/main/resources/vm/java/editBo.java.vm
index 60b7e34..3533a91 100644
--- a/ruoyi-generator/src/main/resources/vm/java/editBo.java.vm
+++ b/ruoyi-generator/src/main/resources/vm/java/editBo.java.vm
@@ -2,7 +2,6 @@
 
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
-import com.fasterxml.jackson.annotation.JsonFormat;
 import lombok.Data;
 import java.util.Date;
 import javax.validation.constraints.*;
@@ -26,9 +25,6 @@
 
     /** $column.columnComment */
     @ApiModelProperty("$column.columnComment")
-#if($column.javaType == 'Date')
-    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
-#end
 #if($column.isRequired==1)
 #if($column.javaType == 'String')
     @NotBlank(message = "$column.columnComment涓嶈兘涓虹┖")
diff --git a/ruoyi-generator/src/main/resources/vm/java/mapper.java.vm b/ruoyi-generator/src/main/resources/vm/java/mapper.java.vm
index 36a9864..6d4f40f 100644
--- a/ruoyi-generator/src/main/resources/vm/java/mapper.java.vm
+++ b/ruoyi-generator/src/main/resources/vm/java/mapper.java.vm
@@ -1,8 +1,8 @@
 package ${packageName}.mapper;
 
 import ${packageName}.domain.${ClassName};
-import com.ruoyi.common.core.page.BaseMapperPlus;
-import com.ruoyi.common.core.mybatisplus.MybatisPlusRedisCache;
+import com.ruoyi.common.core.mybatisplus.core.BaseMapperPlus;
+import com.ruoyi.common.core.mybatisplus.cache.MybatisPlusRedisCache;
 import org.apache.ibatis.annotations.CacheNamespace;
 
 /**
@@ -11,6 +11,7 @@
  * @author ${author}
  * @date ${datetime}
  */
+// 濡備娇闇�鍒囨崲鏁版嵁婧� 璇峰嬁浣跨敤缂撳瓨 浼氶�犳垚鏁版嵁涓嶄竴鑷寸幇璞�
 @CacheNamespace(implementation = MybatisPlusRedisCache.class, eviction = MybatisPlusRedisCache.class)
 public interface ${ClassName}Mapper extends BaseMapperPlus<${ClassName}> {
 
diff --git a/ruoyi-generator/src/main/resources/vm/java/queryBo.java.vm b/ruoyi-generator/src/main/resources/vm/java/queryBo.java.vm
index c7be089..4c2b7ee 100644
--- a/ruoyi-generator/src/main/resources/vm/java/queryBo.java.vm
+++ b/ruoyi-generator/src/main/resources/vm/java/queryBo.java.vm
@@ -50,9 +50,6 @@
 #foreach ($column in $columns)
 #if(!$table.isSuperColumn($column.javaField) && $column.query)
 	/** $column.columnComment */
-#if($column.javaType == 'Date')
-	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
-#end
 	@ApiModelProperty("$column.columnComment")
 	private $column.javaType $column.javaField;
 #end
diff --git a/ruoyi-generator/src/main/resources/vm/java/service.java.vm b/ruoyi-generator/src/main/resources/vm/java/service.java.vm
index d5016d4..9ae8620 100644
--- a/ruoyi-generator/src/main/resources/vm/java/service.java.vm
+++ b/ruoyi-generator/src/main/resources/vm/java/service.java.vm
@@ -5,7 +5,7 @@
 import ${packageName}.bo.${ClassName}QueryBo;
 import ${packageName}.bo.${ClassName}AddBo;
 import ${packageName}.bo.${ClassName}EditBo;
-import com.ruoyi.common.core.page.IServicePlus;
+import com.ruoyi.common.core.mybatisplus.core.IServicePlus;
 #if($table.crud || $table.sub)
 import com.ruoyi.common.core.page.TableDataInfo;
 #end
@@ -58,5 +58,5 @@
 	 * @param isValid 鏄惁鏍¢獙,true-鍒犻櫎鍓嶆牎楠�,false-涓嶆牎楠�
 	 * @return
 	 */
-	Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+	Boolean deleteWithValidByIds(Collection<${pkColumn.javaType}> ids, Boolean isValid);
 }
diff --git a/ruoyi-generator/src/main/resources/vm/java/serviceImpl.java.vm b/ruoyi-generator/src/main/resources/vm/java/serviceImpl.java.vm
index c727ce6..2421f31 100644
--- a/ruoyi-generator/src/main/resources/vm/java/serviceImpl.java.vm
+++ b/ruoyi-generator/src/main/resources/vm/java/serviceImpl.java.vm
@@ -8,7 +8,7 @@
 import com.ruoyi.common.core.page.TableDataInfo;
 #end
 import org.springframework.stereotype.Service;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.common.core.mybatisplus.core.ServicePlusImpl;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import ${packageName}.bo.${ClassName}AddBo;
@@ -30,7 +30,7 @@
  * @date ${datetime}
  */
 @Service
-public class ${ClassName}ServiceImpl extends ServiceImpl<${ClassName}Mapper, ${ClassName}> implements I${ClassName}Service {
+public class ${ClassName}ServiceImpl extends ServicePlusImpl<${ClassName}Mapper, ${ClassName}> implements I${ClassName}Service {
 
     @Override
     public ${ClassName}Vo queryById(${pkColumn.javaType} ${pkColumn.javaField}){
@@ -101,7 +101,7 @@
     }
 
     @Override
-    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
+    public Boolean deleteWithValidByIds(Collection<${pkColumn.javaType}> ids, Boolean isValid) {
         if(isValid){
             //TODO 鍋氫竴浜涗笟鍔′笂鐨勬牎楠�,鍒ゆ柇鏄惁闇�瑕佹牎楠�
         }
diff --git a/ruoyi-generator/src/main/resources/vm/java/vo.java.vm b/ruoyi-generator/src/main/resources/vm/java/vo.java.vm
index 4641d78..b07a7b4 100644
--- a/ruoyi-generator/src/main/resources/vm/java/vo.java.vm
+++ b/ruoyi-generator/src/main/resources/vm/java/vo.java.vm
@@ -1,7 +1,6 @@
 package ${packageName}.vo;
 
 import com.ruoyi.common.annotation.Excel;
-import com.fasterxml.jackson.annotation.JsonFormat;
 #foreach ($import in $importList)
 import ${import};
 #end
@@ -41,7 +40,6 @@
 	@Excel(name = "${comment}" , readConverterExp = "$column.readConverterExp()")
 #elseif($column.javaType == 'Date')
 	@Excel(name = "${comment}" , width = 30, dateFormat = "yyyy-MM-dd")
-	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
 #else
 	@Excel(name = "${comment}")
 #end
diff --git a/ruoyi-generator/src/main/resources/vm/vue/index-tree.vue.vm b/ruoyi-generator/src/main/resources/vm/vue/index-tree.vue.vm
index 0b971b2..d43c2ce 100644
--- a/ruoyi-generator/src/main/resources/vm/vue/index-tree.vue.vm
+++ b/ruoyi-generator/src/main/resources/vm/vue/index-tree.vue.vm
@@ -1,548 +1,546 @@
-<template>
-  <div class="app-container">
-    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
-#foreach($column in $columns)
-#if($column.query)
-#set($dictType=$column.dictType)
-#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
-#set($parentheseIndex=$column.columnComment.indexOf("锛�"))
-#if($parentheseIndex != -1)
-#set($comment=$column.columnComment.substring(0, $parentheseIndex))
-#else
-#set($comment=$column.columnComment)
-#end
-#if($column.htmlType == "input")
-      <el-form-item label="${comment}" prop="${column.javaField}">
-        <el-input
-          v-model="queryParams.${column.javaField}"
-          placeholder="璇疯緭鍏�${comment}"
-          clearable
-          size="small"
-          @keyup.enter.native="handleQuery"
-        />
-      </el-form-item>
-#elseif(($column.htmlType == "select" || $column.htmlType == "radio") && "" != $dictType)
-      <el-form-item label="${comment}" prop="${column.javaField}">
-        <el-select v-model="queryParams.${column.javaField}" placeholder="璇烽�夋嫨${comment}" clearable size="small">
-          <el-option
-            v-for="dict in ${column.javaField}Options"
-            :key="dict.dictValue"
-            :label="dict.dictLabel"
-            :value="dict.dictValue"
-          />
-        </el-select>
-      </el-form-item>
-#elseif(($column.htmlType == "select" || $column.htmlType == "radio") && $dictType)
-      <el-form-item label="${comment}" prop="${column.javaField}">
-        <el-select v-model="queryParams.${column.javaField}" placeholder="璇烽�夋嫨${comment}" clearable size="small">
-          <el-option label="璇烽�夋嫨瀛楀吀鐢熸垚" value="" />
-        </el-select>
-      </el-form-item>
-#elseif($column.htmlType == "datetime" && $column.queryType != "BETWEEN")
-      <el-form-item label="${comment}" prop="${column.javaField}">
-        <el-date-picker clearable size="small"
-          v-model="queryParams.${column.javaField}"
-          type="date"
-          value-format="yyyy-MM-dd"
-          placeholder="閫夋嫨${comment}">
-        </el-date-picker>
-      </el-form-item>
-#elseif($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
-      <el-form-item label="${comment}">
-        <el-date-picker
-          v-model="daterange${AttrName}"
-          size="small"
-          style="width: 240px"
-          value-format="yyyy-MM-dd"
-          type="daterange"
-          range-separator="-"
-          start-placeholder="寮�濮嬫棩鏈�"
-          end-placeholder="缁撴潫鏃ユ湡"
-        ></el-date-picker>
-      </el-form-item>
-#end
-#end
-#end
-      <el-form-item>
-	    <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">鎼滅储</el-button>
-        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">閲嶇疆</el-button>
-      </el-form-item>
-    </el-form>
-
-    <el-row :gutter="10" class="mb8">
-      <el-col :span="1.5">
-        <el-button
-          type="primary"
-          plain
-          icon="el-icon-plus"
-          size="mini"
-          @click="handleAdd"
-          v-hasPermi="['${moduleName}:${businessName}:add']"
-        >鏂板</el-button>
-      </el-col>
-      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
-    </el-row>
-
-    <el-table
-      v-loading="loading"
-      :data="${businessName}List"
-      row-key="${treeCode}"
-      default-expand-all
-      :tree-props="{children: 'children', hasChildren: 'hasChildren'}"
-    >
-#foreach($column in $columns)
-#set($javaField=$column.javaField)
-#set($parentheseIndex=$column.columnComment.indexOf("锛�"))
-#if($parentheseIndex != -1)
-#set($comment=$column.columnComment.substring(0, $parentheseIndex))
-#else
-#set($comment=$column.columnComment)
-#end
-#if($column.pk)
-#elseif($column.list && $column.htmlType == "datetime")
-      <el-table-column label="${comment}" align="center" prop="${javaField}" width="180">
-        <template slot-scope="scope">
-          <span>{{ parseTime(scope.row.${javaField}, '{y}-{m}-{d}') }}</span>
-        </template>
-      </el-table-column>
-#elseif($column.list && "" != $column.dictType)
-      <el-table-column label="${comment}" align="center" prop="${javaField}" :formatter="${javaField}Format" />
-#elseif($column.list && "" != $javaField)
-#if(${foreach.index} == 1)
-      <el-table-column label="${comment}" prop="${javaField}" />
-#else
-      <el-table-column label="${comment}" align="center" prop="${javaField}" />
-#end
-#end
-#end
-      <el-table-column label="鎿嶄綔" align="center" class-name="small-padding fixed-width">
-        <template slot-scope="scope">
-          <el-button
-            size="mini"
-            type="text"
-            icon="el-icon-edit"
-            @click="handleUpdate(scope.row)"
-            v-hasPermi="['${moduleName}:${businessName}:edit']"
-          >淇敼</el-button>
-          <el-button
-            size="mini"
-            type="text"
-            icon="el-icon-plus"
-            @click="handleAdd(scope.row)"
-            v-hasPermi="['${moduleName}:${businessName}:add']"
-          >鏂板</el-button>
-          <el-button
-            size="mini"
-            type="text"
-            icon="el-icon-delete"
-            @click="handleDelete(scope.row)"
-            v-hasPermi="['${moduleName}:${businessName}:remove']"
-          >鍒犻櫎</el-button>
-        </template>
-      </el-table-column>
-    </el-table>
-
-    <!-- 娣诲姞鎴栦慨鏀�${functionName}瀵硅瘽妗� -->
-    <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
-      <el-form ref="form" :model="form" :rules="rules" label-width="80px">
-#foreach($column in $columns)
-#set($field=$column.javaField)
-#if($column.insert && !$column.pk)
-#if(($column.usableColumn) || (!$column.superColumn))
-#set($parentheseIndex=$column.columnComment.indexOf("锛�"))
-#if($parentheseIndex != -1)
-#set($comment=$column.columnComment.substring(0, $parentheseIndex))
-#else
-#set($comment=$column.columnComment)
-#end
-#set($dictType=$column.dictType)
-#if("" != $treeParentCode && $column.javaField == $treeParentCode)
-        <el-form-item label="${comment}" prop="${treeParentCode}">
-          <treeselect v-model="form.${treeParentCode}" :options="${businessName}Options" :normalizer="normalizer" placeholder="璇烽�夋嫨${comment}" />
-        </el-form-item>
-#elseif($column.htmlType == "input")
-        <el-form-item label="${comment}" prop="${field}">
-          <el-input v-model="form.${field}" placeholder="璇疯緭鍏�${comment}" />
-        </el-form-item>
-#elseif($column.htmlType == "imageUpload")
-        <el-form-item label="${comment}">
-          <imageUpload v-model="form.${field}"/>
-        </el-form-item>
-#elseif($column.htmlType == "fileUpload")
-        <el-form-item label="${comment}">
-          <fileUpload v-model="form.${field}"/>
-        </el-form-item>
-#elseif($column.htmlType == "editor")
-        <el-form-item label="${comment}">
-          <editor v-model="form.${field}" :min-height="192"/>
-        </el-form-item>
-#elseif($column.htmlType == "select" && "" != $dictType)
-        <el-form-item label="${comment}" prop="${field}">
-          <el-select v-model="form.${field}" placeholder="璇烽�夋嫨${comment}">
-            <el-option
-              v-for="dict in ${field}Options"
-              :key="dict.dictValue"
-              :label="dict.dictLabel"
-              #if($column.javaType == "Integer" || $column.javaType == "Long"):value="parseInt(dict.dictValue)"#else:value="dict.dictValue"#end
-
-            ></el-option>
-          </el-select>
-        </el-form-item>
-#elseif($column.htmlType == "select" && $dictType)
-        <el-form-item label="${comment}" prop="${field}">
-          <el-select v-model="form.${field}" placeholder="璇烽�夋嫨${comment}">
-            <el-option label="璇烽�夋嫨瀛楀吀鐢熸垚" value="" />
-          </el-select>
-        </el-form-item>
-#elseif($column.htmlType == "checkbox" && "" != $dictType)
-        <el-form-item label="${comment}">
-          <el-checkbox-group v-model="form.${field}">
-            <el-checkbox
-              v-for="dict in ${field}Options"
-              :key="dict.dictValue"
-              :label="dict.dictValue">
-              {{dict.dictLabel}}
-            </el-checkbox>
-          </el-checkbox-group>
-        </el-form-item>
-#elseif($column.htmlType == "checkbox" && $dictType)
-        <el-form-item label="${comment}">
-          <el-checkbox-group v-model="form.${field}">
-            <el-checkbox>璇烽�夋嫨瀛楀吀鐢熸垚</el-checkbox>
-          </el-checkbox-group>
-        </el-form-item>
-#elseif($column.htmlType == "radio" && "" != $dictType)
-        <el-form-item label="${comment}">
-          <el-radio-group v-model="form.${field}">
-            <el-radio
-              v-for="dict in ${field}Options"
-              :key="dict.dictValue"
-              #if($column.javaType == "Integer" || $column.javaType == "Long"):label="parseInt(dict.dictValue)"#else:label="dict.dictValue"#end
-
-            >{{dict.dictLabel}}</el-radio>
-          </el-radio-group>
-        </el-form-item>
-#elseif($column.htmlType == "radio" && $dictType)
-        <el-form-item label="${comment}">
-          <el-radio-group v-model="form.${field}">
-            <el-radio label="1">璇烽�夋嫨瀛楀吀鐢熸垚</el-radio>
-          </el-radio-group>
-        </el-form-item>
-#elseif($column.htmlType == "datetime")
-        <el-form-item label="${comment}" prop="${field}">
-          <el-date-picker clearable size="small"
-            v-model="form.${field}"
-            type="datetime"
-            value-format="yyyy-MM-dd HH:mm:ss"
-            placeholder="閫夋嫨${comment}">
-          </el-date-picker>
-        </el-form-item>
-#elseif($column.htmlType == "textarea")
-        <el-form-item label="${comment}" prop="${field}">
-          <el-input v-model="form.${field}" type="textarea" placeholder="璇疯緭鍏ュ唴瀹�" />
-        </el-form-item>
-#end
-#end
-#end
-#end
-      </el-form>
-      <div slot="footer" class="dialog-footer">
-        <el-button :loading="buttonLoading" type="primary" @click="submitForm">纭� 瀹�</el-button>
-        <el-button @click="cancel">鍙� 娑�</el-button>
-      </div>
-    </el-dialog>
-  </div>
-</template>
-
-<script>
-import { list${BusinessName}, get${BusinessName}, del${BusinessName}, add${BusinessName}, update${BusinessName}, export${BusinessName} } from "@/api/${moduleName}/${businessName}";
-import Treeselect from "@riophae/vue-treeselect";
-import "@riophae/vue-treeselect/dist/vue-treeselect.css";
-#foreach($column in $columns)
-#if($column.insert && !$column.superColumn && !$column.pk && $column.htmlType == "imageUpload")
-import ImageUpload from '@/components/ImageUpload';
-#break
-#end
-#end
-#foreach($column in $columns)
-#if($column.insert && !$column.superColumn && !$column.pk && $column.htmlType == "fileUpload")
-import FileUpload from '@/components/FileUpload';
-#break
-#end
-#end
-#foreach($column in $columns)
-#if($column.insert && !$column.superColumn && !$column.pk && $column.htmlType == "editor")
-import Editor from '@/components/Editor';
-#break
-#end
-#end
-
-export default {
-  name: "${BusinessName}",
-  components: {
-#foreach($column in $columns)
-#if($column.insert && !$column.superColumn && !$column.pk && $column.htmlType == "imageUpload")
-    ImageUpload,
-#break
-#end
-#end
-#foreach($column in $columns)
-#if($column.insert && !$column.superColumn && !$column.pk && $column.htmlType == "fileUpload")
-    FileUpload,
-#break
-#end
-#end
-#foreach($column in $columns)
-#if($column.insert && !$column.superColumn && !$column.pk && $column.htmlType == "editor")
-    Editor,
-#break
-#end
-#end
-    Treeselect
-  },
-  data() {
-    return {
-	  //鎸夐挳loading
-	  buttonLoading: false,
-      // 閬僵灞�
-      loading: true,
-      // 鏄剧ず鎼滅储鏉′欢
-      showSearch: true,
-      // ${functionName}琛ㄦ牸鏁版嵁
-      ${businessName}List: [],
-      // ${functionName}鏍戦�夐」
-      ${businessName}Options: [],
-      // 寮瑰嚭灞傛爣棰�
-      title: "",
-      // 鏄惁鏄剧ず寮瑰嚭灞�
-      open: false,
-#foreach ($column in $columns)
-#set($parentheseIndex=$column.columnComment.indexOf("锛�"))
-#if($parentheseIndex != -1)
-#set($comment=$column.columnComment.substring(0, $parentheseIndex))
-#else
-#set($comment=$column.columnComment)
-#end
-#if(${column.dictType} != '')
-      // $comment瀛楀吀
-      ${column.javaField}Options: [],
-#elseif($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
-#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
-      // $comment鏃堕棿鑼冨洿
-      daterange${AttrName}: [],
-#end
-#end
-      // 鏌ヨ鍙傛暟
-      queryParams: {
-#foreach ($column in $columns)
-#if($column.query)
-        $column.javaField: null#if($velocityCount != $columns.size()),#end
-
-#end
-#end
-      },
-      // 琛ㄥ崟鍙傛暟
-      form: {},
-      // 琛ㄥ崟鏍¢獙
-      rules: {
-#foreach ($column in $columns)
-#if($column.required)
-#set($parentheseIndex=$column.columnComment.indexOf("锛�"))
-#if($parentheseIndex != -1)
-#set($comment=$column.columnComment.substring(0, $parentheseIndex))
-#else
-#set($comment=$column.columnComment)
-#end
-        $column.javaField: [
-          { required: true, message: "$comment涓嶈兘涓虹┖", trigger: #if($column.htmlType == "select")"change"#else"blur"#end }
-        ]#if($velocityCount != $columns.size()),#end
-
-#end
-#end
-      }
-    };
-  },
-  created() {
-    this.getList();
-#foreach ($column in $columns)
-#if(${column.dictType} != '')
-    this.getDicts("${column.dictType}").then(response => {
-      this.${column.javaField}Options = response.data;
-    });
-#end
-#end
-  },
-  methods: {
-    /** 鏌ヨ${functionName}鍒楄〃 */
-    getList() {
-      this.loading = true;
-#foreach ($column in $columns)
-#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
-      this.queryParams.params = {};
-#break
-#end
-#end
-#foreach ($column in $columns)
-#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
-#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
-      if (null != this.daterange${AttrName} && '' != this.daterange${AttrName}) {
-        this.queryParams.params["begin${AttrName}"] = this.daterange${AttrName}[0];
-        this.queryParams.params["end${AttrName}"] = this.daterange${AttrName}[1];
-      }
-#end
-#end
-      list${BusinessName}(this.queryParams).then(response => {
-        this.${businessName}List = this.handleTree(response.data, "${treeCode}", "${treeParentCode}");
-        this.loading = false;
-      });
-    },
-    /** 杞崲${functionName}鏁版嵁缁撴瀯 */
-    normalizer(node) {
-      if (node.children && !node.children.length) {
-        delete node.children;
-      }
-      return {
-        id: node.${treeCode},
-        label: node.${treeName},
-        children: node.children
-      };
-    },
-	/** 鏌ヨ${functionName}涓嬫媺鏍戠粨鏋� */
-    getTreeselect() {
-      list${BusinessName}().then(response => {
-        this.${businessName}Options = [];
-        const data = { ${treeCode}: 0, ${treeName}: '椤剁骇鑺傜偣', children: [] };
-        data.children = this.handleTree(response.data, "${treeCode}", "${treeParentCode}");
-        this.${businessName}Options.push(data);
-      });
-    },
-#foreach ($column in $columns)
-#if(${column.dictType} != '')
-#set($parentheseIndex=$column.columnComment.indexOf("锛�"))
-#if($parentheseIndex != -1)
-#set($comment=$column.columnComment.substring(0, $parentheseIndex))
-#else
-#set($comment=$column.columnComment)
-#end
-    // $comment瀛楀吀缈昏瘧
-    ${column.javaField}Format(row, column) {
-      return this.selectDictLabel#if($column.htmlType == "checkbox")s#end(this.${column.javaField}Options, row.${column.javaField});
-    },
-#end
-#end
-    // 鍙栨秷鎸夐挳
-    cancel() {
-      this.open = false;
-      this.reset();
-    },
-    // 琛ㄥ崟閲嶇疆
-    reset() {
-      this.form = {
-#foreach ($column in $columns)
-#if($column.htmlType == "radio")
-        $column.javaField: #if($column.javaType == "Integer" || $column.javaType == "Long")0#else"0"#end#if($velocityCount != $columns.size()),#end
-
-#elseif($column.htmlType == "checkbox")
-        $column.javaField: []#if($velocityCount != $columns.size()),#end
-
-#else
-        $column.javaField: null#if($velocityCount != $columns.size()),#end
-
-#end
-#end
-      };
-      this.resetForm("form");
-    },
-    /** 鎼滅储鎸夐挳鎿嶄綔 */
-    handleQuery() {
-      this.getList();
-    },
-    /** 閲嶇疆鎸夐挳鎿嶄綔 */
-    resetQuery() {
-#foreach ($column in $columns)
-#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
-#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
-      this.daterange${AttrName} = [];
-#end
-#end
-      this.resetForm("queryForm");
-      this.handleQuery();
-    },
-    /** 鏂板鎸夐挳鎿嶄綔 */
-    handleAdd(row) {
-      this.reset();
-      this.getTreeselect();
-      if (row != null && row.${treeCode}) {
-        this.form.${treeParentCode} = row.${treeCode};
-      } else {
-        this.form.${treeParentCode} = 0;
-      }
-      this.open = true;
-      this.title = "娣诲姞${functionName}";
-    },
-    /** 淇敼鎸夐挳鎿嶄綔 */
-    handleUpdate(row) {
-	  this.loading = true;
-      this.reset();
-      this.getTreeselect();
-      if (row != null) {
-        this.form.${treeParentCode} = row.${treeCode};
-      }
-      get${BusinessName}(row.${pkColumn.javaField}).then(response => {
-	    this.loading = false;
-        this.form = response.data;
-#foreach ($column in $columns)
-#if($column.htmlType == "checkbox")
-        this.form.$column.javaField = this.form.${column.javaField}.split(",");
-#end
-#end
-        this.open = true;
-        this.title = "淇敼${functionName}";
-      });
-    },
-    /** 鎻愪氦鎸夐挳 */
-    submitForm() {
-      this.#[[$]]#refs["form"].validate(valid => {
-        if (valid) {
-		  this.buttonLoading = true;
-#foreach ($column in $columns)
-#if($column.htmlType == "checkbox")
-          this.form.$column.javaField = this.form.${column.javaField}.join(",");
-#end
-#end
-          if (this.form.${pkColumn.javaField} != null) {
-            update${BusinessName}(this.form).then(response => {
-			  this.buttonLoading = false;
-              this.msgSuccess("淇敼鎴愬姛");
-              this.open = false;
-              this.getList();
-            });
-          } else {
-            add${BusinessName}(this.form).then(response => {
-			  this.buttonLoading = false;
-              this.msgSuccess("鏂板鎴愬姛");
-              this.open = false;
-              this.getList();
-            });
-          }
-        }
-      });
-    },
-    /** 鍒犻櫎鎸夐挳鎿嶄綔 */
-    handleDelete(row) {
-      this.$confirm('鏄惁纭鍒犻櫎${functionName}缂栧彿涓�"' + row.${pkColumn.javaField} + '"鐨勬暟鎹」?', "璀﹀憡", {
-          confirmButtonText: "纭畾",
-          cancelButtonText: "鍙栨秷",
-          type: "warning"
-        }).then(() => {
-		  this.loading = true;
-          return del${BusinessName}(row.${pkColumn.javaField});
-        }).then(() => {
-		  this.loading = false;
-          this.getList();
-          this.msgSuccess("鍒犻櫎鎴愬姛");
-        }).catch(() => {});
-    }
-  }
-};
-</script>
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
+#foreach($column in $columns)
+#if($column.query)
+#set($dictType=$column.dictType)
+#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
+#set($parentheseIndex=$column.columnComment.indexOf("锛�"))
+#if($parentheseIndex != -1)
+#set($comment=$column.columnComment.substring(0, $parentheseIndex))
+#else
+#set($comment=$column.columnComment)
+#end
+#if($column.htmlType == "input")
+      <el-form-item label="${comment}" prop="${column.javaField}">
+        <el-input
+          v-model="queryParams.${column.javaField}"
+          placeholder="璇疯緭鍏�${comment}"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+#elseif(($column.htmlType == "select" || $column.htmlType == "radio") && "" != $dictType)
+      <el-form-item label="${comment}" prop="${column.javaField}">
+        <el-select v-model="queryParams.${column.javaField}" placeholder="璇烽�夋嫨${comment}" clearable size="small">
+          <el-option
+            v-for="dict in ${column.javaField}Options"
+            :key="dict.dictValue"
+            :label="dict.dictLabel"
+            :value="dict.dictValue"
+          />
+        </el-select>
+      </el-form-item>
+#elseif(($column.htmlType == "select" || $column.htmlType == "radio") && $dictType)
+      <el-form-item label="${comment}" prop="${column.javaField}">
+        <el-select v-model="queryParams.${column.javaField}" placeholder="璇烽�夋嫨${comment}" clearable size="small">
+          <el-option label="璇烽�夋嫨瀛楀吀鐢熸垚" value="" />
+        </el-select>
+      </el-form-item>
+#elseif($column.htmlType == "datetime" && $column.queryType != "BETWEEN")
+      <el-form-item label="${comment}" prop="${column.javaField}">
+        <el-date-picker clearable size="small"
+          v-model="queryParams.${column.javaField}"
+          type="date"
+          value-format="yyyy-MM-dd"
+          placeholder="閫夋嫨${comment}">
+        </el-date-picker>
+      </el-form-item>
+#elseif($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
+      <el-form-item label="${comment}">
+        <el-date-picker
+          v-model="daterange${AttrName}"
+          size="small"
+          style="width: 240px"
+          value-format="yyyy-MM-dd"
+          type="daterange"
+          range-separator="-"
+          start-placeholder="寮�濮嬫棩鏈�"
+          end-placeholder="缁撴潫鏃ユ湡"
+        ></el-date-picker>
+      </el-form-item>
+#end
+#end
+#end
+      <el-form-item>
+	    <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">鎼滅储</el-button>
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">閲嶇疆</el-button>
+      </el-form-item>
+    </el-form>
+
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button
+          type="primary"
+          plain
+          icon="el-icon-plus"
+          size="mini"
+          @click="handleAdd"
+          v-hasPermi="['${moduleName}:${businessName}:add']"
+        >鏂板</el-button>
+      </el-col>
+      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table
+      v-loading="loading"
+      :data="${businessName}List"
+      row-key="${treeCode}"
+      default-expand-all
+      :tree-props="{children: 'children', hasChildren: 'hasChildren'}"
+    >
+#foreach($column in $columns)
+#set($javaField=$column.javaField)
+#set($parentheseIndex=$column.columnComment.indexOf("锛�"))
+#if($parentheseIndex != -1)
+#set($comment=$column.columnComment.substring(0, $parentheseIndex))
+#else
+#set($comment=$column.columnComment)
+#end
+#if($column.pk)
+#elseif($column.list && $column.htmlType == "datetime")
+      <el-table-column label="${comment}" align="center" prop="${javaField}" width="180">
+        <template slot-scope="scope">
+          <span>{{ parseTime(scope.row.${javaField}, '{y}-{m}-{d}') }}</span>
+        </template>
+      </el-table-column>
+#elseif($column.list && "" != $column.dictType)
+      <el-table-column label="${comment}" align="center" prop="${javaField}" :formatter="${javaField}Format" />
+#elseif($column.list && "" != $javaField)
+#if(${foreach.index} == 1)
+      <el-table-column label="${comment}" prop="${javaField}" />
+#else
+      <el-table-column label="${comment}" align="center" prop="${javaField}" />
+#end
+#end
+#end
+      <el-table-column label="鎿嶄綔" align="center" class-name="small-padding fixed-width">
+        <template slot-scope="scope">
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-edit"
+            @click="handleUpdate(scope.row)"
+            v-hasPermi="['${moduleName}:${businessName}:edit']"
+          >淇敼</el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-plus"
+            @click="handleAdd(scope.row)"
+            v-hasPermi="['${moduleName}:${businessName}:add']"
+          >鏂板</el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-delete"
+            @click="handleDelete(scope.row)"
+            v-hasPermi="['${moduleName}:${businessName}:remove']"
+          >鍒犻櫎</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <!-- 娣诲姞鎴栦慨鏀�${functionName}瀵硅瘽妗� -->
+    <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
+      <el-form ref="form" :model="form" :rules="rules" label-width="80px">
+#foreach($column in $columns)
+#set($field=$column.javaField)
+#if($column.insert && !$column.pk)
+#set($parentheseIndex=$column.columnComment.indexOf("锛�"))
+#if($parentheseIndex != -1)
+#set($comment=$column.columnComment.substring(0, $parentheseIndex))
+#else
+#set($comment=$column.columnComment)
+#end
+#set($dictType=$column.dictType)
+#if("" != $treeParentCode && $column.javaField == $treeParentCode)
+        <el-form-item label="${comment}" prop="${treeParentCode}">
+          <treeselect v-model="form.${treeParentCode}" :options="${businessName}Options" :normalizer="normalizer" placeholder="璇烽�夋嫨${comment}" />
+        </el-form-item>
+#elseif($column.htmlType == "input")
+        <el-form-item label="${comment}" prop="${field}">
+          <el-input v-model="form.${field}" placeholder="璇疯緭鍏�${comment}" />
+        </el-form-item>
+#elseif($column.htmlType == "imageUpload")
+        <el-form-item label="${comment}">
+          <imageUpload v-model="form.${field}"/>
+        </el-form-item>
+#elseif($column.htmlType == "fileUpload")
+        <el-form-item label="${comment}">
+          <fileUpload v-model="form.${field}"/>
+        </el-form-item>
+#elseif($column.htmlType == "editor")
+        <el-form-item label="${comment}">
+          <editor v-model="form.${field}" :min-height="192"/>
+        </el-form-item>
+#elseif($column.htmlType == "select" && "" != $dictType)
+        <el-form-item label="${comment}" prop="${field}">
+          <el-select v-model="form.${field}" placeholder="璇烽�夋嫨${comment}">
+            <el-option
+              v-for="dict in ${field}Options"
+              :key="dict.dictValue"
+              :label="dict.dictLabel"
+              #if($column.javaType == "Integer" || $column.javaType == "Long"):value="parseInt(dict.dictValue)"#else:value="dict.dictValue"#end
+
+            ></el-option>
+          </el-select>
+        </el-form-item>
+#elseif($column.htmlType == "select" && $dictType)
+        <el-form-item label="${comment}" prop="${field}">
+          <el-select v-model="form.${field}" placeholder="璇烽�夋嫨${comment}">
+            <el-option label="璇烽�夋嫨瀛楀吀鐢熸垚" value="" />
+          </el-select>
+        </el-form-item>
+#elseif($column.htmlType == "checkbox" && "" != $dictType)
+        <el-form-item label="${comment}">
+          <el-checkbox-group v-model="form.${field}">
+            <el-checkbox
+              v-for="dict in ${field}Options"
+              :key="dict.dictValue"
+              :label="dict.dictValue">
+              {{dict.dictLabel}}
+            </el-checkbox>
+          </el-checkbox-group>
+        </el-form-item>
+#elseif($column.htmlType == "checkbox" && $dictType)
+        <el-form-item label="${comment}">
+          <el-checkbox-group v-model="form.${field}">
+            <el-checkbox>璇烽�夋嫨瀛楀吀鐢熸垚</el-checkbox>
+          </el-checkbox-group>
+        </el-form-item>
+#elseif($column.htmlType == "radio" && "" != $dictType)
+        <el-form-item label="${comment}">
+          <el-radio-group v-model="form.${field}">
+            <el-radio
+              v-for="dict in ${field}Options"
+              :key="dict.dictValue"
+              #if($column.javaType == "Integer" || $column.javaType == "Long"):label="parseInt(dict.dictValue)"#else:label="dict.dictValue"#end
+
+            >{{dict.dictLabel}}</el-radio>
+          </el-radio-group>
+        </el-form-item>
+#elseif($column.htmlType == "radio" && $dictType)
+        <el-form-item label="${comment}">
+          <el-radio-group v-model="form.${field}">
+            <el-radio label="1">璇烽�夋嫨瀛楀吀鐢熸垚</el-radio>
+          </el-radio-group>
+        </el-form-item>
+#elseif($column.htmlType == "datetime")
+        <el-form-item label="${comment}" prop="${field}">
+          <el-date-picker clearable size="small"
+            v-model="form.${field}"
+            type="datetime"
+            value-format="yyyy-MM-dd HH:mm:ss"
+            placeholder="閫夋嫨${comment}">
+          </el-date-picker>
+        </el-form-item>
+#elseif($column.htmlType == "textarea")
+        <el-form-item label="${comment}" prop="${field}">
+          <el-input v-model="form.${field}" type="textarea" placeholder="璇疯緭鍏ュ唴瀹�" />
+        </el-form-item>
+#end
+#end
+#end
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button :loading="buttonLoading" type="primary" @click="submitForm">纭� 瀹�</el-button>
+        <el-button @click="cancel">鍙� 娑�</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { list${BusinessName}, get${BusinessName}, del${BusinessName}, add${BusinessName}, update${BusinessName}, export${BusinessName} } from "@/api/${moduleName}/${businessName}";
+import Treeselect from "@riophae/vue-treeselect";
+import "@riophae/vue-treeselect/dist/vue-treeselect.css";
+#foreach($column in $columns)
+#if($column.insert && !$column.pk && $column.htmlType == "imageUpload")
+import ImageUpload from '@/components/ImageUpload';
+#break
+#end
+#end
+#foreach($column in $columns)
+#if($column.insert && !$column.pk && $column.htmlType == "fileUpload")
+import FileUpload from '@/components/FileUpload';
+#break
+#end
+#end
+#foreach($column in $columns)
+#if($column.insert && !$column.pk && $column.htmlType == "editor")
+import Editor from '@/components/Editor';
+#break
+#end
+#end
+
+export default {
+  name: "${BusinessName}",
+  components: {
+#foreach($column in $columns)
+#if($column.insert && !$column.pk && $column.htmlType == "imageUpload")
+    ImageUpload,
+#break
+#end
+#end
+#foreach($column in $columns)
+#if($column.insert && !$column.pk && $column.htmlType == "fileUpload")
+    FileUpload,
+#break
+#end
+#end
+#foreach($column in $columns)
+#if($column.insert && !$column.pk && $column.htmlType == "editor")
+    Editor,
+#break
+#end
+#end
+    Treeselect
+  },
+  data() {
+    return {
+	  //鎸夐挳loading
+	  buttonLoading: false,
+      // 閬僵灞�
+      loading: true,
+      // 鏄剧ず鎼滅储鏉′欢
+      showSearch: true,
+      // ${functionName}琛ㄦ牸鏁版嵁
+      ${businessName}List: [],
+      // ${functionName}鏍戦�夐」
+      ${businessName}Options: [],
+      // 寮瑰嚭灞傛爣棰�
+      title: "",
+      // 鏄惁鏄剧ず寮瑰嚭灞�
+      open: false,
+#foreach ($column in $columns)
+#set($parentheseIndex=$column.columnComment.indexOf("锛�"))
+#if($parentheseIndex != -1)
+#set($comment=$column.columnComment.substring(0, $parentheseIndex))
+#else
+#set($comment=$column.columnComment)
+#end
+#if(${column.dictType} != '')
+      // $comment瀛楀吀
+      ${column.javaField}Options: [],
+#elseif($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
+#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
+      // $comment鏃堕棿鑼冨洿
+      daterange${AttrName}: [],
+#end
+#end
+      // 鏌ヨ鍙傛暟
+      queryParams: {
+#foreach ($column in $columns)
+#if($column.query)
+        $column.javaField: null#if($velocityCount != $columns.size()),#end
+
+#end
+#end
+      },
+      // 琛ㄥ崟鍙傛暟
+      form: {},
+      // 琛ㄥ崟鏍¢獙
+      rules: {
+#foreach ($column in $columns)
+#if($column.required)
+#set($parentheseIndex=$column.columnComment.indexOf("锛�"))
+#if($parentheseIndex != -1)
+#set($comment=$column.columnComment.substring(0, $parentheseIndex))
+#else
+#set($comment=$column.columnComment)
+#end
+        $column.javaField: [
+          { required: true, message: "$comment涓嶈兘涓虹┖", trigger: #if($column.htmlType == "select")"change"#else"blur"#end }
+        ]#if($velocityCount != $columns.size()),#end
+
+#end
+#end
+      }
+    };
+  },
+  created() {
+    this.getList();
+#foreach ($column in $columns)
+#if(${column.dictType} != '')
+    this.getDicts("${column.dictType}").then(response => {
+      this.${column.javaField}Options = response.data;
+    });
+#end
+#end
+  },
+  methods: {
+    /** 鏌ヨ${functionName}鍒楄〃 */
+    getList() {
+      this.loading = true;
+#foreach ($column in $columns)
+#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
+      this.queryParams.params = {};
+#break
+#end
+#end
+#foreach ($column in $columns)
+#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
+#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
+      if (null != this.daterange${AttrName} && '' != this.daterange${AttrName}) {
+        this.queryParams.params["begin${AttrName}"] = this.daterange${AttrName}[0];
+        this.queryParams.params["end${AttrName}"] = this.daterange${AttrName}[1];
+      }
+#end
+#end
+      list${BusinessName}(this.queryParams).then(response => {
+        this.${businessName}List = this.handleTree(response.data, "${treeCode}", "${treeParentCode}");
+        this.loading = false;
+      });
+    },
+    /** 杞崲${functionName}鏁版嵁缁撴瀯 */
+    normalizer(node) {
+      if (node.children && !node.children.length) {
+        delete node.children;
+      }
+      return {
+        id: node.${treeCode},
+        label: node.${treeName},
+        children: node.children
+      };
+    },
+	/** 鏌ヨ${functionName}涓嬫媺鏍戠粨鏋� */
+    getTreeselect() {
+      list${BusinessName}().then(response => {
+        this.${businessName}Options = [];
+        const data = { ${treeCode}: 0, ${treeName}: '椤剁骇鑺傜偣', children: [] };
+        data.children = this.handleTree(response.data, "${treeCode}", "${treeParentCode}");
+        this.${businessName}Options.push(data);
+      });
+    },
+#foreach ($column in $columns)
+#if(${column.dictType} != '')
+#set($parentheseIndex=$column.columnComment.indexOf("锛�"))
+#if($parentheseIndex != -1)
+#set($comment=$column.columnComment.substring(0, $parentheseIndex))
+#else
+#set($comment=$column.columnComment)
+#end
+    // $comment瀛楀吀缈昏瘧
+    ${column.javaField}Format(row, column) {
+      return this.selectDictLabel#if($column.htmlType == "checkbox")s#end(this.${column.javaField}Options, row.${column.javaField});
+    },
+#end
+#end
+    // 鍙栨秷鎸夐挳
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    // 琛ㄥ崟閲嶇疆
+    reset() {
+      this.form = {
+#foreach ($column in $columns)
+#if($column.htmlType == "radio")
+        $column.javaField: #if($column.javaType == "Integer" || $column.javaType == "Long")0#else"0"#end#if($velocityCount != $columns.size()),#end
+
+#elseif($column.htmlType == "checkbox")
+        $column.javaField: []#if($velocityCount != $columns.size()),#end
+
+#else
+        $column.javaField: null#if($velocityCount != $columns.size()),#end
+
+#end
+#end
+      };
+      this.resetForm("form");
+    },
+    /** 鎼滅储鎸夐挳鎿嶄綔 */
+    handleQuery() {
+      this.getList();
+    },
+    /** 閲嶇疆鎸夐挳鎿嶄綔 */
+    resetQuery() {
+#foreach ($column in $columns)
+#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
+#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
+      this.daterange${AttrName} = [];
+#end
+#end
+      this.resetForm("queryForm");
+      this.handleQuery();
+    },
+    /** 鏂板鎸夐挳鎿嶄綔 */
+    handleAdd(row) {
+      this.reset();
+      this.getTreeselect();
+      if (row != null && row.${treeCode}) {
+        this.form.${treeParentCode} = row.${treeCode};
+      } else {
+        this.form.${treeParentCode} = 0;
+      }
+      this.open = true;
+      this.title = "娣诲姞${functionName}";
+    },
+    /** 淇敼鎸夐挳鎿嶄綔 */
+    handleUpdate(row) {
+	  this.loading = true;
+      this.reset();
+      this.getTreeselect();
+      if (row != null) {
+        this.form.${treeParentCode} = row.${treeCode};
+      }
+      get${BusinessName}(row.${pkColumn.javaField}).then(response => {
+	    this.loading = false;
+        this.form = response.data;
+#foreach ($column in $columns)
+#if($column.htmlType == "checkbox")
+        this.form.$column.javaField = this.form.${column.javaField}.split(",");
+#end
+#end
+        this.open = true;
+        this.title = "淇敼${functionName}";
+      });
+    },
+    /** 鎻愪氦鎸夐挳 */
+    submitForm() {
+      this.#[[$]]#refs["form"].validate(valid => {
+        if (valid) {
+		  this.buttonLoading = true;
+#foreach ($column in $columns)
+#if($column.htmlType == "checkbox")
+          this.form.$column.javaField = this.form.${column.javaField}.join(",");
+#end
+#end
+          if (this.form.${pkColumn.javaField} != null) {
+            update${BusinessName}(this.form).then(response => {
+			  this.buttonLoading = false;
+              this.msgSuccess("淇敼鎴愬姛");
+              this.open = false;
+              this.getList();
+            });
+          } else {
+            add${BusinessName}(this.form).then(response => {
+			  this.buttonLoading = false;
+              this.msgSuccess("鏂板鎴愬姛");
+              this.open = false;
+              this.getList();
+            });
+          }
+        }
+      });
+    },
+    /** 鍒犻櫎鎸夐挳鎿嶄綔 */
+    handleDelete(row) {
+      this.$confirm('鏄惁纭鍒犻櫎${functionName}缂栧彿涓�"' + row.${pkColumn.javaField} + '"鐨勬暟鎹」?', "璀﹀憡", {
+          confirmButtonText: "纭畾",
+          cancelButtonText: "鍙栨秷",
+          type: "warning"
+        }).then(() => {
+		  this.loading = true;
+          return del${BusinessName}(row.${pkColumn.javaField});
+        }).then(() => {
+		  this.loading = false;
+          this.getList();
+          this.msgSuccess("鍒犻櫎鎴愬姛");
+        }).catch(() => {});
+    }
+  }
+};
+</script>
diff --git a/ruoyi-generator/src/main/resources/vm/vue/index.vue.vm b/ruoyi-generator/src/main/resources/vm/vue/index.vue.vm
index d6b311c..abc799e 100644
--- a/ruoyi-generator/src/main/resources/vm/vue/index.vue.vm
+++ b/ruoyi-generator/src/main/resources/vm/vue/index.vue.vm
@@ -174,7 +174,6 @@
 #foreach($column in $columns)
 #set($field=$column.javaField)
 #if($column.insert && !$column.pk)
-#if(($column.usableColumn) || (!$column.superColumn))
 #set($parentheseIndex=$column.columnComment.indexOf("锛�"))
 #if($parentheseIndex != -1)
 #set($comment=$column.columnComment.substring(0, $parentheseIndex))
@@ -266,7 +265,6 @@
 #end
 #end
 #end
-#end
 #if($table.sub)
         <el-divider content-position="center">${subTable.functionName}淇℃伅</el-divider>
         <el-row :gutter="10" class="mb8">
@@ -311,19 +309,19 @@
 <script>
 import { list${BusinessName}, get${BusinessName}, del${BusinessName}, add${BusinessName}, update${BusinessName}, export${BusinessName} } from "@/api/${moduleName}/${businessName}";
 #foreach($column in $columns)
-#if($column.insert && !$column.superColumn && !$column.pk && $column.htmlType == "imageUpload")
+#if($column.insert && !$column.pk && $column.htmlType == "imageUpload")
 import ImageUpload from '@/components/ImageUpload';
 #break
 #end
 #end
 #foreach($column in $columns)
-#if($column.insert && !$column.superColumn && !$column.pk && $column.htmlType == "fileUpload")
+#if($column.insert && !$column.pk && $column.htmlType == "fileUpload")
 import FileUpload from '@/components/FileUpload';
 #break
 #end
 #end
 #foreach($column in $columns)
-#if($column.insert && !$column.superColumn && !$column.pk && $column.htmlType == "editor")
+#if($column.insert && !$column.pk && $column.htmlType == "editor")
 import Editor from '@/components/Editor';
 #break
 #end
@@ -333,19 +331,19 @@
   name: "${BusinessName}",
   components: {
 #foreach($column in $columns)
-#if($column.insert && !$column.superColumn && !$column.pk && $column.htmlType == "imageUpload")
+#if($column.insert && !$column.pk && $column.htmlType == "imageUpload")
     ImageUpload,
 #break
 #end
 #end
 #foreach($column in $columns)
-#if($column.insert && !$column.superColumn && !$column.pk && $column.htmlType == "fileUpload")
+#if($column.insert && !$column.pk && $column.htmlType == "fileUpload")
     FileUpload,
 #break
 #end
 #end
 #foreach($column in $columns)
-#if($column.insert && !$column.superColumn && !$column.pk && $column.htmlType == "editor")
+#if($column.insert && !$column.pk && $column.htmlType == "editor")
     Editor,
 #break
 #end
diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/controller/SysJobController.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/controller/SysJobController.java
index 4289d32..2725cd8 100644
--- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/controller/SysJobController.java
+++ b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/controller/SysJobController.java
@@ -1,134 +1,144 @@
-package com.ruoyi.quartz.controller;
-
-import com.ruoyi.common.annotation.Log;
-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.exception.job.TaskException;
-import com.ruoyi.common.utils.SecurityUtils;
-import com.ruoyi.common.utils.poi.ExcelUtil;
-import com.ruoyi.quartz.domain.SysJob;
-import com.ruoyi.quartz.service.ISysJobService;
-import com.ruoyi.quartz.util.CronUtils;
-import org.quartz.SchedulerException;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.web.bind.annotation.*;
-
-import java.util.List;
-
-/**
- * 璋冨害浠诲姟淇℃伅鎿嶄綔澶勭悊
- * 
- * @author ruoyi
- */
-@RestController
-@RequestMapping("/monitor/job")
-public class SysJobController extends BaseController
-{
-    @Autowired
-    private ISysJobService jobService;
-
-    /**
-     * 鏌ヨ瀹氭椂浠诲姟鍒楄〃
-     */
-    @PreAuthorize("@ss.hasPermi('monitor:job:list')")
-    @GetMapping("/list")
-    public TableDataInfo list(SysJob sysJob)
-    {
-        return jobService.selectPageJobList(sysJob);
-    }
-
-    /**
-     * 瀵煎嚭瀹氭椂浠诲姟鍒楄〃
-     */
-    @PreAuthorize("@ss.hasPermi('monitor:job:export')")
-    @Log(title = "瀹氭椂浠诲姟", businessType = BusinessType.EXPORT)
-    @GetMapping("/export")
-    public AjaxResult export(SysJob sysJob)
-    {
-        List<SysJob> list = jobService.selectJobList(sysJob);
-        ExcelUtil<SysJob> util = new ExcelUtil<SysJob>(SysJob.class);
-        return util.exportExcel(list, "瀹氭椂浠诲姟");
-    }
-
-    /**
-     * 鑾峰彇瀹氭椂浠诲姟璇︾粏淇℃伅
-     */
-    @PreAuthorize("@ss.hasPermi('monitor:job:query')")
-    @GetMapping(value = "/{jobId}")
-    public AjaxResult getInfo(@PathVariable("jobId") Long jobId)
-    {
-        return AjaxResult.success(jobService.selectJobById(jobId));
-    }
-
-    /**
-     * 鏂板瀹氭椂浠诲姟
-     */
-    @PreAuthorize("@ss.hasPermi('monitor:job:add')")
-    @Log(title = "瀹氭椂浠诲姟", businessType = BusinessType.INSERT)
-    @PostMapping
-    public AjaxResult add(@RequestBody SysJob sysJob) throws SchedulerException, TaskException
-    {
-        if (!CronUtils.isValid(sysJob.getCronExpression()))
-        {
-            return AjaxResult.error("cron琛ㄨ揪寮忎笉姝g‘");
-        }
-        sysJob.setCreateBy(SecurityUtils.getUsername());
-        return toAjax(jobService.insertJob(sysJob));
-    }
-
-    /**
-     * 淇敼瀹氭椂浠诲姟
-     */
-    @PreAuthorize("@ss.hasPermi('monitor:job:edit')")
-    @Log(title = "瀹氭椂浠诲姟", businessType = BusinessType.UPDATE)
-    @PutMapping
-    public AjaxResult edit(@RequestBody SysJob sysJob) throws SchedulerException, TaskException
-    {
-        if (!CronUtils.isValid(sysJob.getCronExpression()))
-        {
-            return AjaxResult.error("cron琛ㄨ揪寮忎笉姝g‘");
-        }
-        sysJob.setUpdateBy(SecurityUtils.getUsername());
-        return toAjax(jobService.updateJob(sysJob));
-    }
-
-    /**
-     * 瀹氭椂浠诲姟鐘舵�佷慨鏀�
-     */
-    @PreAuthorize("@ss.hasPermi('monitor:job:changeStatus')")
-    @Log(title = "瀹氭椂浠诲姟", businessType = BusinessType.UPDATE)
-    @PutMapping("/changeStatus")
-    public AjaxResult changeStatus(@RequestBody SysJob job) throws SchedulerException
-    {
-        SysJob newJob = jobService.selectJobById(job.getJobId());
-        newJob.setStatus(job.getStatus());
-        return toAjax(jobService.changeStatus(newJob));
-    }
-
-    /**
-     * 瀹氭椂浠诲姟绔嬪嵆鎵ц涓�娆�
-     */
-    @PreAuthorize("@ss.hasPermi('monitor:job:changeStatus')")
-    @Log(title = "瀹氭椂浠诲姟", businessType = BusinessType.UPDATE)
-    @PutMapping("/run")
-    public AjaxResult run(@RequestBody SysJob job) throws SchedulerException
-    {
-        jobService.run(job);
-        return AjaxResult.success();
-    }
-
-    /**
-     * 鍒犻櫎瀹氭椂浠诲姟
-     */
-    @PreAuthorize("@ss.hasPermi('monitor:job:remove')")
-    @Log(title = "瀹氭椂浠诲姟", businessType = BusinessType.DELETE)
-    @DeleteMapping("/{jobIds}")
-    public AjaxResult remove(@PathVariable Long[] jobIds) throws SchedulerException, TaskException
-    {
-        jobService.deleteJobByIds(jobIds);
-        return AjaxResult.success();
-    }
-}
+package com.ruoyi.quartz.controller;
+
+import cn.hutool.core.util.StrUtil;
+import com.ruoyi.common.annotation.Log;
+import com.ruoyi.common.constant.Constants;
+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.exception.job.TaskException;
+import com.ruoyi.common.utils.SecurityUtils;
+import com.ruoyi.common.utils.poi.ExcelUtil;
+import com.ruoyi.quartz.domain.SysJob;
+import com.ruoyi.quartz.service.ISysJobService;
+import com.ruoyi.quartz.util.CronUtils;
+import org.quartz.SchedulerException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 璋冨害浠诲姟淇℃伅鎿嶄綔澶勭悊
+ *
+ * @author ruoyi
+ */
+@RestController
+@RequestMapping("/monitor/job")
+public class SysJobController extends BaseController
+{
+    @Autowired
+    private ISysJobService jobService;
+
+    /**
+     * 鏌ヨ瀹氭椂浠诲姟鍒楄〃
+     */
+    @PreAuthorize("@ss.hasPermi('monitor:job:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(SysJob sysJob)
+    {
+        return jobService.selectPageJobList(sysJob);
+    }
+
+    /**
+     * 瀵煎嚭瀹氭椂浠诲姟鍒楄〃
+     */
+    @PreAuthorize("@ss.hasPermi('monitor:job:export')")
+    @Log(title = "瀹氭椂浠诲姟", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(SysJob sysJob)
+    {
+        List<SysJob> list = jobService.selectJobList(sysJob);
+        ExcelUtil<SysJob> util = new ExcelUtil<SysJob>(SysJob.class);
+        return util.exportExcel(list, "瀹氭椂浠诲姟");
+    }
+
+    /**
+     * 鑾峰彇瀹氭椂浠诲姟璇︾粏淇℃伅
+     */
+    @PreAuthorize("@ss.hasPermi('monitor:job:query')")
+    @GetMapping(value = "/{jobId}")
+    public AjaxResult getInfo(@PathVariable("jobId") Long jobId)
+    {
+        return AjaxResult.success(jobService.selectJobById(jobId));
+    }
+
+    /**
+     * 鏂板瀹氭椂浠诲姟
+     */
+    @PreAuthorize("@ss.hasPermi('monitor:job:add')")
+    @Log(title = "瀹氭椂浠诲姟", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody SysJob sysJob) throws SchedulerException, TaskException
+    {
+        if (!CronUtils.isValid(sysJob.getCronExpression()))
+        {
+            return AjaxResult.error("鏂板浠诲姟'" + sysJob.getJobName() + "'澶辫触锛孋ron琛ㄨ揪寮忎笉姝g‘");
+        }
+        else if (StrUtil.containsIgnoreCase(sysJob.getInvokeTarget(), Constants.LOOKUP_RMI))
+        {
+            return AjaxResult.error("鏂板浠诲姟'" + sysJob.getJobName() + "'澶辫触锛岀洰鏍囧瓧绗︿覆涓嶅厑璁�'rmi://'璋冪敤");
+        }
+        sysJob.setCreateBy(SecurityUtils.getUsername());
+        return toAjax(jobService.insertJob(sysJob));
+    }
+
+    /**
+     * 淇敼瀹氭椂浠诲姟
+     */
+    @PreAuthorize("@ss.hasPermi('monitor:job:edit')")
+    @Log(title = "瀹氭椂浠诲姟", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody SysJob sysJob) throws SchedulerException, TaskException
+    {
+        if (!CronUtils.isValid(sysJob.getCronExpression()))
+        {
+            return AjaxResult.error("淇敼浠诲姟'" + sysJob.getJobName() + "'澶辫触锛孋ron琛ㄨ揪寮忎笉姝g‘");
+        }
+        else if (StrUtil.containsIgnoreCase(sysJob.getInvokeTarget(), Constants.LOOKUP_RMI))
+        {
+            return AjaxResult.error("淇敼浠诲姟'" + sysJob.getJobName() + "'澶辫触锛岀洰鏍囧瓧绗︿覆涓嶅厑璁�'rmi://'璋冪敤");
+        }
+        sysJob.setUpdateBy(SecurityUtils.getUsername());
+        return toAjax(jobService.updateJob(sysJob));
+    }
+
+    /**
+     * 瀹氭椂浠诲姟鐘舵�佷慨鏀�
+     */
+    @PreAuthorize("@ss.hasPermi('monitor:job:changeStatus')")
+    @Log(title = "瀹氭椂浠诲姟", businessType = BusinessType.UPDATE)
+    @PutMapping("/changeStatus")
+    public AjaxResult changeStatus(@RequestBody SysJob job) throws SchedulerException
+    {
+        SysJob newJob = jobService.selectJobById(job.getJobId());
+        newJob.setStatus(job.getStatus());
+        return toAjax(jobService.changeStatus(newJob));
+    }
+
+    /**
+     * 瀹氭椂浠诲姟绔嬪嵆鎵ц涓�娆�
+     */
+    @PreAuthorize("@ss.hasPermi('monitor:job:changeStatus')")
+    @Log(title = "瀹氭椂浠诲姟", businessType = BusinessType.UPDATE)
+    @PutMapping("/run")
+    public AjaxResult run(@RequestBody SysJob job) throws SchedulerException
+    {
+        jobService.run(job);
+        return AjaxResult.success();
+    }
+
+    /**
+     * 鍒犻櫎瀹氭椂浠诲姟
+     */
+    @PreAuthorize("@ss.hasPermi('monitor:job:remove')")
+    @Log(title = "瀹氭椂浠诲姟", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{jobIds}")
+    public AjaxResult remove(@PathVariable Long[] jobIds) throws SchedulerException, TaskException
+    {
+        jobService.deleteJobByIds(jobIds);
+        return AjaxResult.success();
+    }
+}
diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/mapper/SysJobLogMapper.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/mapper/SysJobLogMapper.java
index 03d4501..fe1a059 100644
--- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/mapper/SysJobLogMapper.java
+++ b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/mapper/SysJobLogMapper.java
@@ -1,13 +1,13 @@
-package com.ruoyi.quartz.mapper;
-
-import com.ruoyi.common.core.page.BaseMapperPlus;
-import com.ruoyi.quartz.domain.SysJobLog;
-
-/**
- * 璋冨害浠诲姟鏃ュ織淇℃伅 鏁版嵁灞�
- *
- * @author ruoyi
- */
-public interface SysJobLogMapper extends BaseMapperPlus<SysJobLog> {
-
-}
+package com.ruoyi.quartz.mapper;
+
+import com.ruoyi.common.core.mybatisplus.core.BaseMapperPlus;
+import com.ruoyi.quartz.domain.SysJobLog;
+
+/**
+ * 璋冨害浠诲姟鏃ュ織淇℃伅 鏁版嵁灞�
+ *
+ * @author ruoyi
+ */
+public interface SysJobLogMapper extends BaseMapperPlus<SysJobLog> {
+
+}
diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/mapper/SysJobMapper.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/mapper/SysJobMapper.java
index 8e73f0a..14566b4 100644
--- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/mapper/SysJobMapper.java
+++ b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/mapper/SysJobMapper.java
@@ -1,13 +1,13 @@
-package com.ruoyi.quartz.mapper;
-
-import com.ruoyi.common.core.page.BaseMapperPlus;
-import com.ruoyi.quartz.domain.SysJob;
-
-/**
- * 璋冨害浠诲姟淇℃伅 鏁版嵁灞�
- *
- * @author ruoyi
- */
-public interface SysJobMapper extends BaseMapperPlus<SysJob> {
-
-}
+package com.ruoyi.quartz.mapper;
+
+import com.ruoyi.common.core.mybatisplus.core.BaseMapperPlus;
+import com.ruoyi.quartz.domain.SysJob;
+
+/**
+ * 璋冨害浠诲姟淇℃伅 鏁版嵁灞�
+ *
+ * @author ruoyi
+ */
+public interface SysJobMapper extends BaseMapperPlus<SysJob> {
+
+}
diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/ISysJobLogService.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/ISysJobLogService.java
index 6b51886..cb5b7d5 100644
--- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/ISysJobLogService.java
+++ b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/ISysJobLogService.java
@@ -1,62 +1,62 @@
-package com.ruoyi.quartz.service;
-
-import com.ruoyi.common.core.page.IServicePlus;
-import com.ruoyi.common.core.page.TableDataInfo;
-import com.ruoyi.quartz.domain.SysJobLog;
-
-import java.util.List;
-
-/**
- * 瀹氭椂浠诲姟璋冨害鏃ュ織淇℃伅淇℃伅 鏈嶅姟灞�
- *
- * @author ruoyi
- */
-public interface ISysJobLogService extends IServicePlus<SysJobLog> {
-
-
-    TableDataInfo<SysJobLog> selectPageJobLogList(SysJobLog jobLog);
-
-    /**
-     * 鑾峰彇quartz璋冨害鍣ㄦ棩蹇楃殑璁″垝浠诲姟
-     *
-     * @param jobLog 璋冨害鏃ュ織淇℃伅
-     * @return 璋冨害浠诲姟鏃ュ織闆嗗悎
-     */
-    public List<SysJobLog> selectJobLogList(SysJobLog jobLog);
-
-    /**
-     * 閫氳繃璋冨害浠诲姟鏃ュ織ID鏌ヨ璋冨害淇℃伅
-     *
-     * @param jobLogId 璋冨害浠诲姟鏃ュ織ID
-     * @return 璋冨害浠诲姟鏃ュ織瀵硅薄淇℃伅
-     */
-    public SysJobLog selectJobLogById(Long jobLogId);
-
-    /**
-     * 鏂板浠诲姟鏃ュ織
-     *
-     * @param jobLog 璋冨害鏃ュ織淇℃伅
-     */
-    public void addJobLog(SysJobLog jobLog);
-
-    /**
-     * 鎵归噺鍒犻櫎璋冨害鏃ュ織淇℃伅
-     *
-     * @param logIds 闇�瑕佸垹闄ょ殑鏃ュ織ID
-     * @return 缁撴灉
-     */
-    public int deleteJobLogByIds(Long[] logIds);
-
-    /**
-     * 鍒犻櫎浠诲姟鏃ュ織
-     *
-     * @param jobId 璋冨害鏃ュ織ID
-     * @return 缁撴灉
-     */
-    public int deleteJobLogById(Long jobId);
-
-    /**
-     * 娓呯┖浠诲姟鏃ュ織
-     */
-    public void cleanJobLog();
-}
+package com.ruoyi.quartz.service;
+
+import com.ruoyi.common.core.mybatisplus.core.IServicePlus;
+import com.ruoyi.common.core.page.TableDataInfo;
+import com.ruoyi.quartz.domain.SysJobLog;
+
+import java.util.List;
+
+/**
+ * 瀹氭椂浠诲姟璋冨害鏃ュ織淇℃伅淇℃伅 鏈嶅姟灞�
+ *
+ * @author ruoyi
+ */
+public interface ISysJobLogService extends IServicePlus<SysJobLog> {
+
+
+    TableDataInfo<SysJobLog> selectPageJobLogList(SysJobLog jobLog);
+
+    /**
+     * 鑾峰彇quartz璋冨害鍣ㄦ棩蹇楃殑璁″垝浠诲姟
+     *
+     * @param jobLog 璋冨害鏃ュ織淇℃伅
+     * @return 璋冨害浠诲姟鏃ュ織闆嗗悎
+     */
+    public List<SysJobLog> selectJobLogList(SysJobLog jobLog);
+
+    /**
+     * 閫氳繃璋冨害浠诲姟鏃ュ織ID鏌ヨ璋冨害淇℃伅
+     *
+     * @param jobLogId 璋冨害浠诲姟鏃ュ織ID
+     * @return 璋冨害浠诲姟鏃ュ織瀵硅薄淇℃伅
+     */
+    public SysJobLog selectJobLogById(Long jobLogId);
+
+    /**
+     * 鏂板浠诲姟鏃ュ織
+     *
+     * @param jobLog 璋冨害鏃ュ織淇℃伅
+     */
+    public void addJobLog(SysJobLog jobLog);
+
+    /**
+     * 鎵归噺鍒犻櫎璋冨害鏃ュ織淇℃伅
+     *
+     * @param logIds 闇�瑕佸垹闄ょ殑鏃ュ織ID
+     * @return 缁撴灉
+     */
+    public int deleteJobLogByIds(Long[] logIds);
+
+    /**
+     * 鍒犻櫎浠诲姟鏃ュ織
+     *
+     * @param jobId 璋冨害鏃ュ織ID
+     * @return 缁撴灉
+     */
+    public int deleteJobLogById(Long jobId);
+
+    /**
+     * 娓呯┖浠诲姟鏃ュ織
+     */
+    public void cleanJobLog();
+}
diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/ISysJobService.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/ISysJobService.java
index fbbf4c5..11150c7 100644
--- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/ISysJobService.java
+++ b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/ISysJobService.java
@@ -1,106 +1,106 @@
-package com.ruoyi.quartz.service;
-
-import com.ruoyi.common.core.page.IServicePlus;
-import com.ruoyi.common.core.page.TableDataInfo;
-import com.ruoyi.common.exception.job.TaskException;
-import com.ruoyi.quartz.domain.SysJob;
-import org.quartz.SchedulerException;
-
-import java.util.List;
-
-/**
- * 瀹氭椂浠诲姟璋冨害淇℃伅淇℃伅 鏈嶅姟灞�
- *
- * @author ruoyi
- */
-public interface ISysJobService extends IServicePlus<SysJob> {
-    /**
-     * 鑾峰彇quartz璋冨害鍣ㄧ殑璁″垝浠诲姟
-     *
-     * @param job 璋冨害淇℃伅
-     * @return 璋冨害浠诲姟闆嗗悎
-     */
-    public TableDataInfo<SysJob> selectPageJobList(SysJob job);
-
-    public List<SysJob> selectJobList(SysJob job);
-
-    /**
-     * 閫氳繃璋冨害浠诲姟ID鏌ヨ璋冨害淇℃伅
-     *
-     * @param jobId 璋冨害浠诲姟ID
-     * @return 璋冨害浠诲姟瀵硅薄淇℃伅
-     */
-    public SysJob selectJobById(Long jobId);
-
-    /**
-     * 鏆傚仠浠诲姟
-     *
-     * @param job 璋冨害淇℃伅
-     * @return 缁撴灉
-     */
-    public int pauseJob(SysJob job) throws SchedulerException;
-
-    /**
-     * 鎭㈠浠诲姟
-     *
-     * @param job 璋冨害淇℃伅
-     * @return 缁撴灉
-     */
-    public int resumeJob(SysJob job) throws SchedulerException;
-
-    /**
-     * 鍒犻櫎浠诲姟鍚庯紝鎵�瀵瑰簲鐨則rigger涔熷皢琚垹闄�
-     *
-     * @param job 璋冨害淇℃伅
-     * @return 缁撴灉
-     */
-    public int deleteJob(SysJob job) throws SchedulerException;
-
-    /**
-     * 鎵归噺鍒犻櫎璋冨害淇℃伅
-     *
-     * @param jobIds 闇�瑕佸垹闄ょ殑浠诲姟ID
-     * @return 缁撴灉
-     */
-    public void deleteJobByIds(Long[] jobIds) throws SchedulerException;
-
-    /**
-     * 浠诲姟璋冨害鐘舵�佷慨鏀�
-     *
-     * @param job 璋冨害淇℃伅
-     * @return 缁撴灉
-     */
-    public int changeStatus(SysJob job) throws SchedulerException;
-
-    /**
-     * 绔嬪嵆杩愯浠诲姟
-     *
-     * @param job 璋冨害淇℃伅
-     * @return 缁撴灉
-     */
-    public void run(SysJob job) throws SchedulerException;
-
-    /**
-     * 鏂板浠诲姟
-     *
-     * @param job 璋冨害淇℃伅
-     * @return 缁撴灉
-     */
-    public int insertJob(SysJob job) throws SchedulerException, TaskException;
-
-    /**
-     * 鏇存柊浠诲姟
-     *
-     * @param job 璋冨害淇℃伅
-     * @return 缁撴灉
-     */
-    public int updateJob(SysJob job) throws SchedulerException, TaskException;
-
-    /**
-     * 鏍¢獙cron琛ㄨ揪寮忔槸鍚︽湁鏁�
-     *
-     * @param cronExpression 琛ㄨ揪寮�
-     * @return 缁撴灉
-     */
-    public boolean checkCronExpressionIsValid(String cronExpression);
-}
+package com.ruoyi.quartz.service;
+
+import com.ruoyi.common.core.mybatisplus.core.IServicePlus;
+import com.ruoyi.common.core.page.TableDataInfo;
+import com.ruoyi.common.exception.job.TaskException;
+import com.ruoyi.quartz.domain.SysJob;
+import org.quartz.SchedulerException;
+
+import java.util.List;
+
+/**
+ * 瀹氭椂浠诲姟璋冨害淇℃伅淇℃伅 鏈嶅姟灞�
+ *
+ * @author ruoyi
+ */
+public interface ISysJobService extends IServicePlus<SysJob> {
+    /**
+     * 鑾峰彇quartz璋冨害鍣ㄧ殑璁″垝浠诲姟
+     *
+     * @param job 璋冨害淇℃伅
+     * @return 璋冨害浠诲姟闆嗗悎
+     */
+    public TableDataInfo<SysJob> selectPageJobList(SysJob job);
+
+    public List<SysJob> selectJobList(SysJob job);
+
+    /**
+     * 閫氳繃璋冨害浠诲姟ID鏌ヨ璋冨害淇℃伅
+     *
+     * @param jobId 璋冨害浠诲姟ID
+     * @return 璋冨害浠诲姟瀵硅薄淇℃伅
+     */
+    public SysJob selectJobById(Long jobId);
+
+    /**
+     * 鏆傚仠浠诲姟
+     *
+     * @param job 璋冨害淇℃伅
+     * @return 缁撴灉
+     */
+    public int pauseJob(SysJob job) throws SchedulerException;
+
+    /**
+     * 鎭㈠浠诲姟
+     *
+     * @param job 璋冨害淇℃伅
+     * @return 缁撴灉
+     */
+    public int resumeJob(SysJob job) throws SchedulerException;
+
+    /**
+     * 鍒犻櫎浠诲姟鍚庯紝鎵�瀵瑰簲鐨則rigger涔熷皢琚垹闄�
+     *
+     * @param job 璋冨害淇℃伅
+     * @return 缁撴灉
+     */
+    public int deleteJob(SysJob job) throws SchedulerException;
+
+    /**
+     * 鎵归噺鍒犻櫎璋冨害淇℃伅
+     *
+     * @param jobIds 闇�瑕佸垹闄ょ殑浠诲姟ID
+     * @return 缁撴灉
+     */
+    public void deleteJobByIds(Long[] jobIds) throws SchedulerException;
+
+    /**
+     * 浠诲姟璋冨害鐘舵�佷慨鏀�
+     *
+     * @param job 璋冨害淇℃伅
+     * @return 缁撴灉
+     */
+    public int changeStatus(SysJob job) throws SchedulerException;
+
+    /**
+     * 绔嬪嵆杩愯浠诲姟
+     *
+     * @param job 璋冨害淇℃伅
+     * @return 缁撴灉
+     */
+    public void run(SysJob job) throws SchedulerException;
+
+    /**
+     * 鏂板浠诲姟
+     *
+     * @param job 璋冨害淇℃伅
+     * @return 缁撴灉
+     */
+    public int insertJob(SysJob job) throws SchedulerException, TaskException;
+
+    /**
+     * 鏇存柊浠诲姟
+     *
+     * @param job 璋冨害淇℃伅
+     * @return 缁撴灉
+     */
+    public int updateJob(SysJob job) throws SchedulerException, TaskException;
+
+    /**
+     * 鏍¢獙cron琛ㄨ揪寮忔槸鍚︽湁鏁�
+     *
+     * @param cronExpression 琛ㄨ揪寮�
+     * @return 缁撴灉
+     */
+    public boolean checkCronExpressionIsValid(String cronExpression);
+}
diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/impl/SysJobLogServiceImpl.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/impl/SysJobLogServiceImpl.java
index 28c9d8a..e10ad14 100644
--- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/impl/SysJobLogServiceImpl.java
+++ b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/impl/SysJobLogServiceImpl.java
@@ -1,114 +1,114 @@
-package com.ruoyi.quartz.service.impl;
-
-import cn.hutool.core.lang.Validator;
-import cn.hutool.core.util.StrUtil;
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.ruoyi.common.core.page.TableDataInfo;
-import com.ruoyi.common.utils.PageUtils;
-import com.ruoyi.quartz.domain.SysJobLog;
-import com.ruoyi.quartz.mapper.SysJobLogMapper;
-import com.ruoyi.quartz.service.ISysJobLogService;
-import org.springframework.stereotype.Service;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-
-/**
- * 瀹氭椂浠诲姟璋冨害鏃ュ織淇℃伅 鏈嶅姟灞�
- *
- * @author ruoyi
- */
-@Service
-public class SysJobLogServiceImpl extends ServiceImpl<SysJobLogMapper, SysJobLog> implements ISysJobLogService {
-
-    @Override
-    public TableDataInfo<SysJobLog> selectPageJobLogList(SysJobLog jobLog) {
-        Map<String, Object> params = jobLog.getParams();
-        LambdaQueryWrapper<SysJobLog> lqw = new LambdaQueryWrapper<SysJobLog>()
-                .like(StrUtil.isNotBlank(jobLog.getJobName()), SysJobLog::getJobName, jobLog.getJobName())
-                .eq(StrUtil.isNotBlank(jobLog.getJobGroup()), SysJobLog::getJobGroup, jobLog.getJobGroup())
-                .eq(StrUtil.isNotBlank(jobLog.getStatus()), SysJobLog::getStatus, jobLog.getStatus())
-                .like(StrUtil.isNotBlank(jobLog.getInvokeTarget()), SysJobLog::getInvokeTarget, jobLog.getInvokeTarget())
-                .apply(Validator.isNotEmpty(params.get("beginTime")),
-                        "date_format(create_time,'%y%m%d') >= date_format({0},'%y%m%d')",
-                        params.get("beginTime"))
-                .apply(Validator.isNotEmpty(params.get("endTime")),
-                        "date_format(create_time,'%y%m%d') <= date_format({0},'%y%m%d')",
-                        params.get("endTime"));
-        return PageUtils.buildDataInfo(page(PageUtils.buildPage(), lqw));
-    }
-
-    /**
-     * 鑾峰彇quartz璋冨害鍣ㄦ棩蹇楃殑璁″垝浠诲姟
-     *
-     * @param jobLog 璋冨害鏃ュ織淇℃伅
-     * @return 璋冨害浠诲姟鏃ュ織闆嗗悎
-     */
-    @Override
-    public List<SysJobLog> selectJobLogList(SysJobLog jobLog) {
-        Map<String, Object> params = jobLog.getParams();
-        return list(new LambdaQueryWrapper<SysJobLog>()
-                .like(StrUtil.isNotBlank(jobLog.getJobName()), SysJobLog::getJobName, jobLog.getJobName())
-                .eq(StrUtil.isNotBlank(jobLog.getJobGroup()), SysJobLog::getJobGroup, jobLog.getJobGroup())
-                .eq(StrUtil.isNotBlank(jobLog.getStatus()), SysJobLog::getStatus, jobLog.getStatus())
-                .like(StrUtil.isNotBlank(jobLog.getInvokeTarget()), SysJobLog::getInvokeTarget, jobLog.getInvokeTarget())
-                .apply(Validator.isNotEmpty(params.get("beginTime")),
-                        "date_format(create_time,'%y%m%d') >= date_format({0},'%y%m%d')",
-                        params.get("beginTime"))
-                .apply(Validator.isNotEmpty(params.get("endTime")),
-                        "date_format(create_time,'%y%m%d') <= date_format({0},'%y%m%d')",
-                        params.get("endTime")));
-    }
-
-    /**
-     * 閫氳繃璋冨害浠诲姟鏃ュ織ID鏌ヨ璋冨害淇℃伅
-     *
-     * @param jobLogId 璋冨害浠诲姟鏃ュ織ID
-     * @return 璋冨害浠诲姟鏃ュ織瀵硅薄淇℃伅
-     */
-    @Override
-    public SysJobLog selectJobLogById(Long jobLogId) {
-        return getById(jobLogId);
-    }
-
-    /**
-     * 鏂板浠诲姟鏃ュ織
-     *
-     * @param jobLog 璋冨害鏃ュ織淇℃伅
-     */
-    @Override
-    public void addJobLog(SysJobLog jobLog) {
-        baseMapper.insert(jobLog);
-    }
-
-    /**
-     * 鎵归噺鍒犻櫎璋冨害鏃ュ織淇℃伅
-     *
-     * @param logIds 闇�瑕佸垹闄ょ殑鏁版嵁ID
-     * @return 缁撴灉
-     */
-    @Override
-    public int deleteJobLogByIds(Long[] logIds) {
-        return baseMapper.deleteBatchIds(Arrays.asList(logIds));
-    }
-
-    /**
-     * 鍒犻櫎浠诲姟鏃ュ織
-     *
-     * @param jobId 璋冨害鏃ュ織ID
-     */
-    @Override
-    public int deleteJobLogById(Long jobId) {
-        return baseMapper.deleteById(jobId);
-    }
-
-    /**
-     * 娓呯┖浠诲姟鏃ュ織
-     */
-    @Override
-    public void cleanJobLog() {
-        remove(new LambdaQueryWrapper<>());
-    }
-}
+package com.ruoyi.quartz.service.impl;
+
+import cn.hutool.core.lang.Validator;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.ruoyi.common.core.mybatisplus.core.ServicePlusImpl;
+import com.ruoyi.common.core.page.TableDataInfo;
+import com.ruoyi.common.utils.PageUtils;
+import com.ruoyi.quartz.domain.SysJobLog;
+import com.ruoyi.quartz.mapper.SysJobLogMapper;
+import com.ruoyi.quartz.service.ISysJobLogService;
+import org.springframework.stereotype.Service;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 瀹氭椂浠诲姟璋冨害鏃ュ織淇℃伅 鏈嶅姟灞�
+ *
+ * @author ruoyi
+ */
+@Service
+public class SysJobLogServiceImpl extends ServicePlusImpl<SysJobLogMapper, SysJobLog> implements ISysJobLogService {
+
+    @Override
+    public TableDataInfo<SysJobLog> selectPageJobLogList(SysJobLog jobLog) {
+        Map<String, Object> params = jobLog.getParams();
+        LambdaQueryWrapper<SysJobLog> lqw = new LambdaQueryWrapper<SysJobLog>()
+                .like(StrUtil.isNotBlank(jobLog.getJobName()), SysJobLog::getJobName, jobLog.getJobName())
+                .eq(StrUtil.isNotBlank(jobLog.getJobGroup()), SysJobLog::getJobGroup, jobLog.getJobGroup())
+                .eq(StrUtil.isNotBlank(jobLog.getStatus()), SysJobLog::getStatus, jobLog.getStatus())
+                .like(StrUtil.isNotBlank(jobLog.getInvokeTarget()), SysJobLog::getInvokeTarget, jobLog.getInvokeTarget())
+                .apply(Validator.isNotEmpty(params.get("beginTime")),
+                        "date_format(create_time,'%y%m%d') >= date_format({0},'%y%m%d')",
+                        params.get("beginTime"))
+                .apply(Validator.isNotEmpty(params.get("endTime")),
+                        "date_format(create_time,'%y%m%d') <= date_format({0},'%y%m%d')",
+                        params.get("endTime"));
+        return PageUtils.buildDataInfo(page(PageUtils.buildPage(), lqw));
+    }
+
+    /**
+     * 鑾峰彇quartz璋冨害鍣ㄦ棩蹇楃殑璁″垝浠诲姟
+     *
+     * @param jobLog 璋冨害鏃ュ織淇℃伅
+     * @return 璋冨害浠诲姟鏃ュ織闆嗗悎
+     */
+    @Override
+    public List<SysJobLog> selectJobLogList(SysJobLog jobLog) {
+        Map<String, Object> params = jobLog.getParams();
+        return list(new LambdaQueryWrapper<SysJobLog>()
+                .like(StrUtil.isNotBlank(jobLog.getJobName()), SysJobLog::getJobName, jobLog.getJobName())
+                .eq(StrUtil.isNotBlank(jobLog.getJobGroup()), SysJobLog::getJobGroup, jobLog.getJobGroup())
+                .eq(StrUtil.isNotBlank(jobLog.getStatus()), SysJobLog::getStatus, jobLog.getStatus())
+                .like(StrUtil.isNotBlank(jobLog.getInvokeTarget()), SysJobLog::getInvokeTarget, jobLog.getInvokeTarget())
+                .apply(Validator.isNotEmpty(params.get("beginTime")),
+                        "date_format(create_time,'%y%m%d') >= date_format({0},'%y%m%d')",
+                        params.get("beginTime"))
+                .apply(Validator.isNotEmpty(params.get("endTime")),
+                        "date_format(create_time,'%y%m%d') <= date_format({0},'%y%m%d')",
+                        params.get("endTime")));
+    }
+
+    /**
+     * 閫氳繃璋冨害浠诲姟鏃ュ織ID鏌ヨ璋冨害淇℃伅
+     *
+     * @param jobLogId 璋冨害浠诲姟鏃ュ織ID
+     * @return 璋冨害浠诲姟鏃ュ織瀵硅薄淇℃伅
+     */
+    @Override
+    public SysJobLog selectJobLogById(Long jobLogId) {
+        return getById(jobLogId);
+    }
+
+    /**
+     * 鏂板浠诲姟鏃ュ織
+     *
+     * @param jobLog 璋冨害鏃ュ織淇℃伅
+     */
+    @Override
+    public void addJobLog(SysJobLog jobLog) {
+        baseMapper.insert(jobLog);
+    }
+
+    /**
+     * 鎵归噺鍒犻櫎璋冨害鏃ュ織淇℃伅
+     *
+     * @param logIds 闇�瑕佸垹闄ょ殑鏁版嵁ID
+     * @return 缁撴灉
+     */
+    @Override
+    public int deleteJobLogByIds(Long[] logIds) {
+        return baseMapper.deleteBatchIds(Arrays.asList(logIds));
+    }
+
+    /**
+     * 鍒犻櫎浠诲姟鏃ュ織
+     *
+     * @param jobId 璋冨害鏃ュ織ID
+     */
+    @Override
+    public int deleteJobLogById(Long jobId) {
+        return baseMapper.deleteById(jobId);
+    }
+
+    /**
+     * 娓呯┖浠诲姟鏃ュ織
+     */
+    @Override
+    public void cleanJobLog() {
+        remove(new LambdaQueryWrapper<>());
+    }
+}
diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/impl/SysJobServiceImpl.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/impl/SysJobServiceImpl.java
index 9b97b4f..7d111d7 100644
--- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/impl/SysJobServiceImpl.java
+++ b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/impl/SysJobServiceImpl.java
@@ -1,246 +1,246 @@
-package com.ruoyi.quartz.service.impl;
-
-import cn.hutool.core.util.StrUtil;
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.ruoyi.common.constant.ScheduleConstants;
-import com.ruoyi.common.core.page.TableDataInfo;
-import com.ruoyi.common.exception.job.TaskException;
-import com.ruoyi.common.utils.PageUtils;
-import com.ruoyi.quartz.domain.SysJob;
-import com.ruoyi.quartz.mapper.SysJobMapper;
-import com.ruoyi.quartz.service.ISysJobService;
-import com.ruoyi.quartz.util.CronUtils;
-import com.ruoyi.quartz.util.ScheduleUtils;
-import org.quartz.JobDataMap;
-import org.quartz.JobKey;
-import org.quartz.Scheduler;
-import org.quartz.SchedulerException;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
-import javax.annotation.PostConstruct;
-import java.util.List;
-
-/**
- * 瀹氭椂浠诲姟璋冨害淇℃伅 鏈嶅姟灞�
- *
- * @author ruoyi
- */
-@Service
-public class SysJobServiceImpl extends ServiceImpl<SysJobMapper, SysJob> implements ISysJobService {
-    @Autowired
-    private Scheduler scheduler;
-
-    /**
-     * 椤圭洰鍚姩鏃讹紝鍒濆鍖栧畾鏃跺櫒 涓昏鏄槻姝㈡墜鍔ㄤ慨鏀规暟鎹簱瀵艰嚧鏈悓姝ュ埌瀹氭椂浠诲姟澶勭悊锛堟敞锛氫笉鑳芥墜鍔ㄤ慨鏀规暟鎹簱ID鍜屼换鍔$粍鍚嶏紝鍚﹀垯浼氬鑷磋剰鏁版嵁锛�
-     */
-    @PostConstruct
-    public void init() throws SchedulerException, TaskException {
-        scheduler.clear();
-        List<SysJob> jobList = list();
-        for (SysJob job : jobList) {
-            ScheduleUtils.createScheduleJob(scheduler, job);
-        }
-    }
-
-    @Override
-    public TableDataInfo<SysJob> selectPageJobList(SysJob job) {
-        LambdaQueryWrapper<SysJob> lqw = new LambdaQueryWrapper<SysJob>()
-                .like(StrUtil.isNotBlank(job.getJobName()), SysJob::getJobName, job.getJobName())
-                .eq(StrUtil.isNotBlank(job.getJobGroup()), SysJob::getJobGroup, job.getJobGroup())
-                .eq(StrUtil.isNotBlank(job.getStatus()), SysJob::getStatus, job.getStatus())
-                .like(StrUtil.isNotBlank(job.getInvokeTarget()), SysJob::getInvokeTarget, job.getInvokeTarget());
-        return PageUtils.buildDataInfo(page(PageUtils.buildPage(), lqw));
-    }
-
-    /**
-     * 鑾峰彇quartz璋冨害鍣ㄧ殑璁″垝浠诲姟鍒楄〃
-     *
-     * @param job 璋冨害淇℃伅
-     * @return
-     */
-    @Override
-    public List<SysJob> selectJobList(SysJob job) {
-        return list(new LambdaQueryWrapper<SysJob>()
-                .like(StrUtil.isNotBlank(job.getJobName()), SysJob::getJobName, job.getJobName())
-                .eq(StrUtil.isNotBlank(job.getJobGroup()), SysJob::getJobGroup, job.getJobGroup())
-                .eq(StrUtil.isNotBlank(job.getStatus()), SysJob::getStatus, job.getStatus())
-                .like(StrUtil.isNotBlank(job.getInvokeTarget()), SysJob::getInvokeTarget, job.getInvokeTarget()));
-    }
-
-    /**
-     * 閫氳繃璋冨害浠诲姟ID鏌ヨ璋冨害淇℃伅
-     *
-     * @param jobId 璋冨害浠诲姟ID
-     * @return 璋冨害浠诲姟瀵硅薄淇℃伅
-     */
-    @Override
-    public SysJob selectJobById(Long jobId) {
-        return getById(jobId);
-    }
-
-    /**
-     * 鏆傚仠浠诲姟
-     *
-     * @param job 璋冨害淇℃伅
-     */
-    @Override
-    @Transactional
-    public int pauseJob(SysJob job) throws SchedulerException {
-        Long jobId = job.getJobId();
-        String jobGroup = job.getJobGroup();
-        job.setStatus(ScheduleConstants.Status.PAUSE.getValue());
-        int rows = baseMapper.updateById(job);
-        if (rows > 0) {
-            scheduler.pauseJob(ScheduleUtils.getJobKey(jobId, jobGroup));
-        }
-        return rows;
-    }
-
-    /**
-     * 鎭㈠浠诲姟
-     *
-     * @param job 璋冨害淇℃伅
-     */
-    @Override
-    @Transactional
-    public int resumeJob(SysJob job) throws SchedulerException {
-        Long jobId = job.getJobId();
-        String jobGroup = job.getJobGroup();
-        job.setStatus(ScheduleConstants.Status.NORMAL.getValue());
-        int rows = baseMapper.updateById(job);
-        if (rows > 0) {
-            scheduler.resumeJob(ScheduleUtils.getJobKey(jobId, jobGroup));
-        }
-        return rows;
-    }
-
-    /**
-     * 鍒犻櫎浠诲姟鍚庯紝鎵�瀵瑰簲鐨則rigger涔熷皢琚垹闄�
-     *
-     * @param job 璋冨害淇℃伅
-     */
-    @Override
-    @Transactional
-    public int deleteJob(SysJob job) throws SchedulerException {
-        Long jobId = job.getJobId();
-        String jobGroup = job.getJobGroup();
-        int rows = baseMapper.deleteById(jobId);
-        if (rows > 0) {
-            scheduler.deleteJob(ScheduleUtils.getJobKey(jobId, jobGroup));
-        }
-        return rows;
-    }
-
-    /**
-     * 鎵归噺鍒犻櫎璋冨害淇℃伅
-     *
-     * @param jobIds 闇�瑕佸垹闄ょ殑浠诲姟ID
-     * @return 缁撴灉
-     */
-    @Override
-    @Transactional
-    public void deleteJobByIds(Long[] jobIds) throws SchedulerException {
-        for (Long jobId : jobIds) {
-            SysJob job = getById(jobId);
-            deleteJob(job);
-        }
-    }
-
-    /**
-     * 浠诲姟璋冨害鐘舵�佷慨鏀�
-     *
-     * @param job 璋冨害淇℃伅
-     */
-    @Override
-    @Transactional
-    public int changeStatus(SysJob job) throws SchedulerException {
-        int rows = 0;
-        String status = job.getStatus();
-        if (ScheduleConstants.Status.NORMAL.getValue().equals(status)) {
-            rows = resumeJob(job);
-        } else if (ScheduleConstants.Status.PAUSE.getValue().equals(status)) {
-            rows = pauseJob(job);
-        }
-        return rows;
-    }
-
-    /**
-     * 绔嬪嵆杩愯浠诲姟
-     *
-     * @param job 璋冨害淇℃伅
-     */
-    @Override
-    @Transactional
-    public void run(SysJob job) throws SchedulerException {
-        Long jobId = job.getJobId();
-        String jobGroup = job.getJobGroup();
-        SysJob properties = selectJobById(job.getJobId());
-        // 鍙傛暟
-        JobDataMap dataMap = new JobDataMap();
-        dataMap.put(ScheduleConstants.TASK_PROPERTIES, properties);
-        scheduler.triggerJob(ScheduleUtils.getJobKey(jobId, jobGroup), dataMap);
-    }
-
-    /**
-     * 鏂板浠诲姟
-     *
-     * @param job 璋冨害淇℃伅 璋冨害淇℃伅
-     */
-    @Override
-    @Transactional
-    public int insertJob(SysJob job) throws SchedulerException, TaskException {
-        job.setStatus(ScheduleConstants.Status.PAUSE.getValue());
-        int rows = baseMapper.insert(job);
-        if (rows > 0) {
-            ScheduleUtils.createScheduleJob(scheduler, job);
-        }
-        return rows;
-    }
-
-    /**
-     * 鏇存柊浠诲姟鐨勬椂闂磋〃杈惧紡
-     *
-     * @param job 璋冨害淇℃伅
-     */
-    @Override
-    @Transactional
-    public int updateJob(SysJob job) throws SchedulerException, TaskException {
-        SysJob properties = selectJobById(job.getJobId());
-        int rows = baseMapper.updateById(job);
-        if (rows > 0) {
-            updateSchedulerJob(job, properties.getJobGroup());
-        }
-        return rows;
-    }
-
-    /**
-     * 鏇存柊浠诲姟
-     *
-     * @param job      浠诲姟瀵硅薄
-     * @param jobGroup 浠诲姟缁勫悕
-     */
-    public void updateSchedulerJob(SysJob job, String jobGroup) throws SchedulerException, TaskException {
-        Long jobId = job.getJobId();
-        // 鍒ゆ柇鏄惁瀛樺湪
-        JobKey jobKey = ScheduleUtils.getJobKey(jobId, jobGroup);
-        if (scheduler.checkExists(jobKey)) {
-            // 闃叉鍒涘缓鏃跺瓨鍦ㄦ暟鎹棶棰� 鍏堢Щ闄わ紝鐒跺悗鍦ㄦ墽琛屽垱寤烘搷浣�
-            scheduler.deleteJob(jobKey);
-        }
-        ScheduleUtils.createScheduleJob(scheduler, job);
-    }
-
-    /**
-     * 鏍¢獙cron琛ㄨ揪寮忔槸鍚︽湁鏁�
-     *
-     * @param cronExpression 琛ㄨ揪寮�
-     * @return 缁撴灉
-     */
-    @Override
-    public boolean checkCronExpressionIsValid(String cronExpression) {
-        return CronUtils.isValid(cronExpression);
-    }
-}
+package com.ruoyi.quartz.service.impl;
+
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.ruoyi.common.constant.ScheduleConstants;
+import com.ruoyi.common.core.mybatisplus.core.ServicePlusImpl;
+import com.ruoyi.common.core.page.TableDataInfo;
+import com.ruoyi.common.exception.job.TaskException;
+import com.ruoyi.common.utils.PageUtils;
+import com.ruoyi.quartz.domain.SysJob;
+import com.ruoyi.quartz.mapper.SysJobMapper;
+import com.ruoyi.quartz.service.ISysJobService;
+import com.ruoyi.quartz.util.CronUtils;
+import com.ruoyi.quartz.util.ScheduleUtils;
+import org.quartz.JobDataMap;
+import org.quartz.JobKey;
+import org.quartz.Scheduler;
+import org.quartz.SchedulerException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.annotation.PostConstruct;
+import java.util.List;
+
+/**
+ * 瀹氭椂浠诲姟璋冨害淇℃伅 鏈嶅姟灞�
+ *
+ * @author ruoyi
+ */
+@Service
+public class SysJobServiceImpl extends ServicePlusImpl<SysJobMapper, SysJob> implements ISysJobService {
+    @Autowired
+    private Scheduler scheduler;
+
+    /**
+     * 椤圭洰鍚姩鏃讹紝鍒濆鍖栧畾鏃跺櫒 涓昏鏄槻姝㈡墜鍔ㄤ慨鏀规暟鎹簱瀵艰嚧鏈悓姝ュ埌瀹氭椂浠诲姟澶勭悊锛堟敞锛氫笉鑳芥墜鍔ㄤ慨鏀规暟鎹簱ID鍜屼换鍔$粍鍚嶏紝鍚﹀垯浼氬鑷磋剰鏁版嵁锛�
+     */
+    @PostConstruct
+    public void init() throws SchedulerException, TaskException {
+        scheduler.clear();
+        List<SysJob> jobList = list();
+        for (SysJob job : jobList) {
+            ScheduleUtils.createScheduleJob(scheduler, job);
+        }
+    }
+
+    @Override
+    public TableDataInfo<SysJob> selectPageJobList(SysJob job) {
+        LambdaQueryWrapper<SysJob> lqw = new LambdaQueryWrapper<SysJob>()
+                .like(StrUtil.isNotBlank(job.getJobName()), SysJob::getJobName, job.getJobName())
+                .eq(StrUtil.isNotBlank(job.getJobGroup()), SysJob::getJobGroup, job.getJobGroup())
+                .eq(StrUtil.isNotBlank(job.getStatus()), SysJob::getStatus, job.getStatus())
+                .like(StrUtil.isNotBlank(job.getInvokeTarget()), SysJob::getInvokeTarget, job.getInvokeTarget());
+        return PageUtils.buildDataInfo(page(PageUtils.buildPage(), lqw));
+    }
+
+    /**
+     * 鑾峰彇quartz璋冨害鍣ㄧ殑璁″垝浠诲姟鍒楄〃
+     *
+     * @param job 璋冨害淇℃伅
+     * @return
+     */
+    @Override
+    public List<SysJob> selectJobList(SysJob job) {
+        return list(new LambdaQueryWrapper<SysJob>()
+                .like(StrUtil.isNotBlank(job.getJobName()), SysJob::getJobName, job.getJobName())
+                .eq(StrUtil.isNotBlank(job.getJobGroup()), SysJob::getJobGroup, job.getJobGroup())
+                .eq(StrUtil.isNotBlank(job.getStatus()), SysJob::getStatus, job.getStatus())
+                .like(StrUtil.isNotBlank(job.getInvokeTarget()), SysJob::getInvokeTarget, job.getInvokeTarget()));
+    }
+
+    /**
+     * 閫氳繃璋冨害浠诲姟ID鏌ヨ璋冨害淇℃伅
+     *
+     * @param jobId 璋冨害浠诲姟ID
+     * @return 璋冨害浠诲姟瀵硅薄淇℃伅
+     */
+    @Override
+    public SysJob selectJobById(Long jobId) {
+        return getById(jobId);
+    }
+
+    /**
+     * 鏆傚仠浠诲姟
+     *
+     * @param job 璋冨害淇℃伅
+     */
+    @Override
+    @Transactional
+    public int pauseJob(SysJob job) throws SchedulerException {
+        Long jobId = job.getJobId();
+        String jobGroup = job.getJobGroup();
+        job.setStatus(ScheduleConstants.Status.PAUSE.getValue());
+        int rows = baseMapper.updateById(job);
+        if (rows > 0) {
+            scheduler.pauseJob(ScheduleUtils.getJobKey(jobId, jobGroup));
+        }
+        return rows;
+    }
+
+    /**
+     * 鎭㈠浠诲姟
+     *
+     * @param job 璋冨害淇℃伅
+     */
+    @Override
+    @Transactional
+    public int resumeJob(SysJob job) throws SchedulerException {
+        Long jobId = job.getJobId();
+        String jobGroup = job.getJobGroup();
+        job.setStatus(ScheduleConstants.Status.NORMAL.getValue());
+        int rows = baseMapper.updateById(job);
+        if (rows > 0) {
+            scheduler.resumeJob(ScheduleUtils.getJobKey(jobId, jobGroup));
+        }
+        return rows;
+    }
+
+    /**
+     * 鍒犻櫎浠诲姟鍚庯紝鎵�瀵瑰簲鐨則rigger涔熷皢琚垹闄�
+     *
+     * @param job 璋冨害淇℃伅
+     */
+    @Override
+    @Transactional
+    public int deleteJob(SysJob job) throws SchedulerException {
+        Long jobId = job.getJobId();
+        String jobGroup = job.getJobGroup();
+        int rows = baseMapper.deleteById(jobId);
+        if (rows > 0) {
+            scheduler.deleteJob(ScheduleUtils.getJobKey(jobId, jobGroup));
+        }
+        return rows;
+    }
+
+    /**
+     * 鎵归噺鍒犻櫎璋冨害淇℃伅
+     *
+     * @param jobIds 闇�瑕佸垹闄ょ殑浠诲姟ID
+     * @return 缁撴灉
+     */
+    @Override
+    @Transactional
+    public void deleteJobByIds(Long[] jobIds) throws SchedulerException {
+        for (Long jobId : jobIds) {
+            SysJob job = getById(jobId);
+            deleteJob(job);
+        }
+    }
+
+    /**
+     * 浠诲姟璋冨害鐘舵�佷慨鏀�
+     *
+     * @param job 璋冨害淇℃伅
+     */
+    @Override
+    @Transactional
+    public int changeStatus(SysJob job) throws SchedulerException {
+        int rows = 0;
+        String status = job.getStatus();
+        if (ScheduleConstants.Status.NORMAL.getValue().equals(status)) {
+            rows = resumeJob(job);
+        } else if (ScheduleConstants.Status.PAUSE.getValue().equals(status)) {
+            rows = pauseJob(job);
+        }
+        return rows;
+    }
+
+    /**
+     * 绔嬪嵆杩愯浠诲姟
+     *
+     * @param job 璋冨害淇℃伅
+     */
+    @Override
+    @Transactional
+    public void run(SysJob job) throws SchedulerException {
+        Long jobId = job.getJobId();
+        String jobGroup = job.getJobGroup();
+        SysJob properties = selectJobById(job.getJobId());
+        // 鍙傛暟
+        JobDataMap dataMap = new JobDataMap();
+        dataMap.put(ScheduleConstants.TASK_PROPERTIES, properties);
+        scheduler.triggerJob(ScheduleUtils.getJobKey(jobId, jobGroup), dataMap);
+    }
+
+    /**
+     * 鏂板浠诲姟
+     *
+     * @param job 璋冨害淇℃伅 璋冨害淇℃伅
+     */
+    @Override
+    @Transactional
+    public int insertJob(SysJob job) throws SchedulerException, TaskException {
+        job.setStatus(ScheduleConstants.Status.PAUSE.getValue());
+        int rows = baseMapper.insert(job);
+        if (rows > 0) {
+            ScheduleUtils.createScheduleJob(scheduler, job);
+        }
+        return rows;
+    }
+
+    /**
+     * 鏇存柊浠诲姟鐨勬椂闂磋〃杈惧紡
+     *
+     * @param job 璋冨害淇℃伅
+     */
+    @Override
+    @Transactional
+    public int updateJob(SysJob job) throws SchedulerException, TaskException {
+        SysJob properties = selectJobById(job.getJobId());
+        int rows = baseMapper.updateById(job);
+        if (rows > 0) {
+            updateSchedulerJob(job, properties.getJobGroup());
+        }
+        return rows;
+    }
+
+    /**
+     * 鏇存柊浠诲姟
+     *
+     * @param job      浠诲姟瀵硅薄
+     * @param jobGroup 浠诲姟缁勫悕
+     */
+    public void updateSchedulerJob(SysJob job, String jobGroup) throws SchedulerException, TaskException {
+        Long jobId = job.getJobId();
+        // 鍒ゆ柇鏄惁瀛樺湪
+        JobKey jobKey = ScheduleUtils.getJobKey(jobId, jobGroup);
+        if (scheduler.checkExists(jobKey)) {
+            // 闃叉鍒涘缓鏃跺瓨鍦ㄦ暟鎹棶棰� 鍏堢Щ闄わ紝鐒跺悗鍦ㄦ墽琛屽垱寤烘搷浣�
+            scheduler.deleteJob(jobKey);
+        }
+        ScheduleUtils.createScheduleJob(scheduler, job);
+    }
+
+    /**
+     * 鏍¢獙cron琛ㄨ揪寮忔槸鍚︽湁鏁�
+     *
+     * @param cronExpression 琛ㄨ揪寮�
+     * @return 缁撴灉
+     */
+    @Override
+    public boolean checkCronExpressionIsValid(String cronExpression) {
+        return CronUtils.isValid(cronExpression);
+    }
+}
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysConfigMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysConfigMapper.java
index fb3f068..97aaa52 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysConfigMapper.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysConfigMapper.java
@@ -1,6 +1,6 @@
 package com.ruoyi.system.mapper;
 
-import com.ruoyi.common.core.page.BaseMapperPlus;
+import com.ruoyi.common.core.mybatisplus.core.BaseMapperPlus;
 import com.ruoyi.system.domain.SysConfig;
 
 /**
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDeptMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDeptMapper.java
index 54fe261..ecee7ea 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDeptMapper.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDeptMapper.java
@@ -1,7 +1,7 @@
 package com.ruoyi.system.mapper;
 
 import com.ruoyi.common.core.domain.entity.SysDept;
-import com.ruoyi.common.core.page.BaseMapperPlus;
+import com.ruoyi.common.core.mybatisplus.core.BaseMapperPlus;
 import org.apache.ibatis.annotations.Param;
 
 import java.util.List;
@@ -24,7 +24,7 @@
     /**
      * 鏍规嵁瑙掕壊ID鏌ヨ閮ㄩ棬鏍戜俊鎭�
      *
-     * @param roleId            瑙掕壊ID
+     * @param roleId 瑙掕壊ID
      * @param deptCheckStrictly 閮ㄩ棬鏍戦�夋嫨椤规槸鍚﹀叧鑱旀樉绀�
      * @return 閫変腑閮ㄩ棬鍒楄〃
      */
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDictDataMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDictDataMapper.java
index 3d8971d..db5c98e 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDictDataMapper.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDictDataMapper.java
@@ -2,7 +2,7 @@
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.ruoyi.common.core.domain.entity.SysDictData;
-import com.ruoyi.common.core.page.BaseMapperPlus;
+import com.ruoyi.common.core.mybatisplus.core.BaseMapperPlus;
 
 import java.util.List;
 
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDictTypeMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDictTypeMapper.java
index 911386d..7ff8c46 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDictTypeMapper.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDictTypeMapper.java
@@ -1,7 +1,7 @@
 package com.ruoyi.system.mapper;
 
 import com.ruoyi.common.core.domain.entity.SysDictType;
-import com.ruoyi.common.core.page.BaseMapperPlus;
+import com.ruoyi.common.core.mybatisplus.core.BaseMapperPlus;
 
 /**
  * 瀛楀吀琛� 鏁版嵁灞�
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysLogininforMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysLogininforMapper.java
index bf37f9b..cc99c10 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysLogininforMapper.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysLogininforMapper.java
@@ -1,6 +1,6 @@
 package com.ruoyi.system.mapper;
 
-import com.ruoyi.common.core.page.BaseMapperPlus;
+import com.ruoyi.common.core.mybatisplus.core.BaseMapperPlus;
 import com.ruoyi.system.domain.SysLogininfor;
 
 /**
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysMenuMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysMenuMapper.java
index 6a8e729..f54ceea 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysMenuMapper.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysMenuMapper.java
@@ -1,7 +1,7 @@
 package com.ruoyi.system.mapper;
 
 import com.ruoyi.common.core.domain.entity.SysMenu;
-import com.ruoyi.common.core.page.BaseMapperPlus;
+import com.ruoyi.common.core.mybatisplus.core.BaseMapperPlus;
 import org.apache.ibatis.annotations.Param;
 
 import java.util.List;
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysNoticeMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysNoticeMapper.java
index 0061170..68c2825 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysNoticeMapper.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysNoticeMapper.java
@@ -1,6 +1,6 @@
 package com.ruoyi.system.mapper;
 
-import com.ruoyi.common.core.page.BaseMapperPlus;
+import com.ruoyi.common.core.mybatisplus.core.BaseMapperPlus;
 import com.ruoyi.system.domain.SysNotice;
 
 /**
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysOperLogMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysOperLogMapper.java
index 3f38256..93d3262 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysOperLogMapper.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysOperLogMapper.java
@@ -1,6 +1,6 @@
 package com.ruoyi.system.mapper;
 
-import com.ruoyi.common.core.page.BaseMapperPlus;
+import com.ruoyi.common.core.mybatisplus.core.BaseMapperPlus;
 import com.ruoyi.system.domain.SysOperLog;
 
 /**
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysPostMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysPostMapper.java
index 1eef04f..8a1b309 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysPostMapper.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysPostMapper.java
@@ -1,6 +1,6 @@
 package com.ruoyi.system.mapper;
 
-import com.ruoyi.common.core.page.BaseMapperPlus;
+import com.ruoyi.common.core.mybatisplus.core.BaseMapperPlus;
 import com.ruoyi.system.domain.SysPost;
 
 import java.util.List;
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleDeptMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleDeptMapper.java
index 331ecb9..af248c1 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleDeptMapper.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleDeptMapper.java
@@ -1,9 +1,7 @@
 package com.ruoyi.system.mapper;
 
-import com.ruoyi.common.core.page.BaseMapperPlus;
+import com.ruoyi.common.core.mybatisplus.core.BaseMapperPlus;
 import com.ruoyi.system.domain.SysRoleDept;
-
-import java.util.List;
 
 /**
  * 瑙掕壊涓庨儴闂ㄥ叧鑱旇〃 鏁版嵁灞�
@@ -11,13 +9,5 @@
  * @author ruoyi
  */
 public interface SysRoleDeptMapper extends BaseMapperPlus<SysRoleDept> {
-
-	/**
-	 * 鎵归噺鏂板瑙掕壊閮ㄩ棬淇℃伅
-	 *
-	 * @param roleDeptList 瑙掕壊閮ㄩ棬鍒楄〃
-	 * @return 缁撴灉
-	 */
-	public int batchRoleDept(List<SysRoleDept> roleDeptList);
 
 }
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleMapper.java
index e0792c7..972f8f6 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleMapper.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleMapper.java
@@ -2,7 +2,7 @@
 
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.ruoyi.common.core.domain.entity.SysRole;
-import com.ruoyi.common.core.page.BaseMapperPlus;
+import com.ruoyi.common.core.mybatisplus.core.BaseMapperPlus;
 import org.apache.ibatis.annotations.Param;
 
 import java.util.List;
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleMenuMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleMenuMapper.java
index 4f08cea..c7e743e 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleMenuMapper.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleMenuMapper.java
@@ -1,9 +1,7 @@
 package com.ruoyi.system.mapper;
 
-import com.ruoyi.common.core.page.BaseMapperPlus;
+import com.ruoyi.common.core.mybatisplus.core.BaseMapperPlus;
 import com.ruoyi.system.domain.SysRoleMenu;
-
-import java.util.List;
 
 /**
  * 瑙掕壊涓庤彍鍗曞叧鑱旇〃 鏁版嵁灞�
@@ -11,13 +9,5 @@
  * @author ruoyi
  */
 public interface SysRoleMenuMapper extends BaseMapperPlus<SysRoleMenu> {
-
-	/**
-	 * 鎵归噺鏂板瑙掕壊鑿滃崟淇℃伅
-	 *
-	 * @param roleMenuList 瑙掕壊鑿滃崟鍒楄〃
-	 * @return 缁撴灉
-	 */
-	public int batchRoleMenu(List<SysRoleMenu> roleMenuList);
 
 }
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserMapper.java
index a3fcfdb..17b17b0 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserMapper.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserMapper.java
@@ -2,7 +2,7 @@
 
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.ruoyi.common.core.domain.entity.SysUser;
-import com.ruoyi.common.core.page.BaseMapperPlus;
+import com.ruoyi.common.core.mybatisplus.core.BaseMapperPlus;
 import org.apache.ibatis.annotations.Param;
 
 import java.util.List;
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserPostMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserPostMapper.java
index 7839bbe..e5c63e3 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserPostMapper.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserPostMapper.java
@@ -1,9 +1,7 @@
 package com.ruoyi.system.mapper;
 
-import com.ruoyi.common.core.page.BaseMapperPlus;
+import com.ruoyi.common.core.mybatisplus.core.BaseMapperPlus;
 import com.ruoyi.system.domain.SysUserPost;
-
-import java.util.List;
 
 /**
  * 鐢ㄦ埛涓庡矖浣嶅叧鑱旇〃 鏁版嵁灞�
@@ -11,13 +9,5 @@
  * @author ruoyi
  */
 public interface SysUserPostMapper extends BaseMapperPlus<SysUserPost> {
-
-	/**
-	 * 鎵归噺鏂板鐢ㄦ埛宀椾綅淇℃伅
-	 *
-	 * @param userPostList 鐢ㄦ埛瑙掕壊鍒楄〃
-	 * @return 缁撴灉
-	 */
-	public int batchUserPost(List<SysUserPost> userPostList);
 
 }
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserRoleMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserRoleMapper.java
index 365bbf4..260ec32 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserRoleMapper.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserRoleMapper.java
@@ -1,9 +1,7 @@
 package com.ruoyi.system.mapper;
 
-import com.ruoyi.common.core.page.BaseMapperPlus;
+import com.ruoyi.common.core.mybatisplus.core.BaseMapperPlus;
 import com.ruoyi.system.domain.SysUserRole;
-
-import java.util.List;
 
 /**
  * 鐢ㄦ埛涓庤鑹插叧鑱旇〃 鏁版嵁灞�
@@ -11,13 +9,5 @@
  * @author ruoyi
  */
 public interface SysUserRoleMapper extends BaseMapperPlus<SysUserRole> {
-
-	/**
-	 * 鎵归噺鏂板鐢ㄦ埛瑙掕壊淇℃伅
-	 *
-	 * @param userRoleList 鐢ㄦ埛瑙掕壊鍒楄〃
-	 * @return 缁撴灉
-	 */
-	public int batchUserRole(List<SysUserRole> userRoleList);
 
 }
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysConfigService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysConfigService.java
index 569ecf9..429559b 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysConfigService.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysConfigService.java
@@ -1,6 +1,6 @@
 package com.ruoyi.system.service;
 
-import com.ruoyi.common.core.page.IServicePlus;
+import com.ruoyi.common.core.mybatisplus.core.IServicePlus;
 import com.ruoyi.common.core.page.TableDataInfo;
 import com.ruoyi.system.domain.SysConfig;
 
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDeptService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDeptService.java
index 59521c0..7afbf4b 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDeptService.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDeptService.java
@@ -2,7 +2,7 @@
 
 import com.ruoyi.common.core.domain.TreeSelect;
 import com.ruoyi.common.core.domain.entity.SysDept;
-import com.ruoyi.common.core.page.IServicePlus;
+import com.ruoyi.common.core.mybatisplus.core.IServicePlus;
 
 import java.util.List;
 
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDictDataService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDictDataService.java
index 5a19aa7..570c7d1 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDictDataService.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDictDataService.java
@@ -1,7 +1,7 @@
 package com.ruoyi.system.service;
 
 import com.ruoyi.common.core.domain.entity.SysDictData;
-import com.ruoyi.common.core.page.IServicePlus;
+import com.ruoyi.common.core.mybatisplus.core.IServicePlus;
 import com.ruoyi.common.core.page.TableDataInfo;
 
 import java.util.List;
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDictTypeService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDictTypeService.java
index a806cbd..a5d8de5 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDictTypeService.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDictTypeService.java
@@ -2,7 +2,7 @@
 
 import com.ruoyi.common.core.domain.entity.SysDictData;
 import com.ruoyi.common.core.domain.entity.SysDictType;
-import com.ruoyi.common.core.page.IServicePlus;
+import com.ruoyi.common.core.mybatisplus.core.IServicePlus;
 import com.ruoyi.common.core.page.TableDataInfo;
 
 import java.util.List;
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysLogininforService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysLogininforService.java
index ccf0e9e..4976d3f 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysLogininforService.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysLogininforService.java
@@ -1,6 +1,6 @@
 package com.ruoyi.system.service;
 
-import com.ruoyi.common.core.page.IServicePlus;
+import com.ruoyi.common.core.mybatisplus.core.IServicePlus;
 import com.ruoyi.common.core.page.TableDataInfo;
 import com.ruoyi.system.domain.SysLogininfor;
 
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysMenuService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysMenuService.java
index a9f70b3..d278743 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysMenuService.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysMenuService.java
@@ -2,7 +2,7 @@
 
 import com.ruoyi.common.core.domain.TreeSelect;
 import com.ruoyi.common.core.domain.entity.SysMenu;
-import com.ruoyi.common.core.page.IServicePlus;
+import com.ruoyi.common.core.mybatisplus.core.IServicePlus;
 import com.ruoyi.system.domain.vo.RouterVo;
 
 import java.util.List;
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysNoticeService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysNoticeService.java
index 4ede9bc..2db8422 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysNoticeService.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysNoticeService.java
@@ -1,6 +1,6 @@
 package com.ruoyi.system.service;
 
-import com.ruoyi.common.core.page.IServicePlus;
+import com.ruoyi.common.core.mybatisplus.core.IServicePlus;
 import com.ruoyi.common.core.page.TableDataInfo;
 import com.ruoyi.system.domain.SysNotice;
 
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysOperLogService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysOperLogService.java
index f2485b7..dcd2c08 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysOperLogService.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysOperLogService.java
@@ -1,6 +1,6 @@
 package com.ruoyi.system.service;
 
-import com.ruoyi.common.core.page.IServicePlus;
+import com.ruoyi.common.core.mybatisplus.core.IServicePlus;
 import com.ruoyi.common.core.page.TableDataInfo;
 import com.ruoyi.system.domain.SysOperLog;
 
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysPostService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysPostService.java
index 08058d6..f56c5fd 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysPostService.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysPostService.java
@@ -1,6 +1,6 @@
 package com.ruoyi.system.service;
 
-import com.ruoyi.common.core.page.IServicePlus;
+import com.ruoyi.common.core.mybatisplus.core.IServicePlus;
 import com.ruoyi.common.core.page.TableDataInfo;
 import com.ruoyi.system.domain.SysPost;
 
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysRoleService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysRoleService.java
index 00c7d5f..2f46822 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysRoleService.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysRoleService.java
@@ -1,7 +1,7 @@
 package com.ruoyi.system.service;
 
 import com.ruoyi.common.core.domain.entity.SysRole;
-import com.ruoyi.common.core.page.IServicePlus;
+import com.ruoyi.common.core.mybatisplus.core.IServicePlus;
 import com.ruoyi.common.core.page.TableDataInfo;
 
 import java.util.List;
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserService.java
index 3f423a6..4c67091 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserService.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserService.java
@@ -1,7 +1,7 @@
 package com.ruoyi.system.service;
 
 import com.ruoyi.common.core.domain.entity.SysUser;
-import com.ruoyi.common.core.page.IServicePlus;
+import com.ruoyi.common.core.mybatisplus.core.IServicePlus;
 import com.ruoyi.common.core.page.TableDataInfo;
 
 import java.util.List;
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysConfigServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysConfigServiceImpl.java
index d0b37c5..dd7321a 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysConfigServiceImpl.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysConfigServiceImpl.java
@@ -4,10 +4,10 @@
 import cn.hutool.core.lang.Validator;
 import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.ruoyi.common.annotation.DataSource;
 import com.ruoyi.common.constant.Constants;
 import com.ruoyi.common.constant.UserConstants;
+import com.ruoyi.common.core.mybatisplus.core.ServicePlusImpl;
 import com.ruoyi.common.core.page.TableDataInfo;
 import com.ruoyi.common.core.redis.RedisCache;
 import com.ruoyi.common.enums.DataSourceType;
@@ -31,7 +31,7 @@
  * @author ruoyi
  */
 @Service
-public class SysConfigServiceImpl extends ServiceImpl<SysConfigMapper, SysConfig> implements ISysConfigService {
+public class SysConfigServiceImpl extends ServicePlusImpl<SysConfigMapper, SysConfig> implements ISysConfigService {
 
 	@Autowired
 	private RedisCache redisCache;
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDeptServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDeptServiceImpl.java
index 7cdda23..745e62f 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDeptServiceImpl.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDeptServiceImpl.java
@@ -1,16 +1,16 @@
 package com.ruoyi.system.service.impl;
 
+import cn.hutool.core.convert.Convert;
 import cn.hutool.core.lang.Validator;
-import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.ruoyi.common.annotation.DataScope;
 import com.ruoyi.common.constant.UserConstants;
 import com.ruoyi.common.core.domain.TreeSelect;
 import com.ruoyi.common.core.domain.entity.SysDept;
 import com.ruoyi.common.core.domain.entity.SysRole;
 import com.ruoyi.common.core.domain.entity.SysUser;
+import com.ruoyi.common.core.mybatisplus.core.ServicePlusImpl;
 import com.ruoyi.common.exception.CustomException;
 import com.ruoyi.system.mapper.SysDeptMapper;
 import com.ruoyi.system.mapper.SysRoleMapper;
@@ -21,7 +21,6 @@
 
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Iterator;
 import java.util.List;
 import java.util.stream.Collectors;
 
@@ -31,7 +30,7 @@
  * @author ruoyi
  */
 @Service
-public class SysDeptServiceImpl extends ServiceImpl<SysDeptMapper, SysDept> implements ISysDeptService {
+public class SysDeptServiceImpl extends ServicePlusImpl<SysDeptMapper, SysDept> implements ISysDeptService {
 
     @Autowired
     private SysRoleMapper roleMapper;
@@ -64,14 +63,13 @@
         for (SysDept dept : depts) {
             tempList.add(dept.getDeptId());
         }
-        for (Iterator<SysDept> iterator = depts.iterator(); iterator.hasNext(); ) {
-            SysDept dept = (SysDept) iterator.next();
-            // 濡傛灉鏄《绾ц妭鐐�, 閬嶅巻璇ョ埗鑺傜偣鐨勬墍鏈夊瓙鑺傜偣
-            if (!tempList.contains(dept.getParentId())) {
-                recursionFn(depts, dept);
-                returnList.add(dept);
-            }
-        }
+		for (SysDept dept : depts) {
+			// 濡傛灉鏄《绾ц妭鐐�, 閬嶅巻璇ョ埗鑺傜偣鐨勬墍鏈夊瓙鑺傜偣
+			if (!tempList.contains(dept.getParentId())) {
+				recursionFn(depts, dept);
+				returnList.add(dept);
+			}
+		}
         if (returnList.isEmpty()) {
             returnList = depts;
         }
@@ -137,7 +135,7 @@
         int result = count(new LambdaQueryWrapper<SysDept>()
                 .eq(SysDept::getParentId, deptId)
                 .last("limit 1"));
-        return result > 0 ? true : false;
+        return result > 0;
     }
 
     /**
@@ -150,7 +148,7 @@
     public boolean checkDeptExistUser(Long deptId) {
         int result = userMapper.selectCount(new LambdaQueryWrapper<SysUser>()
                 .eq(SysUser::getDeptId, deptId));
-        return result > 0 ? true : false;
+        return result > 0;
     }
 
     /**
@@ -208,7 +206,7 @@
         int result = baseMapper.updateById(dept);
         if (UserConstants.DEPT_NORMAL.equals(dept.getStatus())) {
             // 濡傛灉璇ラ儴闂ㄦ槸鍚敤鐘舵�侊紝鍒欏惎鐢ㄨ閮ㄩ棬鐨勬墍鏈変笂绾ч儴闂�
-            updateParentDeptStatus(dept);
+            updateParentDeptStatusNormal(dept);
         }
         return result;
     }
@@ -218,22 +216,18 @@
      *
      * @param dept 褰撳墠閮ㄩ棬
      */
-    private void updateParentDeptStatus(SysDept dept) {
-        String updateBy = dept.getUpdateBy();
-        dept = getById(dept.getDeptId());
-        dept.setUpdateBy(updateBy);
-        update(null,new LambdaUpdateWrapper<SysDept>()
-                .set(StrUtil.isNotBlank(dept.getStatus()),
-                        SysDept::getStatus,dept.getStatus())
-                .set(StrUtil.isNotBlank(dept.getUpdateBy()),
-                        SysDept::getUpdateBy,dept.getUpdateBy())
-                .in(SysDept::getDeptId, Arrays.asList(dept.getAncestors().split(","))));
+    private void updateParentDeptStatusNormal(SysDept dept) {
+		String ancestors = dept.getAncestors();
+		Long[] deptIds = Convert.toLongArray(ancestors);
+        update(null, new LambdaUpdateWrapper<SysDept>()
+                .set(SysDept::getStatus, "0")
+                .in(SysDept::getDeptId, Arrays.asList(deptIds)));
     }
 
     /**
      * 淇敼瀛愬厓绱犲叧绯�
      *
-     * @param deptId       琚慨鏀圭殑閮ㄩ棬ID
+     * @param deptId 琚慨鏀圭殑閮ㄩ棬ID
      * @param newAncestors 鏂扮殑鐖禝D闆嗗悎
      * @param oldAncestors 鏃х殑鐖禝D闆嗗悎
      */
@@ -278,13 +272,11 @@
      */
     private List<SysDept> getChildList(List<SysDept> list, SysDept t) {
         List<SysDept> tlist = new ArrayList<SysDept>();
-        Iterator<SysDept> it = list.iterator();
-        while (it.hasNext()) {
-            SysDept n = (SysDept) it.next();
-            if (Validator.isNotNull(n.getParentId()) && n.getParentId().longValue() == t.getDeptId().longValue()) {
-                tlist.add(n);
-            }
-        }
+		for (SysDept n : list) {
+			if (Validator.isNotNull(n.getParentId()) && n.getParentId().longValue() == t.getDeptId().longValue()) {
+				tlist.add(n);
+			}
+		}
         return tlist;
     }
 
@@ -292,6 +284,6 @@
      * 鍒ゆ柇鏄惁鏈夊瓙鑺傜偣
      */
     private boolean hasChild(List<SysDept> list, SysDept t) {
-        return getChildList(list, t).size() > 0 ? true : false;
+        return getChildList(list, t).size() > 0;
     }
 }
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDictDataServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDictDataServiceImpl.java
index 4b08a14..92be9d5 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDictDataServiceImpl.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDictDataServiceImpl.java
@@ -2,8 +2,8 @@
 
 import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.ruoyi.common.core.domain.entity.SysDictData;
+import com.ruoyi.common.core.mybatisplus.core.ServicePlusImpl;
 import com.ruoyi.common.core.page.TableDataInfo;
 import com.ruoyi.common.utils.DictUtils;
 import com.ruoyi.common.utils.PageUtils;
@@ -20,7 +20,7 @@
  * @author ruoyi
  */
 @Service
-public class SysDictDataServiceImpl extends ServiceImpl<SysDictDataMapper, SysDictData> implements ISysDictDataService {
+public class SysDictDataServiceImpl extends ServicePlusImpl<SysDictDataMapper, SysDictData> implements ISysDictDataService {
 
 	@Override
 	public TableDataInfo<SysDictData> selectPageDictDataList(SysDictData dictData) {
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDictTypeServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDictTypeServiceImpl.java
index c4f9d95..82f67c3 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDictTypeServiceImpl.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDictTypeServiceImpl.java
@@ -5,10 +5,10 @@
 import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.ruoyi.common.constant.UserConstants;
 import com.ruoyi.common.core.domain.entity.SysDictData;
 import com.ruoyi.common.core.domain.entity.SysDictType;
+import com.ruoyi.common.core.mybatisplus.core.ServicePlusImpl;
 import com.ruoyi.common.core.page.TableDataInfo;
 import com.ruoyi.common.exception.CustomException;
 import com.ruoyi.common.utils.DictUtils;
@@ -31,7 +31,7 @@
  * @author ruoyi
  */
 @Service
-public class SysDictTypeServiceImpl extends ServiceImpl<SysDictTypeMapper, SysDictType> implements ISysDictTypeService {
+public class SysDictTypeServiceImpl extends ServicePlusImpl<SysDictTypeMapper, SysDictType> implements ISysDictTypeService {
 
 	@Autowired
 	private SysDictDataMapper dictDataMapper;
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysLogininforServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysLogininforServiceImpl.java
index ff5d47d..0284ed7 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysLogininforServiceImpl.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysLogininforServiceImpl.java
@@ -3,7 +3,7 @@
 import cn.hutool.core.lang.Validator;
 import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.common.core.mybatisplus.core.ServicePlusImpl;
 import com.ruoyi.common.core.page.TableDataInfo;
 import com.ruoyi.common.utils.PageUtils;
 import com.ruoyi.system.domain.SysLogininfor;
@@ -22,7 +22,7 @@
  * @author ruoyi
  */
 @Service
-public class SysLogininforServiceImpl extends ServiceImpl<SysLogininforMapper, SysLogininfor> implements ISysLogininforService {
+public class SysLogininforServiceImpl extends ServicePlusImpl<SysLogininforMapper, SysLogininfor> implements ISysLogininforService {
 
     @Override
     public TableDataInfo<SysLogininfor> selectPageLogininforList(SysLogininfor logininfor) {
@@ -36,9 +36,8 @@
                         params.get("beginTime"))
                 .apply(Validator.isNotEmpty(params.get("endTime")),
                         "date_format(login_time,'%y%m%d') <= date_format({0},'%y%m%d')",
-                        params.get("endTime"))
-                .orderByDesc(SysLogininfor::getInfoId);
-        return PageUtils.buildDataInfo(page(PageUtils.buildPage(), lqw));
+                        params.get("endTime"));
+        return PageUtils.buildDataInfo(page(PageUtils.buildPage("info_id","desc"), lqw));
     }
 
     /**
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysMenuServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysMenuServiceImpl.java
index 6f7cc41..f8b4706 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysMenuServiceImpl.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysMenuServiceImpl.java
@@ -3,12 +3,12 @@
 import cn.hutool.core.lang.Validator;
 import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.ruoyi.common.constant.UserConstants;
 import com.ruoyi.common.core.domain.TreeSelect;
 import com.ruoyi.common.core.domain.entity.SysMenu;
 import com.ruoyi.common.core.domain.entity.SysRole;
 import com.ruoyi.common.core.domain.entity.SysUser;
+import com.ruoyi.common.core.mybatisplus.core.ServicePlusImpl;
 import com.ruoyi.common.utils.SecurityUtils;
 import com.ruoyi.system.domain.SysRoleMenu;
 import com.ruoyi.system.domain.vo.MetaVo;
@@ -25,11 +25,11 @@
 
 /**
  * 鑿滃崟 涓氬姟灞傚鐞�
- * 
+ *
  * @author ruoyi
  */
 @Service
-public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements ISysMenuService {
+public class SysMenuServiceImpl extends ServicePlusImpl<SysMenuMapper, SysMenu> implements ISysMenuService {
     public static final String PREMISSION_STRING = "perms[\"{0}\"]";
 
     @Autowired
@@ -137,7 +137,7 @@
             router.setComponent(getComponent(menu));
             router.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon(), StrUtil.equals("1", menu.getIsCache())));
             List<SysMenu> cMenus = menu.getChildren();
-            if (!cMenus.isEmpty() && cMenus.size() > 0 && UserConstants.TYPE_DIR.equals(menu.getMenuType())) {
+            if (!cMenus.isEmpty() && UserConstants.TYPE_DIR.equals(menu.getMenuType())) {
                 router.setAlwaysShow(true);
                 router.setRedirect("noRedirect");
                 router.setChildren(buildMenus(cMenus));
@@ -170,14 +170,13 @@
         for (SysMenu dept : menus) {
             tempList.add(dept.getMenuId());
         }
-        for (Iterator<SysMenu> iterator = menus.iterator(); iterator.hasNext(); ) {
-            SysMenu menu = (SysMenu) iterator.next();
-            // 濡傛灉鏄《绾ц妭鐐�, 閬嶅巻璇ョ埗鑺傜偣鐨勬墍鏈夊瓙鑺傜偣
-            if (!tempList.contains(menu.getParentId())) {
-                recursionFn(menus, menu);
-                returnList.add(menu);
-            }
-        }
+		for (SysMenu menu : menus) {
+			// 濡傛灉鏄《绾ц妭鐐�, 閬嶅巻璇ョ埗鑺傜偣鐨勬墍鏈夊瓙鑺傜偣
+			if (!tempList.contains(menu.getParentId())) {
+				recursionFn(menus, menu);
+				returnList.add(menu);
+			}
+		}
         if (returnList.isEmpty()) {
             returnList = menus;
         }
@@ -216,7 +215,7 @@
     @Override
     public boolean hasChildByMenuId(Long menuId) {
         int result = count(new LambdaQueryWrapper<SysMenu>().eq(SysMenu::getParentId,menuId));
-        return result > 0 ? true : false;
+        return result > 0;
     }
 
     /**
@@ -228,7 +227,7 @@
     @Override
     public boolean checkMenuExistRole(Long menuId) {
         int result = roleMenuMapper.selectCount(new LambdaQueryWrapper<SysRoleMenu>().eq(SysRoleMenu::getMenuId,menuId));
-        return result > 0 ? true : false;
+        return result > 0;
     }
 
     /**
@@ -364,14 +363,13 @@
      */
     public List<SysMenu> getChildPerms(List<SysMenu> list, int parentId) {
         List<SysMenu> returnList = new ArrayList<SysMenu>();
-        for (Iterator<SysMenu> iterator = list.iterator(); iterator.hasNext(); ) {
-            SysMenu t = (SysMenu) iterator.next();
-            // 涓�銆佹牴鎹紶鍏ョ殑鏌愪釜鐖惰妭鐐笽D,閬嶅巻璇ョ埗鑺傜偣鐨勬墍鏈夊瓙鑺傜偣
-            if (t.getParentId() == parentId) {
-                recursionFn(list, t);
-                returnList.add(t);
-            }
-        }
+		for (SysMenu t : list) {
+			// 涓�銆佹牴鎹紶鍏ョ殑鏌愪釜鐖惰妭鐐笽D,閬嶅巻璇ョ埗鑺傜偣鐨勬墍鏈夊瓙鑺傜偣
+			if (t.getParentId() == parentId) {
+				recursionFn(list, t);
+				returnList.add(t);
+			}
+		}
         return returnList;
     }
 
@@ -397,13 +395,11 @@
      */
     private List<SysMenu> getChildList(List<SysMenu> list, SysMenu t) {
         List<SysMenu> tlist = new ArrayList<SysMenu>();
-        Iterator<SysMenu> it = list.iterator();
-        while (it.hasNext()) {
-            SysMenu n = (SysMenu) it.next();
-            if (n.getParentId().longValue() == t.getMenuId().longValue()) {
-                tlist.add(n);
-            }
-        }
+		for (SysMenu n : list) {
+			if (n.getParentId().longValue() == t.getMenuId().longValue()) {
+				tlist.add(n);
+			}
+		}
         return tlist;
     }
 
@@ -411,6 +407,6 @@
      * 鍒ゆ柇鏄惁鏈夊瓙鑺傜偣
      */
     private boolean hasChild(List<SysMenu> list, SysMenu t) {
-        return getChildList(list, t).size() > 0 ? true : false;
+        return getChildList(list, t).size() > 0;
     }
 }
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysNoticeServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysNoticeServiceImpl.java
index e063470..977e644 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysNoticeServiceImpl.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysNoticeServiceImpl.java
@@ -2,7 +2,7 @@
 
 import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.common.core.mybatisplus.core.ServicePlusImpl;
 import com.ruoyi.common.core.page.TableDataInfo;
 import com.ruoyi.common.utils.PageUtils;
 import com.ruoyi.system.domain.SysNotice;
@@ -19,7 +19,7 @@
  * @author ruoyi
  */
 @Service
-public class SysNoticeServiceImpl extends ServiceImpl<SysNoticeMapper, SysNotice> implements ISysNoticeService {
+public class SysNoticeServiceImpl extends ServicePlusImpl<SysNoticeMapper, SysNotice> implements ISysNoticeService {
 
     @Override
     public TableDataInfo<SysNotice> selectPageNoticeList(SysNotice notice) {
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysOperLogServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysOperLogServiceImpl.java
index 0a3186e..5d24356 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysOperLogServiceImpl.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysOperLogServiceImpl.java
@@ -4,7 +4,7 @@
 import cn.hutool.core.util.ArrayUtil;
 import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.common.core.mybatisplus.core.ServicePlusImpl;
 import com.ruoyi.common.core.page.TableDataInfo;
 import com.ruoyi.common.utils.PageUtils;
 import com.ruoyi.system.domain.SysOperLog;
@@ -23,7 +23,7 @@
  * @author ruoyi
  */
 @Service
-public class SysOperLogServiceImpl extends ServiceImpl<SysOperLogMapper, SysOperLog> implements ISysOperLogService {
+public class SysOperLogServiceImpl extends ServicePlusImpl<SysOperLogMapper, SysOperLog> implements ISysOperLogService {
 
     @Override
     public TableDataInfo<SysOperLog> selectPageOperLogList(SysOperLog operLog) {
@@ -45,9 +45,8 @@
                         params.get("beginTime"))
                 .apply(Validator.isNotEmpty(params.get("endTime")),
                         "date_format(oper_time,'%y%m%d') <= date_format({0},'%y%m%d')",
-                        params.get("endTime"))
-                .orderByDesc(SysOperLog::getOperId);
-        return PageUtils.buildDataInfo(page(PageUtils.buildPage(), lqw));
+                        params.get("endTime"));
+        return PageUtils.buildDataInfo(page(PageUtils.buildPage("oper_id","desc"), lqw));
     }
 
     /**
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysPostServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysPostServiceImpl.java
index d2aeab0..93f8e98 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysPostServiceImpl.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysPostServiceImpl.java
@@ -3,8 +3,8 @@
 import cn.hutool.core.lang.Validator;
 import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.ruoyi.common.constant.UserConstants;
+import com.ruoyi.common.core.mybatisplus.core.ServicePlusImpl;
 import com.ruoyi.common.core.page.TableDataInfo;
 import com.ruoyi.common.exception.CustomException;
 import com.ruoyi.common.utils.PageUtils;
@@ -25,7 +25,7 @@
  * @author ruoyi
  */
 @Service
-public class SysPostServiceImpl extends ServiceImpl<SysPostMapper, SysPost> implements ISysPostService {
+public class SysPostServiceImpl extends ServicePlusImpl<SysPostMapper, SysPost> implements ISysPostService {
 
     @Autowired
     private SysUserPostMapper userPostMapper;
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysRoleServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysRoleServiceImpl.java
index c46c45f..1bac225 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysRoleServiceImpl.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysRoleServiceImpl.java
@@ -2,10 +2,10 @@
 
 import cn.hutool.core.lang.Validator;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.ruoyi.common.annotation.DataScope;
 import com.ruoyi.common.constant.UserConstants;
 import com.ruoyi.common.core.domain.entity.SysRole;
+import com.ruoyi.common.core.mybatisplus.core.ServicePlusImpl;
 import com.ruoyi.common.core.page.TableDataInfo;
 import com.ruoyi.common.exception.CustomException;
 import com.ruoyi.common.utils.PageUtils;
@@ -30,7 +30,7 @@
  * @author ruoyi
  */
 @Service
-public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> implements ISysRoleService {
+public class SysRoleServiceImpl extends ServicePlusImpl<SysRoleMapper, SysRole> implements ISysRoleService {
 
     @Autowired
     private SysRoleMenuMapper roleMenuMapper;
@@ -240,7 +240,7 @@
             list.add(rm);
         }
         if (list.size() > 0) {
-			rows = roleMenuMapper.batchRoleMenu(list);
+			rows = roleMenuMapper.insertAll(list);
         }
         return rows;
     }
@@ -261,7 +261,7 @@
             list.add(rd);
         }
         if (list.size() > 0) {
-			rows = roleDeptMapper.batchRoleDept(list);
+			rows = roleDeptMapper.insertAll(list);
         }
         return rows;
     }
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java
index dd12f10..7363040 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java
@@ -3,11 +3,11 @@
 import cn.hutool.core.lang.Validator;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.ruoyi.common.annotation.DataScope;
 import com.ruoyi.common.constant.UserConstants;
 import com.ruoyi.common.core.domain.entity.SysRole;
 import com.ruoyi.common.core.domain.entity.SysUser;
+import com.ruoyi.common.core.mybatisplus.core.ServicePlusImpl;
 import com.ruoyi.common.core.page.TableDataInfo;
 import com.ruoyi.common.exception.CustomException;
 import com.ruoyi.common.utils.PageUtils;
@@ -34,7 +34,7 @@
  */
 @Slf4j
 @Service
-public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements ISysUserService {
+public class SysUserServiceImpl extends ServicePlusImpl<SysUserMapper, SysUser> implements ISysUserService {
 
     @Autowired
     private SysRoleMapper roleMapper;
@@ -311,7 +311,7 @@
                 list.add(ur);
             }
             if (list.size() > 0) {
-				userRoleMapper.batchUserRole(list);
+				userRoleMapper.insertAll(list);
             }
         }
     }
@@ -333,7 +333,7 @@
                 list.add(up);
             }
             if (list.size() > 0) {
-				userPostMapper.batchUserPost(list);
+				userPostMapper.insertAll(list);
             }
         }
     }
diff --git a/ruoyi-system/src/main/resources/mapper/system/SysRoleDeptMapper.xml b/ruoyi-system/src/main/resources/mapper/system/SysRoleDeptMapper.xml
index cace1f5..e64cb45 100644
--- a/ruoyi-system/src/main/resources/mapper/system/SysRoleDeptMapper.xml
+++ b/ruoyi-system/src/main/resources/mapper/system/SysRoleDeptMapper.xml
@@ -9,11 +9,4 @@
         <result property="deptId" column="dept_id"/>
     </resultMap>
 
-    <insert id="batchRoleDept">
-        insert into sys_role_dept(role_id, dept_id) values
-        <foreach item="item" index="index" collection="list" separator=",">
-            (#{item.roleId},#{item.deptId})
-        </foreach>
-    </insert>
-
 </mapper>
diff --git a/ruoyi-system/src/main/resources/mapper/system/SysRoleMenuMapper.xml b/ruoyi-system/src/main/resources/mapper/system/SysRoleMenuMapper.xml
index 356b612..efc5a79 100644
--- a/ruoyi-system/src/main/resources/mapper/system/SysRoleMenuMapper.xml
+++ b/ruoyi-system/src/main/resources/mapper/system/SysRoleMenuMapper.xml
@@ -9,11 +9,4 @@
         <result property="menuId" column="menu_id"/>
     </resultMap>
 
-    <insert id="batchRoleMenu">
-        insert into sys_role_menu(role_id, menu_id) values
-        <foreach item="item" index="index" collection="list" separator=",">
-            (#{item.roleId},#{item.menuId})
-        </foreach>
-    </insert>
-
 </mapper>
diff --git a/ruoyi-system/src/main/resources/mapper/system/SysUserPostMapper.xml b/ruoyi-system/src/main/resources/mapper/system/SysUserPostMapper.xml
index 8d70825..0ff9265 100644
--- a/ruoyi-system/src/main/resources/mapper/system/SysUserPostMapper.xml
+++ b/ruoyi-system/src/main/resources/mapper/system/SysUserPostMapper.xml
@@ -9,11 +9,4 @@
         <result property="postId" column="post_id"/>
     </resultMap>
 
-    <insert id="batchUserPost">
-        insert into sys_user_post(user_id, post_id) values
-        <foreach item="item" index="index" collection="list" separator=",">
-            (#{item.userId},#{item.postId})
-        </foreach>
-    </insert>
-
 </mapper>
diff --git a/ruoyi-system/src/main/resources/mapper/system/SysUserRoleMapper.xml b/ruoyi-system/src/main/resources/mapper/system/SysUserRoleMapper.xml
index 1db2f0f..3066f47 100644
--- a/ruoyi-system/src/main/resources/mapper/system/SysUserRoleMapper.xml
+++ b/ruoyi-system/src/main/resources/mapper/system/SysUserRoleMapper.xml
@@ -9,11 +9,4 @@
         <result property="roleId" column="role_id"/>
     </resultMap>
 
-    <insert id="batchUserRole">
-        insert into sys_user_role(user_id, role_id) values
-        <foreach item="item" index="index" collection="list" separator=",">
-            (#{item.userId},#{item.roleId})
-        </foreach>
-    </insert>
-
 </mapper>
diff --git a/ruoyi-ui/.env.development b/ruoyi-ui/.env.development
index 28b97c7..abb97d4 100644
--- a/ruoyi-ui/.env.development
+++ b/ruoyi-ui/.env.development
@@ -1,3 +1,6 @@
+# 椤甸潰鏍囬
+VUE_APP_TITLE = RuoYi-Vue-Plus鍚庡彴绠$悊绯荤粺
+
 # 寮�鍙戠幆澧冮厤缃�
 ENV = 'development'
 
diff --git a/ruoyi-ui/.env.production b/ruoyi-ui/.env.production
index 27c717e..7179b32 100644
--- a/ruoyi-ui/.env.production
+++ b/ruoyi-ui/.env.production
@@ -1,3 +1,6 @@
+# 椤甸潰鏍囬
+VUE_APP_TITLE = RuoYi-Vue-Plus鍚庡彴绠$悊绯荤粺
+
 # 鐢熶骇鐜閰嶇疆
 ENV = 'production'
 
diff --git a/ruoyi-ui/.env.staging b/ruoyi-ui/.env.staging
index 6195736..b5723d7 100644
--- a/ruoyi-ui/.env.staging
+++ b/ruoyi-ui/.env.staging
@@ -1,3 +1,6 @@
+# 椤甸潰鏍囬
+VUE_APP_TITLE = RuoYi-Vue-Plus鍚庡彴绠$悊绯荤粺
+
 NODE_ENV = production
 
 # 娴嬭瘯鐜閰嶇疆
diff --git a/ruoyi-ui/package.json b/ruoyi-ui/package.json
index d90fdba..48009be 100644
--- a/ruoyi-ui/package.json
+++ b/ruoyi-ui/package.json
@@ -41,7 +41,7 @@
     "clipboard": "2.0.6",
     "core-js": "3.8.1",
     "echarts": "4.9.0",
-    "element-ui": "2.15.0",
+    "element-ui": "2.15.2",
     "file-saver": "2.0.4",
     "fuse.js": "6.4.3",
     "highlight.js": "9.18.5",
@@ -55,6 +55,7 @@
     "vue": "2.6.12",
     "vue-count-to": "1.0.13",
     "vue-cropper": "0.5.5",
+    "vue-meta": "^2.4.0",
     "vue-router": "3.4.9",
     "vuedraggable": "2.24.3",
     "vuex": "3.6.0"
diff --git a/ruoyi-ui/src/App.vue b/ruoyi-ui/src/App.vue
index e448b11..391d951 100644
--- a/ruoyi-ui/src/App.vue
+++ b/ruoyi-ui/src/App.vue
@@ -6,6 +6,14 @@
 
 <script>
 export default  {
-  name:  'App'
+  name:  'App',
+    metaInfo() {
+        return {
+            title: this.$store.state.settings.dynamicTitle && this.$store.state.settings.title,
+            titleTemplate: title => {
+                return title ? `${title} - ${process.env.VUE_APP_TITLE}` : process.env.VUE_APP_TITLE
+            }
+        }
+    }
 }
 </script>
diff --git a/ruoyi-ui/src/assets/styles/ruoyi.scss b/ruoyi-ui/src/assets/styles/ruoyi.scss
index de1db7f..dee6d09 100644
--- a/ruoyi-ui/src/assets/styles/ruoyi.scss
+++ b/ruoyi-ui/src/assets/styles/ruoyi.scss
@@ -105,6 +105,15 @@
 	position: absolute;
 }
 
+@media ( max-width : 768px) {
+  .pagination-container .el-pagination > .el-pagination__jump {
+    display: none !important;
+  }
+  .pagination-container .el-pagination > .el-pagination__sizes {
+    display: none !important;
+  }
+}
+
 .el-table .fixed-width .el-button--mini {
 	padding-left: 0;
 	padding-right: 0;
diff --git a/ruoyi-ui/src/components/DictTag/index.vue b/ruoyi-ui/src/components/DictTag/index.vue
new file mode 100644
index 0000000..4779415
--- /dev/null
+++ b/ruoyi-ui/src/components/DictTag/index.vue
@@ -0,0 +1,51 @@
+<template>
+  <div>
+    <template v-for="(item, index) in options">
+      <template v-if="values.includes(item.dictValue)">
+        <span
+          v-if="item.listClass == 'default' || item.listClass == ''"
+          :key="item.dictValue"
+          :index="index"
+          :class="item.cssClass"
+          >{{ item.dictLabel }}</span
+        >
+        <el-tag
+          v-else
+          :key="item.dictValue"
+          :index="index"
+          :type="item.listClass == 'primary' ? '' : item.listClass"
+          :class="item.cssClass"
+        >
+          {{ item.dictLabel }}
+        </el-tag>
+      </template>
+    </template>
+  </div>
+</template>
+
+<script>
+export default {
+  name: "DictTag",
+  props: {
+    options: {
+      type: Array,
+      default: null,
+    },
+    value: [String, Array],
+  },
+  computed: {
+    values() {
+      if (this.value) {
+        return Array.isArray(this.value) ? this.value : [this.value];
+      } else {
+        return [];
+      }
+    },
+  },
+};
+</script>
+<style scoped>
+.el-tag + .el-tag {
+  margin-left: 10px;
+}
+</style>
\ No newline at end of file
diff --git a/ruoyi-ui/src/components/Pagination/index.vue b/ruoyi-ui/src/components/Pagination/index.vue
index c815e13..5e5d890 100644
--- a/ruoyi-ui/src/components/Pagination/index.vue
+++ b/ruoyi-ui/src/components/Pagination/index.vue
@@ -6,6 +6,7 @@
       :page-size.sync="pageSize"
       :layout="layout"
       :page-sizes="pageSizes"
+      :pager-count="pagerCount"
       :total="total"
       v-bind="$attrs"
       @size-change="handleSizeChange"
@@ -38,6 +39,11 @@
         return [10, 20, 30, 50]
       }
     },
+    // 绉诲姩绔〉鐮佹寜閽殑鏁伴噺绔粯璁ゅ��5
+    pagerCount: {
+      type: Number,
+      default: document.body.clientWidth < 992 ? 5 : 7
+    },
     layout: {
       type: String,
       default: 'total, sizes, prev, pager, next, jumper'
diff --git a/ruoyi-ui/src/components/iFrame/index.vue b/ruoyi-ui/src/components/iFrame/index.vue
new file mode 100644
index 0000000..4b85f36
--- /dev/null
+++ b/ruoyi-ui/src/components/iFrame/index.vue
@@ -0,0 +1,36 @@
+<template>
+  <div v-loading="loading" :style="'height:' + height">
+    <iframe
+      :src="src"
+      frameborder="no"
+      style="width: 100%; height: 100%"
+      scrolling="auto"
+    />
+  </div>
+</template>
+<script>
+export default {
+  props: {
+    src: {
+      type: String,
+      required: true
+    },
+  },
+  data() {
+    return {
+      height: document.documentElement.clientHeight - 94.5 + "px;",
+      loading: true,
+      url: this.src
+    };
+  },
+  mounted: function () {
+    setTimeout(() => {
+      this.loading = false;
+    }, 300);
+    const that = this;
+    window.onresize = function temp() {
+      that.height = document.documentElement.clientHeight - 94.5 + "px;";
+    };
+  }
+};
+</script>
diff --git a/ruoyi-ui/src/layout/components/Settings/index.vue b/ruoyi-ui/src/layout/components/Settings/index.vue
index 3895199..a96b73f 100644
--- a/ruoyi-ui/src/layout/components/Settings/index.vue
+++ b/ruoyi-ui/src/layout/components/Settings/index.vue
@@ -41,7 +41,7 @@
       <el-divider/>
 
       <h3 class="drawer-title">绯荤粺甯冨眬閰嶇疆</h3>
-      
+
       <div class="drawer-item">
         <span>寮�鍚� TopNav</span>
         <el-switch v-model="topNav" class="drawer-switch" />
@@ -60,6 +60,11 @@
       <div class="drawer-item">
         <span>鏄剧ず Logo</span>
         <el-switch v-model="sidebarLogo" class="drawer-switch" />
+      </div>
+
+      <div class="drawer-item">
+        <span>鍔ㄦ�佹爣棰�</span>
+        <el-switch v-model="dynamicTitle" class="drawer-switch" />
       </div>
 
       <el-divider/>
@@ -129,6 +134,17 @@
         })
       }
     },
+    dynamicTitle: {
+      get() {
+        return this.$store.state.settings.dynamicTitle
+      },
+      set(val) {
+        this.$store.dispatch('settings/changeSetting', {
+          key: 'dynamicTitle',
+          value: val
+        })
+      }
+    },
   },
   methods: {
     themeChange(val) {
@@ -160,6 +176,7 @@
             "tagsView":${this.tagsView},
             "fixedHeader":${this.fixedHeader},
             "sidebarLogo":${this.sidebarLogo},
+            "dynamicTitle":${this.dynamicTitle},
             "sideTheme":"${this.sideTheme}",
             "theme":"${this.theme}"
           }`
diff --git a/ruoyi-ui/src/layout/components/Sidebar/Logo.vue b/ruoyi-ui/src/layout/components/Sidebar/Logo.vue
index 4c26fd3..0de00ce 100644
--- a/ruoyi-ui/src/layout/components/Sidebar/Logo.vue
+++ b/ruoyi-ui/src/layout/components/Sidebar/Logo.vue
@@ -2,11 +2,11 @@
   <div class="sidebar-logo-container" :class="{'collapse':collapse}" :style="{ backgroundColor: sideTheme === 'theme-dark' ? variables.menuBg : variables.menuLightBg }">
     <transition name="sidebarLogoFade">
       <router-link v-if="collapse" key="collapse" class="sidebar-logo-link" to="/">
-        <img v-if="logo" :src="logo" class="sidebar-logo">
+        <img v-if="logo" :src="logo" class="sidebar-logo" />
         <h1 v-else class="sidebar-title" :style="{ color: sideTheme === 'theme-dark' ? variables.sidebarTitle : variables.sidebarLightTitle }">{{ title }} </h1>
       </router-link>
       <router-link v-else key="expand" class="sidebar-logo-link" to="/">
-        <img v-if="logo" :src="logo" class="sidebar-logo">
+        <img v-if="logo" :src="logo" class="sidebar-logo" />
         <h1 class="sidebar-title" :style="{ color: sideTheme === 'theme-dark' ? variables.sidebarTitle : variables.sidebarLightTitle }">{{ title }} </h1>
       </router-link>
     </transition>
diff --git a/ruoyi-ui/src/main.js b/ruoyi-ui/src/main.js
index 5668d91..d1f8973 100644
--- a/ruoyi-ui/src/main.js
+++ b/ruoyi-ui/src/main.js
@@ -18,8 +18,12 @@
 import { getConfigKey } from "@/api/system/config";
 import { parseTime, resetForm, addDateRange, selectDictLabel, selectDictLabels, download, handleTree } from "@/utils/ruoyi";
 import Pagination from "@/components/Pagination";
-// 鑷畾涔夎〃鏍煎伐鍏锋墿灞�
+// 鑷畾涔夎〃鏍煎伐鍏风粍浠�
 import RightToolbar from "@/components/RightToolbar"
+// 瀛楀吀鏍囩缁勪欢
+import DictTag from '@/components/DictTag'
+// 澶撮儴鏍囩缁勪欢
+import VueMeta from 'vue-meta'
 
 // 鍏ㄥ眬鏂规硶鎸傝浇
 Vue.prototype.getDicts = getDicts
@@ -45,10 +49,12 @@
 }
 
 // 鍏ㄥ眬缁勪欢鎸傝浇
+Vue.component('DictTag', DictTag)
 Vue.component('Pagination', Pagination)
 Vue.component('RightToolbar', RightToolbar)
 
 Vue.use(permission)
+Vue.use(VueMeta)
 
 /**
  * If you don't want to use mock-server
diff --git a/ruoyi-ui/src/permission.js b/ruoyi-ui/src/permission.js
index 5632e7d..7e770d4 100644
--- a/ruoyi-ui/src/permission.js
+++ b/ruoyi-ui/src/permission.js
@@ -12,6 +12,7 @@
 router.beforeEach((to, from, next) => {
   NProgress.start()
   if (getToken()) {
+    to.meta.title && store.dispatch('settings/setTitle', to.meta.title)
     /* has token*/
     if (to.path === '/login') {
       next({ path: '/' })
diff --git a/ruoyi-ui/src/settings.js b/ruoyi-ui/src/settings.js
index 5d177b2..6a0b09f 100644
--- a/ruoyi-ui/src/settings.js
+++ b/ruoyi-ui/src/settings.js
@@ -1,6 +1,4 @@
 module.exports = {
-  title: 'RuoYi-Vue-Plus鍚庡彴绠$悊绯荤粺',
-
   /**
    * 渚ц竟鏍忎富棰� 娣辫壊涓婚theme-dark锛屾祬鑹蹭富棰榯heme-light
    */
@@ -32,6 +30,11 @@
   sidebarLogo: true,
 
   /**
+   * 鏄惁鏄剧ず鍔ㄦ�佹爣棰�
+   */
+  dynamicTitle: false,
+
+  /**
    * @type {string | array} 'production' | ['production', 'development']
    * @description Need show err logs component.
    * The default is only used in the production env
diff --git a/ruoyi-ui/src/store/modules/settings.js b/ruoyi-ui/src/store/modules/settings.js
index 93f7c04..647a8ce 100644
--- a/ruoyi-ui/src/store/modules/settings.js
+++ b/ruoyi-ui/src/store/modules/settings.js
@@ -1,17 +1,19 @@
 import variables from '@/assets/styles/element-variables.scss'
 import defaultSettings from '@/settings'
 
-const { sideTheme, showSettings, topNav, tagsView, fixedHeader, sidebarLogo } = defaultSettings
+const { sideTheme, showSettings, topNav, tagsView, fixedHeader, sidebarLogo, dynamicTitle } = defaultSettings
 
 const storageSetting = JSON.parse(localStorage.getItem('layout-setting')) || ''
 const state = {
+  title: '',
   theme: storageSetting.theme || variables.theme,
   sideTheme: storageSetting.sideTheme || sideTheme,
   showSettings: showSettings,
   topNav:  storageSetting.topNav === undefined ? topNav : storageSetting.topNav,
   tagsView: storageSetting.tagsView === undefined ? tagsView : storageSetting.tagsView,
   fixedHeader: storageSetting.fixedHeader === undefined ? fixedHeader : storageSetting.fixedHeader,
-  sidebarLogo: storageSetting.sidebarLogo === undefined ? sidebarLogo : storageSetting.sidebarLogo
+  sidebarLogo: storageSetting.sidebarLogo === undefined ? sidebarLogo : storageSetting.sidebarLogo,
+  dynamicTitle: storageSetting.dynamicTitle === undefined ? dynamicTitle : storageSetting.dynamicTitle
 }
 const mutations = {
   CHANGE_SETTING: (state, { key, value }) => {
@@ -22,8 +24,13 @@
 }
 
 const actions = {
+  // 淇敼甯冨眬璁剧疆
   changeSetting({ commit }, data) {
     commit('CHANGE_SETTING', data)
+  },
+  // 璁剧疆缃戦〉鏍囬
+  setTitle({ commit }, title) {
+    state.title = title
   }
 }
 
diff --git a/ruoyi-ui/src/views/demo/demo/index.vue b/ruoyi-ui/src/views/demo/demo/index.vue
index 48fa368..279c469 100644
--- a/ruoyi-ui/src/views/demo/demo/index.vue
+++ b/ruoyi-ui/src/views/demo/demo/index.vue
@@ -150,6 +150,14 @@
         <el-form-item label="鍊�" prop="value">
           <el-input v-model="form.value" placeholder="璇疯緭鍏ュ��" />
         </el-form-item>
+        <el-form-item label="鍒涘缓鏃堕棿" prop="createTime">
+          <el-date-picker clearable size="small"
+                          v-model="form.createTime"
+                          type="datetime"
+                          value-format="yyyy-MM-dd HH:mm:ss"
+                          placeholder="閫夋嫨鍒涘缓鏃堕棿">
+          </el-date-picker>
+        </el-form-item>
       </el-form>
       <div slot="footer" class="dialog-footer">
         <el-button :loading="buttonLoading" type="primary" @click="submitForm">纭� 瀹�</el-button>
diff --git a/ruoyi-ui/src/views/index.vue b/ruoyi-ui/src/views/index.vue
index 5f487c9..d16cf12 100644
--- a/ruoyi-ui/src/views/index.vue
+++ b/ruoyi-ui/src/views/index.vue
@@ -53,7 +53,7 @@
               <li>JWT</li>
               <li>MyBatis</li>
               <li>Druid</li>
-              <li>Fastjson</li>
+              <li>Jackson</li>
               <li>...</li>
             </ul>
           </el-col>
diff --git a/ruoyi-ui/src/views/monitor/druid/index.vue b/ruoyi-ui/src/views/monitor/druid/index.vue
index a1a0bd9..c6ad585 100644
--- a/ruoyi-ui/src/views/monitor/druid/index.vue
+++ b/ruoyi-ui/src/views/monitor/druid/index.vue
@@ -1,26 +1,15 @@
 <template>
-  <div v-loading="loading" :style="'height:'+ height">
-    <iframe :src="src" frameborder="no" style="width: 100%;height: 100%" scrolling="auto" />
-  </div>
+  <i-frame :src="url" />
 </template>
 <script>
+import iFrame from "@/components/iFrame/index";
 export default {
   name: "Druid",
+  components: { iFrame },
   data() {
     return {
-      src: process.env.VUE_APP_BASE_API + "/druid/login.html",
-      height: document.documentElement.clientHeight - 94.5 + "px;",
-      loading: true
+      url: process.env.VUE_APP_BASE_API + "/druid/login.html"
     };
   },
-  mounted: function() {
-    setTimeout(() => {
-      this.loading = false;
-    }, 230);
-    const that = this;
-    window.onresize = function temp() {
-      that.height = document.documentElement.clientHeight - 94.5 + "px;";
-    };
-  }
 };
 </script>
diff --git a/ruoyi-ui/src/views/monitor/logininfor/index.vue b/ruoyi-ui/src/views/monitor/logininfor/index.vue
index 92baaa9..07937b4 100644
--- a/ruoyi-ui/src/views/monitor/logininfor/index.vue
+++ b/ruoyi-ui/src/views/monitor/logininfor/index.vue
@@ -91,17 +91,17 @@
       <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
     </el-row>
 
-    <el-table v-loading="loading" :data="list" @selection-change="handleSelectionChange">
+    <el-table ref="tables" v-loading="loading" :data="list" @selection-change="handleSelectionChange" :default-sort="defaultSort" @sort-change="handleSortChange">
       <el-table-column type="selection" width="55" align="center" />
       <el-table-column label="璁块棶缂栧彿" align="center" prop="infoId" />
-      <el-table-column label="鐢ㄦ埛鍚嶇О" align="center" prop="userName" />
+      <el-table-column label="鐢ㄦ埛鍚嶇О" align="center" prop="userName" :show-overflow-tooltip="true" sortable="custom" :sort-orders="['descending', 'ascending']" />
       <el-table-column label="鐧诲綍鍦板潃" align="center" prop="ipaddr" width="130" :show-overflow-tooltip="true" />
       <el-table-column label="鐧诲綍鍦扮偣" align="center" prop="loginLocation" :show-overflow-tooltip="true" />
-      <el-table-column label="娴忚鍣�" align="center" prop="browser" />
+      <el-table-column label="娴忚鍣�" align="center" prop="browser" :show-overflow-tooltip="true" />
       <el-table-column label="鎿嶄綔绯荤粺" align="center" prop="os" />
       <el-table-column label="鐧诲綍鐘舵��" align="center" prop="status" :formatter="statusFormat" />
       <el-table-column label="鎿嶄綔淇℃伅" align="center" prop="msg" />
-      <el-table-column label="鐧诲綍鏃ユ湡" align="center" prop="loginTime" width="180">
+      <el-table-column label="鐧诲綍鏃ユ湡" align="center" prop="loginTime" sortable="custom" :sort-orders="['descending', 'ascending']" width="180">
         <template slot-scope="scope">
           <span>{{ parseTime(scope.row.loginTime) }}</span>
         </template>
@@ -143,6 +143,8 @@
       statusOptions: [],
       // 鏃ユ湡鑼冨洿
       dateRange: [],
+      // 榛樿鎺掑簭
+      defaultSort: {prop: 'loginTime', order: 'descending'},
       // 鏌ヨ鍙傛暟
       queryParams: {
         pageNum: 1,
@@ -183,13 +185,20 @@
     resetQuery() {
       this.dateRange = [];
       this.resetForm("queryForm");
+      this.$refs.tables.sort(this.defaultSort.prop, this.defaultSort.order)
       this.handleQuery();
     },
-    // 澶氶�夋閫変腑鏁版嵁
+    /** 澶氶�夋閫変腑鏁版嵁 */
     handleSelectionChange(selection) {
       this.ids = selection.map(item => item.infoId)
       this.multiple = !selection.length
     },
+    /** 鎺掑簭瑙﹀彂浜嬩欢 */
+    handleSortChange(column, prop, order) {
+      this.queryParams.orderByColumn = column.prop;
+      this.queryParams.isAsc = column.order;
+      this.getList();
+    },
     /** 鍒犻櫎鎸夐挳鎿嶄綔 */
     handleDelete(row) {
       const infoIds = row.infoId || this.ids;
diff --git a/ruoyi-ui/src/views/monitor/operlog/index.vue b/ruoyi-ui/src/views/monitor/operlog/index.vue
index d45f6e9..ff6c798 100644
--- a/ruoyi-ui/src/views/monitor/operlog/index.vue
+++ b/ruoyi-ui/src/views/monitor/operlog/index.vue
@@ -107,17 +107,17 @@
       <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
     </el-row>
 
-    <el-table v-loading="loading" :data="list" @selection-change="handleSelectionChange">
+    <el-table ref="tables" v-loading="loading" :data="list" @selection-change="handleSelectionChange" :default-sort="defaultSort" @sort-change="handleSortChange">
       <el-table-column type="selection" width="55" align="center" />
       <el-table-column label="鏃ュ織缂栧彿" align="center" prop="operId" />
       <el-table-column label="绯荤粺妯″潡" align="center" prop="title" />
       <el-table-column label="鎿嶄綔绫诲瀷" align="center" prop="businessType" :formatter="typeFormat" />
       <el-table-column label="璇锋眰鏂瑰紡" align="center" prop="requestMethod" />
-      <el-table-column label="鎿嶄綔浜哄憳" align="center" prop="operName" />
-      <el-table-column label="涓绘満" align="center" prop="operIp" width="130" :show-overflow-tooltip="true" />
+      <el-table-column label="鎿嶄綔浜哄憳" align="center" prop="operName" width="100" :show-overflow-tooltip="true" sortable="custom" :sort-orders="['descending', 'ascending']" />
+      <el-table-column label="鎿嶄綔鍦板潃" align="center" prop="operIp" width="130" :show-overflow-tooltip="true" />
       <el-table-column label="鎿嶄綔鍦扮偣" align="center" prop="operLocation" :show-overflow-tooltip="true" />
       <el-table-column label="鎿嶄綔鐘舵��" align="center" prop="status" :formatter="statusFormat" />
-      <el-table-column label="鎿嶄綔鏃ユ湡" align="center" prop="operTime" width="180">
+      <el-table-column label="鎿嶄綔鏃ユ湡" align="center" prop="operTime" sortable="custom" :sort-orders="['descending', 'ascending']" width="180">
         <template slot-scope="scope">
           <span>{{ parseTime(scope.row.operTime) }}</span>
         </template>
@@ -216,6 +216,8 @@
       statusOptions: [],
       // 鏃ユ湡鑼冨洿
       dateRange: [],
+      // 榛樿鎺掑簭
+      defaultSort: {prop: 'operTime', order: 'descending'},
       // 琛ㄥ崟鍙傛暟
       form: {},
       // 鏌ヨ鍙傛暟
@@ -266,13 +268,20 @@
     resetQuery() {
       this.dateRange = [];
       this.resetForm("queryForm");
+      this.$refs.tables.sort(this.defaultSort.prop, this.defaultSort.order)
       this.handleQuery();
     },
-    // 澶氶�夋閫変腑鏁版嵁
+    /** 澶氶�夋閫変腑鏁版嵁 */
     handleSelectionChange(selection) {
       this.ids = selection.map(item => item.operId)
       this.multiple = !selection.length
     },
+    /** 鎺掑簭瑙﹀彂浜嬩欢 */
+    handleSortChange(column, prop, order) {
+      this.queryParams.orderByColumn = column.prop;
+      this.queryParams.isAsc = column.order;
+      this.getList();
+    },
     /** 璇︾粏鎸夐挳鎿嶄綔 */
     handleView(row) {
       this.open = true;
diff --git a/ruoyi-ui/src/views/system/dict/data.vue b/ruoyi-ui/src/views/system/dict/data.vue
index 9a4b429..bd46d8b 100644
--- a/ruoyi-ui/src/views/system/dict/data.vue
+++ b/ruoyi-ui/src/views/system/dict/data.vue
@@ -86,10 +86,19 @@
     <el-table v-loading="loading" :data="dataList" @selection-change="handleSelectionChange">
       <el-table-column type="selection" width="55" align="center" />
       <el-table-column label="瀛楀吀缂栫爜" align="center" prop="dictCode" />
-      <el-table-column label="瀛楀吀鏍囩" align="center" prop="dictLabel" />
+      <el-table-column label="瀛楀吀鏍囩" align="center" prop="dictLabel">
+        <template slot-scope="scope">
+          <span v-if="scope.row.listClass == '' || scope.row.listClass == 'default'">{{scope.row.dictLabel}}</span>
+          <el-tag v-else :type="scope.row.listClass == 'primary' ? '' : scope.row.listClass">{{scope.row.dictLabel}}</el-tag>
+        </template>
+      </el-table-column>
       <el-table-column label="瀛楀吀閿��" align="center" prop="dictValue" />
       <el-table-column label="瀛楀吀鎺掑簭" align="center" prop="dictSort" />
-      <el-table-column label="鐘舵��" align="center" prop="status" :formatter="statusFormat" />
+      <el-table-column label="鐘舵��" align="center" prop="status">
+        <template slot-scope="scope">
+          <dict-tag :options="statusOptions" :value="scope.row.status"/>
+        </template>
+      </el-table-column>
       <el-table-column label="澶囨敞" align="center" prop="remark" :show-overflow-tooltip="true" />
       <el-table-column label="鍒涘缓鏃堕棿" align="center" prop="createTime" width="180">
         <template slot-scope="scope">
@@ -136,8 +145,21 @@
         <el-form-item label="鏁版嵁閿��" prop="dictValue">
           <el-input v-model="form.dictValue" placeholder="璇疯緭鍏ユ暟鎹敭鍊�" />
         </el-form-item>
+        <el-form-item label="鏍峰紡灞炴��" prop="cssClass">
+          <el-input v-model="form.cssClass" placeholder="璇疯緭鍏ユ牱寮忓睘鎬�" />
+        </el-form-item>
         <el-form-item label="鏄剧ず鎺掑簭" prop="dictSort">
           <el-input-number v-model="form.dictSort" controls-position="right" :min="0" />
+        </el-form-item>
+        <el-form-item label="鍥炴樉鏍峰紡" prop="listClass">
+          <el-select v-model="form.listClass">
+            <el-option
+              v-for="item in listClassOptions"
+              :key="item.value"
+              :label="item.label"
+              :value="item.value"
+            ></el-option>
+          </el-select>
         </el-form-item>
         <el-form-item label="鐘舵��" prop="status">
           <el-radio-group v-model="form.status">
@@ -190,6 +212,33 @@
       title: "",
       // 鏄惁鏄剧ず寮瑰嚭灞�
       open: false,
+      // 鏁版嵁鏍囩鍥炴樉鏍峰紡
+      listClassOptions: [
+        {
+          value: "default",
+          label: "榛樿"
+        },
+        {
+          value: "primary",
+          label: "涓昏"
+        },
+        {
+          value: "success",
+          label: "鎴愬姛"
+        },
+        {
+          value: "info",
+          label: "淇℃伅"
+        },
+        {
+          value: "warning",
+          label: "璀﹀憡"
+        },
+        {
+          value: "danger",
+          label: "鍗遍櫓"
+        }
+      ],
       // 鐘舵�佹暟鎹瓧鍏�
       statusOptions: [],
       // 绫诲瀷鏁版嵁瀛楀吀
@@ -250,10 +299,6 @@
         this.loading = false;
       });
     },
-    // 鏁版嵁鐘舵�佸瓧鍏哥炕璇�
-    statusFormat(row, column) {
-      return this.selectDictLabel(this.statusOptions, row.status);
-    },
     // 鍙栨秷鎸夐挳
     cancel() {
       this.open = false;
@@ -265,6 +310,8 @@
         dictCode: undefined,
         dictLabel: undefined,
         dictValue: undefined,
+        cssClass: undefined,
+        listClass: 'default',
         dictSort: 0,
         status: "0",
         remark: undefined
diff --git a/ruoyi-ui/src/views/system/dict/index.vue b/ruoyi-ui/src/views/system/dict/index.vue
index a6b8ba3..3ced195 100644
--- a/ruoyi-ui/src/views/system/dict/index.vue
+++ b/ruoyi-ui/src/views/system/dict/index.vue
@@ -123,7 +123,11 @@
           </router-link>
         </template>
       </el-table-column>
-      <el-table-column label="鐘舵��" align="center" prop="status" :formatter="statusFormat" />
+      <el-table-column label="鐘舵��" align="center" prop="status">
+        <template slot-scope="scope">
+          <dict-tag :options="statusOptions" :value="scope.row.status"/>
+        </template>
+      </el-table-column>
       <el-table-column label="澶囨敞" align="center" prop="remark" :show-overflow-tooltip="true" />
       <el-table-column label="鍒涘缓鏃堕棿" align="center" prop="createTime" width="180">
         <template slot-scope="scope">
@@ -256,10 +260,6 @@
           this.loading = false;
         }
       );
-    },
-    // 瀛楀吀鐘舵�佸瓧鍏哥炕璇�
-    statusFormat(row, column) {
-      return this.selectDictLabel(this.statusOptions, row.status);
     },
     // 鍙栨秷鎸夐挳
     cancel() {
diff --git a/ruoyi-ui/src/views/system/user/index.vue b/ruoyi-ui/src/views/system/user/index.vue
index 1a89876..471e66f 100644
--- a/ruoyi-ui/src/views/system/user/index.vue
+++ b/ruoyi-ui/src/views/system/user/index.vue
@@ -210,7 +210,7 @@
         <el-row>
           <el-col :span="12">
             <el-form-item label="鐢ㄦ埛鏄电О" prop="nickName">
-              <el-input v-model="form.nickName" placeholder="璇疯緭鍏ョ敤鎴锋樀绉�" />
+              <el-input v-model="form.nickName" placeholder="璇疯緭鍏ョ敤鎴锋樀绉�" maxlength="30" />
             </el-form-item>
           </el-col>
           <el-col :span="12">
@@ -234,12 +234,12 @@
         <el-row>
           <el-col :span="12">
             <el-form-item v-if="form.userId == undefined" label="鐢ㄦ埛鍚嶇О" prop="userName">
-              <el-input v-model="form.userName" placeholder="璇疯緭鍏ョ敤鎴峰悕绉�" />
+              <el-input v-model="form.userName" placeholder="璇疯緭鍏ョ敤鎴峰悕绉�" maxlength="30" />
             </el-form-item>
           </el-col>
           <el-col :span="12">
             <el-form-item v-if="form.userId == undefined" label="鐢ㄦ埛瀵嗙爜" prop="password">
-              <el-input v-model="form.password" placeholder="璇疯緭鍏ョ敤鎴峰瘑鐮�" type="password" />
+              <el-input v-model="form.password" placeholder="璇疯緭鍏ョ敤鎴峰瘑鐮�" type="password" maxlength="20" />
             </el-form-item>
           </el-col>
         </el-row>
@@ -440,7 +440,8 @@
           { required: true, message: "鐢ㄦ埛鏄电О涓嶈兘涓虹┖", trigger: "blur" }
         ],
         password: [
-          { required: true, message: "鐢ㄦ埛瀵嗙爜涓嶈兘涓虹┖", trigger: "blur" }
+          { required: true, message: "鐢ㄦ埛瀵嗙爜涓嶈兘涓虹┖", trigger: "blur" },
+          { min: 5, max: 20, message: '鐢ㄦ埛瀵嗙爜闀垮害蹇呴』浠嬩簬 5 鍜� 20 涔嬮棿', trigger: 'blur' }
         ],
         email: [
           {
@@ -545,7 +546,7 @@
     },
     /** 鎼滅储鎸夐挳鎿嶄綔 */
     handleQuery() {
-      this.queryParams.page = 1;
+      this.queryParams.pageNum = 1;
       this.getList();
     },
     /** 閲嶇疆鎸夐挳鎿嶄綔 */
@@ -592,7 +593,10 @@
     handleResetPwd(row) {
       this.$prompt('璇疯緭鍏�"' + row.userName + '"鐨勬柊瀵嗙爜', "鎻愮ず", {
         confirmButtonText: "纭畾",
-        cancelButtonText: "鍙栨秷"
+        cancelButtonText: "鍙栨秷",
+        closeOnClickModal: false,
+        inputPattern: /^.{5,20}$/,
+        inputErrorMessage: "鐢ㄦ埛瀵嗙爜闀垮害蹇呴』浠嬩簬 5 鍜� 20 涔嬮棿",
       }).then(({ value }) => {
           resetUserPwd(row.userId, value).then(response => {
             this.msgSuccess("淇敼鎴愬姛锛屾柊瀵嗙爜鏄細" + value);
diff --git a/ruoyi-ui/src/views/system/user/profile/userInfo.vue b/ruoyi-ui/src/views/system/user/profile/userInfo.vue
index fbb5308..bde2423 100644
--- a/ruoyi-ui/src/views/system/user/profile/userInfo.vue
+++ b/ruoyi-ui/src/views/system/user/profile/userInfo.vue
@@ -1,7 +1,7 @@
 <template>
   <el-form ref="form" :model="user" :rules="rules" label-width="80px">
     <el-form-item label="鐢ㄦ埛鏄电О" prop="nickName">
-      <el-input v-model="user.nickName" />
+      <el-input v-model="user.nickName" maxlength="30" />
     </el-form-item>
     <el-form-item label="鎵嬫満鍙风爜" prop="phonenumber">
       <el-input v-model="user.phonenumber" maxlength="11" />
diff --git a/ruoyi-ui/src/views/tool/gen/genInfoForm.vue b/ruoyi-ui/src/views/tool/gen/genInfoForm.vue
index 27d6a22..f227156 100644
--- a/ruoyi-ui/src/views/tool/gen/genInfoForm.vue
+++ b/ruoyi-ui/src/views/tool/gen/genInfoForm.vue
@@ -7,7 +7,7 @@
           <el-select v-model="info.tplCategory" @change="tplSelectChange">
             <el-option label="鍗曡〃锛堝鍒犳敼鏌ワ級" value="crud" />
             <el-option label="鏍戣〃锛堝鍒犳敼鏌ワ級" value="tree" />
-            <el-option label="涓诲瓙琛紙澧炲垹鏀规煡锛�" value="sub" />
+<!--            <el-option label="涓诲瓙琛紙澧炲垹鏀规煡锛�" value="sub" />-->
           </el-select>
         </el-form-item>
       </el-col>
diff --git a/ruoyi-ui/src/views/tool/swagger/index.vue b/ruoyi-ui/src/views/tool/swagger/index.vue
index 8504daf..b782968 100644
--- a/ruoyi-ui/src/views/tool/swagger/index.vue
+++ b/ruoyi-ui/src/views/tool/swagger/index.vue
@@ -1,26 +1,15 @@
 <template>
-  <div v-loading="loading" :style="'height:'+ height">
-    <iframe :src="src" frameborder="no" style="width: 100%;height: 100%" scrolling="auto" />
-  </div>
+  <i-frame :src="url" />
 </template>
 <script>
+import iFrame from "@/components/iFrame/index";
 export default {
   name: "Swagger",
+  components: { iFrame },
   data() {
     return {
-      src: process.env.VUE_APP_BASE_API + "/doc.html",
-      height: document.documentElement.clientHeight - 94.5 + "px;",
-      loading: true
+      url: process.env.VUE_APP_BASE_API + "/doc.html"
     };
   },
-  mounted: function() {
-    setTimeout(() => {
-      this.loading = false;
-    }, 230);
-    const that = this;
-    window.onresize = function temp() {
-      that.height = document.documentElement.clientHeight - 94.5 + "px;";
-    };
-  }
 };
 </script>
diff --git a/ruoyi-ui/vue.config.js b/ruoyi-ui/vue.config.js
index 5eb7edd..c749c8c 100644
--- a/ruoyi-ui/vue.config.js
+++ b/ruoyi-ui/vue.config.js
@@ -1,12 +1,11 @@
 'use strict'
 const path = require('path')
-const defaultSettings = require('./src/settings.js')
 
 function resolve(dir) {
   return path.join(__dirname, dir)
 }
 
-const name = defaultSettings.title || 'RuoYi-Vue-Plus鍚庡彴绠$悊绯荤粺' // 鏍囬
+const name = process.env.VUE_APP_TITLE || 'RuoYi-Vue-Plus鍚庡彴绠$悊绯荤粺' // 缃戦〉鏍囬
 
 const port = process.env.port || process.env.npm_config_port || 80 // 绔彛
 
diff --git a/ry.sh b/ry.sh
index d296c55..d8e1a78 100644
--- a/ry.sh
+++ b/ry.sh
@@ -3,7 +3,7 @@
 # ./ry.sh start 鍚姩
 # ./ry.sh stop 鍋滄
 # ./ry.sh restart 閲嶅惎
-# ./ry.sh start 鐘舵��
+# ./ry.sh status 鐘舵��
 AppName=ruoyi-admin.jar
 
 # JVM鍙傛暟

--
Gitblit v1.9.3