From 42295ef2ac0a5e78674cf24b62d6834138f0ffdc Mon Sep 17 00:00:00 2001
From: 疯狂的狮子li <15040126243@163.com>
Date: 星期一, 29 十一月 2021 13:56:25 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/dev' into satoken

---
 ruoyi-oss/src/main/java/com/ruoyi/oss/service/impl/MinioOssStrategy.java                          |   12 
 ruoyi-extend/ruoyi-xxl-job-admin/src/main/resources/application.yml                               |   17 
 ruoyi-framework/src/main/java/com/ruoyi/framework/web/exception/GlobalExceptionHandler.java       |   10 
 ruoyi-ui/src/views/demo/demo/index.vue                                                            |   74 +
 ruoyi-oss/src/main/java/com/ruoyi/oss/factory/OssFactory.java                                     |   50 
 ruoyi-extend/ruoyi-xxl-job-admin/src/main/resources/application-dev.yml                           |   15 
 script/bin/ry.bat                                                                                 |   22 
 ruoyi-generator/src/main/java/com/ruoyi/generator/controller/GenController.java                   |    4 
 ruoyi-ui/src/views/register.vue                                                                   |    3 
 ruoyi-ui/src/views/system/dict/index.vue                                                          |    9 
 ruoyi-ui/package.json                                                                             |   10 
 ruoyi-common/src/main/java/com/ruoyi/common/core/service/ConfigService.java                       |   18 
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDictDataServiceImpl.java              |   19 
 ruoyi-generator/src/main/resources/vm/java/controller.java.vm                                     |    7 
 ruoyi-ui/src/plugins/index.js                                                                     |    3 
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDictTypeServiceImpl.java              |  149 +
 ruoyi-ui/src/layout/components/TagsView/index.vue                                                 |   19 
 ruoyi-common/src/main/java/com/ruoyi/common/core/service/LogininforService.java                   |    5 
 ruoyi-ui/src/views/system/post/index.vue                                                          |    7 
 ruoyi-ui/src/utils/ruoyi.js                                                                       |   41 
 ruoyi-ui/src/views/system/role/authUser.vue                                                       |    4 
 ruoyi-common/src/main/java/com/ruoyi/common/utils/ValidatorUtils.java                             |   25 
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysOssServiceImpl.java                   |    6 
 ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisCacheController.java                      |  134 +-
 ruoyi-demo/src/main/resources/mapper/package-info.md                                              |    3 
 ruoyi-generator/src/main/resources/vm/vue/index.vue.vm                                            |   26 
 ruoyi-ui/src/api/system/post.js                                                                   |    9 
 ruoyi-ui/src/views/system/dept/index.vue                                                          |    6 
 ruoyi-admin/Dockerfile                                                                            |    1 
 ruoyi-generator/pom.xml                                                                           |    2 
 ruoyi-admin/src/main/resources/application.yml                                                    |   65 
 ruoyi-common/src/main/java/com/ruoyi/common/excel/DefaultExcelListener.java                       |  108 +
 ruoyi-common/src/main/java/com/ruoyi/common/core/service/OperLogService.java                      |    6 
 ruoyi-admin/src/main/resources/application-prod.yml                                               |    7 
 ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisRateLimiterController.java                |   60 
 ruoyi-ui/.env.development                                                                         |    3 
 ruoyi-ui/src/components/RuoYi/Doc/index.vue                                                       |    2 
 ruoyi-extend/ruoyi-monitor-admin/src/main/java/com/ruoyi/monitor/admin/config/SecurityConfig.java |    2 
 ruoyi-oss/src/main/java/com/ruoyi/oss/service/impl/QcloudOssStrategy.java                         |   12 
 ruoyi-system/src/main/java/com/ruoyi/system/runner/SystemApplicationRunner.java                   |   42 
 ruoyi-common/src/main/java/com/ruoyi/common/utils/RedisUtils.java                                 |   25 
 ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestI18nController.java                        |   45 
 ruoyi-extend/ruoyi-xxl-job-admin/pom.xml                                                          |    5 
 ruoyi-ui/src/utils/index.js                                                                       |   14 
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDeptServiceImpl.java                  |  100 -
 ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml                                   |    4 
 ruoyi-ui/src/components/RuoYi/Git/index.vue                                                       |    2 
 ruoyi-extend/ruoyi-monitor-admin/src/main/resources/application-prod.yml                          |   14 
 ruoyi-ui/src/views/index.vue                                                                      |   36 
 ruoyi-ui/src/views/system/role/index.vue                                                          |   12 
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysLogininforServiceImpl.java            |   32 
 ruoyi-ui/src/views/system/menu/index.vue                                                          |   35 
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysOssConfigServiceImpl.java             |   19 
 ruoyi-demo/src/main/java/com/ruoyi/demo/domain/bo/TestDemoImportVo.java                           |   61 
 pom.xml                                                                                           |   54 
 ruoyi-demo/src/main/java/com/ruoyi/demo/mapper/TestDemoMapper.java                                |    4 
 ruoyi-common/src/main/java/com/ruoyi/common/convert/ExcelDictConvert.java                         |    6 
 ruoyi-generator/src/main/java/com/ruoyi/generator/service/GenTableServiceImpl.java                |    8 
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictDataController.java              |    9 
 ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestDemoController.java                        |   47 
 ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java                              |  244 +-
 ruoyi-demo/src/main/java/com/ruoyi/demo/controller/Swagger3DemoController.java                    |   26 
 ruoyi-ui/src/plugins/tab.js                                                                       |   66 +
 ruoyi-ui/src/api/login.js                                                                         |    8 
 ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java                               |    9 
 ruoyi-ui/src/views/system/user/profile/userAvatar.vue                                             |    6 
 ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestBatchController.java                       |   54 
 script/sql/ry_20210908.sql                                                                        |   68 -
 ruoyi-framework/src/main/java/com/ruoyi/framework/config/I18nConfig.java                          |    4 
 ruoyi-common/src/main/java/com/ruoyi/common/utils/PageUtils.java                                  |    9 
 ruoyi-framework/src/main/java/com/ruoyi/framework/manager/ShutdownManager.java                    |    2 
 ruoyi-system/src/main/resources/mapper/package-info.md                                            |    3 
 ruoyi-ui/src/views/system/role/selectUser.vue                                                     |    4 
 ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDeptService.java                          |   12 
 ruoyi-framework/src/main/java/com/ruoyi/framework/config/TLogConfig.java                          |    6 
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysMenuController.java                  |   11 
 ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysUserImportVo.java                        |    2 
 script/docker/docker-compose.yml                                                                  |   13 
 ruoyi-common/src/main/java/com/ruoyi/common/excel/ExcelListener.java                              |   14 
 ruoyi-ui/src/views/monitor/operlog/index.vue                                                      |   11 
 ruoyi-ui/src/views/login.vue                                                                      |    8 
 ruoyi-ui/src/utils/request.js                                                                     |   55 
 ruoyi-framework/src/main/java/com/ruoyi/framework/config/ValidatorConfig.java                     |   26 
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java                  |   19 
 ruoyi-generator/src/main/resources/vm/vue/index-tree.vue.vm                                       |   18 
 ruoyi-framework/src/main/java/com/ruoyi/framework/config/SwaggerConfig.java                       |    5 
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDeptController.java                  |   13 
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysPostController.java                  |    7 
 ruoyi-system/src/main/java/com/ruoyi/system/service/ISysMenuService.java                          |   14 
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysOssController.java                   |   17 
 ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisPubSubController.java                     |   33 
 ruoyi-extend/ruoyi-monitor-admin/src/main/resources/application-dev.yml                           |   14 
 ruoyi-ui/src/views/system/user/index.vue                                                          |   14 
 ruoyi-common/src/main/java/com/ruoyi/common/utils/DictUtils.java                                  |    7 
 ruoyi-common/src/main/java/com/ruoyi/common/config/RuoYiConfig.java                               |    5 
 ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java                                         |    5 
 ruoyi-ui/src/views/system/user/authRole.vue                                                       |    8 
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java                 |    4 
 ruoyi-common/src/main/java/com/ruoyi/common/excel/DefautExcelResult.java                          |   73 +
 ruoyi-ui/.env.production                                                                          |    3 
 ruoyi-ui/.env.staging                                                                             |    3 
 ruoyi-ui/src/views/tool/gen/editTable.vue                                                         |    4 
 ruoyi-ui/src/main.js                                                                              |    4 
 ruoyi-extend/ruoyi-xxl-job-admin/src/main/resources/application-prod.yml                          |   15 
 ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/RepeatSubmitAspect.java                 |   66 
 ruoyi-ui/src/router/index.js                                                                      |   22 
 ruoyi-ui/src/views/system/user/profile/userInfo.vue                                               |    5 
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysConfigServiceImpl.java                |   55 
 ruoyi-ui/src/store/modules/tagsView.js                                                            |    4 
 ruoyi-extend/ruoyi-monitor-admin/pom.xml                                                          |    6 
 ruoyi-generator/src/main/java/com/ruoyi/generator/util/VelocityInitializer.java                   |    3 
 ruoyi-oss/src/main/java/com/ruoyi/oss/service/IOssStrategy.java                                   |   12 
 ruoyi-admin/src/main/resources/spy.properties                                                     |    2 
 ruoyi-oss/src/main/java/com/ruoyi/oss/enumd/OssEnumd.java                                         |   63 
 ruoyi-ui/vue.config.js                                                                            |    3 
 ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestTreeController.java                        |   13 
 ruoyi-system/src/main/java/com/ruoyi/system/service/ISysOssConfigService.java                     |    5 
 ruoyi-common/src/main/java/com/ruoyi/common/utils/TreeBuildUtils.java                             |   31 
 ruoyi-framework/src/main/java/com/ruoyi/framework/config/FilterConfig.java                        |    2 
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysConfigController.java                |   11 
 ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisLockController.java                       |   96 
 README.md                                                                                         |   14 
 ruoyi-ui/src/components/RightToolbar/index.vue                                                    |    2 
 ruoyi-ui/src/layout/components/Navbar.vue                                                         |    2 
 ruoyi-ui/src/views/system/config/index.vue                                                        |    7 
 ruoyi-oss/src/main/java/com/ruoyi/oss/service/impl/AliyunOssStrategy.java                         |   12 
 ruoyi-admin/src/main/resources/logback.xml                                                        |   30 
 ruoyi-ui/src/layout/index.vue                                                                     |    2 
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysProfileController.java               |   10 
 ruoyi-ui/src/layout/components/Sidebar/Logo.vue                                                   |    2 
 ruoyi-ui/src/plugins/download.js                                                                  |   60 
 ruoyi-system/src/main/resources/mapper/system/SysMenuMapper.xml                                   |    4 
 ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysMenuMapper.java                             |    2 
 ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/DataScopeAspect.java                    |    1 
 ruoyi-ui/src/components/SizeSelect/index.vue                                                      |    3 
 ruoyi-ui/src/store/modules/settings.js                                                            |    2 
 ruoyi-generator/src/main/java/com/ruoyi/generator/util/VelocityUtils.java                         |    3 
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysPostServiceImpl.java                  |   14 
 script/docker/redis/redis.conf                                                                    |   25 
 ruoyi-common/src/main/java/com/ruoyi/common/excel/ExcelResult.java                                |   26 
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysOperLogServiceImpl.java               |   62 
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java                  |   28 
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysMenuServiceImpl.java                  |   65 
 ruoyi-ui/src/views/monitor/logininfor/index.vue                                                   |   11 
 ruoyi-oss/src/main/java/com/ruoyi/oss/properties/OssProperties.java                               |    9 
 ruoyi-ui/src/views/system/dict/data.vue                                                           |   23 
 ruoyi-ui/src/store/modules/permission.js                                                          |    4 
 ruoyi-admin/pom.xml                                                                               |    6 
 ruoyi-ui/src/views/system/user/profile/resetPwd.vue                                               |   12 
 ruoyi-oss/src/main/java/com/ruoyi/oss/service/impl/QiniuOssStrategy.java                          |   24 
 ruoyi-oss/src/main/java/com/ruoyi/oss/service/abstractd/AbstractOssStrategy.java                  |   12 
 ruoyi-common/src/main/java/com/ruoyi/common/core/service/DictService.java                         |   57 
 ruoyi-common/pom.xml                                                                              |   28 
 ruoyi-ui/src/components/Breadcrumb/index.vue                                                      |    2 
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysOssConfigController.java             |    7 
 ruoyi-ui/src/utils/dict/index.js                                                                  |    2 
 /dev/null                                                                                         |  174 --
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysRoleController.java                  |   17 
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictTypeController.java              |    7 
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysOperlogController.java              |    2 
 ruoyi-generator/src/main/resources/mapper/package-info.md                                         |    3 
 ruoyi-extend/ruoyi-monitor-admin/src/main/resources/application.yml                               |   20 
 ruoyi-oss/src/main/java/com/ruoyi/oss/constant/OssConstant.java                                   |    6 
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysRoleServiceImpl.java                  |   14 
 ruoyi-system/src/main/java/com/ruoyi/system/listener/SysUserImportListener.java                   |  109 +
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysLogininforController.java           |    2 
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysNoticeController.java                |    5 
 167 files changed, 2,268 insertions(+), 1,558 deletions(-)

diff --git a/README.md b/README.md
index a5cae93..1d0b346 100644
--- a/README.md
+++ b/README.md
@@ -10,12 +10,14 @@
 [![JDK-11](https://img.shields.io/badge/JDK-11-green.svg)]()
 [![JDK-17](https://img.shields.io/badge/JDK-17-green.svg)]()
 
-RuoYi-Vue-Plus 鏄熀浜� RuoYi-Vue 閽堝 `鍒嗗竷寮忛泦缇 鍦烘櫙鍗囩骇(涓嶅吋瀹瑰師妗嗘灦)
+> RuoYi-Vue-Plus 鏄熀浜� RuoYi-Vue 閽堝 `鍒嗗竷寮忛泦缇 鍦烘櫙鍗囩骇(涓嶅吋瀹瑰師妗嗘灦)
+
+> 绯荤粺婕旂ず: [浼犻�侀棬](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/wikis/绯荤粺婕旂ず?sort_id=4836388)
 
 | 鍔熻兘浠嬬粛 | 浣跨敤鎶�鏈� | 鏂囨。鍦板潃 | 鐗规�ф敞鎰忎簨椤� |
 |---|---|---|---|
 | 褰撳墠妗嗘灦 | RuoYi-Vue-Plus | [RuoYi-Vue-Plus鏂囨。](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/wikis/pages) | 閲嶅啓RuoYi-Vue鍏ㄦ柟浣嶅崌绾�(涓嶅吋瀹瑰師妗嗘灦) |
-| satoken鍒嗘敮 | RuoYi-Vue-Plus-satoken | [satoken鍒嗘敮鍦板潃](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/tree/satoken/) | 浣跨敤satoken閲嶆瀯鏉冮檺閴存潈(浠呬緵瀛︿範涓嶆帹鑽愪笂鐢熶骇) |
+| satoken鍒嗘敮 | RuoYi-Vue-Plus-satoken | [satoken鍒嗘敮鍦板潃](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/tree/satoken/) | 浣跨敤satoken閲嶆瀯鏉冮檺閴存潈(鍏祴 鍙皾璇曚笂鐢熶骇) |
 | 鍗曚綋鍒嗘敮 | RuoYi-Vue-Plus-fast | [fast鍒嗘敮鍦板潃](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/tree/fast/) | 鍗曚綋搴旂敤缁撴瀯 |
 | 鍘熸鏋� | RuoYi-Vue | [RuoYi-Vue瀹樼綉](http://ruoyi.vip/) | 瀹氭湡鍚屾闇�瑕佺殑鍔熻兘 |
 | 鍓嶇寮�鍙戞鏋� | Vue銆丒lement UI | [Element UI瀹樼綉](https://element.eleme.cn/#/zh-CN) | |
@@ -28,17 +30,16 @@
 | 鏁版嵁搴撴鏋� | p6spy | [p6spy瀹樼綉](https://p6spy.readthedocs.io/) | 鏇村己鍔茬殑 SQL 鍒嗘瀽 |
 | 澶氭暟鎹簮妗嗘灦 | dynamic-datasource | [dynamic-ds鏂囨。](https://www.kancloud.cn/tracy5546/dynamic-datasource/content) | 鏀寔涓讳粠涓庡绉嶇被鏁版嵁搴撳紓鏋� |
 | 搴忓垪鍖栨鏋� | Jackson | [Jackson瀹樼綉](https://github.com/FasterXML/jackson) | 缁熶竴浣跨敤 jackson 楂樻晥鍙潬 |
-| 缃戠粶妗嗘灦 | Feign銆丱kHttp3 | [Feign瀹樼綉](https://github.com/OpenFeign/feign) | 鎺ュ彛鍖栫鐞� HTTP 璇锋眰 |
 | Redis瀹㈡埛绔� | Redisson | [Redisson鏂囨。](https://github.com/redisson/redisson/wiki/%E7%9B%AE%E5%BD%95) | 鏀寔鍗曟満銆侀泦缇ら厤缃� |
 | 鍒嗗竷寮忛檺娴� | Redisson | [Redisson鏂囨。](https://github.com/redisson/redisson/wiki/%E7%9B%AE%E5%BD%95) | 鍏ㄥ眬銆佽姹侷P銆侀泦缇D 澶氱闄愭祦 |
 | 鍒嗗竷寮忛攣 | Lock4j | [Lock4j瀹樼綉](https://gitee.com/baomidou/lock4j) | 娉ㄨВ閿併�佸伐鍏烽攣 澶氱澶氭牱 |
-| 鍒嗗竷寮忓箓绛� | Lock4j | [Lock4j鏂囨。](https://gitee.com/baomidou/lock4j) | 鍩轰簬鍒嗗竷寮忛攣瀹炵幇 |
+| 鍒嗗竷寮忓箓绛� | Redisson | [Lock4j鏂囨。](https://gitee.com/baomidou/lock4j) | 鎷︽埅閲嶅鎻愪氦 |
 | 鍒嗗竷寮忔棩蹇� | TLog | [TLog鏂囨。](https://yomahub.com/tlog/docs) | 鏀寔璺熻釜閾捐矾鏃ュ織璁板綍銆佹�ц兘鍒嗘瀽銆侀摼璺帓鏌� |
 | 鍒嗗竷寮忎换鍔¤皟搴� | Xxl-Job | [Xxl-Job瀹樼綉](https://www.xuxueli.com/xxl-job/) | 楂樻�ц兘 楂樺彲闈� 鏄撴墿灞� |
 | 鏂囦欢瀛樺偍 | Minio | [Minio鏂囨。](https://docs.min.io/) | 鏈湴瀛樺偍 |
 | 鏂囦欢瀛樺偍 | 涓冪墰銆侀樋閲屻�佽吘璁� | [OSS浣跨敤鏂囨。](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/wikis/pages?sort_id=4359146&doc_id=1469725) | 浜戝瓨鍌� |
 | 鐩戞帶妗嗘灦 | SpringBoot-Admin | [SpringBoot-Admin鏂囨。](https://codecentric.github.io/spring-boot-admin/current/) | 鍏ㄦ柟浣嶆湇鍔$洃鎺� |
-| 鏍¢獙妗嗘灦 | Validation | [Validation鏂囨。](https://docs.jboss.org/hibernate/stable/validator/reference/en-US/html_single/) | 澧炲己鎺ュ彛瀹夊叏鎬с�佷弗璋ㄦ�� |
+| 鏍¢獙妗嗘灦 | Validation | [Validation鏂囨。](https://docs.jboss.org/hibernate/stable/validator/reference/en-US/html_single/) | 澧炲己鎺ュ彛瀹夊叏鎬с�佷弗璋ㄦ�� 鏀寔鍥介檯鍖� |
 | Excel妗嗘灦 | Alibaba EasyExcel | [EasyExcel鏂囨。](https://www.yuque.com/easyexcel/doc/easyexcel) | 鎬ц兘浼樺紓 鎵╁睍鎬у己 |
 | 鏂囨。妗嗘灦 | Knife4j | [Knife4j鏂囨。](https://doc.xiaominfo.com/knife4j/documentation/) | 缇庡寲鎺ュ彛鏂囨。 |
 | 宸ュ叿绫绘鏋� | Hutool銆丩ombok | [Hutool鏂囨。](https://www.hutool.cn/docs/) | 鍑忓皯浠g爜鍐椾綑 澧炲姞瀹夊叏鎬� |
@@ -61,8 +62,7 @@
 
 ## 杞欢鏋舵瀯鍥�
 
-![Plus閮ㄧ讲鏋舵瀯鍥綸(https://images.gitee.com/uploads/images/2021/0729/112230_4295e5ce_1766278.png "Plus閮ㄧ讲鏋舵瀯鍥�.png")
-
+![Plus閮ㄧ讲鏋舵瀯鍥綸(https://images.gitee.com/uploads/images/2021/1112/202137_673ac5d2_1766278.png "Plus閮ㄧ讲鏋舵瀯鍥�.png")
 ## 璐$尞浠g爜
 
 娆㈣繋鍚勮矾鑻遍泟璞澃 `PR` 浠g爜 璇锋彁浜ゅ埌 `dev` 寮�鍙戝垎鏀� 缁熶竴娴嬭瘯鍙戠増
diff --git a/pom.xml b/pom.xml
index 956d167..9274e6a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -14,7 +14,7 @@
 
     <properties>
         <ruoyi-vue-plus.version>3.3.0</ruoyi-vue-plus.version>
-        <spring-boot.version>2.5.6</spring-boot.version>
+        <spring-boot.version>2.5.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>
@@ -24,19 +24,17 @@
         <swagger-annotations.version>1.5.22</swagger-annotations.version>
         <poi.version>4.1.2</poi.version>
         <easyexcel.version>2.2.11</easyexcel.version>
-        <velocity.version>1.7</velocity.version>
+        <velocity.version>2.3</velocity.version>
         <satoken.version>1.28.0</satoken.version>
         <mybatis-plus.version>3.4.3.4</mybatis-plus.version>
         <p6spy.version>3.9.1</p6spy.version>
-        <hutool.version>5.7.15</hutool.version>
-        <feign.version>3.0.3</feign.version>
-        <feign-okhttp.version>11.6</feign-okhttp.version>
-        <okhttp.version>4.9.1</okhttp.version>
-        <spring-boot-admin.version>2.5.2</spring-boot-admin.version>
-        <redisson.version>3.16.3</redisson.version>
+        <hutool.version>5.7.16</hutool.version>
+        <okhttp.version>4.9.2</okhttp.version>
+        <spring-boot-admin.version>2.5.4</spring-boot-admin.version>
+        <redisson.version>3.16.4</redisson.version>
         <lock4j.version>2.2.1</lock4j.version>
         <dynamic-ds.version>3.4.1</dynamic-ds.version>
-        <tlog.version>1.3.3</tlog.version>
+        <tlog.version>1.3.4</tlog.version>
         <xxl-job.version>2.3.0</xxl-job.version>
 
         <!-- jdk11 缂哄け渚濊禆 jaxb-->
@@ -120,7 +118,7 @@
             <!-- velocity浠g爜鐢熸垚浣跨敤妯℃澘 -->
             <dependency>
                 <groupId>org.apache.velocity</groupId>
-                <artifactId>velocity</artifactId>
+                <artifactId>velocity-engine-core</artifactId>
                 <version>${velocity.version}</version>
             </dependency>
 
@@ -172,25 +170,6 @@
                 <groupId>cn.hutool</groupId>
                 <artifactId>hutool-all</artifactId>
                 <version>${hutool.version}</version>
-            </dependency>
-
-            <!-- @deprecated 鐢变簬浣跨敤浜烘暟杈冨皯 鍐冲畾涓� 3.4.0 鐗堟湰绉婚櫎 -->
-            <dependency>
-                <groupId>org.springframework.cloud</groupId>
-                <artifactId>spring-cloud-starter-openfeign</artifactId>
-                <version>${feign.version}</version>
-                <exclusions>
-                    <exclusion>
-                        <artifactId>feign-core</artifactId>
-                        <groupId>io.github.openfeign</groupId>
-                    </exclusion>
-                </exclusions>
-            </dependency>
-            <!-- @deprecated 鐢变簬浣跨敤浜烘暟杈冨皯 鍐冲畾涓� 3.4.0 鐗堟湰绉婚櫎 -->
-            <dependency>
-                <groupId>io.github.openfeign</groupId>
-                <artifactId>feign-okhttp</artifactId>
-                <version>${feign-okhttp.version}</version>
             </dependency>
 
             <dependency>
@@ -253,21 +232,8 @@
 
             <dependency>
                 <groupId>com.yomahub</groupId>
-                <artifactId>tlog-feign</artifactId>
-                <version>${tlog.version}</version>
-            </dependency>
-
-            <dependency>
-                <groupId>com.yomahub</groupId>
                 <artifactId>tlog-xxl-job</artifactId>
                 <version>${tlog.version}</version>
-            </dependency>
-
-            <!-- 瀹氭椂浠诲姟 @deprecated 3.4.0鍒犻櫎 杩佺Щ鑷硏xl-job -->
-            <dependency>
-                <groupId>com.ruoyi</groupId>
-                <artifactId>ruoyi-quartz</artifactId>
-                <version>${ruoyi-vue-plus.version}</version>
             </dependency>
 
             <!-- 瀹氭椂浠诲姟 -->
@@ -326,7 +292,6 @@
         <module>ruoyi-admin</module>
         <module>ruoyi-framework</module>
         <module>ruoyi-system</module>
-        <module>ruoyi-quartz</module>
         <module>ruoyi-job</module>
         <module>ruoyi-generator</module>
         <module>ruoyi-common</module>
@@ -391,6 +356,7 @@
                 <!-- 鐜鏍囪瘑锛岄渶瑕佷笌閰嶇疆鏂囦欢鐨勫悕绉扮浉瀵瑰簲 -->
                 <profiles.active>local</profiles.active>
                 <logging.level>debug</logging.level>
+                <knife4j.production>false</knife4j.production>
                 <endpoints.include>'*'</endpoints.include>
             </properties>
         </profile>
@@ -400,6 +366,7 @@
                 <!-- 鐜鏍囪瘑锛岄渶瑕佷笌閰嶇疆鏂囦欢鐨勫悕绉扮浉瀵瑰簲 -->
                 <profiles.active>dev</profiles.active>
                 <logging.level>debug</logging.level>
+                <knife4j.production>false</knife4j.production>
                 <endpoints.include>'*'</endpoints.include>
             </properties>
             <activation>
@@ -412,6 +379,7 @@
             <properties>
                 <profiles.active>prod</profiles.active>
                 <logging.level>warn</logging.level>
+                <knife4j.production>true</knife4j.production>
                 <endpoints.include>health, info, logfile</endpoints.include>
             </properties>
         </profile>
diff --git a/ruoyi-admin/Dockerfile b/ruoyi-admin/Dockerfile
index 88f4932..1bbd2cc 100644
--- a/ruoyi-admin/Dockerfile
+++ b/ruoyi-admin/Dockerfile
@@ -4,6 +4,7 @@
 
 RUN mkdir -p /ruoyi/server
 RUN mkdir -p /ruoyi/server/logs
+RUN mkdir -p /ruoyi/server/temp
 
 WORKDIR /ruoyi/server
 
diff --git a/ruoyi-admin/pom.xml b/ruoyi-admin/pom.xml
index 9ec68cd..b736a42 100644
--- a/ruoyi-admin/pom.xml
+++ b/ruoyi-admin/pom.xml
@@ -41,12 +41,6 @@
             <artifactId>ruoyi-system</artifactId>
         </dependency>
 
-        <!-- 瀹氭椂浠诲姟 @deprecated 3.4.0鍒犻櫎 杩佺Щ鑷硏xl-job -->
-<!--        <dependency>-->
-<!--            <groupId>com.ruoyi</groupId>-->
-<!--            <artifactId>ruoyi-quartz</artifactId>-->
-<!--        </dependency>-->
-
         <dependency>
             <groupId>com.ruoyi</groupId>
             <artifactId>ruoyi-job</artifactId>
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java b/ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java
index f389ff4..b52d32d 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java
@@ -2,6 +2,7 @@
 
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.context.metrics.buffering.BufferingApplicationStartup;
 
 /**
  * 鍚姩绋嬪簭
@@ -14,7 +15,9 @@
 
     public static void main(String[] args) {
         System.setProperty("spring.devtools.restart.enabled", "false");
-        SpringApplication.run(RuoYiApplication.class, args);
+        SpringApplication application = new SpringApplication(RuoYiApplication.class);
+        application.setApplicationStartup(new BufferingApplicationStartup(2048));
+        application.run(args);
         System.out.println("(鈾モ棤鈥库棤)锞夛緸  RuoYi-Vue-Plus鍚姩鎴愬姛   醿�(麓凇`醿�)锞�");
     }
 
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysLogininforController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysLogininforController.java
index 9ecc5a7..cd02bba 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysLogininforController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysLogininforController.java
@@ -43,7 +43,7 @@
     @ApiOperation("瀵煎嚭绯荤粺璁块棶璁板綍鍒楄〃")
     @Log(title = "鐧诲綍鏃ュ織", businessType = BusinessType.EXPORT)
     @SaCheckPermission("monitor:logininfor:export")
-    @GetMapping("/export")
+    @PostMapping("/export")
     public void export(SysLogininfor logininfor, HttpServletResponse response) {
         List<SysLogininfor> list = logininforService.selectLogininforList(logininfor);
         ExcelUtil.exportExcel(list, "鐧诲綍鏃ュ織", SysLogininfor.class, response);
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysOperlogController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysOperlogController.java
index cec09ff..6978101 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysOperlogController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysOperlogController.java
@@ -43,7 +43,7 @@
     @ApiOperation("瀵煎嚭鎿嶄綔鏃ュ織璁板綍鍒楄〃")
     @Log(title = "鎿嶄綔鏃ュ織", businessType = BusinessType.EXPORT)
     @SaCheckPermission("monitor:operlog:export")
-    @GetMapping("/export")
+    @PostMapping("/export")
     public void export(SysOperLog operLog, HttpServletResponse response) {
         List<SysOperLog> list = operLogService.selectOperLogList(operLog);
         ExcelUtil.exportExcel(list, "鎿嶄綔鏃ュ織", SysOperLog.class, response);
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysConfigController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysConfigController.java
index 3cb6655..f5dac6f 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysConfigController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysConfigController.java
@@ -2,7 +2,6 @@
 
 import cn.dev33.satoken.annotation.SaCheckPermission;
 import com.ruoyi.common.annotation.Log;
-import com.ruoyi.common.annotation.RepeatSubmit;
 import com.ruoyi.common.constant.UserConstants;
 import com.ruoyi.common.core.controller.BaseController;
 import com.ruoyi.common.core.domain.AjaxResult;
@@ -13,6 +12,7 @@
 import com.ruoyi.system.service.ISysConfigService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
 import lombok.RequiredArgsConstructor;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.validation.annotation.Validated;
@@ -48,7 +48,7 @@
     @ApiOperation("瀵煎嚭鍙傛暟閰嶇疆鍒楄〃")
     @Log(title = "鍙傛暟绠$悊", businessType = BusinessType.EXPORT)
     @SaCheckPermission("system:config:export")
-    @GetMapping("/export")
+    @PostMapping("/export")
     public void export(SysConfig config, HttpServletResponse response) {
         List<SysConfig> list = configService.selectConfigList(config);
         ExcelUtil.exportExcel(list, "鍙傛暟鏁版嵁", SysConfig.class, response);
@@ -60,7 +60,7 @@
     @ApiOperation("鏍规嵁鍙傛暟缂栧彿鑾峰彇璇︾粏淇℃伅")
     @SaCheckPermission("system:config:query")
     @GetMapping(value = "/{configId}")
-    public AjaxResult<SysConfig> getInfo(@PathVariable Long configId) {
+    public AjaxResult<SysConfig> getInfo(@ApiParam("鍙傛暟ID") @PathVariable Long configId) {
         return AjaxResult.success(configService.selectConfigById(configId));
     }
 
@@ -69,7 +69,7 @@
      */
     @ApiOperation("鏍规嵁鍙傛暟閿悕鏌ヨ鍙傛暟鍊�")
     @GetMapping(value = "/configKey/{configKey}")
-    public AjaxResult<Void> getConfigKey(@PathVariable String configKey) {
+    public AjaxResult<Void> getConfigKey(@ApiParam("鍙傛暟Key") @PathVariable String configKey) {
         return AjaxResult.success(configService.selectConfigByKey(configKey));
     }
 
@@ -80,7 +80,6 @@
     @SaCheckPermission("system:config:add")
     @Log(title = "鍙傛暟绠$悊", businessType = BusinessType.INSERT)
     @PostMapping
-    @RepeatSubmit
     public AjaxResult<Void> add(@Validated @RequestBody SysConfig config) {
         if (UserConstants.NOT_UNIQUE.equals(configService.checkConfigKeyUnique(config))) {
             return AjaxResult.error("鏂板鍙傛暟'" + config.getConfigName() + "'澶辫触锛屽弬鏁伴敭鍚嶅凡瀛樺湪");
@@ -109,7 +108,7 @@
     @SaCheckPermission("system:config:remove")
     @Log(title = "鍙傛暟绠$悊", businessType = BusinessType.DELETE)
     @DeleteMapping("/{configIds}")
-    public AjaxResult<Void> remove(@PathVariable Long[] configIds) {
+    public AjaxResult<Void> remove(@ApiParam("鍙傛暟ID涓�") @PathVariable Long[] configIds) {
         configService.deleteConfigByIds(configIds);
         return success();
     }
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 a8630b1..08ebf96 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
@@ -1,18 +1,19 @@
 package com.ruoyi.web.controller.system;
 
 import cn.dev33.satoken.annotation.SaCheckPermission;
+import cn.hutool.core.lang.tree.Tree;
 import cn.hutool.core.util.ArrayUtil;
 import com.ruoyi.common.annotation.Log;
 import com.ruoyi.common.constant.UserConstants;
 import com.ruoyi.common.core.controller.BaseController;
 import com.ruoyi.common.core.domain.AjaxResult;
-import com.ruoyi.common.core.domain.TreeSelect;
 import com.ruoyi.common.core.domain.entity.SysDept;
 import com.ruoyi.common.enums.BusinessType;
 import com.ruoyi.common.utils.StringUtils;
 import com.ruoyi.system.service.ISysDeptService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
 import lombok.RequiredArgsConstructor;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.validation.annotation.Validated;
@@ -53,7 +54,7 @@
     @ApiOperation("鏌ヨ閮ㄩ棬鍒楄〃锛堟帓闄よ妭鐐癸級")
     @SaCheckPermission("system:dept:list")
     @GetMapping("/list/exclude/{deptId}")
-    public AjaxResult<List<SysDept>> excludeChild(@PathVariable(value = "deptId", required = false) Long deptId) {
+    public AjaxResult<List<SysDept>> excludeChild(@ApiParam("閮ㄩ棬ID") @PathVariable(value = "deptId", required = false) Long deptId) {
         List<SysDept> depts = deptService.selectDeptList(new SysDept());
         depts.removeIf(d -> d.getDeptId().equals(deptId)
                 || ArrayUtil.contains(StringUtils.split(d.getAncestors(), ","), deptId + ""));
@@ -66,7 +67,7 @@
     @ApiOperation("鏍规嵁閮ㄩ棬缂栧彿鑾峰彇璇︾粏淇℃伅")
     @SaCheckPermission("system:dept:query")
     @GetMapping(value = "/{deptId}")
-    public AjaxResult<SysDept> getInfo(@PathVariable Long deptId) {
+    public AjaxResult<SysDept> getInfo(@ApiParam("閮ㄩ棬ID") @PathVariable Long deptId) {
         deptService.checkDeptDataScope(deptId);
         return AjaxResult.success(deptService.selectDeptById(deptId));
     }
@@ -76,7 +77,7 @@
      */
     @ApiOperation("鑾峰彇閮ㄩ棬涓嬫媺鏍戝垪琛�")
     @GetMapping("/treeselect")
-    public AjaxResult<List<TreeSelect>> treeselect(SysDept dept) {
+    public AjaxResult<List<Tree<Long>>> treeselect(SysDept dept) {
         List<SysDept> depts = deptService.selectDeptList(dept);
         return AjaxResult.success(deptService.buildDeptTreeSelect(depts));
     }
@@ -86,7 +87,7 @@
      */
     @ApiOperation("鍔犺浇瀵瑰簲瑙掕壊閮ㄩ棬鍒楄〃鏍�")
     @GetMapping(value = "/roleDeptTreeselect/{roleId}")
-    public AjaxResult<Map<String, Object>> roleDeptTreeselect(@PathVariable("roleId") Long roleId) {
+    public AjaxResult<Map<String, Object>> roleDeptTreeselect(@ApiParam("瑙掕壊ID") @PathVariable("roleId") Long roleId) {
         List<SysDept> depts = deptService.selectDeptList(new SysDept());
         Map<String, Object> ajax = new HashMap<>();
         ajax.put("checkedKeys", deptService.selectDeptListByRoleId(roleId));
@@ -134,7 +135,7 @@
     @SaCheckPermission("system:dept:remove")
     @Log(title = "閮ㄩ棬绠$悊", businessType = BusinessType.DELETE)
     @DeleteMapping("/{deptId}")
-    public AjaxResult<Void> remove(@PathVariable Long deptId) {
+    public AjaxResult<Void> remove(@ApiParam("閮ㄩ棬ID涓�") @PathVariable Long deptId) {
         if (deptService.hasChildByDeptId(deptId)) {
             return AjaxResult.error("瀛樺湪涓嬬骇閮ㄩ棬,涓嶅厑璁稿垹闄�");
         }
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictDataController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictDataController.java
index dafd666..6d472d7 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictDataController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictDataController.java
@@ -13,6 +13,7 @@
 import com.ruoyi.system.service.ISysDictTypeService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
 import lombok.RequiredArgsConstructor;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.validation.annotation.Validated;
@@ -47,7 +48,7 @@
     @ApiOperation("瀵煎嚭瀛楀吀鏁版嵁鍒楄〃")
     @Log(title = "瀛楀吀鏁版嵁", businessType = BusinessType.EXPORT)
     @SaCheckPermission("system:dict:export")
-    @GetMapping("/export")
+    @PostMapping("/export")
     public void export(SysDictData dictData, HttpServletResponse response) {
         List<SysDictData> list = dictDataService.selectDictDataList(dictData);
         ExcelUtil.exportExcel(list, "瀛楀吀鏁版嵁", SysDictData.class, response);
@@ -59,7 +60,7 @@
     @ApiOperation("鏌ヨ瀛楀吀鏁版嵁璇︾粏")
     @SaCheckPermission("system:dict:query")
     @GetMapping(value = "/{dictCode}")
-    public AjaxResult<SysDictData> getInfo(@PathVariable Long dictCode) {
+    public AjaxResult<SysDictData> getInfo(@ApiParam("瀛楀吀code") @PathVariable Long dictCode) {
         return AjaxResult.success(dictDataService.selectDictDataById(dictCode));
     }
 
@@ -68,7 +69,7 @@
      */
     @ApiOperation("鏍规嵁瀛楀吀绫诲瀷鏌ヨ瀛楀吀鏁版嵁淇℃伅")
     @GetMapping(value = "/type/{dictType}")
-    public AjaxResult<List<SysDictData>> dictType(@PathVariable String dictType) {
+    public AjaxResult<List<SysDictData>> dictType(@ApiParam("瀛楀吀绫诲瀷") @PathVariable String dictType) {
         List<SysDictData> data = dictTypeService.selectDictDataByType(dictType);
         if (StringUtils.isNull(data)) {
             data = new ArrayList<>();
@@ -105,7 +106,7 @@
     @SaCheckPermission("system:dict:remove")
     @Log(title = "瀛楀吀绫诲瀷", businessType = BusinessType.DELETE)
     @DeleteMapping("/{dictCodes}")
-    public AjaxResult<Void> remove(@PathVariable Long[] dictCodes) {
+    public AjaxResult<Void> remove(@ApiParam("瀛楀吀code涓�") @PathVariable Long[] dictCodes) {
         dictDataService.deleteDictDataByIds(dictCodes);
         return success();
     }
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictTypeController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictTypeController.java
index 1743fd0..1e54404 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictTypeController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictTypeController.java
@@ -12,6 +12,7 @@
 import com.ruoyi.system.service.ISysDictTypeService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
 import lombok.RequiredArgsConstructor;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.validation.annotation.Validated;
@@ -44,7 +45,7 @@
     @ApiOperation("瀵煎嚭瀛楀吀绫诲瀷鍒楄〃")
     @Log(title = "瀛楀吀绫诲瀷", businessType = BusinessType.EXPORT)
     @SaCheckPermission("system:dict:export")
-    @GetMapping("/export")
+    @PostMapping("/export")
     public void export(SysDictType dictType, HttpServletResponse response) {
         List<SysDictType> list = dictTypeService.selectDictTypeList(dictType);
         ExcelUtil.exportExcel(list, "瀛楀吀绫诲瀷", SysDictType.class, response);
@@ -56,7 +57,7 @@
     @ApiOperation("鏌ヨ瀛楀吀绫诲瀷璇︾粏")
     @SaCheckPermission("system:dict:query")
     @GetMapping(value = "/{dictId}")
-    public AjaxResult<SysDictType> getInfo(@PathVariable Long dictId) {
+    public AjaxResult<SysDictType> getInfo(@ApiParam("瀛楀吀ID") @PathVariable Long dictId) {
         return AjaxResult.success(dictTypeService.selectDictTypeById(dictId));
     }
 
@@ -95,7 +96,7 @@
     @SaCheckPermission("system:dict:remove")
     @Log(title = "瀛楀吀绫诲瀷", businessType = BusinessType.DELETE)
     @DeleteMapping("/{dictIds}")
-    public AjaxResult<Void> remove(@PathVariable Long[] dictIds) {
+    public AjaxResult<Void> remove(@ApiParam("瀛楀吀ID涓�") @PathVariable Long[] dictIds) {
         dictTypeService.deleteDictTypeByIds(dictIds);
         return success();
     }
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java
index d6ea043..5cf5170 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java
@@ -10,6 +10,7 @@
 import com.ruoyi.common.utils.SecurityUtils;
 import com.ruoyi.system.domain.vo.RouterVo;
 import com.ruoyi.system.service.ISysMenuService;
+import com.ruoyi.system.service.ISysUserService;
 import com.ruoyi.system.service.SysLoginService;
 import com.ruoyi.system.service.SysPermissionService;
 import io.swagger.annotations.Api;
@@ -33,13 +34,14 @@
  * @author Lion Li
  */
 @Validated
-@Api(value = "鏁版嵁瀛楀吀淇℃伅鎺у埗鍣�", tags = {"鏁版嵁瀛楀吀淇℃伅绠$悊"})
+@Api(value = "鐧诲綍楠岃瘉鎺у埗鍣�", tags = {"鐧诲綍楠岃瘉绠$悊"})
 @RequiredArgsConstructor(onConstructor_ = @Autowired)
 @RestController
 public class SysLoginController {
 
     private final SysLoginService loginService;
     private final ISysMenuService menuService;
+    private final ISysUserService userService;
     private final SysPermissionService permissionService;
 
     /**
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysMenuController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysMenuController.java
index 0f496cc..118f87b 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysMenuController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysMenuController.java
@@ -1,17 +1,18 @@
 package com.ruoyi.web.controller.system;
 
 import cn.dev33.satoken.annotation.SaCheckPermission;
+import cn.hutool.core.lang.tree.Tree;
 import com.ruoyi.common.annotation.Log;
 import com.ruoyi.common.constant.UserConstants;
 import com.ruoyi.common.core.controller.BaseController;
 import com.ruoyi.common.core.domain.AjaxResult;
-import com.ruoyi.common.core.domain.TreeSelect;
 import com.ruoyi.common.core.domain.entity.SysMenu;
 import com.ruoyi.common.enums.BusinessType;
 import com.ruoyi.common.utils.StringUtils;
 import com.ruoyi.system.service.ISysMenuService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
 import lombok.RequiredArgsConstructor;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.validation.annotation.Validated;
@@ -52,7 +53,7 @@
     @ApiOperation("鏍规嵁鑿滃崟缂栧彿鑾峰彇璇︾粏淇℃伅")
     @SaCheckPermission("system:menu:query")
     @GetMapping(value = "/{menuId}")
-    public AjaxResult<SysMenu> getInfo(@PathVariable Long menuId) {
+    public AjaxResult<SysMenu> getInfo(@ApiParam("鑿滃崟ID") @PathVariable Long menuId) {
         return AjaxResult.success(menuService.selectMenuById(menuId));
     }
 
@@ -61,7 +62,7 @@
      */
     @ApiOperation("鑾峰彇鑿滃崟涓嬫媺鏍戝垪琛�")
     @GetMapping("/treeselect")
-    public AjaxResult<List<TreeSelect>> treeselect(SysMenu menu) {
+    public AjaxResult<List<Tree<Long>>> treeselect(SysMenu menu) {
         List<SysMenu> menus = menuService.selectMenuList(menu, getUserId());
         return AjaxResult.success(menuService.buildMenuTreeSelect(menus));
     }
@@ -71,7 +72,7 @@
      */
     @ApiOperation("鍔犺浇瀵瑰簲瑙掕壊鑿滃崟鍒楄〃鏍�")
     @GetMapping(value = "/roleMenuTreeselect/{roleId}")
-    public AjaxResult<Map<String, Object>> roleMenuTreeselect(@PathVariable("roleId") Long roleId) {
+    public AjaxResult<Map<String, Object>> roleMenuTreeselect(@ApiParam("瑙掕壊ID") @PathVariable("roleId") Long roleId) {
         List<SysMenu> menus = menuService.selectMenuList(getUserId());
         Map<String, Object> ajax = new HashMap<>();
         ajax.put("checkedKeys", menuService.selectMenuListByRoleId(roleId));
@@ -120,7 +121,7 @@
     @SaCheckPermission("system:menu:remove")
     @Log(title = "鑿滃崟绠$悊", businessType = BusinessType.DELETE)
     @DeleteMapping("/{menuId}")
-    public AjaxResult<Void> remove(@PathVariable("menuId") Long menuId) {
+    public AjaxResult<Void> remove(@ApiParam("鑿滃崟ID") @PathVariable("menuId") Long menuId) {
         if (menuService.hasChildByMenuId(menuId)) {
             return AjaxResult.error("瀛樺湪瀛愯彍鍗�,涓嶅厑璁稿垹闄�");
         }
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysNoticeController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysNoticeController.java
index 9414e5d..31ed439 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysNoticeController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysNoticeController.java
@@ -13,6 +13,7 @@
 import org.springframework.web.bind.annotation.*;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
 import lombok.RequiredArgsConstructor;
 
 /**
@@ -45,7 +46,7 @@
     @ApiOperation("鏍规嵁閫氱煡鍏憡缂栧彿鑾峰彇璇︾粏淇℃伅")
     @SaCheckPermission("system:notice:query")
     @GetMapping(value = "/{noticeId}")
-    public AjaxResult<SysNotice> getInfo(@PathVariable Long noticeId) {
+    public AjaxResult<SysNotice> getInfo(@ApiParam("鍏憡ID") @PathVariable Long noticeId) {
         return AjaxResult.success(noticeService.selectNoticeById(noticeId));
     }
 
@@ -78,7 +79,7 @@
     @SaCheckPermission("system:notice:remove")
     @Log(title = "閫氱煡鍏憡", businessType = BusinessType.DELETE)
     @DeleteMapping("/{noticeIds}")
-    public AjaxResult<Void> remove(@PathVariable Long[] noticeIds) {
+    public AjaxResult<Void> remove(@ApiParam("鍏憡ID涓�") @PathVariable Long[] noticeIds) {
         return toAjax(noticeService.deleteNoticeByIds(noticeIds));
     }
 }
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysOssConfigController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysOssConfigController.java
index 6fa75be..18dfd51 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysOssConfigController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysOssConfigController.java
@@ -15,6 +15,7 @@
 import com.ruoyi.system.service.ISysOssConfigService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
 import lombok.RequiredArgsConstructor;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.validation.annotation.Validated;
@@ -56,7 +57,8 @@
     @ApiOperation("鑾峰彇瀵硅薄瀛樺偍閰嶇疆璇︾粏淇℃伅")
     @SaCheckPermission("system:oss:query")
     @GetMapping("/{ossConfigId}")
-    public AjaxResult<SysOssConfigVo> getInfo(@NotNull(message = "涓婚敭涓嶈兘涓虹┖")
+    public AjaxResult<SysOssConfigVo> getInfo(@ApiParam("OSS閰嶇疆ID")
+                                              @NotNull(message = "涓婚敭涓嶈兘涓虹┖")
                                               @PathVariable("ossConfigId") Integer ossConfigId) {
         return AjaxResult.success(iSysOssConfigService.queryById(ossConfigId));
     }
@@ -92,7 +94,8 @@
     @SaCheckPermission("system:oss:remove")
     @Log(title = "瀵硅薄瀛樺偍閰嶇疆", businessType = BusinessType.DELETE)
     @DeleteMapping("/{ossConfigIds}")
-    public AjaxResult<Void> remove(@NotEmpty(message = "涓婚敭涓嶈兘涓虹┖")
+    public AjaxResult<Void> remove(@ApiParam("OSS閰嶇疆ID涓�")
+                                   @NotEmpty(message = "涓婚敭涓嶈兘涓虹┖")
                                    @PathVariable Long[] ossConfigIds) {
         return toAjax(iSysOssConfigService.deleteWithValidByIds(Arrays.asList(ossConfigIds), true) ? 1 : 0);
     }
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysOssController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysOssController.java
index 24c1588..5d229c8 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysOssController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysOssController.java
@@ -17,17 +17,14 @@
 import com.ruoyi.common.exception.ServiceException;
 import com.ruoyi.common.utils.JsonUtils;
 import com.ruoyi.common.utils.file.FileUtils;
-import com.ruoyi.oss.constant.CloudConstant;
+import com.ruoyi.oss.constant.OssConstant;
 import com.ruoyi.system.domain.SysConfig;
 import com.ruoyi.system.domain.SysOss;
 import com.ruoyi.system.domain.bo.SysOssBo;
 import com.ruoyi.system.domain.vo.SysOssVo;
 import com.ruoyi.system.service.ISysConfigService;
 import com.ruoyi.system.service.ISysOssService;
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiImplicitParam;
-import io.swagger.annotations.ApiImplicitParams;
-import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.*;
 import lombok.RequiredArgsConstructor;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.MediaType;
@@ -37,6 +34,7 @@
 
 import javax.servlet.http.HttpServletResponse;
 import javax.validation.constraints.NotEmpty;
+import java.io.File;
 import java.io.IOException;
 import java.util.Arrays;
 import java.util.HashMap;
@@ -72,7 +70,7 @@
      */
     @ApiOperation("涓婁紶OSS瀵硅薄瀛樺偍")
     @ApiImplicitParams({
-            @ApiImplicitParam(name = "file", value = "鏂囦欢", dataType = "java.io.File", required = true),
+        @ApiImplicitParam(name = "file", value = "鏂囦欢", dataTypeClass = File.class, required = true),
     })
     @SaCheckPermission("system:oss:upload")
     @Log(title = "OSS瀵硅薄瀛樺偍", businessType = BusinessType.INSERT)
@@ -92,7 +90,7 @@
     @ApiOperation("涓嬭浇OSS瀵硅薄瀛樺偍")
     @SaCheckPermission("system:oss:download")
     @GetMapping("/download/{ossId}")
-    public void download(@PathVariable Long ossId, HttpServletResponse response) throws IOException {
+    public void download(@ApiParam("OSS瀵硅薄ID") @PathVariable Long ossId, HttpServletResponse response) throws IOException {
         SysOss sysOss = iSysOssService.getById(ossId);
         if (ObjectUtil.isNull(sysOss)) {
             throw new ServiceException("鏂囦欢鏁版嵁涓嶅瓨鍦�!");
@@ -120,7 +118,8 @@
     @SaCheckPermission("system:oss:remove")
     @Log(title = "OSS瀵硅薄瀛樺偍", businessType = BusinessType.DELETE)
     @DeleteMapping("/{ossIds}")
-    public AjaxResult<Void> remove(@NotEmpty(message = "涓婚敭涓嶈兘涓虹┖")
+    public AjaxResult<Void> remove(@ApiParam("OSS瀵硅薄ID涓�")
+                                   @NotEmpty(message = "涓婚敭涓嶈兘涓虹┖")
                                    @PathVariable Long[] ossIds) {
         return toAjax(iSysOssService.deleteWithValidByIds(Arrays.asList(ossIds), true) ? 1 : 0);
     }
@@ -135,7 +134,7 @@
     public AjaxResult<Void> changePreviewListResource(@RequestBody String body) {
         Map<String, Boolean> map = JsonUtils.parseMap(body);
         SysConfig config = iSysConfigService.getOne(new LambdaQueryWrapper<SysConfig>()
-                .eq(SysConfig::getConfigKey, CloudConstant.PEREVIEW_LIST_RESOURCE_KEY));
+            .eq(SysConfig::getConfigKey, OssConstant.PEREVIEW_LIST_RESOURCE_KEY));
         config.setConfigValue(map.get("previewListResource").toString());
         return toAjax(iSysConfigService.updateConfig(config));
     }
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysPostController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysPostController.java
index 3ca73fd..b41d75b 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysPostController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysPostController.java
@@ -12,6 +12,7 @@
 import com.ruoyi.system.service.ISysPostService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
 import lombok.RequiredArgsConstructor;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.validation.annotation.Validated;
@@ -47,7 +48,7 @@
     @ApiOperation("瀵煎嚭宀椾綅鍒楄〃")
     @Log(title = "宀椾綅绠$悊", businessType = BusinessType.EXPORT)
     @SaCheckPermission("system:post:export")
-    @GetMapping("/export")
+    @PostMapping("/export")
     public void export(SysPost post, HttpServletResponse response) {
         List<SysPost> list = postService.selectPostList(post);
         ExcelUtil.exportExcel(list, "宀椾綅鏁版嵁", SysPost.class, response);
@@ -59,7 +60,7 @@
     @ApiOperation("鏍规嵁宀椾綅缂栧彿鑾峰彇璇︾粏淇℃伅")
     @SaCheckPermission("system:post:query")
     @GetMapping(value = "/{postId}")
-    public AjaxResult<SysPost> getInfo(@PathVariable Long postId) {
+    public AjaxResult<SysPost> getInfo(@ApiParam("宀椾綅ID") @PathVariable Long postId) {
         return AjaxResult.success(postService.selectPostById(postId));
     }
 
@@ -102,7 +103,7 @@
     @SaCheckPermission("system:post:remove")
     @Log(title = "宀椾綅绠$悊", businessType = BusinessType.DELETE)
     @DeleteMapping("/{postIds}")
-    public AjaxResult<Void> remove(@PathVariable Long[] postIds) {
+    public AjaxResult<Void> remove(@ApiParam("宀椾綅ID涓�") @PathVariable Long[] postIds) {
         return toAjax(postService.deletePostByIds(postIds));
     }
 
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysProfileController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysProfileController.java
index 71d9de2..50ba930 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysProfileController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysProfileController.java
@@ -18,6 +18,7 @@
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.multipart.MultipartFile;
 
+import java.io.File;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -43,7 +44,7 @@
     @GetMapping
     public AjaxResult<Map<String, Object>> profile() {
         SysUser user = userService.getById(getUserId());
-		Map<String,Object> ajax = new HashMap<>();
+		Map<String, Object> ajax = new HashMap<>();
 		ajax.put("user", user);
         ajax.put("roleGroup", userService.selectUserRoleGroup(user.getUserName()));
         ajax.put("postGroup", userService.selectUserPostGroup(user.getUserName()));
@@ -66,6 +67,7 @@
             return AjaxResult.error("淇敼鐢ㄦ埛'" + user.getUserName() + "'澶辫触锛岄偖绠辫处鍙峰凡瀛樺湪");
         }
         user.setUserId(getUserId());
+        user.setUserName(null);
         user.setPassword(null);
         if (userService.updateUserProfile(user) > 0) {
             return AjaxResult.success();
@@ -77,6 +79,10 @@
      * 閲嶇疆瀵嗙爜
      */
     @ApiOperation("閲嶇疆瀵嗙爜")
+    @ApiImplicitParams({
+        @ApiImplicitParam(name = "oldPassword", value = "鏃у瘑鐮�", paramType = "query", dataTypeClass = String.class),
+        @ApiImplicitParam(name = "newPassword", value = "鏂板瘑鐮�", paramType = "query", dataTypeClass = String.class)
+    })
     @Log(title = "涓汉淇℃伅", businessType = BusinessType.UPDATE)
     @PutMapping("/updatePwd")
     public AjaxResult<Void> updatePwd(String oldPassword, String newPassword) {
@@ -100,7 +106,7 @@
      */
     @ApiOperation("澶村儚涓婁紶")
     @ApiImplicitParams({
-            @ApiImplicitParam(name = "file", value = "鐢ㄦ埛澶村儚", dataType = "java.io.File", required = true),
+        @ApiImplicitParam(name = "avatarfile", value = "鐢ㄦ埛澶村儚", dataTypeClass = File.class, required = true),
     })
     @Log(title = "鐢ㄦ埛澶村儚", businessType = BusinessType.UPDATE)
     @PostMapping("/avatar")
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysRoleController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysRoleController.java
index f1d7e77..2a33918 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysRoleController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysRoleController.java
@@ -13,8 +13,7 @@
 import com.ruoyi.system.domain.SysUserRole;
 import com.ruoyi.system.service.ISysRoleService;
 import com.ruoyi.system.service.ISysUserService;
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.*;
 import lombok.RequiredArgsConstructor;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.validation.annotation.Validated;
@@ -48,7 +47,7 @@
     @ApiOperation("瀵煎嚭瑙掕壊淇℃伅鍒楄〃")
     @Log(title = "瑙掕壊绠$悊", businessType = BusinessType.EXPORT)
     @SaCheckPermission("system:role:export")
-    @GetMapping("/export")
+    @PostMapping("/export")
     public void export(SysRole role, HttpServletResponse response) {
         List<SysRole> list = roleService.selectRoleList(role);
         ExcelUtil.exportExcel(list, "瑙掕壊鏁版嵁", SysRole.class, response);
@@ -60,7 +59,7 @@
     @ApiOperation("鏍规嵁瑙掕壊缂栧彿鑾峰彇璇︾粏淇℃伅")
     @SaCheckPermission("system:role:query")
     @GetMapping(value = "/{roleId}")
-    public AjaxResult<SysRole> getInfo(@PathVariable Long roleId) {
+    public AjaxResult<SysRole> getInfo(@ApiParam("瑙掕壊ID") @PathVariable Long roleId) {
         roleService.checkRoleDataScope(roleId);
         return AjaxResult.success(roleService.selectRoleById(roleId));
     }
@@ -134,7 +133,7 @@
     @SaCheckPermission("system:role:remove")
     @Log(title = "瑙掕壊绠$悊", businessType = BusinessType.DELETE)
     @DeleteMapping("/{roleIds}")
-    public AjaxResult<Void> remove(@PathVariable Long[] roleIds) {
+    public AjaxResult<Void> remove(@ApiParam("宀椾綅ID涓�") @PathVariable Long[] roleIds) {
         return toAjax(roleService.deleteRoleByIds(roleIds));
     }
 
@@ -183,6 +182,10 @@
      * 鎵归噺鍙栨秷鎺堟潈鐢ㄦ埛
      */
     @ApiOperation("鎵归噺鍙栨秷鎺堟潈鐢ㄦ埛")
+    @ApiImplicitParams({
+        @ApiImplicitParam(name = "roleId", value = "瑙掕壊ID", paramType = "query", dataTypeClass = String.class),
+        @ApiImplicitParam(name = "userIds", value = "鐢ㄦ埛ID涓�", paramType = "query", dataTypeClass = String.class)
+    })
     @SaCheckPermission("system:role:edit")
     @Log(title = "瑙掕壊绠$悊", businessType = BusinessType.GRANT)
     @PutMapping("/authUser/cancelAll")
@@ -194,6 +197,10 @@
      * 鎵归噺閫夋嫨鐢ㄦ埛鎺堟潈
      */
     @ApiOperation("鎵归噺閫夋嫨鐢ㄦ埛鎺堟潈")
+    @ApiImplicitParams({
+        @ApiImplicitParam(name = "roleId", value = "瑙掕壊ID", paramType = "query", dataTypeClass = String.class),
+        @ApiImplicitParam(name = "userIds", value = "鐢ㄦ埛ID涓�", paramType = "query", dataTypeClass = String.class)
+    })
     @SaCheckPermission("system:role:edit")
     @Log(title = "瑙掕壊绠$悊", businessType = BusinessType.GRANT)
     @PutMapping("/authUser/selectAll")
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java
index b7328d6..bd77f61 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java
@@ -13,18 +13,17 @@
 import com.ruoyi.common.core.domain.entity.SysUser;
 import com.ruoyi.common.core.page.TableDataInfo;
 import com.ruoyi.common.enums.BusinessType;
+import com.ruoyi.common.excel.ExcelResult;
 import com.ruoyi.common.utils.SecurityUtils;
 import com.ruoyi.common.utils.StringUtils;
 import com.ruoyi.common.utils.poi.ExcelUtil;
 import com.ruoyi.system.domain.vo.SysUserExportVo;
 import com.ruoyi.system.domain.vo.SysUserImportVo;
+import com.ruoyi.system.listener.SysUserImportListener;
 import com.ruoyi.system.service.ISysPostService;
 import com.ruoyi.system.service.ISysRoleService;
 import com.ruoyi.system.service.ISysUserService;
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiImplicitParam;
-import io.swagger.annotations.ApiImplicitParams;
-import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.*;
 import lombok.RequiredArgsConstructor;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.validation.annotation.Validated;
@@ -67,7 +66,7 @@
     @ApiOperation("瀵煎嚭鐢ㄦ埛鍒楄〃")
     @Log(title = "鐢ㄦ埛绠$悊", businessType = BusinessType.EXPORT)
     @SaCheckPermission("system:user:export")
-    @GetMapping("/export")
+    @PostMapping("/export")
     public void export(SysUser user, HttpServletResponse response) {
         List<SysUser> list = userService.selectUserList(user);
         List<SysUserExportVo> listVo = BeanUtil.copyToList(list, SysUserExportVo.class);
@@ -90,15 +89,12 @@
     @SaCheckPermission("system:user:import")
     @PostMapping("/importData")
     public AjaxResult<Void> importData(@RequestPart("file") MultipartFile file, boolean updateSupport) throws Exception {
-		List<SysUserImportVo> userListVo = ExcelUtil.importExcel(file.getInputStream(), SysUserImportVo.class);
-		List<SysUser> userList = BeanUtil.copyToList(userListVo, SysUser.class);
-        String operName = userService.getById(getUserId()).getUserName();
-        String message = userService.importUser(userList, updateSupport, operName);
-        return AjaxResult.success(message);
+        ExcelResult<SysUserImportVo> result = ExcelUtil.importExcel(file.getInputStream(), SysUserImportVo.class, new SysUserImportListener(updateSupport));
+        return AjaxResult.success(result.getAnalysis());
     }
 
     @ApiOperation("涓嬭浇瀵煎叆妯℃澘")
-    @GetMapping("/importTemplate")
+    @PostMapping("/importTemplate")
     public void importTemplate(HttpServletResponse response) {
         ExcelUtil.exportExcel(new ArrayList<>(), "鐢ㄦ埛鏁版嵁", SysUserImportVo.class, response);
     }
@@ -109,7 +105,7 @@
     @ApiOperation("鏍规嵁鐢ㄦ埛缂栧彿鑾峰彇璇︾粏淇℃伅")
     @SaCheckPermission("system:user:query")
     @GetMapping(value = {"/", "/{userId}" })
-    public AjaxResult<Map<String, Object>> getInfo(@PathVariable(value = "userId", required = false) Long userId) {
+    public AjaxResult<Map<String, Object>> getInfo(@ApiParam("鐢ㄦ埛ID") @PathVariable(value = "userId", required = false) Long userId) {
 		userService.checkUserDataScope(userId);
         Map<String, Object> ajax = new HashMap<>();
         List<SysRole> roles = roleService.selectRoleAll();
@@ -170,7 +166,7 @@
     @SaCheckPermission("system:user:remove")
     @Log(title = "鐢ㄦ埛绠$悊", businessType = BusinessType.DELETE)
     @DeleteMapping("/{userIds}")
-    public AjaxResult<Void> remove(@PathVariable Long[] userIds) {
+    public AjaxResult<Void> remove(@ApiParam("瑙掕壊ID涓�") @PathVariable Long[] userIds) {
         if (ArrayUtil.contains(userIds, getUserId())) {
             return error("褰撳墠鐢ㄦ埛涓嶈兘鍒犻櫎");
         }
@@ -208,7 +204,7 @@
     @ApiOperation("鏍规嵁鐢ㄦ埛缂栧彿鑾峰彇鎺堟潈瑙掕壊")
     @SaCheckPermission("system:user:query")
     @GetMapping("/authRole/{userId}")
-    public AjaxResult<Map<String, Object>> authRole(@PathVariable("userId") Long userId) {
+    public AjaxResult<Map<String, Object>> authRole(@ApiParam("鐢ㄦ埛ID") @PathVariable("userId") Long userId) {
         SysUser user = userService.selectUserById(userId);
         List<SysRole> roles = roleService.selectRolesByUserId(userId);
         Map<String, Object> ajax = new HashMap<>();
@@ -221,6 +217,10 @@
      * 鐢ㄦ埛鎺堟潈瑙掕壊
      */
     @ApiOperation("鐢ㄦ埛鎺堟潈瑙掕壊")
+    @ApiImplicitParams({
+        @ApiImplicitParam(name = "userId", value = "鐢ㄦ埛Id", paramType = "query", dataTypeClass = String.class),
+        @ApiImplicitParam(name = "roleIds", value = "瑙掕壊ID涓�", paramType = "query", dataTypeClass = String.class)
+    })
     @SaCheckPermission("system:user:edit")
     @Log(title = "鐢ㄦ埛绠$悊", businessType = BusinessType.GRANT)
     @PutMapping("/authRole")
diff --git a/ruoyi-admin/src/main/resources/application-prod.yml b/ruoyi-admin/src/main/resources/application-prod.yml
index 9aac0e3..1d680d7 100644
--- a/ruoyi-admin/src/main/resources/application-prod.yml
+++ b/ruoyi-admin/src/main/resources/application-prod.yml
@@ -1,3 +1,10 @@
+--- # 閰嶇疆涓存椂璺緞瀛樺偍
+spring:
+  servlet:
+    multipart:
+      # 涓存椂鏂囦欢瀛樺偍浣嶇疆 閬垮厤涓存椂鏂囦欢琚郴缁熸竻鐞嗘姤閿�
+      location: /ruoyi/server/temp
+
 --- # 鐩戞帶閰嶇疆
 spring:
   boot:
diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml
index 4a0aebc..dbd182f 100644
--- a/ruoyi-admin/src/main/resources/application.yml
+++ b/ruoyi-admin/src/main/resources/application.yml
@@ -10,6 +10,8 @@
   demoEnabled: true
   # 鑾峰彇ip鍦板潃寮�鍏�
   addressEnabled: true
+  # 缂撳瓨鎳掑姞杞�
+  cacheLazy: true
 
 captcha:
   # 椤甸潰 <鍙傛暟璁剧疆> 鍙紑鍚叧闂� 楠岃瘉鐮佹牎楠�
@@ -234,6 +236,22 @@
     - name: 3.浠g爜鐢熸垚妯″潡
       basePackage: com.ruoyi.generator
 
+knife4j:
+  # 鏄惁寮�鍚疜nife4j澧炲己妯″紡
+  enable: true
+  # 鏄惁寮�鍚敓浜х幆澧冧繚鎶ょ瓥鐣�
+  production: @knife4j.production@
+  # 鍓嶇Ui鐨勪釜鎬у寲閰嶇疆灞炴��
+  setting:
+    # 榛樿璇█
+    language: zh-CN
+    # 鏄惁鏄剧ずFooter
+    enableFooter: false
+    # 鏄惁寮�鍚姩鎬佸弬鏁拌皟璇曞姛鑳�
+    enableDynamicParameter: true
+    # 鏄惁鍦ㄦ瘡涓狣ebug璋冭瘯鏍忓悗鏄剧ず鍒锋柊鍙橀噺鎸夐挳
+    enableReloadCacheParameter: true
+
 # 闃叉XSS鏀诲嚮
 xss:
   # 杩囨护寮�鍏�
@@ -261,22 +279,6 @@
   # DISCARD_POLICY 涓㈠純
   # ABORT_POLICY 涓
   rejectedExecutionHandler: CALLER_RUNS_POLICY
-
-# feign 鐩稿叧閰嶇疆
-feign:
-  # 涓嶆敮鎸佸鍖�, 濡傛湁闇�瑕佸彲鍦ㄦ敞瑙i厤缃� 鎴� 鎻愬崌鎵寘绛夌骇
-  # 渚嬪 com.**.**.feign
-  package: com.ruoyi.**.feign
-  # 寮�鍚帇缂�
-  compression:
-    request:
-      enabled: true
-    response:
-      enabled: true
-  okhttp:
-    enabled: true
-  circuitbreaker:
-    enabled: true
 
 --- # redisson 缂撳瓨閰嶇疆
 redisson:
@@ -313,34 +315,3 @@
   endpoint:
     logfile:
       external-file: ./logs/sys-console.log
-
---- # 瀹氭椂浠诲姟閰嶇疆
-spring:
-  quartz:
-    scheduler-name: RuoyiScheduler
-    startup-delay: 1s
-    overwrite-existing-jobs: true
-    auto-startup: true
-    job-store-type: jdbc
-    properties:
-      org:
-        quartz:
-          # Scheduler 鐩稿叧閰嶇疆
-          scheduler:
-            instanceName: RuoyiScheduler
-            instanceId: AUTO
-          # 绾跨▼姹犵浉鍏抽厤缃�
-          threadPool:
-            class: org.quartz.simpl.SimpleThreadPool
-            threadCount: 20
-            threadPriority: 5
-          # JobStore 闆嗙兢閰嶇疆
-          jobStore:
-            class: org.quartz.impl.jdbcjobstore.JobStoreTX
-            isClustered: true
-            clusterCheckinInterval: 15000
-            txIsolationLevelSerializable: true
-            misfireThreshold: 60000
-            tablePrefix: QRTZ_
-            # sqlserver 鍚敤
-            # selectWithLockSQL: SELECT * FROM {0}LOCKS UPDLOCK WHERE LOCK_NAME = ?
diff --git a/ruoyi-admin/src/main/resources/logback.xml b/ruoyi-admin/src/main/resources/logback.xml
index 33a1697..6e3280f 100644
--- a/ruoyi-admin/src/main/resources/logback.xml
+++ b/ruoyi-admin/src/main/resources/logback.xml
@@ -31,7 +31,7 @@
             <level>INFO</level>
         </filter>
     </appender>
-	
+
 	<!-- 绯荤粺鏃ュ織杈撳嚭 -->
 	<appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
 	    <file>${log.path}/sys-info.log</file>
@@ -54,7 +54,7 @@
             <onMismatch>DENY</onMismatch>
         </filter>
 	</appender>
-	
+
 	<appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
 	    <file>${log.path}/sys-error.log</file>
         <!-- 寰幆鏀跨瓥锛氬熀浜庢椂闂村垱寤烘棩蹇楁枃浠� -->
@@ -76,21 +76,7 @@
             <onMismatch>DENY</onMismatch>
         </filter>
     </appender>
-	
-	<!-- 鐢ㄦ埛璁块棶鏃ュ織杈撳嚭  -->
-    <appender name="sys-user" class="ch.qos.logback.core.rolling.RollingFileAppender">
-		<file>${log.path}/sys-user.log</file>
-        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
-            <!-- 鎸夊ぉ鍥炴粴 daily -->
-            <fileNamePattern>${log.path}/sys-user.%d{yyyy-MM-dd}.log</fileNamePattern>
-            <!-- 鏃ュ織鏈�澶х殑鍘嗗彶 60澶� -->
-            <maxHistory>60</maxHistory>
-        </rollingPolicy>
-        <encoder class="com.yomahub.tlog.core.enhance.logback.AspectLogbackEncoder">
-            <pattern>${log.pattern}</pattern>
-        </encoder>
-    </appender>
-	
+
 	<!-- 绯荤粺妯″潡鏃ュ織绾у埆鎺у埗  -->
 	<logger name="com.ruoyi" level="info" />
 	<!-- Spring鏃ュ織绾у埆鎺у埗  -->
@@ -99,16 +85,12 @@
 	<root level="info">
 		<appender-ref ref="console" />
 	</root>
-	
+
 	<!--绯荤粺鎿嶄綔鏃ュ織-->
     <root level="info">
         <appender-ref ref="file_info" />
         <appender-ref ref="file_error" />
         <appender-ref ref="file_console" />
     </root>
-	
-	<!--绯荤粺鐢ㄦ埛鎿嶄綔鏃ュ織-->
-    <logger name="sys-user" level="info">
-        <appender-ref ref="sys-user"/>
-    </logger>
-</configuration> 
\ No newline at end of file
+
+</configuration>
diff --git a/ruoyi-admin/src/main/resources/spy.properties b/ruoyi-admin/src/main/resources/spy.properties
index 0ed983b..918f1cb 100644
--- a/ruoyi-admin/src/main/resources/spy.properties
+++ b/ruoyi-admin/src/main/resources/spy.properties
@@ -22,5 +22,3 @@
 outagedetectioninterval=2
 # 鏄惁杩囨护 Log
 filter=true
-# 杩囨护 Log 鏃舵墍鎺掗櫎鐨勮〃鍚嶅垪琛紝浠ラ�楀彿鍒嗛殧
-exclude=QRTZ_
diff --git a/ruoyi-common/pom.xml b/ruoyi-common/pom.xml
index a033c7f..fa3bbc8 100644
--- a/ruoyi-common/pom.xml
+++ b/ruoyi-common/pom.xml
@@ -87,18 +87,6 @@
             <artifactId>jaxb-impl</artifactId>
         </dependency>
 
-        <!-- redis 缂撳瓨鎿嶄綔 -->
-        <dependency>
-            <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter-data-redis</artifactId>
-        </dependency>
-
-        <!-- pool 瀵硅薄姹� -->
-        <dependency>
-            <groupId>org.apache.commons</groupId>
-            <artifactId>commons-pool2</artifactId>
-        </dependency>
-
         <!-- servlet鍖� -->
         <dependency>
             <groupId>javax.servlet</groupId>
@@ -120,18 +108,6 @@
         <dependency>
             <groupId>org.projectlombok</groupId>
             <artifactId>lombok</artifactId>
-        </dependency>
-
-        <!-- @deprecated 鐢变簬浣跨敤浜烘暟杈冨皯 鍐冲畾涓� 3.4.0 鐗堟湰绉婚櫎 -->
-        <dependency>
-            <groupId>org.springframework.cloud</groupId>
-            <artifactId>spring-cloud-starter-openfeign</artifactId>
-        </dependency>
-
-        <!-- @deprecated 鐢变簬浣跨敤浜烘暟杈冨皯 鍐冲畾涓� 3.4.0 鐗堟湰绉婚櫎 -->
-        <dependency>
-            <groupId>io.github.openfeign</groupId>
-            <artifactId>feign-okhttp</artifactId>
         </dependency>
 
         <dependency>
@@ -180,10 +156,6 @@
             <artifactId>tlog-webroot</artifactId>
         </dependency>
 
-        <dependency>
-            <groupId>com.yomahub</groupId>
-            <artifactId>tlog-feign</artifactId>
-        </dependency>
     </dependencies>
 
 </project>
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/config/RuoYiConfig.java b/ruoyi-common/src/main/java/com/ruoyi/common/config/RuoYiConfig.java
index 9343a4a..bcfc677 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/config/RuoYiConfig.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/config/RuoYiConfig.java
@@ -39,6 +39,11 @@
     private boolean demoEnabled;
 
     /**
+     * 缂撳瓨鎳掑姞杞�
+     */
+    private boolean cacheLazy;
+
+    /**
      * 鑾峰彇鍦板潃寮�鍏�
      */
     @Getter
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 b41f5d7..fc1137b 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
@@ -106,13 +106,4 @@
      */
     public static final String SYS_DICT_KEY = "sys_dict:";
 
-    /**
-     * RMI 杩滅▼鏂规硶璋冪敤
-     */
-    public static final String LOOKUP_RMI = "rmi://";
-
-    /**
-     * LDAP 杩滅▼鏂规硶璋冪敤
-     */
-    public static final String LOOKUP_LDAP = "ldap://";
 }
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/constant/ScheduleConstants.java b/ruoyi-common/src/main/java/com/ruoyi/common/constant/ScheduleConstants.java
deleted file mode 100644
index ec430c2..0000000
--- a/ruoyi-common/src/main/java/com/ruoyi/common/constant/ScheduleConstants.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package com.ruoyi.common.constant;
-
-/**
- * 浠诲姟璋冨害閫氱敤甯搁噺
- *
- * @deprecated 3.4.0鍒犻櫎 杩佺Щ鑷硏xl-job
- * @author ruoyi
- */
-public class ScheduleConstants
-{
-    public static final String TASK_CLASS_NAME = "TASK_CLASS_NAME";
-
-    /** 鎵ц鐩爣key */
-    public static final String TASK_PROPERTIES = "TASK_PROPERTIES";
-
-    /** 榛樿 */
-    public static final String MISFIRE_DEFAULT = "0";
-
-    /** 绔嬪嵆瑙﹀彂鎵ц */
-    public static final String MISFIRE_IGNORE_MISFIRES = "1";
-
-    /** 瑙﹀彂涓�娆℃墽琛� */
-    public static final String MISFIRE_FIRE_AND_PROCEED = "2";
-
-    /** 涓嶈Е鍙戠珛鍗虫墽琛� */
-    public static final String MISFIRE_DO_NOTHING = "3";
-
-    public enum Status
-    {
-        /**
-         * 姝e父
-         */
-        NORMAL("0"),
-        /**
-         * 鏆傚仠
-         */
-        PAUSE("1");
-
-        private String value;
-
-        private Status(String value)
-        {
-            this.value = value;
-        }
-
-        public String getValue()
-        {
-            return value;
-        }
-    }
-}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/convert/ExcelDictConvert.java b/ruoyi-common/src/main/java/com/ruoyi/common/convert/ExcelDictConvert.java
index 58560d0..7c4d631 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/convert/ExcelDictConvert.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/convert/ExcelDictConvert.java
@@ -8,8 +8,10 @@
 import com.alibaba.excel.metadata.GlobalConfiguration;
 import com.alibaba.excel.metadata.property.ExcelContentProperty;
 import com.ruoyi.common.annotation.ExcelDictFormat;
+import com.ruoyi.common.core.service.DictService;
 import com.ruoyi.common.utils.StringUtils;
 import com.ruoyi.common.utils.poi.ExcelUtil;
+import com.ruoyi.common.utils.spring.SpringUtils;
 import lombok.extern.slf4j.Slf4j;
 
 import java.lang.reflect.Field;
@@ -41,7 +43,7 @@
 		if (StringUtils.isBlank(type)) {
 			value = ExcelUtil.reverseByExp(label, anno.readConverterExp(), anno.separator());
 		} else {
-			value = ExcelUtil.reverseDictByExp(label, type, anno.separator());
+			value = SpringUtils.getBean(DictService.class).getDictValue(type, label, anno.separator());
 		}
 		return Convert.convert(contentProperty.getField().getType(), value);
 	}
@@ -58,7 +60,7 @@
 		if (StringUtils.isBlank(type)) {
 			label = ExcelUtil.convertByExp(value, anno.readConverterExp(), anno.separator());
 		} else {
-			label = ExcelUtil.convertDictByExp(value, type, anno.separator());
+			label = SpringUtils.getBean(DictService.class).getDictLabel(type, value, anno.separator());
 		}
 		return new CellData<>(label);
 	}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/TreeSelect.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/TreeSelect.java
deleted file mode 100644
index 963ac5c..0000000
--- a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/TreeSelect.java
+++ /dev/null
@@ -1,67 +0,0 @@
-package com.ruoyi.common.core.domain;
-
-import com.fasterxml.jackson.annotation.JsonInclude;
-import com.ruoyi.common.core.domain.entity.SysDept;
-import com.ruoyi.common.core.domain.entity.SysMenu;
-import io.swagger.annotations.ApiModel;
-import io.swagger.annotations.ApiModelProperty;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-import lombok.experimental.Accessors;
-
-import java.io.Serializable;
-import java.util.List;
-import java.util.stream.Collectors;
-
-/**
- * Treeselect鏍戠粨鏋勫疄浣撶被
- *
- * @author Lion Li
- */
-
-@Data
-@NoArgsConstructor
-@Accessors(chain = true)
-@ApiModel("鏍戠粨鏋勫疄浣撶被")
-public class TreeSelect implements Serializable {
-
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * 鑺傜偣ID
-     */
-    @ApiModelProperty(value = "鑺傜偣ID")
-    private Long id;
-
-    /**
-     * 鑺傜偣鍚嶇О
-     */
-    @ApiModelProperty(value = "鑺傜偣鍚嶇О")
-    private String label;
-
-    /**
-     * 瀛愯妭鐐�
-     */
-    @ApiModelProperty(value = "瀛愯妭鐐�")
-    @JsonInclude(JsonInclude.Include.NON_EMPTY)
-    private List<TreeSelect> children;
-
-    public TreeSelect(SysDept dept) {
-        this.id = dept.getDeptId();
-        this.label = dept.getDeptName();
-        this.children = dept.getChildren()
-                .stream()
-                .map(d -> new TreeSelect((SysDept) d))
-                .collect(Collectors.toList());
-    }
-
-    public TreeSelect(SysMenu menu) {
-        this.id = menu.getMenuId();
-        this.label = menu.getMenuName();
-        this.children = menu.getChildren()
-                .stream()
-                .map(d -> new TreeSelect((SysMenu) d))
-                .collect(Collectors.toList());
-    }
-
-}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/mybatisplus/cache/MybatisPlusRedisCache.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/mybatisplus/cache/MybatisPlusRedisCache.java
deleted file mode 100644
index c790c66..0000000
--- a/ruoyi-common/src/main/java/com/ruoyi/common/core/mybatisplus/cache/MybatisPlusRedisCache.java
+++ /dev/null
@@ -1,91 +0,0 @@
-package com.ruoyi.common.core.mybatisplus.cache;
-
-import cn.hutool.extra.spring.SpringUtil;
-import com.ruoyi.common.utils.RedisUtils;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.ibatis.cache.Cache;
-import org.springframework.data.redis.connection.RedisServerCommands;
-import org.springframework.data.redis.core.RedisTemplate;
-import org.springframework.util.CollectionUtils;
-
-import java.util.Collection;
-import java.util.concurrent.locks.ReadWriteLock;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
-
-/**
- * mybatis-redis 浜岀骇缂撳瓨
- *
- * 浣跨敤鏂规硶 閰嶇疆鏂囦欢寮�鍚� mybatis-plus 浜岀骇缂撳瓨
- * 鍦� XxxMapper.java 绫讳笂娣诲姞娉ㄨВ @CacheNamespace(implementation = MybatisPlusRedisCache.class, eviction = MybatisPlusRedisCache.class)
- *
- * @deprecated 3.4.0鍒犻櫎 鎺ㄨ崘浣跨敤spirng-cache
- * @author Lion Li
- */
-@Slf4j
-public class MybatisPlusRedisCache implements Cache {
-
-	private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock(true);
-
-	private String id;
-
-	public MybatisPlusRedisCache(final String id) {
-		if (id == null) {
-			throw new IllegalArgumentException("Cache instances require an ID");
-		}
-		this.id = id;
-	}
-
-	@Override
-	public String getId() {
-		return this.id;
-	}
-
-	@Override
-	public void putObject(Object key, Object value) {
-		if (value != null) {
-			RedisUtils.setCacheObject(key.toString(), value);
-		}
-	}
-
-	@Override
-	public Object getObject(Object key) {
-		try {
-			if (key != null) {
-				return RedisUtils.getCacheObject(key.toString());
-			}
-		} catch (Exception e) {
-			e.printStackTrace();
-			log.error("缂撳瓨鍑洪敊");
-		}
-		return null;
-	}
-
-	@Override
-	public Object removeObject(Object key) {
-		if (key != null) {
-			RedisUtils.deleteObject(key.toString());
-		}
-		return null;
-	}
-
-	@Override
-	public void clear() {
-		log.debug("娓呯┖缂撳瓨");
-		Collection<String> keys = RedisUtils.keys("*:" + this.id + "*");
-		if (!CollectionUtils.isEmpty(keys)) {
-			RedisUtils.deleteObject(keys);
-		}
-	}
-
-	@Override
-	public int getSize() {
-		RedisTemplate<String, Object> redisTemplate = SpringUtil.getBean("redisTemplate");
-		Long size = redisTemplate.execute(RedisServerCommands::dbSize);
-		return size.intValue();
-	}
-
-	@Override
-	public ReadWriteLock getReadWriteLock() {
-		return this.readWriteLock;
-	}
-}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/service/ConfigService.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/service/ConfigService.java
new file mode 100644
index 0000000..c6badf6
--- /dev/null
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/service/ConfigService.java
@@ -0,0 +1,18 @@
+package com.ruoyi.common.core.service;
+
+/**
+ * 閫氱敤 鍙傛暟閰嶇疆鏈嶅姟
+ *
+ * @author Lion Li
+ */
+public interface ConfigService {
+
+    /**
+     * 鏍规嵁鍙傛暟 key 鑾峰彇鍙傛暟鍊�
+     *
+     * @param configKey 鍙傛暟 key
+     * @return 鍙傛暟鍊�
+     */
+    String getConfigValue(String configKey);
+
+}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/service/DictService.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/service/DictService.java
new file mode 100644
index 0000000..b334c82
--- /dev/null
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/service/DictService.java
@@ -0,0 +1,57 @@
+package com.ruoyi.common.core.service;
+
+/**
+ * 閫氱敤 瀛楀吀鏈嶅姟
+ *
+ * @author Lion Li
+ */
+public interface DictService {
+
+    /**
+     * 鍒嗛殧绗�
+     */
+    String SEPARATOR = ",";
+
+    /**
+     * 鏍规嵁瀛楀吀绫诲瀷鍜屽瓧鍏稿�艰幏鍙栧瓧鍏告爣绛�
+     *
+     * @param dictType  瀛楀吀绫诲瀷
+     * @param dictValue 瀛楀吀鍊�
+     * @return 瀛楀吀鏍囩
+     */
+    default String getDictLabel(String dictType, String dictValue) {
+        return getDictLabel(dictType, dictValue, SEPARATOR);
+    }
+
+    /**
+     * 鏍规嵁瀛楀吀绫诲瀷鍜屽瓧鍏告爣绛捐幏鍙栧瓧鍏稿��
+     *
+     * @param dictType  瀛楀吀绫诲瀷
+     * @param dictLabel 瀛楀吀鏍囩
+     * @return 瀛楀吀鍊�
+     */
+    default String getDictValue(String dictType, String dictLabel) {
+        return getDictValue(dictType, dictLabel, SEPARATOR);
+    }
+
+    /**
+     * 鏍规嵁瀛楀吀绫诲瀷鍜屽瓧鍏稿�艰幏鍙栧瓧鍏告爣绛�
+     *
+     * @param dictType  瀛楀吀绫诲瀷
+     * @param dictValue 瀛楀吀鍊�
+     * @param separator 鍒嗛殧绗�
+     * @return 瀛楀吀鏍囩
+     */
+    String getDictLabel(String dictType, String dictValue, String separator);
+
+    /**
+     * 鏍规嵁瀛楀吀绫诲瀷鍜屽瓧鍏告爣绛捐幏鍙栧瓧鍏稿��
+     *
+     * @param dictType  瀛楀吀绫诲瀷
+     * @param dictLabel 瀛楀吀鏍囩
+     * @param separator 鍒嗛殧绗�
+     * @return 瀛楀吀鍊�
+     */
+    String getDictValue(String dictType, String dictLabel, String separator);
+
+}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/service/LogininforService.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/service/LogininforService.java
index 1bf34d5..91aee43 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/core/service/LogininforService.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/service/LogininforService.java
@@ -2,6 +2,11 @@
 
 import javax.servlet.http.HttpServletRequest;
 
+/**
+ * 閫氱敤 绯荤粺璁块棶鏃ュ織
+ *
+ * @author Lion Li
+ */
 public interface LogininforService {
 
     void recordLogininfor(String username, String status, String message,
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/service/OperLogService.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/service/OperLogService.java
index 71e5647..a3b27e6 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/core/service/OperLogService.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/service/OperLogService.java
@@ -3,7 +3,13 @@
 import com.ruoyi.common.core.domain.dto.OperLogDTO;
 import org.springframework.scheduling.annotation.Async;
 
+/**
+ * 閫氱敤 鎿嶄綔鏃ュ織
+ *
+ * @author Lion Li
+ */
 public interface OperLogService {
+
     @Async
     void recordOper(OperLogDTO operLogDTO);
 }
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/excel/DefaultExcelListener.java b/ruoyi-common/src/main/java/com/ruoyi/common/excel/DefaultExcelListener.java
new file mode 100644
index 0000000..f626a5e
--- /dev/null
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/excel/DefaultExcelListener.java
@@ -0,0 +1,108 @@
+package com.ruoyi.common.excel;
+
+import cn.hutool.core.util.StrUtil;
+import com.alibaba.excel.context.AnalysisContext;
+import com.alibaba.excel.event.AnalysisEventListener;
+import com.alibaba.excel.exception.ExcelAnalysisException;
+import com.alibaba.excel.exception.ExcelDataConvertException;
+import com.alibaba.fastjson.JSON;
+import com.ruoyi.common.utils.ValidatorUtils;
+import lombok.NoArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+
+import javax.validation.ConstraintViolation;
+import javax.validation.ConstraintViolationException;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * Excel 瀵煎叆鐩戝惉
+ *
+ * @author Yjoioooo
+ * @author Lion Li
+ */
+@Slf4j
+@NoArgsConstructor
+public class DefaultExcelListener<T> extends AnalysisEventListener<T> implements ExcelListener<T> {
+
+    /**
+     * 鏄惁Validator妫�楠岋紝榛樿涓烘槸
+     */
+    private Boolean isValidate = Boolean.TRUE;
+
+    /**
+     * excel 琛ㄥご鏁版嵁
+     */
+    private Map<Integer, String> headMap;
+
+    /**
+     * 瀵煎叆鍥炴墽
+     */
+    private ExcelResult<T> excelResult;
+
+    public DefaultExcelListener(boolean isValidate) {
+        this.excelResult = new DefautExcelResult<>();
+        this.isValidate = isValidate;
+    }
+
+    /**
+     * 澶勭悊寮傚父
+     *
+     * @param exception ExcelDataConvertException
+     * @param context   Excel 涓婁笅鏂�
+     */
+    @Override
+    public void onException(Exception exception, AnalysisContext context) throws Exception {
+        String errMsg = null;
+        if (exception instanceof ExcelDataConvertException) {
+            // 濡傛灉鏄煇涓�涓崟鍏冩牸鐨勮浆鎹㈠紓甯� 鑳借幏鍙栧埌鍏蜂綋琛屽彿
+            ExcelDataConvertException excelDataConvertException = (ExcelDataConvertException) exception;
+            Integer rowIndex = excelDataConvertException.getRowIndex();
+            Integer columnIndex = excelDataConvertException.getColumnIndex();
+            errMsg = StrUtil.format("绗瑊}琛�-绗瑊}鍒�-琛ㄥご{}: 瑙f瀽寮傚父<br/>",
+                rowIndex + 1, columnIndex + 1, headMap.get(columnIndex));
+            if (log.isDebugEnabled()) {
+                log.error(errMsg);
+            }
+        }
+        if (exception instanceof ConstraintViolationException) {
+            ConstraintViolationException constraintViolationException = (ConstraintViolationException) exception;
+            Set<ConstraintViolation<?>> constraintViolations = constraintViolationException.getConstraintViolations();
+            String constraintViolationsMsg = constraintViolations.stream()
+                .map(ConstraintViolation::getMessage)
+                .collect(Collectors.joining(", "));
+            errMsg = StrUtil.format("绗瑊}琛屾暟鎹牎楠屽紓甯�: {}", context.readRowHolder().getRowIndex() + 1, constraintViolationsMsg);
+            if (log.isDebugEnabled()) {
+                log.error(errMsg);
+            }
+        }
+        excelResult.getErrorList().add(errMsg);
+        throw new ExcelAnalysisException(errMsg);
+    }
+
+    @Override
+    public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
+        this.headMap = headMap;
+        log.debug("瑙f瀽鍒颁竴鏉¤〃澶存暟鎹�: {}", JSON.toJSONString(headMap));
+    }
+
+    @Override
+    public void invoke(T data, AnalysisContext context) {
+        if (isValidate) {
+            ValidatorUtils.validate(data);
+        }
+        excelResult.getList().add(data);
+    }
+
+    @Override
+    public void doAfterAllAnalysed(AnalysisContext context) {
+        log.debug("鎵�鏈夋暟鎹В鏋愬畬鎴愶紒");
+    }
+
+    @Override
+    public ExcelResult<T> getExcelResult() {
+        return excelResult;
+    }
+
+}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/excel/DefautExcelResult.java b/ruoyi-common/src/main/java/com/ruoyi/common/excel/DefautExcelResult.java
new file mode 100644
index 0000000..c852ce6
--- /dev/null
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/excel/DefautExcelResult.java
@@ -0,0 +1,73 @@
+package com.ruoyi.common.excel;
+
+import cn.hutool.core.util.StrUtil;
+import lombok.Setter;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 榛樿excel杩斿洖瀵硅薄
+ *
+ * @author Yjoioooo
+ * @author Lion Li
+ */
+public class DefautExcelResult<T> implements ExcelResult<T> {
+
+    /**
+     * 鏁版嵁瀵硅薄list
+     */
+    @Setter
+    private List<T> list;
+
+    /**
+     * 閿欒淇℃伅鍒楄〃
+     */
+    @Setter
+    private List<String> errorList;
+
+    public DefautExcelResult() {
+        this.list = new ArrayList<>();
+        this.errorList = new ArrayList<>();
+    }
+
+    public DefautExcelResult(List<T> list, List<String> errorList) {
+        this.list = list;
+        this.errorList = errorList;
+    }
+
+    public DefautExcelResult(ExcelResult<T> excelResult) {
+        this.list = excelResult.getList();
+        this.errorList = excelResult.getErrorList();
+    }
+
+    @Override
+    public List<T> getList() {
+        return list;
+    }
+
+    @Override
+    public List<String> getErrorList() {
+        return errorList;
+    }
+
+    /**
+     * 鑾峰彇瀵煎叆鍥炴墽
+     *
+     * @return 瀵煎叆鍥炴墽
+     */
+    @Override
+    public String getAnalysis() {
+        int successCount = list.size();
+        int errorCount = errorList.size();
+        if (successCount == 0) {
+            return "璇诲彇澶辫触锛屾湭瑙f瀽鍒版暟鎹�";
+        } else {
+            if (errorCount == 0) {
+                return StrUtil.format("鎭枩鎮紝鍏ㄩ儴璇诲彇鎴愬姛锛佸叡{}鏉�", successCount);
+            } else {
+                return "";
+            }
+        }
+    }
+}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/excel/ExcelListener.java b/ruoyi-common/src/main/java/com/ruoyi/common/excel/ExcelListener.java
new file mode 100644
index 0000000..2064cad
--- /dev/null
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/excel/ExcelListener.java
@@ -0,0 +1,14 @@
+package com.ruoyi.common.excel;
+
+import com.alibaba.excel.read.listener.ReadListener;
+
+/**
+ * Excel 瀵煎叆鐩戝惉
+ *
+ * @author Lion Li
+ */
+public interface ExcelListener<T> extends ReadListener<T> {
+
+    ExcelResult<T> getExcelResult();
+
+}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/excel/ExcelResult.java b/ruoyi-common/src/main/java/com/ruoyi/common/excel/ExcelResult.java
new file mode 100644
index 0000000..63f8b8a
--- /dev/null
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/excel/ExcelResult.java
@@ -0,0 +1,26 @@
+package com.ruoyi.common.excel;
+
+import java.util.List;
+
+/**
+ * excel杩斿洖瀵硅薄
+ *
+ * @author Lion Li
+ */
+public interface ExcelResult<T> {
+
+    /**
+     * 瀵硅薄鍒楄〃
+     */
+    List<T> getList();
+
+    /**
+     * 閿欒鍒楄〃
+     */
+    List<String> getErrorList();
+
+    /**
+     * 瀵煎叆鍥炴墽
+     */
+    String getAnalysis();
+}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/exception/file/InvalidExtensionException.java b/ruoyi-common/src/main/java/com/ruoyi/common/exception/file/InvalidExtensionException.java
deleted file mode 100644
index 7de92e2..0000000
--- a/ruoyi-common/src/main/java/com/ruoyi/common/exception/file/InvalidExtensionException.java
+++ /dev/null
@@ -1,61 +0,0 @@
-package com.ruoyi.common.exception.file;
-
-import lombok.*;
-import org.apache.commons.fileupload.FileUploadException;
-
-import java.util.Arrays;
-
-/**
- * 鏂囦欢涓婁紶 璇紓甯哥被
- *
- * @author ruoyi
- */
-@Data
-@EqualsAndHashCode(callSuper = true)
-@NoArgsConstructor
-public class InvalidExtensionException extends FileUploadException {
-    private static final long serialVersionUID = 1L;
-
-    private String[] allowedExtension;
-    private String extension;
-    private String filename;
-
-    public InvalidExtensionException(String[] allowedExtension, String extension, String filename) {
-        super("filename : [" + filename + "], extension : [" + extension + "], allowed extension : [" + Arrays.toString(allowedExtension) + "]");
-        this.allowedExtension = allowedExtension;
-        this.extension = extension;
-        this.filename = filename;
-    }
-
-    public static class InvalidImageExtensionException extends InvalidExtensionException {
-        private static final long serialVersionUID = 1L;
-
-        public InvalidImageExtensionException(String[] allowedExtension, String extension, String filename) {
-            super(allowedExtension, extension, filename);
-        }
-    }
-
-    public static class InvalidFlashExtensionException extends InvalidExtensionException {
-        private static final long serialVersionUID = 1L;
-
-        public InvalidFlashExtensionException(String[] allowedExtension, String extension, String filename) {
-            super(allowedExtension, extension, filename);
-        }
-    }
-
-    public static class InvalidMediaExtensionException extends InvalidExtensionException {
-        private static final long serialVersionUID = 1L;
-
-        public InvalidMediaExtensionException(String[] allowedExtension, String extension, String filename) {
-            super(allowedExtension, extension, filename);
-        }
-    }
-
-    public static class InvalidVideoExtensionException extends InvalidExtensionException {
-        private static final long serialVersionUID = 1L;
-
-        public InvalidVideoExtensionException(String[] allowedExtension, String extension, String filename) {
-            super(allowedExtension, extension, filename);
-        }
-    }
-}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/exception/job/TaskException.java b/ruoyi-common/src/main/java/com/ruoyi/common/exception/job/TaskException.java
deleted file mode 100644
index 59ea3a6..0000000
--- a/ruoyi-common/src/main/java/com/ruoyi/common/exception/job/TaskException.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package com.ruoyi.common.exception.job;
-
-/**
- * 璁″垝绛栫暐寮傚父
- *
- * @deprecated 3.4.0鍒犻櫎 杩佺Щ鑷硏xl-job
- * @author ruoyi
- */
-public class TaskException extends Exception
-{
-    private static final long serialVersionUID = 1L;
-
-    private Code code;
-
-    public TaskException(String msg, Code code)
-    {
-        this(msg, code, null);
-    }
-
-    public TaskException(String msg, Code code, Exception nestedEx)
-    {
-        super(msg, nestedEx);
-        this.code = code;
-    }
-
-    public Code getCode()
-    {
-        return code;
-    }
-
-    public enum Code
-    {
-        TASK_EXISTS, NO_TASK_EXISTS, TASK_ALREADY_STARTED, UNKNOWN, CONFIG_ERROR, TASK_NODE_NOT_AVAILABLE
-    }
-}
\ No newline at end of file
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/DictUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/DictUtils.java
index f24d0e8..3309da1 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/DictUtils.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/DictUtils.java
@@ -11,7 +11,9 @@
  * 瀛楀吀宸ュ叿绫�
  *
  * @author ruoyi
+ * @deprecated 3.5.0 鐗堟湰鍒犻櫎 杩佺Щ鑷� {@link com.ruoyi.common.core.service.DictService}
  */
+@Deprecated
 public class DictUtils {
 
     /**
@@ -36,9 +38,8 @@
      * @return dictDatas 瀛楀吀鏁版嵁鍒楄〃
      */
     public static List<SysDictData> getDictCache(String key) {
-        Object cacheObj = RedisUtils.getCacheObject(getCacheKey(key));
-        if (StringUtils.isNotNull(cacheObj)) {
-            List<SysDictData> dictDatas = (List<SysDictData>) cacheObj;
+        List<SysDictData> dictDatas = RedisUtils.getCacheObject(getCacheKey(key));
+        if (StringUtils.isNotNull(dictDatas)) {
             return dictDatas;
         }
         return null;
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 b358e3b..abc42dd 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
@@ -1,5 +1,6 @@
 package com.ruoyi.common.utils;
 
+import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.http.HttpStatus;
 import com.baomidou.mybatisplus.core.metadata.OrderItem;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -63,7 +64,9 @@
         }
         PagePlus<T, K> page = new PagePlus<>(pageNum, pageSize);
         OrderItem orderItem = buildOrderItem(orderByColumn, isAsc);
-        page.addOrder(orderItem);
+        if (ObjectUtil.isNotNull(orderItem)) {
+            page.addOrder(orderItem);
+        }
         return page;
     }
 
@@ -87,7 +90,9 @@
         }
         Page<T> page = new Page<>(pageNum, pageSize);
         OrderItem orderItem = buildOrderItem(orderByColumn, isAsc);
-        page.addOrder(orderItem);
+        if (ObjectUtil.isNotNull(orderItem)) {
+            page.addOrder(orderItem);
+        }
         return page;
     }
 
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/RedisUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/RedisUtils.java
index 27472a7..04db787 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/RedisUtils.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/RedisUtils.java
@@ -88,7 +88,30 @@
      * @param value 缂撳瓨鐨勫��
      */
     public static <T> void setCacheObject(final String key, final T value) {
-        client.getBucket(key).set(value);
+        setCacheObject(key, value, false);
+    }
+
+    /**
+     * 缂撳瓨鍩烘湰鐨勫璞★紝淇濈暀褰撳墠瀵硅薄 TTL 鏈夋晥鏈�
+     *
+     * @param key   缂撳瓨鐨勯敭鍊�
+     * @param value 缂撳瓨鐨勫��
+     * @param isSaveTtl 鏄惁淇濈暀TTL鏈夋晥鏈�(渚嬪: set涔嬪墠ttl鍓╀綑90 set涔嬪悗杩樻槸涓�90)
+     * @since Redis 6.X 浠ヤ笂浣跨敤 setAndKeepTTL 鍏煎 5.X 鏂规
+     */
+    public static <T> void setCacheObject(final String key, final T value, final boolean isSaveTtl) {
+        RBucket<Object> bucket = client.getBucket(key);
+        if (isSaveTtl) {
+            try {
+                bucket.setAndKeepTTL(value);
+            } catch (Exception e) {
+                long timeToLive = bucket.remainTimeToLive();
+                bucket.set(value);
+                bucket.expire(timeToLive, TimeUnit.MILLISECONDS);
+            }
+        } else {
+            bucket.set(value);
+        }
     }
 
     /**
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/TreeBuildUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/TreeBuildUtils.java
new file mode 100644
index 0000000..a8380a2
--- /dev/null
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/TreeBuildUtils.java
@@ -0,0 +1,31 @@
+package com.ruoyi.common.utils;
+
+import cn.hutool.core.lang.tree.Tree;
+import cn.hutool.core.lang.tree.TreeNodeConfig;
+import cn.hutool.core.lang.tree.TreeUtil;
+import cn.hutool.core.lang.tree.parser.NodeParser;
+
+import java.util.List;
+
+/**
+ * 鎵╁睍 hutool TreeUtil 灏佽绯荤粺鏍戞瀯寤�
+ *
+ * @author Lion Li
+ */
+public class TreeBuildUtils extends TreeUtil {
+
+    /**
+     * 鏍规嵁鍓嶇瀹氬埗宸紓鍖栧瓧娈�
+     */
+    public static final TreeNodeConfig DEFAULT_CONFIG = TreeNodeConfig.DEFAULT_CONFIG.setNameKey("label");
+
+    /**
+     * 榛樿鏍戠埗鑺傜偣id
+     */
+    public static final Long DEFAULT_PARENT_ID = 0L;
+
+    public static <T> List<Tree<Long>> build(List<T> list, NodeParser<T, Long> nodeParser) {
+        return TreeUtil.build(list, DEFAULT_PARENT_ID, DEFAULT_CONFIG, nodeParser);
+    }
+
+}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/ValidatorUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/ValidatorUtils.java
new file mode 100644
index 0000000..c28cf80
--- /dev/null
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/ValidatorUtils.java
@@ -0,0 +1,25 @@
+package com.ruoyi.common.utils;
+
+import javax.validation.ConstraintViolation;
+import javax.validation.ConstraintViolationException;
+import javax.validation.Validation;
+import javax.validation.Validator;
+import java.util.Set;
+
+/**
+ * Validator 鏍¢獙妗嗘灦宸ュ叿
+ *
+ * @author Lion Li
+ */
+public class ValidatorUtils {
+
+	private static final Validator VALID = Validation.buildDefaultValidatorFactory().getValidator();
+
+	public static <T> void validate(T object, Class<?>... groups) {
+        Set<ConstraintViolation<T>> validate = VALID.validate(object, groups);
+        if (!validate.isEmpty()) {
+            throw new ConstraintViolationException("鍙傛暟鏍¢獙寮傚父", validate);
+        }
+    }
+
+}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java
index 813fc97..6c5dc5f 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java
@@ -4,7 +4,9 @@
 import com.alibaba.excel.EasyExcel;
 import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
 import com.ruoyi.common.convert.ExcelBigNumberConvert;
-import com.ruoyi.common.utils.DictUtils;
+import com.ruoyi.common.excel.DefaultExcelListener;
+import com.ruoyi.common.excel.ExcelListener;
+import com.ruoyi.common.excel.ExcelResult;
 import com.ruoyi.common.utils.StringUtils;
 import com.ruoyi.common.utils.file.FileUtils;
 
@@ -21,129 +23,133 @@
  */
 public class ExcelUtil {
 
-	/**
-	 * 瀵筫xcel琛ㄥ崟榛樿绗竴涓储寮曞悕杞崲鎴恖ist锛圗asyExcel锛�
-	 *
-	 * @param is 杈撳叆娴�
-	 * @return 杞崲鍚庨泦鍚�
-	 */
-	public static <T> List<T> importExcel(InputStream is, Class<T> clazz) {
-		return EasyExcel.read(is).head(clazz).autoCloseStream(false).sheet().doReadSync();
-	}
+    /**
+     * 鍚屾瀵煎叆(閫傜敤浜庡皬鏁版嵁閲�)
+     *
+     * @param is 杈撳叆娴�
+     * @return 杞崲鍚庨泦鍚�
+     */
+    public static <T> List<T> importExcel(InputStream is, Class<T> clazz) {
+        return EasyExcel.read(is).head(clazz).autoCloseStream(false).sheet().doReadSync();
+    }
 
-	/**
-	 * 瀵筶ist鏁版嵁婧愬皢鍏堕噷闈㈢殑鏁版嵁瀵煎叆鍒癳xcel琛ㄥ崟锛圗asyExcel锛�
-	 *
-	 * @param list      瀵煎嚭鏁版嵁闆嗗悎
-	 * @param sheetName 宸ヤ綔琛ㄧ殑鍚嶇О
-	 * @return 缁撴灉
-	 */
-	public static <T> void exportExcel(List<T> list, String sheetName, Class<T> clazz, HttpServletResponse response) {
-		try {
-			String filename = encodingFilename(sheetName);
-			response.reset();
-			FileUtils.setAttachmentResponseHeader(response, filename);
-			response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8");
-			ServletOutputStream os = response.getOutputStream();
-			EasyExcel.write(os, clazz)
-				.autoCloseStream(false)
-				// 鑷姩閫傞厤
-				.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
-				// 澶ф暟鍊艰嚜鍔ㄨ浆鎹� 闃叉澶辩湡
-				.registerConverter(new ExcelBigNumberConvert())
-				.sheet(sheetName).doWrite(list);
-		} catch (IOException e) {
-			throw new RuntimeException("瀵煎嚭Excel寮傚父");
-		}
-	}
 
-	/**
-	 * 瑙f瀽瀵煎嚭鍊� 0=鐢�,1=濂�,2=鏈煡
-	 *
-	 * @param propertyValue 鍙傛暟鍊�
-	 * @param converterExp  缈昏瘧娉ㄨВ
-	 * @param separator     鍒嗛殧绗�
-	 * @return 瑙f瀽鍚庡��
-	 */
-	public static String convertByExp(String propertyValue, String converterExp, String separator) {
-		StringBuilder propertyString = new StringBuilder();
-		String[] convertSource = converterExp.split(",");
-		for (String item : convertSource) {
-			String[] itemArray = item.split("=");
-			if (StringUtils.containsAny(separator, propertyValue)) {
-				for (String value : propertyValue.split(separator)) {
-					if (itemArray[0].equals(value)) {
-						propertyString.append(itemArray[1] + separator);
-						break;
-					}
-				}
-			} else {
-				if (itemArray[0].equals(propertyValue)) {
-					return itemArray[1];
-				}
-			}
-		}
-		return StringUtils.stripEnd(propertyString.toString(), separator);
-	}
+    /**
+     * 浣跨敤鏍¢獙鐩戝惉鍣� 寮傛瀵煎叆 鍚屾杩斿洖
+     *
+     * @param is         杈撳叆娴�
+     * @param clazz      瀵硅薄绫诲瀷
+     * @param isValidate 鏄惁 Validator 妫�楠� 榛樿涓烘槸
+     * @return 杞崲鍚庨泦鍚�
+     */
+    public static <T> ExcelResult<T> importExcel(InputStream is, Class<T> clazz, boolean isValidate) {
+        DefaultExcelListener<T> listener = new DefaultExcelListener<>(isValidate);
+        EasyExcel.read(is, clazz, listener).sheet().doRead();
+        return listener.getExcelResult();
+    }
 
-	/**
-	 * 鍙嶅悜瑙f瀽鍊� 鐢�=0,濂�=1,鏈煡=2
-	 *
-	 * @param propertyValue 鍙傛暟鍊�
-	 * @param converterExp  缈昏瘧娉ㄨВ
-	 * @param separator     鍒嗛殧绗�
-	 * @return 瑙f瀽鍚庡��
-	 */
-	public static String reverseByExp(String propertyValue, String converterExp, String separator) {
-		StringBuilder propertyString = new StringBuilder();
-		String[] convertSource = converterExp.split(",");
-		for (String item : convertSource) {
-			String[] itemArray = item.split("=");
-			if (StringUtils.containsAny(separator, propertyValue)) {
-				for (String value : propertyValue.split(separator)) {
-					if (itemArray[1].equals(value)) {
-						propertyString.append(itemArray[0] + separator);
-						break;
-					}
-				}
-			} else {
-				if (itemArray[1].equals(propertyValue)) {
-					return itemArray[0];
-				}
-			}
-		}
-		return StringUtils.stripEnd(propertyString.toString(), separator);
-	}
+    /**
+     * 浣跨敤鑷畾涔夌洃鍚櫒 寮傛瀵煎叆 鑷畾涔夎繑鍥�
+     *
+     * @param is       杈撳叆娴�
+     * @param clazz    瀵硅薄绫诲瀷
+     * @param listener 鑷畾涔夌洃鍚櫒
+     * @return 杞崲鍚庨泦鍚�
+     */
+    public static <T> ExcelResult<T> importExcel(InputStream is, Class<T> clazz, ExcelListener<T> listener) {
+        EasyExcel.read(is, clazz, listener).sheet().doRead();
+        return listener.getExcelResult();
+    }
 
-	/**
-	 * 瑙f瀽瀛楀吀鍊�
-	 *
-	 * @param dictValue 瀛楀吀鍊�
-	 * @param dictType  瀛楀吀绫诲瀷
-	 * @param separator 鍒嗛殧绗�
-	 * @return 瀛楀吀鏍囩
-	 */
-	public static String convertDictByExp(String dictValue, String dictType, String separator) {
-		return DictUtils.getDictLabel(dictType, dictValue, separator);
-	}
+    /**
+     * 瀵煎嚭excel
+     *
+     * @param list      瀵煎嚭鏁版嵁闆嗗悎
+     * @param sheetName 宸ヤ綔琛ㄧ殑鍚嶇О
+     * @return 缁撴灉
+     */
+    public static <T> void exportExcel(List<T> list, String sheetName, Class<T> clazz, HttpServletResponse response) {
+        try {
+            String filename = encodingFilename(sheetName);
+            response.reset();
+            FileUtils.setAttachmentResponseHeader(response, filename);
+            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8");
+            ServletOutputStream os = response.getOutputStream();
+            EasyExcel.write(os, clazz)
+                .autoCloseStream(false)
+                // 鑷姩閫傞厤
+                .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
+                // 澶ф暟鍊艰嚜鍔ㄨ浆鎹� 闃叉澶辩湡
+                .registerConverter(new ExcelBigNumberConvert())
+                .sheet(sheetName).doWrite(list);
+        } catch (IOException e) {
+            throw new RuntimeException("瀵煎嚭Excel寮傚父");
+        }
+    }
 
-	/**
-	 * 鍙嶅悜瑙f瀽鍊煎瓧鍏稿��
-	 *
-	 * @param dictLabel 瀛楀吀鏍囩
-	 * @param dictType  瀛楀吀绫诲瀷
-	 * @param separator 鍒嗛殧绗�
-	 * @return 瀛楀吀鍊�
-	 */
-	public static String reverseDictByExp(String dictLabel, String dictType, String separator) {
-		return DictUtils.getDictValue(dictType, dictLabel, separator);
-	}
+    /**
+     * 瑙f瀽瀵煎嚭鍊� 0=鐢�,1=濂�,2=鏈煡
+     *
+     * @param propertyValue 鍙傛暟鍊�
+     * @param converterExp  缈昏瘧娉ㄨВ
+     * @param separator     鍒嗛殧绗�
+     * @return 瑙f瀽鍚庡��
+     */
+    public static String convertByExp(String propertyValue, String converterExp, String separator) {
+        StringBuilder propertyString = new StringBuilder();
+        String[] convertSource = converterExp.split(",");
+        for (String item : convertSource) {
+            String[] itemArray = item.split("=");
+            if (StringUtils.containsAny(separator, propertyValue)) {
+                for (String value : propertyValue.split(separator)) {
+                    if (itemArray[0].equals(value)) {
+                        propertyString.append(itemArray[1] + separator);
+                        break;
+                    }
+                }
+            } else {
+                if (itemArray[0].equals(propertyValue)) {
+                    return itemArray[1];
+                }
+            }
+        }
+        return StringUtils.stripEnd(propertyString.toString(), separator);
+    }
 
-	/**
-	 * 缂栫爜鏂囦欢鍚�
-	 */
-	public static String encodingFilename(String filename) {
-		return IdUtil.fastSimpleUUID() + "_" + filename + ".xlsx";
-	}
+    /**
+     * 鍙嶅悜瑙f瀽鍊� 鐢�=0,濂�=1,鏈煡=2
+     *
+     * @param propertyValue 鍙傛暟鍊�
+     * @param converterExp  缈昏瘧娉ㄨВ
+     * @param separator     鍒嗛殧绗�
+     * @return 瑙f瀽鍚庡��
+     */
+    public static String reverseByExp(String propertyValue, String converterExp, String separator) {
+        StringBuilder propertyString = new StringBuilder();
+        String[] convertSource = converterExp.split(",");
+        for (String item : convertSource) {
+            String[] itemArray = item.split("=");
+            if (StringUtils.containsAny(separator, propertyValue)) {
+                for (String value : propertyValue.split(separator)) {
+                    if (itemArray[1].equals(value)) {
+                        propertyString.append(itemArray[0] + separator);
+                        break;
+                    }
+                }
+            } else {
+                if (itemArray[1].equals(propertyValue)) {
+                    return itemArray[0];
+                }
+            }
+        }
+        return StringUtils.stripEnd(propertyString.toString(), separator);
+    }
+
+    /**
+     * 缂栫爜鏂囦欢鍚�
+     */
+    public static String encodingFilename(String filename) {
+        return IdUtil.fastSimpleUUID() + "_" + filename + ".xlsx";
+    }
 
 }
diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/FeignTestController.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/FeignTestController.java
deleted file mode 100644
index 2f833e3..0000000
--- a/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/FeignTestController.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package com.ruoyi.demo.controller;
-
-import com.ruoyi.common.core.domain.AjaxResult;
-import com.ruoyi.demo.feign.FeignTestService;
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiOperation;
-import lombok.RequiredArgsConstructor;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-/**
- * feign娴嬭瘯controller
- *
- * @author Lion Li
- * @deprecated 鐢变簬浣跨敤浜烘暟杈冨皯 鍐冲畾涓� 3.4.0 鐗堟湰绉婚櫎
- */
-@Api(value = "feign娴嬭瘯", tags = {"feign娴嬭瘯"})
-@RequiredArgsConstructor(onConstructor_ = @Autowired)
-@RestController
-@RequestMapping("/feign/test")
-public class FeignTestController {
-
-    private final FeignTestService feignTestService;
-
-    /**
-     * 鎼滅储鏁版嵁
-     */
-    @ApiOperation("娴嬭瘯浣跨敤feign璇锋眰鏁版嵁")
-    @GetMapping("/search/{wd}")
-    public AjaxResult search(@PathVariable String wd) {
-        String search = feignTestService.search(wd);
-        return AjaxResult.success("鎿嶄綔鎴愬姛",search);
-    }
-}
diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisCacheController.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisCacheController.java
index 903b982..e01b542 100644
--- a/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisCacheController.java
+++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisCacheController.java
@@ -28,75 +28,75 @@
 @RequestMapping("/demo/cache")
 public class RedisCacheController {
 
-	/**
-	 * 娴嬭瘯 @Cacheable
-	 *
-	 * 琛ㄧず杩欎釜鏂规硶鏈変簡缂撳瓨鐨勫姛鑳�,鏂规硶鐨勮繑鍥炲�间細琚紦瀛樹笅鏉�
-	 * 涓嬩竴娆¤皟鐢ㄨ鏂规硶鍓�,浼氬幓妫�鏌ユ槸鍚︾紦瀛樹腑宸茬粡鏈夊��
-	 * 濡傛灉鏈夊氨鐩存帴杩斿洖,涓嶈皟鐢ㄦ柟娉�
-	 * 濡傛灉娌℃湁,灏辫皟鐢ㄦ柟娉�,鐒跺悗鎶婄粨鏋滅紦瀛樿捣鏉�
-	 * 杩欎釜娉ㄨВ銆屼竴鑸敤鍦ㄦ煡璇㈡柟娉曚笂銆�
-	 *
-	 * 閲嶇偣璇存槑: 缂撳瓨娉ㄨВ涓ヨ皑涓庡叾浠栫瓫閫夋暟鎹姛鑳戒竴璧蜂娇鐢�
-	 * 渚嬪: 鏁版嵁鏉冮檺娉ㄨВ 浼氶�犳垚 缂撳瓨鍑荤┛ 涓� 鏁版嵁涓嶄竴鑷撮棶棰�
-	 *
-	 * cacheNames 涓洪厤缃枃浠跺唴 groupId
-	 */
-	@ApiOperation("娴嬭瘯 @Cacheable")
-	@Cacheable(cacheNames = "redissonCacheMap", key = "#key", condition = "#key != null")
-	@GetMapping("/test1")
-	public AjaxResult<String> test1(String key, String value){
-		return AjaxResult.success("鎿嶄綔鎴愬姛", value);
-	}
+    /**
+     * 娴嬭瘯 @Cacheable
+     * <p>
+     * 琛ㄧず杩欎釜鏂规硶鏈変簡缂撳瓨鐨勫姛鑳�,鏂规硶鐨勮繑鍥炲�间細琚紦瀛樹笅鏉�
+     * 涓嬩竴娆¤皟鐢ㄨ鏂规硶鍓�,浼氬幓妫�鏌ユ槸鍚︾紦瀛樹腑宸茬粡鏈夊��
+     * 濡傛灉鏈夊氨鐩存帴杩斿洖,涓嶈皟鐢ㄦ柟娉�
+     * 濡傛灉娌℃湁,灏辫皟鐢ㄦ柟娉�,鐒跺悗鎶婄粨鏋滅紦瀛樿捣鏉�
+     * 杩欎釜娉ㄨВ銆屼竴鑸敤鍦ㄦ煡璇㈡柟娉曚笂銆�
+     * <p>
+     * 閲嶇偣璇存槑: 缂撳瓨娉ㄨВ涓ヨ皑涓庡叾浠栫瓫閫夋暟鎹姛鑳戒竴璧蜂娇鐢�
+     * 渚嬪: 鏁版嵁鏉冮檺娉ㄨВ 浼氶�犳垚 缂撳瓨鍑荤┛ 涓� 鏁版嵁涓嶄竴鑷撮棶棰�
+     * <p>
+     * cacheNames 涓洪厤缃枃浠跺唴 groupId
+     */
+    @ApiOperation("娴嬭瘯 @Cacheable")
+    @Cacheable(cacheNames = "redissonCacheMap", key = "#key", condition = "#key != null")
+    @GetMapping("/test1")
+    public AjaxResult<String> test1(String key, String value) {
+        return AjaxResult.success("鎿嶄綔鎴愬姛", value);
+    }
 
-	/**
-	 * 娴嬭瘯 @CachePut
-	 *
-	 * 鍔犱簡@CachePut娉ㄨВ鐨勬柟娉�,浼氭妸鏂规硶鐨勮繑鍥炲�紁ut鍒扮紦瀛橀噷闈㈢紦瀛樿捣鏉�,渚涘叾瀹冨湴鏂逛娇鐢�
-	 * 瀹冦�岄�氬父鐢ㄥ湪鏂板鏂规硶涓娿��
-	 *
-	 * cacheNames 涓� 閰嶇疆鏂囦欢鍐� groupId
-	 */
-	@ApiOperation("娴嬭瘯 @CachePut")
-	@CachePut(cacheNames = "redissonCacheMap", key = "#key", condition = "#key != null")
-	@GetMapping("/test2")
-	public AjaxResult<String> test2(String key, String value){
-		return AjaxResult.success("鎿嶄綔鎴愬姛", value);
-	}
+    /**
+     * 娴嬭瘯 @CachePut
+     * <p>
+     * 鍔犱簡@CachePut娉ㄨВ鐨勬柟娉�,浼氭妸鏂规硶鐨勮繑鍥炲�紁ut鍒扮紦瀛橀噷闈㈢紦瀛樿捣鏉�,渚涘叾瀹冨湴鏂逛娇鐢�
+     * 瀹冦�岄�氬父鐢ㄥ湪鏂板鏂规硶涓娿��
+     * <p>
+     * cacheNames 涓� 閰嶇疆鏂囦欢鍐� groupId
+     */
+    @ApiOperation("娴嬭瘯 @CachePut")
+    @CachePut(cacheNames = "redissonCacheMap", key = "#key", condition = "#key != null")
+    @GetMapping("/test2")
+    public AjaxResult<String> test2(String key, String value) {
+        return AjaxResult.success("鎿嶄綔鎴愬姛", value);
+    }
 
-	/**
-	 * 娴嬭瘯 @CacheEvict
-	 *
-	 * 浣跨敤浜咰acheEvict娉ㄨВ鐨勬柟娉�,浼氭竻绌烘寚瀹氱紦瀛�
-	 * 銆屼竴鑸敤鍦ㄦ洿鏂版垨鑰呭垹闄ょ殑鏂规硶涓娿��
-	 *
-	 * cacheNames 涓� 閰嶇疆鏂囦欢鍐� groupId
-	 */
-	@ApiOperation("娴嬭瘯 @CacheEvict")
-	@CacheEvict(cacheNames = "redissonCacheMap", key = "#key", condition = "#key != null")
-	@GetMapping("/test3")
-	public AjaxResult<String> test3(String key, String value){
-		return AjaxResult.success("鎿嶄綔鎴愬姛", value);
-	}
+    /**
+     * 娴嬭瘯 @CacheEvict
+     * <p>
+     * 浣跨敤浜咰acheEvict娉ㄨВ鐨勬柟娉�,浼氭竻绌烘寚瀹氱紦瀛�
+     * 銆屼竴鑸敤鍦ㄦ洿鏂版垨鑰呭垹闄ょ殑鏂规硶涓娿��
+     * <p>
+     * cacheNames 涓� 閰嶇疆鏂囦欢鍐� groupId
+     */
+    @ApiOperation("娴嬭瘯 @CacheEvict")
+    @CacheEvict(cacheNames = "redissonCacheMap", key = "#key", condition = "#key != null")
+    @GetMapping("/test3")
+    public AjaxResult<String> test3(String key, String value) {
+        return AjaxResult.success("鎿嶄綔鎴愬姛", value);
+    }
 
-	/**
-	 * 娴嬭瘯璁剧疆杩囨湡鏃堕棿
-	 * 鎵嬪姩璁剧疆杩囨湡鏃堕棿10绉�
-	 * 11绉掑悗鑾峰彇 鍒ゆ柇鏄惁鐩哥瓑
-	 */
-	@ApiOperation("娴嬭瘯璁剧疆杩囨湡鏃堕棿")
-	@GetMapping("/test6")
-	public AjaxResult<Boolean> test6(String key, String value){
-		RedisUtils.setCacheObject(key, value);
-		boolean flag = RedisUtils.expire(key, 10, TimeUnit.SECONDS);
-		System.out.println("***********" + flag);
-		try {
-			Thread.sleep(11 * 1000);
-		} catch (InterruptedException e) {
-			e.printStackTrace();
-		}
-		Object obj = RedisUtils.getCacheObject(key);
-		return AjaxResult.success("鎿嶄綔鎴愬姛", value.equals(obj));
-	}
+    /**
+     * 娴嬭瘯璁剧疆杩囨湡鏃堕棿
+     * 鎵嬪姩璁剧疆杩囨湡鏃堕棿10绉�
+     * 11绉掑悗鑾峰彇 鍒ゆ柇鏄惁鐩哥瓑
+     */
+    @ApiOperation("娴嬭瘯璁剧疆杩囨湡鏃堕棿")
+    @GetMapping("/test6")
+    public AjaxResult<Boolean> test6(String key, String value) {
+        RedisUtils.setCacheObject(key, value);
+        boolean flag = RedisUtils.expire(key, 10, TimeUnit.SECONDS);
+        System.out.println("***********" + flag);
+        try {
+            Thread.sleep(11 * 1000);
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+        Object obj = RedisUtils.getCacheObject(key);
+        return AjaxResult.success("鎿嶄綔鎴愬姛", value.equals(obj));
+    }
 
 }
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 a720246..94ad3c3 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
@@ -9,7 +9,6 @@
 import io.swagger.annotations.ApiOperation;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.cache.annotation.Cacheable;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
@@ -28,59 +27,50 @@
 @RequestMapping("/demo/redisLock")
 public class RedisLockController {
 
-	@Autowired
-	private LockTemplate lockTemplate;
+    @Autowired
+    private LockTemplate lockTemplate;
 
-	/**
-	 * 娴嬭瘯lock4j 娉ㄨВ
-	 */
-	@ApiOperation("娴嬭瘯lock4j 娉ㄨВ")
-	@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(10000);
-		} catch (InterruptedException e) {
-			e.printStackTrace();
-		}
-		System.out.println("end :"+key+",time:"+LocalTime.now().toString());
-		return AjaxResult.success("鎿嶄綔鎴愬姛",value);
-	}
+    /**
+     * 娴嬭瘯lock4j 娉ㄨВ
+     */
+    @ApiOperation("娴嬭瘯lock4j 娉ㄨВ")
+    @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(10000);
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+        System.out.println("end :" + key + ",time:" + LocalTime.now().toString());
+        return AjaxResult.success("鎿嶄綔鎴愬姛", value);
+    }
 
-	/**
-	 * 娴嬭瘯lock4j 宸ュ叿
-	 */
-	@ApiOperation("娴嬭瘯lock4j 宸ュ叿")
-	@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("涓氬姟澶勭悊涓�,璇风◢鍚庡啀璇�");
-		}
-		// 鑾峰彇閿佹垚鍔燂紝澶勭悊涓氬姟
-		try {
-			try {
-				Thread.sleep(8000);
-			} catch (InterruptedException e) {
-				//
-			}
-			System.out.println("鎵ц绠�鍗曟柟娉�1 , 褰撳墠绾跨▼:" + Thread.currentThread().getName());
-		} finally {
-			//閲婃斁閿�
-			lockTemplate.releaseLock(lockInfo);
-		}
-		//缁撴潫
-		return AjaxResult.success("鎿嶄綔鎴愬姛",value);
-	}
+    /**
+     * 娴嬭瘯lock4j 宸ュ叿
+     */
+    @ApiOperation("娴嬭瘯lock4j 宸ュ叿")
+    @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("涓氬姟澶勭悊涓�,璇风◢鍚庡啀璇�");
+        }
+        // 鑾峰彇閿佹垚鍔燂紝澶勭悊涓氬姟
+        try {
+            try {
+                Thread.sleep(8000);
+            } catch (InterruptedException e) {
+                //
+            }
+            System.out.println("鎵ц绠�鍗曟柟娉�1 , 褰撳墠绾跨▼:" + Thread.currentThread().getName());
+        } finally {
+            //閲婃斁閿�
+            lockTemplate.releaseLock(lockInfo);
+        }
+        //缁撴潫
+        return AjaxResult.success("鎿嶄綔鎴愬姛", value);
+    }
 
-	/**
-	 * 娴嬭瘯spring-cache娉ㄨВ
-	 */
-	@ApiOperation("娴嬭瘯spring-cache娉ㄨВ")
-	@Cacheable(value = "test", key = "#key")
-	@GetMapping("/testCache")
-	public AjaxResult<String> testCache(String key) {
-		return AjaxResult.success("鎿嶄綔鎴愬姛", key);
-	}
 }
diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisPubSubController.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisPubSubController.java
index 810b307..619a690 100644
--- a/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisPubSubController.java
+++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisPubSubController.java
@@ -4,6 +4,7 @@
 import com.ruoyi.common.utils.RedisUtils;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
 import lombok.RequiredArgsConstructor;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.GetMapping;
@@ -21,22 +22,22 @@
 @RequestMapping("/demo/redis/pubsub")
 public class RedisPubSubController {
 
-	@ApiOperation("鍙戝竷娑堟伅")
-	@GetMapping("/pub")
-	public AjaxResult<Void> pub(String key, String value){
-		RedisUtils.publish(key, value, consumer -> {
-			System.out.println("鍙戝竷閫氶亾 => " + key + ", 鍙戦�佸�� => " + value);
-		});
-		return AjaxResult.success("鎿嶄綔鎴愬姛");
-	}
+    @ApiOperation("鍙戝竷娑堟伅")
+    @GetMapping("/pub")
+    public AjaxResult<Void> pub(@ApiParam("閫氶亾Key") String key, @ApiParam("鍙戦�佸唴瀹�") String value) {
+        RedisUtils.publish(key, value, consumer -> {
+            System.out.println("鍙戝竷閫氶亾 => " + key + ", 鍙戦�佸�� => " + value);
+        });
+        return AjaxResult.success("鎿嶄綔鎴愬姛");
+    }
 
-	@ApiOperation("璁㈤槄娑堟伅")
-	@GetMapping("/sub")
-	public AjaxResult<Void> sub(String key){
-		RedisUtils.subscribe(key, String.class, msg -> {
-			System.out.println("璁㈤槄閫氶亾 => " + key + ", 鎺ユ敹鍊� => " + msg);
-		});
-		return AjaxResult.success("鎿嶄綔鎴愬姛");
-	}
+    @ApiOperation("璁㈤槄娑堟伅")
+    @GetMapping("/sub")
+    public AjaxResult<Void> sub(@ApiParam("閫氶亾Key") String key) {
+        RedisUtils.subscribe(key, String.class, msg -> {
+            System.out.println("璁㈤槄閫氶亾 => " + key + ", 鎺ユ敹鍊� => " + msg);
+        });
+        return AjaxResult.success("鎿嶄綔鎴愬姛");
+    }
 
 }
diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisRateLimiterController.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisRateLimiterController.java
index 33d7509..1eeab61 100644
--- a/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisRateLimiterController.java
+++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisRateLimiterController.java
@@ -22,37 +22,37 @@
 @RequestMapping("/demo/rateLimiter")
 public class RedisRateLimiterController {
 
-	/**
-	 * 娴嬭瘯鍏ㄥ眬闄愭祦
-	 * 鍏ㄥ眬褰卞搷
-	 */
-	@ApiOperation("娴嬭瘯鍏ㄥ眬闄愭祦")
-	@RateLimiter(count = 2, time = 10)
-	@GetMapping("/test")
-	public  AjaxResult<String> test(String value){
-		return AjaxResult.success("鎿嶄綔鎴愬姛",value);
-	}
+    /**
+     * 娴嬭瘯鍏ㄥ眬闄愭祦
+     * 鍏ㄥ眬褰卞搷
+     */
+    @ApiOperation("娴嬭瘯鍏ㄥ眬闄愭祦")
+    @RateLimiter(count = 2, time = 10)
+    @GetMapping("/test")
+    public AjaxResult<String> test(String value) {
+        return AjaxResult.success("鎿嶄綔鎴愬姛", value);
+    }
 
-	/**
-	 * 娴嬭瘯璇锋眰IP闄愭祦
-	 * 鍚屼竴IP璇锋眰鍙楀奖鍝�
-	 */
-	@ApiOperation("娴嬭瘯璇锋眰IP闄愭祦")
-	@RateLimiter(count = 2, time = 10, limitType = LimitType.IP)
-	@GetMapping("/testip")
-	public  AjaxResult<String> testip(String value){
-		return AjaxResult.success("鎿嶄綔鎴愬姛",value);
-	}
+    /**
+     * 娴嬭瘯璇锋眰IP闄愭祦
+     * 鍚屼竴IP璇锋眰鍙楀奖鍝�
+     */
+    @ApiOperation("娴嬭瘯璇锋眰IP闄愭祦")
+    @RateLimiter(count = 2, time = 10, limitType = LimitType.IP)
+    @GetMapping("/testip")
+    public AjaxResult<String> testip(String value) {
+        return AjaxResult.success("鎿嶄綔鎴愬姛", value);
+    }
 
-	/**
-	 * 娴嬭瘯闆嗙兢瀹炰緥闄愭祦
-	 * 鍚姩涓や釜鍚庣鏈嶅姟浜掍笉褰卞搷
-	 */
-	@ApiOperation("娴嬭瘯闆嗙兢瀹炰緥闄愭祦")
-	@RateLimiter(count = 2, time = 10, limitType = LimitType.CLUSTER)
-	@GetMapping("/testcluster")
-	public  AjaxResult<String> testcluster(String value){
-		return AjaxResult.success("鎿嶄綔鎴愬姛",value);
-	}
+    /**
+     * 娴嬭瘯闆嗙兢瀹炰緥闄愭祦
+     * 鍚姩涓や釜鍚庣鏈嶅姟浜掍笉褰卞搷
+     */
+    @ApiOperation("娴嬭瘯闆嗙兢瀹炰緥闄愭祦")
+    @RateLimiter(count = 2, time = 10, limitType = LimitType.CLUSTER)
+    @GetMapping("/testcluster")
+    public AjaxResult<String> testcluster(String value) {
+        return AjaxResult.success("鎿嶄綔鎴愬姛", value);
+    }
 
 }
diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/Swagger3DemoController.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/Swagger3DemoController.java
index a8efb64..6b73d64 100644
--- a/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/Swagger3DemoController.java
+++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/Swagger3DemoController.java
@@ -21,18 +21,18 @@
 @RequestMapping("/swagger/demo")
 public class Swagger3DemoController {
 
-	/**
-	 * 涓婁紶璇锋眰
-	 * 蹇呴』浣跨敤 @RequestPart 娉ㄨВ鏍囨敞涓烘枃浠�
-	 * dataType 蹇呴』涓� "java.io.File"
-	 */
-	@ApiOperation(value = "閫氱敤涓婁紶璇锋眰")
-	@ApiImplicitParams({
-		@ApiImplicitParam(name = "file", value = "鏂囦欢", dataType = "java.io.File", required = true),
-	})
-	@PostMapping(value = "/upload")
-	public AjaxResult<String> upload(@RequestPart("file") MultipartFile file) {
-		return AjaxResult.success("鎿嶄綔鎴愬姛", file.getOriginalFilename());
-	}
+    /**
+     * 涓婁紶璇锋眰
+     * 蹇呴』浣跨敤 @RequestPart 娉ㄨВ鏍囨敞涓烘枃浠�
+     * dataType 蹇呴』涓� "java.io.File"
+     */
+    @ApiOperation(value = "閫氱敤涓婁紶璇锋眰")
+    @ApiImplicitParams({
+        @ApiImplicitParam(name = "file", value = "鏂囦欢", dataType = "java.io.File", required = true),
+    })
+    @PostMapping(value = "/upload")
+    public AjaxResult<String> upload(@RequestPart("file") MultipartFile file) {
+        return AjaxResult.success("鎿嶄綔鎴愬姛", file.getOriginalFilename());
+    }
 
 }
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
index ef117a1..d6e691d 100644
--- a/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestBatchController.java
+++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestBatchController.java
@@ -34,48 +34,48 @@
     /**
      * 鏂板鎵归噺鏂规硶 鍙畬缇庢浛浠� saveBatch 绉掔骇鎻掑叆涓婁竾鏁版嵁 (瀵筸ysql璐熻嵎杈冨ぇ)
      */
-	@ApiOperation(value = "鏂板鎵归噺鏂规硶")
+    @ApiOperation(value = "鏂板鎵归噺鏂规硶")
     @PostMapping("/add")
 //	@DataSource(DataSourceType.SLAVE)
     public AjaxResult<Void> add() {
-		List<TestDemo> list = new ArrayList<>();
-		for (int i = 0; i < 1000; i++) {
-			list.add(new TestDemo().setOrderNum(-1L).setTestKey("鎵归噺鏂板").setValue("娴嬭瘯鏂板"));
-		}
+        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);
     }
 
-	/**
-	 * 鏂板鎴栨洿鏂� 鍙畬缇庢浛浠� saveOrUpdateBatch 楂樻�ц兘
-	 */
-	@ApiOperation(value = "鏂板鎴栨洿鏂版壒閲忔柟娉�")
-	@PostMapping("/addOrUpdate")
+    /**
+     * 鏂板鎴栨洿鏂� 鍙畬缇庢浛浠� saveOrUpdateBatch 楂樻�ц兘
+     */
+    @ApiOperation(value = "鏂板鎴栨洿鏂版壒閲忔柟娉�")
+    @PostMapping("/addOrUpdate")
 //	@DataSource(DataSourceType.SLAVE)
-	public AjaxResult<Void> addOrUpdate() {
-		List<TestDemo> list = new ArrayList<>();
-		for (int i = 0; i < 1000; i++) {
-			list.add(new TestDemo().setOrderNum(-1L).setTestKey("鎵归噺鏂板").setValue("娴嬭瘯鏂板"));
-		}
-		iTestDemoService.saveAll(list);
-		for (int i = 0; i < list.size(); i++) {
-			TestDemo testDemo = list.get(i);
-			testDemo.setTestKey("鎵归噺鏂板鎴栦慨鏀�").setValue("鎵归噺鏂板鎴栦慨鏀�");
-			if (i % 2 == 0) {
-				testDemo.setId(null);
-			}
-		}
-		return toAjax(iTestDemoService.saveOrUpdateAll(list) ? 1 : 0);
-	}
+    public AjaxResult<Void> addOrUpdate() {
+        List<TestDemo> list = new ArrayList<>();
+        for (int i = 0; i < 1000; i++) {
+            list.add(new TestDemo().setOrderNum(-1L).setTestKey("鎵归噺鏂板").setValue("娴嬭瘯鏂板"));
+        }
+        iTestDemoService.saveAll(list);
+        for (int i = 0; i < list.size(); i++) {
+            TestDemo testDemo = list.get(i);
+            testDemo.setTestKey("鎵归噺鏂板鎴栦慨鏀�").setValue("鎵归噺鏂板鎴栦慨鏀�");
+            if (i % 2 == 0) {
+                testDemo.setId(null);
+            }
+        }
+        return toAjax(iTestDemoService.saveOrUpdateAll(list) ? 1 : 0);
+    }
 
     /**
      * 鍒犻櫎鎵归噺鏂规硶
      */
-	@ApiOperation(value = "鍒犻櫎鎵归噺鏂规硶")
+    @ApiOperation(value = "鍒犻櫎鎵归噺鏂规硶")
     @DeleteMapping()
 //	@DataSource(DataSourceType.SLAVE)
     public AjaxResult<Void> remove() {
         return toAjax(iTestDemoService.remove(new LambdaQueryWrapper<TestDemo>()
-			.eq(TestDemo::getOrderNum, -1L)) ? 1 : 0);
+            .eq(TestDemo::getOrderNum, -1L)) ? 1 : 0);
     }
 
 }
diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestDemoController.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestDemoController.java
index a137a3d..7d558ae 100644
--- a/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestDemoController.java
+++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestDemoController.java
@@ -1,6 +1,7 @@
 package com.ruoyi.demo.controller;
 
 import cn.dev33.satoken.annotation.SaCheckPermission;
+import cn.hutool.core.bean.BeanUtil;
 import com.ruoyi.common.annotation.Log;
 import com.ruoyi.common.annotation.RepeatSubmit;
 import com.ruoyi.common.core.controller.BaseController;
@@ -10,16 +11,20 @@
 import com.ruoyi.common.core.validate.EditGroup;
 import com.ruoyi.common.core.validate.QueryGroup;
 import com.ruoyi.common.enums.BusinessType;
+import com.ruoyi.common.utils.ValidatorUtils;
+import com.ruoyi.common.excel.ExcelResult;
 import com.ruoyi.common.utils.poi.ExcelUtil;
+import com.ruoyi.demo.domain.TestDemo;
 import com.ruoyi.demo.domain.bo.TestDemoBo;
+import com.ruoyi.demo.domain.bo.TestDemoImportVo;
 import com.ruoyi.demo.domain.vo.TestDemoVo;
 import com.ruoyi.demo.service.ITestDemoService;
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.*;
 import lombok.RequiredArgsConstructor;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
 
 import javax.servlet.http.HttpServletResponse;
 import javax.validation.constraints.NotEmpty;
@@ -63,20 +68,35 @@
 		return iTestDemoService.customPageList(bo);
 	}
 
-	/**
+    @ApiOperation("瀵煎叆娴嬭瘯-鏍¢獙")
+    @ApiImplicitParams({
+        @ApiImplicitParam(name = "file", value = "瀵煎叆鏂囦欢", dataType = "java.io.File", required = true),
+    })
+    @Log(title = "娴嬭瘯鍗曡〃", businessType = BusinessType.IMPORT)
+    @PreAuthorize("@ss.hasPermi('demo:demo:import')")
+    @PostMapping("/importData")
+    public AjaxResult<Void> importData(@RequestPart("file") MultipartFile file) throws Exception {
+        ExcelResult<TestDemoImportVo> excelResult = ExcelUtil.importExcel(file.getInputStream(), TestDemoImportVo.class, true);
+        List<TestDemoImportVo> volist = excelResult.getList();
+        List<TestDemo> list = BeanUtil.copyToList(volist, TestDemo.class);
+        iTestDemoService.saveAll(list);
+        return AjaxResult.success(excelResult.getAnalysis());
+    }
+
+    /**
      * 瀵煎嚭娴嬭瘯鍗曡〃鍒楄〃
      */
     @ApiOperation("瀵煎嚭娴嬭瘯鍗曡〃鍒楄〃")
     @SaCheckPermission("demo:demo:export")
     @Log(title = "娴嬭瘯鍗曡〃", businessType = BusinessType.EXPORT)
-    @GetMapping("/export")
+    @PostMapping("/export")
     public void export(@Validated TestDemoBo bo, HttpServletResponse response) {
         List<TestDemoVo> list = iTestDemoService.queryList(bo);
-		// 娴嬭瘯闆姳id瀵煎嚭
+        // 娴嬭瘯闆姳id瀵煎嚭
 //        for (TestDemoVo vo : list) {
 //			vo.setId(1234567891234567893L);
 //		}
-		ExcelUtil.exportExcel(list, "娴嬭瘯鍗曡〃", TestDemoVo.class, response);
+        ExcelUtil.exportExcel(list, "娴嬭瘯鍗曡〃", TestDemoVo.class, response);
     }
 
     /**
@@ -85,8 +105,9 @@
     @ApiOperation("鑾峰彇娴嬭瘯鍗曡〃璇︾粏淇℃伅")
     @SaCheckPermission("demo:demo:query")
     @GetMapping("/{id}")
-    public AjaxResult<TestDemoVo> getInfo(@NotNull(message = "涓婚敭涓嶈兘涓虹┖")
-                                                  @PathVariable("id") Long id) {
+    public AjaxResult<TestDemoVo> getInfo(@ApiParam("娴嬭瘯ID")
+                                          @NotNull(message = "涓婚敭涓嶈兘涓虹┖")
+                                          @PathVariable("id") Long id) {
         return AjaxResult.success(iTestDemoService.queryById(id));
     }
 
@@ -98,7 +119,10 @@
     @Log(title = "娴嬭瘯鍗曡〃", businessType = BusinessType.INSERT)
     @RepeatSubmit(interval = 2, timeUnit = TimeUnit.SECONDS, message = "涓嶅厑璁搁噸澶嶆彁浜�")
     @PostMapping()
-    public AjaxResult<Void> add(@Validated(AddGroup.class) @RequestBody TestDemoBo bo) {
+    public AjaxResult<Void> add(@RequestBody TestDemoBo bo) {
+        // 浣跨敤鏍¢獙宸ュ叿瀵规爣 @Validated(AddGroup.class) 娉ㄨВ
+        // 鐢ㄤ簬鍦ㄩ潪 Controller 鐨勫湴鏂规牎楠屽璞�
+        ValidatorUtils.validate(bo, AddGroup.class);
         return toAjax(iTestDemoService.insertByBo(bo) ? 1 : 0);
     }
 
@@ -121,8 +145,9 @@
     @SaCheckPermission("demo:demo:remove")
     @Log(title = "娴嬭瘯鍗曡〃" , businessType = BusinessType.DELETE)
     @DeleteMapping("/{ids}")
-    public AjaxResult<Void> remove(@NotEmpty(message = "涓婚敭涓嶈兘涓虹┖")
-                                       @PathVariable Long[] ids) {
+    public AjaxResult<Void> remove(@ApiParam("娴嬭瘯ID涓�")
+                                   @NotEmpty(message = "涓婚敭涓嶈兘涓虹┖")
+                                   @PathVariable Long[] ids) {
         return toAjax(iTestDemoService.deleteWithValidByIds(Arrays.asList(ids), true) ? 1 : 0);
     }
 }
diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestI18nController.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestI18nController.java
index bb0695f..40b031b 100644
--- a/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestI18nController.java
+++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestI18nController.java
@@ -4,9 +4,16 @@
 import com.ruoyi.common.utils.MessageUtils;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import lombok.Data;
+import org.hibernate.validator.constraints.Range;
+import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
 
 
 /**
@@ -14,6 +21,7 @@
  *
  * @author Lion Li
  */
+@Validated
 @Api(value = "娴嬭瘯鍥介檯鍖栨帶鍒跺櫒", tags = {"娴嬭瘯鍥介檯鍖栫鐞�"})
 @RestController
 @RequestMapping("/demo/i18n")
@@ -27,7 +35,42 @@
 	 */
 	@ApiOperation("閫氳繃code鑾峰彇鍥介檯鍖栧唴瀹�")
 	@GetMapping()
-	public AjaxResult<Void> get(String code) {
+	public AjaxResult<Void> get(@ApiParam("鍥介檯鍖朿ode") String code) {
 		return AjaxResult.success(MessageUtils.message(code));
 	}
+
+    /**
+     * Validator 鏍¢獙鍥介檯鍖�
+     * 涓嶄紶鍊� 鍒嗗埆鏌ョ湅寮傚父杩斿洖
+     *
+     * 娴嬭瘯浣跨敤 not.null
+     */
+    @ApiOperation("Validator 鏍¢獙鍥介檯鍖�")
+    @GetMapping("/test1")
+    public AjaxResult<Void> test1(@NotBlank(message = "{not.null}") String str) {
+        return AjaxResult.success(str);
+    }
+
+    /**
+     * Bean 鏍¢獙鍥介檯鍖�
+     * 涓嶄紶鍊� 鍒嗗埆鏌ョ湅寮傚父杩斿洖
+     *
+     * 娴嬭瘯浣跨敤 not.null
+     */
+    @ApiOperation("Bean 鏍¢獙鍥介檯鍖�")
+    @GetMapping("/test2")
+    public AjaxResult<TestI18nBo> test2(@Validated TestI18nBo bo) {
+        return AjaxResult.success(bo);
+    }
+
+    @Data
+    public static class TestI18nBo {
+
+        @NotBlank(message = "{not.null}")
+        private String name;
+
+        @NotNull(message = "{not.null}")
+        @Range(min = 0, max = 100, message = "{length.not.valid}")
+        private Integer age;
+    }
 }
diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestTreeController.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestTreeController.java
index f1d3b3c..f0231bb 100644
--- a/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestTreeController.java
+++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/TestTreeController.java
@@ -15,6 +15,7 @@
 import com.ruoyi.demo.service.ITestTreeService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
 import lombok.RequiredArgsConstructor;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.validation.annotation.Validated;
@@ -61,7 +62,7 @@
     @GetMapping("/export")
     public void export(@Validated TestTreeBo bo, HttpServletResponse response) {
         List<TestTreeVo> list = iTestTreeService.queryList(bo);
-		ExcelUtil.exportExcel(list, "娴嬭瘯鏍戣〃", TestTreeVo.class, response);
+        ExcelUtil.exportExcel(list, "娴嬭瘯鏍戣〃", TestTreeVo.class, response);
     }
 
     /**
@@ -70,8 +71,9 @@
     @ApiOperation("鑾峰彇娴嬭瘯鏍戣〃璇︾粏淇℃伅")
     @SaCheckPermission("demo:tree:query")
     @GetMapping("/{id}")
-    public AjaxResult<TestTreeVo> getInfo(@NotNull(message = "涓婚敭涓嶈兘涓虹┖")
-                                                  @PathVariable("id") Long id) {
+    public AjaxResult<TestTreeVo> getInfo(@ApiParam("娴嬭瘯鏍慖D")
+                                          @NotNull(message = "涓婚敭涓嶈兘涓虹┖")
+                                          @PathVariable("id") Long id) {
         return AjaxResult.success(iTestTreeService.queryById(id));
     }
 
@@ -106,8 +108,9 @@
     @SaCheckPermission("demo:tree:remove")
     @Log(title = "娴嬭瘯鏍戣〃" , businessType = BusinessType.DELETE)
     @DeleteMapping("/{ids}")
-    public AjaxResult<Void> remove(@NotEmpty(message = "涓婚敭涓嶈兘涓虹┖")
-                                       @PathVariable Long[] ids) {
+    public AjaxResult<Void> remove(@ApiParam("娴嬭瘯鏍慖D涓�")
+                                   @NotEmpty(message = "涓婚敭涓嶈兘涓虹┖")
+                                   @PathVariable Long[] ids) {
         return toAjax(iTestTreeService.deleteWithValidByIds(Arrays.asList(ids), true) ? 1 : 0);
     }
 }
diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/domain/bo/TestDemoImportVo.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/domain/bo/TestDemoImportVo.java
new file mode 100644
index 0000000..7185514
--- /dev/null
+++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/domain/bo/TestDemoImportVo.java
@@ -0,0 +1,61 @@
+package com.ruoyi.demo.domain.bo;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+
+/**
+ * 娴嬭瘯鍗曡〃涓氬姟瀵硅薄 test_demo
+ *
+ * @author Lion Li
+ * @date 2021-07-26
+ */
+@Data
+@ApiModel("娴嬭瘯鍗曡〃涓氬姟瀵硅薄")
+public class TestDemoImportVo {
+
+    /**
+     * 閮ㄩ棬id
+     */
+    @ApiModelProperty("閮ㄩ棬id")
+    @NotNull(message = "閮ㄩ棬id涓嶈兘涓虹┖")
+    @ExcelProperty(value = "閮ㄩ棬id")
+    private Long deptId;
+
+    /**
+     * 鐢ㄦ埛id
+     */
+    @ApiModelProperty("鐢ㄦ埛id")
+    @NotNull(message = "鐢ㄦ埛id涓嶈兘涓虹┖")
+    @ExcelProperty(value = "鐢ㄦ埛id")
+    private Long userId;
+
+    /**
+     * 鎺掑簭鍙�
+     */
+    @ApiModelProperty("鎺掑簭鍙�")
+    @NotNull(message = "鎺掑簭鍙蜂笉鑳戒负绌�")
+    @ExcelProperty(value = "鎺掑簭鍙�")
+    private Long orderNum;
+
+    /**
+     * key閿�
+     */
+    @ApiModelProperty("key閿�")
+    @NotBlank(message = "key閿笉鑳戒负绌�")
+    @ExcelProperty(value = "key閿�")
+    private String testKey;
+
+    /**
+     * 鍊�
+     */
+    @ApiModelProperty("鍊�")
+    @NotBlank(message = "鍊间笉鑳戒负绌�")
+    @ExcelProperty(value = "鍊�")
+    private String value;
+
+}
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
deleted file mode 100644
index 50eb4eb..0000000
--- a/ruoyi-demo/src/main/java/com/ruoyi/demo/feign/FeignTestService.java
+++ /dev/null
@@ -1,27 +0,0 @@
-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;
-import org.springframework.web.bind.annotation.RequestParam;
-
-/**
- * feign娴嬭瘯service
- * 瑙勮寖鎺ュ彛 Service 鏃犳劅璋冪敤
- * 甯搁噺绠$悊璇锋眰璺緞 鏇村姞瑙勮寖
- * 鑷畾涔夊閿欏鐞� 瀹夊叏鍙潬 (闇�鑷閰嶇疆鐔旀柇鍣�)
- * 澧炲姞 feign 鐨勭洰鐨勪负浣� http 璇锋眰鎺ュ彛鍖�
- *
- * @author Lion Li
- * @deprecated 鐢变簬浣跨敤浜烘暟杈冨皯 鍐冲畾涓� 3.4.0 鐗堟湰绉婚櫎
- */
-@FeignClient(
-	name = FeignTestConstant.BAIDU_NAME,
-	url = FeignTestConstant.BAIDU_URL,
-	fallback = FeignTestFallback.class)
-public interface FeignTestService {
-
-    @GetMapping("/s")
-    String search(@RequestParam("wd") String wd);
-}
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
deleted file mode 100644
index 28dfa8a..0000000
--- a/ruoyi-demo/src/main/java/com/ruoyi/demo/feign/constant/FeignTestConstant.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package com.ruoyi.demo.feign.constant;
-
-/**
- * @deprecated 鐢变簬浣跨敤浜烘暟杈冨皯 鍐冲畾涓� 3.4.0 鐗堟湰绉婚櫎
- */
-@Deprecated
-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/feign/fallback/FeignTestFallback.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/feign/fallback/FeignTestFallback.java
deleted file mode 100644
index 8e81ad7..0000000
--- a/ruoyi-demo/src/main/java/com/ruoyi/demo/feign/fallback/FeignTestFallback.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package com.ruoyi.demo.feign.fallback;
-
-
-import com.ruoyi.demo.feign.FeignTestService;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.stereotype.Component;
-
-/**
- * feign娴嬭瘯fallback
- * 鑷畾涔夊皝瑁呯粨鏋勪綋鐔旀柇
- * 闇�閲嶅啓瑙g爜鍣� 鏍规嵁鑷畾涔夊疄浣� 鑷瑙f瀽鐔旀柇
- *
- * 鐔旀柇鍣ㄩ渶瑕佽嚜琛屾坊鍔犻厤缃�
- *
- * @see {com.ruoyi.framework.config.FeignConfig#errorDecoder()}
- * @author Lion Li
- * @deprecated 鐢变簬浣跨敤浜烘暟杈冨皯 鍐冲畾涓� 3.4.0 鐗堟湰绉婚櫎
- */
-@Slf4j
-@Component
-public class FeignTestFallback implements FeignTestService {
-
-    @Override
-    public String search(String wd) {
-        log.error("fallback");
-        return "鎶ラ敊鍟�";
-    }
-}
diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/feign/fallback/package-info.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/feign/fallback/package-info.java
deleted file mode 100644
index 47983a0..0000000
--- a/ruoyi-demo/src/main/java/com/ruoyi/demo/feign/fallback/package-info.java
+++ /dev/null
@@ -1 +0,0 @@
-package com.ruoyi.demo.feign.fallback;
\ No newline at end of file
diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/feign/package-info.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/feign/package-info.java
deleted file mode 100644
index 91e4b4a..0000000
--- a/ruoyi-demo/src/main/java/com/ruoyi/demo/feign/package-info.java
+++ /dev/null
@@ -1 +0,0 @@
-package com.ruoyi.demo.feign;
\ No newline at end of file
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 efbbffc..dccea61 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
@@ -2,11 +2,9 @@
 
 import com.baomidou.mybatisplus.core.conditions.Wrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.ruoyi.common.core.mybatisplus.cache.MybatisPlusRedisCache;
 import com.ruoyi.common.core.mybatisplus.core.BaseMapperPlus;
 import com.ruoyi.demo.domain.TestDemo;
 import com.ruoyi.demo.domain.vo.TestDemoVo;
-import org.apache.ibatis.annotations.CacheNamespace;
 import org.apache.ibatis.annotations.Param;
 
 /**
@@ -15,8 +13,6 @@
  * @author Lion Li
  * @date 2021-07-26
  */
-// 濡備娇闇�鍒囨崲鏁版嵁婧� 璇峰嬁浣跨敤缂撳瓨 浼氶�犳垚鏁版嵁涓嶄竴鑷寸幇璞�
-@CacheNamespace(implementation = MybatisPlusRedisCache.class, eviction = MybatisPlusRedisCache.class)
 public interface TestDemoMapper extends BaseMapperPlus<TestDemo> {
 
     Page<TestDemoVo> customPageList(@Param("page") Page<TestDemo> page, @Param("ew") Wrapper<TestDemo> wrapper);
diff --git a/ruoyi-demo/src/main/resources/mapper/demo/package-info.md b/ruoyi-demo/src/main/resources/mapper/demo/package-info.md
deleted file mode 100644
index e69de29..0000000
--- a/ruoyi-demo/src/main/resources/mapper/demo/package-info.md
+++ /dev/null
diff --git a/ruoyi-demo/src/main/resources/mapper/package-info.md b/ruoyi-demo/src/main/resources/mapper/package-info.md
new file mode 100644
index 0000000..c938b1e
--- /dev/null
+++ b/ruoyi-demo/src/main/resources/mapper/package-info.md
@@ -0,0 +1,3 @@
+java鍖呬娇鐢� `.` 鍒嗗壊 resource 鐩綍浣跨敤 `/` 鍒嗗壊
+<br>
+姝ゆ枃浠剁洰鐨� 闃叉鏂囦欢澶圭矘杩炴壘涓嶅埌 `xml` 鏂囦欢
\ No newline at end of file
diff --git a/ruoyi-extend/ruoyi-monitor-admin/pom.xml b/ruoyi-extend/ruoyi-monitor-admin/pom.xml
index 33a7851..fc321bd 100644
--- a/ruoyi-extend/ruoyi-monitor-admin/pom.xml
+++ b/ruoyi-extend/ruoyi-monitor-admin/pom.xml
@@ -28,6 +28,12 @@
             <groupId>de.codecentric</groupId>
             <artifactId>spring-boot-admin-starter-server</artifactId>
         </dependency>
+
+        <dependency>
+            <groupId>de.codecentric</groupId>
+            <artifactId>spring-boot-admin-starter-client</artifactId>
+        </dependency>
+
     </dependencies>
 
     <build>
diff --git a/ruoyi-extend/ruoyi-monitor-admin/src/main/java/com/ruoyi/monitor/admin/config/SecurityConfig.java b/ruoyi-extend/ruoyi-monitor-admin/src/main/java/com/ruoyi/monitor/admin/config/SecurityConfig.java
index ca9072c..7335e2f 100644
--- a/ruoyi-extend/ruoyi-monitor-admin/src/main/java/com/ruoyi/monitor/admin/config/SecurityConfig.java
+++ b/ruoyi-extend/ruoyi-monitor-admin/src/main/java/com/ruoyi/monitor/admin/config/SecurityConfig.java
@@ -34,6 +34,8 @@
 			//鎺堜簣瀵规墍鏈夐潤鎬佽祫浜у拰鐧诲綍椤甸潰鐨勫叕鍏辫闂潈闄愩��
 			.antMatchers(adminContextPath + "/assets/**").permitAll()
 			.antMatchers(adminContextPath + "/login").permitAll()
+            .antMatchers("/actuator").anonymous()
+            .antMatchers("/actuator/**").anonymous()
 			//蹇呴』瀵规瘡涓叾浠栬姹傝繘琛岃韩浠介獙璇�
 			.anyRequest().authenticated().and()
 			//閰嶇疆鐧诲綍鍜屾敞閿�
diff --git a/ruoyi-extend/ruoyi-monitor-admin/src/main/resources/application-dev.yml b/ruoyi-extend/ruoyi-monitor-admin/src/main/resources/application-dev.yml
new file mode 100644
index 0000000..829314b
--- /dev/null
+++ b/ruoyi-extend/ruoyi-monitor-admin/src/main/resources/application-dev.yml
@@ -0,0 +1,14 @@
+--- # 鐩戞帶閰嶇疆
+spring:
+  boot:
+    admin:
+      # Spring Boot Admin Client 瀹㈡埛绔殑鐩稿叧閰嶇疆
+      client:
+        # 澧炲姞瀹㈡埛绔紑鍏�
+        enabled: true
+        # 璁剧疆 Spring Boot Admin Server 鍦板潃
+        url: http://localhost:9090/admin
+        instance:
+          prefer-ip: true # 娉ㄥ唽瀹炰緥鏃讹紝浼樺厛浣跨敤 IP
+        username: ruoyi
+        password: 123456
diff --git a/ruoyi-extend/ruoyi-monitor-admin/src/main/resources/application-prod.yml b/ruoyi-extend/ruoyi-monitor-admin/src/main/resources/application-prod.yml
new file mode 100644
index 0000000..e8cac13
--- /dev/null
+++ b/ruoyi-extend/ruoyi-monitor-admin/src/main/resources/application-prod.yml
@@ -0,0 +1,14 @@
+--- # 鐩戞帶閰嶇疆
+spring:
+  boot:
+    admin:
+      # Spring Boot Admin Client 瀹㈡埛绔殑鐩稿叧閰嶇疆
+      client:
+        # 澧炲姞瀹㈡埛绔紑鍏�
+        enabled: true
+        # 璁剧疆 Spring Boot Admin Server 鍦板潃
+        url: http://172.30.0.90:9090/admin
+        instance:
+          prefer-ip: true # 娉ㄥ唽瀹炰緥鏃讹紝浼樺厛浣跨敤 IP
+        username: ruoyi
+        password: 123456
diff --git a/ruoyi-extend/ruoyi-monitor-admin/src/main/resources/application.yml b/ruoyi-extend/ruoyi-monitor-admin/src/main/resources/application.yml
index 631f3e7..bf0db56 100644
--- a/ruoyi-extend/ruoyi-monitor-admin/src/main/resources/application.yml
+++ b/ruoyi-extend/ruoyi-monitor-admin/src/main/resources/application.yml
@@ -1,6 +1,12 @@
 server:
   port: 9090
+spring:
+  application:
+    name: ruoyi-monitor-admin
+  profiles:
+    active: @profiles.active@
 
+--- # 鐩戞帶涓績鏈嶅姟绔厤缃�
 spring:
   security:
     user:
@@ -9,3 +15,17 @@
   boot:
     admin:
       context-path: /admin
+
+--- # Actuator 鐩戞帶绔偣鐨勯厤缃」
+management:
+  endpoints:
+    web:
+      # Actuator 鎻愪緵鐨� API 鎺ュ彛鐨勬牴鐩綍銆傞粯璁や负 /actuator
+      base-path: /actuator
+      exposure:
+        # 闇�瑕佸紑鏀剧殑绔偣銆傞粯璁ゅ�煎彧鎵撳紑 health 鍜� info 涓や釜绔偣銆傞�氳繃璁剧疆 * 锛屽彲浠ュ紑鏀炬墍鏈夌鐐广��
+        # 鐢熶骇鐜涓嶅缓璁斁寮�鎵�鏈� 鏍规嵁椤圭洰闇�姹傛斁寮�鍗冲彲
+        include: @endpoints.include@
+  endpoint:
+    logfile:
+      external-file: ./logs/ruoyi-monitor-admin.log
diff --git a/ruoyi-extend/ruoyi-xxl-job-admin/pom.xml b/ruoyi-extend/ruoyi-xxl-job-admin/pom.xml
index a2b198f..26892d4 100644
--- a/ruoyi-extend/ruoyi-xxl-job-admin/pom.xml
+++ b/ruoyi-extend/ruoyi-xxl-job-admin/pom.xml
@@ -71,6 +71,11 @@
 			<version>${mysql-connector-java.version}</version>
 		</dependency>
 
+        <dependency>
+            <groupId>de.codecentric</groupId>
+            <artifactId>spring-boot-admin-starter-client</artifactId>
+        </dependency>
+
 		<!-- xxl-job-core -->
 		<dependency>
 			<groupId>com.xuxueli</groupId>
diff --git a/ruoyi-extend/ruoyi-xxl-job-admin/src/main/resources/application-dev.yml b/ruoyi-extend/ruoyi-xxl-job-admin/src/main/resources/application-dev.yml
index 065b342..540a323 100644
--- a/ruoyi-extend/ruoyi-xxl-job-admin/src/main/resources/application-dev.yml
+++ b/ruoyi-extend/ruoyi-xxl-job-admin/src/main/resources/application-dev.yml
@@ -1,3 +1,18 @@
+--- # 鐩戞帶閰嶇疆
+spring:
+  boot:
+    admin:
+      # Spring Boot Admin Client 瀹㈡埛绔殑鐩稿叧閰嶇疆
+      client:
+        # 澧炲姞瀹㈡埛绔紑鍏�
+        enabled: true
+        # 璁剧疆 Spring Boot Admin Server 鍦板潃
+        url: http://localhost:9090/admin
+        instance:
+          prefer-ip: true # 娉ㄥ唽瀹炰緥鏃讹紝浼樺厛浣跨敤 IP
+        username: ruoyi
+        password: 123456
+
 --- # 鏁版嵁搴撻厤缃�
 spring:
   datasource:
diff --git a/ruoyi-extend/ruoyi-xxl-job-admin/src/main/resources/application-prod.yml b/ruoyi-extend/ruoyi-xxl-job-admin/src/main/resources/application-prod.yml
index 2994909..bcec9d8 100644
--- a/ruoyi-extend/ruoyi-xxl-job-admin/src/main/resources/application-prod.yml
+++ b/ruoyi-extend/ruoyi-xxl-job-admin/src/main/resources/application-prod.yml
@@ -1,3 +1,18 @@
+--- # 鐩戞帶閰嶇疆
+spring:
+  boot:
+    admin:
+      # Spring Boot Admin Client 瀹㈡埛绔殑鐩稿叧閰嶇疆
+      client:
+        # 澧炲姞瀹㈡埛绔紑鍏�
+        enabled: true
+        # 璁剧疆 Spring Boot Admin Server 鍦板潃
+        url: http://172.30.0.90:9090/admin
+        instance:
+          prefer-ip: true # 娉ㄥ唽瀹炰緥鏃讹紝浼樺厛浣跨敤 IP
+        username: ruoyi
+        password: 123456
+
 --- # 鏁版嵁搴撻厤缃�
 spring:
   datasource:
diff --git a/ruoyi-extend/ruoyi-xxl-job-admin/src/main/resources/application.yml b/ruoyi-extend/ruoyi-xxl-job-admin/src/main/resources/application.yml
index edafdb0..2022720 100644
--- a/ruoyi-extend/ruoyi-xxl-job-admin/src/main/resources/application.yml
+++ b/ruoyi-extend/ruoyi-xxl-job-admin/src/main/resources/application.yml
@@ -4,6 +4,8 @@
   servlet:
     context-path: /xxl-job-admin
 spring:
+  application:
+    name: ruoyi-xxl-job-admin
   profiles:
     active: @profiles.active@
   mvc:
@@ -28,13 +30,22 @@
     suffix: .ftl
     templateLoaderPath: classpath:/templates/
 
---- # 鐩戞帶閰嶇疆
+--- # Actuator 鐩戞帶绔偣鐨勯厤缃」
 management:
   health:
     mail:
       enabled: false
-  server:
-    base-path: /actuator
+  endpoints:
+    web:
+      # Actuator 鎻愪緵鐨� API 鎺ュ彛鐨勬牴鐩綍銆傞粯璁や负 /actuator
+      base-path: /actuator
+      exposure:
+        # 闇�瑕佸紑鏀剧殑绔偣銆傞粯璁ゅ�煎彧鎵撳紑 health 鍜� info 涓や釜绔偣銆傞�氳繃璁剧疆 * 锛屽彲浠ュ紑鏀炬墍鏈夌鐐广��
+        # 鐢熶骇鐜涓嶅缓璁斁寮�鎵�鏈� 鏍规嵁椤圭洰闇�姹傛斁寮�鍗冲彲
+        include: @endpoints.include@
+  endpoint:
+    logfile:
+      external-file: ./logs/ruoyi-xxl-job-admin.log
 
 --- # xxljob绯荤粺閰嶇疆
 xxl:
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/DataScopeAspect.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/DataScopeAspect.java
index 393b2e6..dcf8058 100644
--- a/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/DataScopeAspect.java
+++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/DataScopeAspect.java
@@ -7,6 +7,7 @@
 import com.ruoyi.common.utils.SecurityUtils;
 import com.ruoyi.common.utils.StringUtils;
 import com.ruoyi.common.utils.reflect.ReflectUtils;
+import com.ruoyi.common.utils.spring.SpringUtils;
 import org.aspectj.lang.JoinPoint;
 import org.aspectj.lang.annotation.Aspect;
 import org.aspectj.lang.annotation.Before;
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/RepeatSubmitAspect.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/RepeatSubmitAspect.java
index bb8b0f1..fd02a9b 100644
--- a/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/RepeatSubmitAspect.java
+++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/RepeatSubmitAspect.java
@@ -1,13 +1,12 @@
 package com.ruoyi.framework.aspectj;
 
 import cn.dev33.satoken.SaManager;
-import cn.hutool.core.util.StrUtil;
 import cn.hutool.crypto.SecureUtil;
-import com.baomidou.lock.LockInfo;
-import com.baomidou.lock.LockTemplate;
 import com.ruoyi.common.annotation.RepeatSubmit;
 import com.ruoyi.common.constant.Constants;
 import com.ruoyi.common.exception.ServiceException;
+import com.ruoyi.common.utils.JsonUtils;
+import com.ruoyi.common.utils.RedisUtils;
 import com.ruoyi.common.utils.ServletUtils;
 import com.ruoyi.common.utils.StringUtils;
 import com.ruoyi.framework.config.properties.RepeatSubmitProperties;
@@ -18,8 +17,14 @@
 import org.aspectj.lang.annotation.Before;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
+import org.springframework.validation.BindingResult;
+import org.springframework.web.multipart.MultipartFile;
 
 import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.Collection;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
 
 /**
  * 闃叉閲嶅鎻愪氦
@@ -33,7 +38,6 @@
 public class RepeatSubmitAspect {
 
     private final RepeatSubmitProperties repeatSubmitProperties;
-    private final LockTemplate lockTemplate;
 
     @Before("@annotation(repeatSubmit)")
     public void doBefore(JoinPoint point, RepeatSubmit repeatSubmit) throws Throwable {
@@ -46,7 +50,7 @@
             throw new ServiceException("閲嶅鎻愪氦闂撮殧鏃堕棿涓嶈兘灏忎簬'1'绉�");
         }
         HttpServletRequest request = ServletUtils.getRequest();
-        String nowParams = StrUtil.join(",", point.getArgs());
+        String nowParams = argsArrayToString(point.getArgs());
 
         // 璇锋眰鍦板潃锛堜綔涓哄瓨鏀綾ache鐨刱ey鍊硷級
         String url = request.getRequestURI();
@@ -59,10 +63,58 @@
         submitKey = SecureUtil.md5(submitKey + ":" + nowParams);
         // 鍞竴鏍囪瘑锛堟寚瀹歬ey + 娑堟伅澶达級
         String cacheRepeatKey = Constants.REPEAT_SUBMIT_KEY + submitKey;
-        LockInfo lock = lockTemplate.lock(cacheRepeatKey, interval, interval / 2);
-        if (lock == null) {
+        String key = RedisUtils.getCacheObject(cacheRepeatKey);
+        if (key == null) {
+            RedisUtils.setCacheObject(cacheRepeatKey, "", interval, TimeUnit.MILLISECONDS);
+        } else {
             throw new ServiceException(repeatSubmit.message());
         }
     }
 
+    /**
+     * 鍙傛暟鎷艰
+     */
+    private String argsArrayToString(Object[] paramsArray) {
+        StringBuilder params = new StringBuilder();
+        if (paramsArray != null && paramsArray.length > 0) {
+            for (Object o : paramsArray) {
+                if (StringUtils.isNotNull(o) && !isFilterObject(o)) {
+                    try {
+                        params.append(JsonUtils.toJsonString(o)).append(" ");
+                    } catch (Exception e) {
+                        e.printStackTrace();
+                    }
+                }
+            }
+        }
+        return params.toString().trim();
+    }
+
+    /**
+     * 鍒ゆ柇鏄惁闇�瑕佽繃婊ょ殑瀵硅薄銆�
+     *
+     * @param o 瀵硅薄淇℃伅銆�
+     * @return 濡傛灉鏄渶瑕佽繃婊ょ殑瀵硅薄锛屽垯杩斿洖true锛涘惁鍒欒繑鍥瀎alse銆�
+     */
+    @SuppressWarnings("rawtypes")
+    public boolean isFilterObject(final Object o) {
+        Class<?> clazz = o.getClass();
+        if (clazz.isArray()) {
+            return clazz.getComponentType().isAssignableFrom(MultipartFile.class);
+        } else if (Collection.class.isAssignableFrom(clazz)) {
+            Collection collection = (Collection) o;
+            for (Object value : collection) {
+                return value instanceof MultipartFile;
+            }
+        } else if (Map.class.isAssignableFrom(clazz)) {
+            Map map = (Map) o;
+            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/config/FeignConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/FeignConfig.java
deleted file mode 100644
index 8b432ad..0000000
--- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/FeignConfig.java
+++ /dev/null
@@ -1,95 +0,0 @@
-package com.ruoyi.framework.config;
-
-import feign.*;
-import okhttp3.ConnectionPool;
-import okhttp3.OkHttpClient;
-import org.springframework.boot.autoconfigure.AutoConfigureBefore;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
-import org.springframework.cloud.openfeign.EnableFeignClients;
-import org.springframework.cloud.openfeign.FeignAutoConfiguration;
-import org.springframework.cloud.openfeign.support.SpringMvcContract;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
-import java.util.concurrent.TimeUnit;
-
-/**
- * openfeign閰嶇疆绫�
- *
- * @author Lion Li
- * @deprecated 鐢变簬浣跨敤浜烘暟杈冨皯 鍐冲畾涓� 3.4.0 鐗堟湰绉婚櫎
- */
-@Deprecated
-@EnableFeignClients("${feign.package}")
-@Configuration
-@ConditionalOnClass(Feign.class)
-@AutoConfigureBefore(FeignAutoConfiguration.class)
-public class FeignConfig {
-
-    @Bean
-    public OkHttpClient okHttpClient(){
-        return new OkHttpClient.Builder()
-                .readTimeout(60, TimeUnit.SECONDS)
-                .connectTimeout(60, TimeUnit.SECONDS)
-                .writeTimeout(120, TimeUnit.SECONDS)
-                .connectionPool(new ConnectionPool())
-                .build();
-    }
-
-    @Bean
-    public Contract feignContract() {
-        return new SpringMvcContract();
-    }
-
-    @Bean
-    public Logger.Level feignLoggerLevel() {
-        return Logger.Level.BASIC;
-    }
-
-    @Bean
-    public Request.Options feignRequestOptions() {
-        return new Request.Options(10, TimeUnit.SECONDS, 60,TimeUnit.SECONDS,true);
-    }
-
-    @Bean
-    public Retryer feignRetry() {
-        return new Retryer.Default();
-    }
-
-//	/**
-//	 * 鑷畾涔夊紓甯歌В鐮佸櫒
-//	 * 鐢ㄤ簬鑷畾涔夎繑鍥炰綋寮傚父鐔旀柇
-//	 */
-//	@Bean
-//	public ErrorDecoder errorDecoder() {
-//		return new CustomErrorDecoder();
-//	}
-//
-//
-//	/**
-//	 * 鑷畾涔夎繑鍥炰綋瑙g爜鍣�
-//	 */
-//	@Slf4j
-//	public static class CustomErrorDecoder implements ErrorDecoder {
-//
-//		@Override
-//		public Exception decode(String methodKey, Response response) {
-//			Exception exception = null;
-//			try {
-//				// 鑾峰彇鍘熷鐨勮繑鍥炲唴瀹�
-//				String json = JsonUtils.toJsonString(response.body().asReader(StandardCharsets.UTF_8));
-//				exception = new RuntimeException(json);
-//				// 灏嗚繑鍥炲唴瀹瑰弽搴忓垪鍖栦负Result锛岃繖閲屽簲鏍规嵁鑷韩椤圭洰浣滀慨鏀�
-//				AjaxResult result = JsonUtils.parseObject(json, AjaxResult.class);
-//				// 涓氬姟寮傚父鎶涘嚭绠�鍗曠殑 RuntimeException锛屼繚鐣欏師鏉ラ敊璇俊鎭�
-//				if (result.getCode() != 200) {
-//					exception = new RuntimeException(result.getMsg());
-//				}
-//			} catch (IOException e) {
-//				log.error(e.getMessage(), e);
-//			}
-//			return exception;
-//		}
-//	}
-
-}
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 459020d..6f3b099 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
@@ -20,7 +20,6 @@
  * @author Lion Li
  */
 @Configuration
-@ConditionalOnProperty(value = "xss.enabled", havingValue = "true")
 public class FilterConfig {
 
     @Autowired
@@ -28,6 +27,7 @@
 
     @SuppressWarnings({"rawtypes", "unchecked"})
     @Bean
+    @ConditionalOnProperty(value = "xss.enabled", havingValue = "true")
     public FilterRegistrationBean xssFilterRegistration() {
         FilterRegistrationBean registration = new FilterRegistrationBean();
         registration.setDispatcherTypes(DispatcherType.REQUEST);
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/I18nConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/I18nConfig.java
index 48b341b..20b52a8 100644
--- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/I18nConfig.java
+++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/I18nConfig.java
@@ -1,7 +1,6 @@
 package com.ruoyi.framework.config;
 
 import cn.hutool.core.util.StrUtil;
-import org.jetbrains.annotations.NotNull;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.web.servlet.LocaleResolver;
@@ -28,7 +27,6 @@
 	 */
 	static class I18nLocaleResolver implements LocaleResolver {
 
-		@NotNull
 		@Override
 		public Locale resolveLocale(HttpServletRequest httpServletRequest) {
 			String language = httpServletRequest.getHeader("content-language");
@@ -41,7 +39,7 @@
 		}
 
 		@Override
-		public void setLocale(@NotNull HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Locale locale) {
+		public void setLocale(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Locale locale) {
 
 		}
 	}
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SwaggerConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SwaggerConfig.java
index 937be35..4a956a2 100644
--- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SwaggerConfig.java
+++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SwaggerConfig.java
@@ -2,6 +2,7 @@
 
 import cn.dev33.satoken.config.SaTokenConfig;
 import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j;
+import com.github.xiaoymin.knife4j.spring.extension.OpenApiExtensionResolver;
 import com.ruoyi.common.utils.StringUtils;
 import com.ruoyi.common.utils.spring.SpringUtils;
 import com.ruoyi.framework.config.properties.SwaggerProperties;
@@ -34,6 +35,9 @@
     @Autowired
     private SaTokenConfig saTokenConfig;
 
+    @Autowired
+    private OpenApiExtensionResolver openApiExtensionResolver;
+
     /**
      * 鍒涘缓API
      */
@@ -58,6 +62,7 @@
 					// 璁剧疆瀹夊叏妯″紡锛宻wagger鍙互璁剧疆璁块棶token
 					.securitySchemes(securitySchemes())
 					.securityContexts(securityContexts())
+                    .extensions(openApiExtensionResolver.buildExtensions(group.getName()))
 					.pathMapping(swaggerProperties.getPathMapping());
 			String beanName = StringUtils.substringAfterLast(basePackage, ".") + "Docket";
 			SpringUtils.registerBean(beanName, docket);
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/TLogConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/TLogConfig.java
index 68bc425..c1665d9 100644
--- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/TLogConfig.java
+++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/TLogConfig.java
@@ -1,7 +1,6 @@
 package com.ruoyi.framework.config;
 
 import com.yomahub.tlog.core.aop.AspectLogAop;
-import com.yomahub.tlog.feign.filter.TLogFeignFilter;
 import com.yomahub.tlog.spring.TLogPropertyInit;
 import com.yomahub.tlog.spring.TLogSpringAware;
 import com.yomahub.tlog.springboot.property.TLogProperty;
@@ -39,11 +38,6 @@
     @Bean
     public AspectLogAop aspectLogAop() {
         return new AspectLogAop();
-    }
-
-    @Bean
-    public TLogFeignFilter tLogFeignFilter() {
-        return new TLogFeignFilter();
     }
 
 }
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ValidatorConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ValidatorConfig.java
index 258e855..0a2007c 100644
--- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ValidatorConfig.java
+++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ValidatorConfig.java
@@ -1,12 +1,14 @@
 package com.ruoyi.framework.config;
 
 import org.hibernate.validator.HibernateValidator;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.MessageSource;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
+import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
 
-import javax.validation.Validation;
 import javax.validation.Validator;
-import javax.validation.ValidatorFactory;
+import java.util.Properties;
 
 /**
  * 鏍¢獙妗嗘灦閰嶇疆绫�
@@ -16,16 +18,26 @@
 @Configuration
 public class ValidatorConfig {
 
+    @Autowired
+    private MessageSource messageSource;
+
     /**
      * 閰嶇疆鏍¢獙妗嗘灦 蹇�熻繑鍥炴ā寮�
      */
     @Bean
     public Validator validator() {
-        ValidatorFactory validatorFactory = Validation.byProvider(HibernateValidator.class)
-                .configure()
-                .failFast(true)
-                .buildValidatorFactory();
-        return validatorFactory.getValidator();
+        LocalValidatorFactoryBean factoryBean = new LocalValidatorFactoryBean();
+        // 鍥介檯鍖�
+        factoryBean.setValidationMessageSource(messageSource);
+        // 璁剧疆浣跨敤 HibernateValidator 鏍¢獙鍣�
+        factoryBean.setProviderClass(HibernateValidator.class);
+        Properties properties = new Properties();
+        // 璁剧疆 蹇�熷紓甯歌繑鍥�
+        properties.setProperty("hibernate.validator.fail_fast", "true");
+        factoryBean.setValidationProperties(properties);
+        // 鍔犺浇閰嶇疆
+        factoryBean.afterPropertiesSet();
+        return factoryBean.getValidator();
     }
 
 }
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 4ed5366..ef77a21 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
@@ -14,7 +14,7 @@
  *
  * @author Lion Li
  */
-@Slf4j(topic = "sys-user")
+@Slf4j
 @Component
 public class ShutdownManager {
 
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/exception/GlobalExceptionHandler.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/exception/GlobalExceptionHandler.java
index d0f00c6..2be7afa 100644
--- a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/exception/GlobalExceptionHandler.java
+++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/exception/GlobalExceptionHandler.java
@@ -16,7 +16,9 @@
 import org.springframework.web.bind.annotation.RestControllerAdvice;
 
 import javax.servlet.http.HttpServletRequest;
+import javax.validation.ConstraintViolation;
 import javax.validation.ConstraintViolationException;
+import java.util.stream.Collectors;
 
 /**
  * 鍏ㄥ眬寮傚父澶勭悊鍣�
@@ -104,7 +106,9 @@
     @ExceptionHandler(BindException.class)
     public AjaxResult<Void> handleBindException(BindException e) {
         log.error(e.getMessage(), e);
-        String message = e.getAllErrors().get(0).getDefaultMessage();
+        String message = e.getAllErrors().stream()
+            .map(DefaultMessageSourceResolvable::getDefaultMessage)
+            .collect(Collectors.joining(", "));
         return AjaxResult.error(message);
     }
 
@@ -114,7 +118,9 @@
     @ExceptionHandler(ConstraintViolationException.class)
     public AjaxResult<Void> constraintViolationException(ConstraintViolationException e) {
         log.error(e.getMessage(), e);
-        String message = e.getConstraintViolations().iterator().next().getMessage();
+        String message = e.getConstraintViolations().stream()
+            .map(ConstraintViolation::getMessage)
+            .collect(Collectors.joining(", "));
         return AjaxResult.error(message);
     }
 
diff --git a/ruoyi-generator/pom.xml b/ruoyi-generator/pom.xml
index 668489f..045ecba 100644
--- a/ruoyi-generator/pom.xml
+++ b/ruoyi-generator/pom.xml
@@ -20,7 +20,7 @@
         <!--velocity浠g爜鐢熸垚浣跨敤妯℃澘 -->
         <dependency>
             <groupId>org.apache.velocity</groupId>
-            <artifactId>velocity</artifactId>
+            <artifactId>velocity-engine-core</artifactId>
         </dependency>
 
         <!-- 閫氱敤宸ュ叿-->
diff --git a/ruoyi-generator/src/main/java/com/ruoyi/generator/controller/GenController.java b/ruoyi-generator/src/main/java/com/ruoyi/generator/controller/GenController.java
index 55c93d8..af85c84 100644
--- a/ruoyi-generator/src/main/java/com/ruoyi/generator/controller/GenController.java
+++ b/ruoyi-generator/src/main/java/com/ruoyi/generator/controller/GenController.java
@@ -2,6 +2,7 @@
 
 import cn.dev33.satoken.annotation.SaCheckPermission;
 import cn.hutool.core.convert.Convert;
+import cn.hutool.core.io.IoUtil;
 import com.ruoyi.common.annotation.Log;
 import com.ruoyi.common.core.controller.BaseController;
 import com.ruoyi.common.core.domain.AjaxResult;
@@ -14,7 +15,6 @@
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import lombok.RequiredArgsConstructor;
-import org.apache.commons.io.IOUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
@@ -201,6 +201,6 @@
         response.setHeader("Content-Disposition", "attachment; filename=\"ruoyi.zip\"");
         response.addHeader("Content-Length", "" + data.length);
         response.setContentType("application/octet-stream; charset=UTF-8");
-        IOUtils.write(data, response.getOutputStream());
+        IoUtil.write(response.getOutputStream(), false, data);
     }
 }
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 62fe67a..b53393f 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
@@ -2,6 +2,7 @@
 
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.convert.Convert;
+import cn.hutool.core.io.IoUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.ruoyi.common.constant.Constants;
 import com.ruoyi.common.constant.GenConstants;
@@ -21,7 +22,7 @@
 import com.ruoyi.generator.util.VelocityInitializer;
 import com.ruoyi.generator.util.VelocityUtils;
 import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.io.IOUtils;
+import org.apache.poi.util.IOUtils;
 import org.apache.velocity.Template;
 import org.apache.velocity.VelocityContext;
 import org.apache.velocity.app.Velocity;
@@ -33,6 +34,7 @@
 import java.io.File;
 import java.io.IOException;
 import java.io.StringWriter;
+import java.nio.charset.StandardCharsets;
 import java.util.*;
 import java.util.stream.Collectors;
 import java.util.zip.ZipEntry;
@@ -341,8 +343,8 @@
             try {
                 // 娣诲姞鍒皕ip
                 zip.putNextEntry(new ZipEntry(VelocityUtils.getFileName(template, table)));
-                IOUtils.write(sw.toString(), zip, Constants.UTF8);
-                IOUtils.closeQuietly(sw);
+                IoUtil.write(zip, StandardCharsets.UTF_8, false, sw.toString());
+                IoUtil.close(sw);
                 zip.flush();
                 zip.closeEntry();
             } catch (IOException e) {
diff --git a/ruoyi-generator/src/main/java/com/ruoyi/generator/util/VelocityInitializer.java b/ruoyi-generator/src/main/java/com/ruoyi/generator/util/VelocityInitializer.java
index 461bc2c..a81bd51 100644
--- a/ruoyi-generator/src/main/java/com/ruoyi/generator/util/VelocityInitializer.java
+++ b/ruoyi-generator/src/main/java/com/ruoyi/generator/util/VelocityInitializer.java
@@ -19,10 +19,9 @@
         Properties p = new Properties();
         try {
             // 鍔犺浇classpath鐩綍涓嬬殑vm鏂囦欢
-            p.setProperty("file.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
+            p.setProperty("resource.loader.file.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
             // 瀹氫箟瀛楃闆�
             p.setProperty(Velocity.INPUT_ENCODING, Constants.UTF8);
-            p.setProperty(Velocity.OUTPUT_ENCODING, Constants.UTF8);
             // 鍒濆鍖朧elocity寮曟搸锛屾寚瀹氶厤缃甈roperties
             Velocity.init(p);
         } catch (Exception e) {
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 0a3ffbc..d2e0e3a 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
@@ -247,7 +247,8 @@
         List<String> dicts = new ArrayList<String>();
         for (GenTableColumn column : columns) {
             if (!column.isSuperColumn() && StringUtils.isNotEmpty(column.getDictType()) && StringUtils.equalsAny(
-                    column.getHtmlType(), new String[]{GenConstants.HTML_SELECT, GenConstants.HTML_RADIO})) {
+                    column.getHtmlType(),
+                new String[] { GenConstants.HTML_SELECT, GenConstants.HTML_RADIO, GenConstants.HTML_CHECKBOX })) {
                 dicts.add("'" + column.getDictType() + "'");
             }
         }
diff --git a/ruoyi-generator/src/main/resources/mapper/package-info.md b/ruoyi-generator/src/main/resources/mapper/package-info.md
new file mode 100644
index 0000000..c938b1e
--- /dev/null
+++ b/ruoyi-generator/src/main/resources/mapper/package-info.md
@@ -0,0 +1,3 @@
+java鍖呬娇鐢� `.` 鍒嗗壊 resource 鐩綍浣跨敤 `/` 鍒嗗壊
+<br>
+姝ゆ枃浠剁洰鐨� 闃叉鏂囦欢澶圭矘杩炴壘涓嶅埌 `xml` 鏂囦欢
\ No newline at end of file
diff --git a/ruoyi-generator/src/main/resources/vm/java/controller.java.vm b/ruoyi-generator/src/main/resources/vm/java/controller.java.vm
index 13e2281..d35642e 100644
--- a/ruoyi-generator/src/main/resources/vm/java/controller.java.vm
+++ b/ruoyi-generator/src/main/resources/vm/java/controller.java.vm
@@ -28,6 +28,7 @@
 #elseif($table.tree)
 #end
 import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiParam;
 import io.swagger.annotations.ApiOperation;
 
 /**
@@ -80,7 +81,8 @@
     @ApiOperation("鑾峰彇${functionName}璇︾粏淇℃伅")
     @SaCheckPermission("${permissionPrefix}:query")
     @GetMapping("/{${pkColumn.javaField}}")
-    public AjaxResult<${ClassName}Vo> getInfo(@NotNull(message = "涓婚敭涓嶈兘涓虹┖")
+    public AjaxResult<${ClassName}Vo> getInfo(@ApiParam("涓婚敭")
+                                                  @NotNull(message = "涓婚敭涓嶈兘涓虹┖")
                                                   @PathVariable("${pkColumn.javaField}") ${pkColumn.javaType} ${pkColumn.javaField}) {
         return AjaxResult.success(i${ClassName}Service.queryById(${pkColumn.javaField}));
     }
@@ -116,7 +118,8 @@
     @SaCheckPermission("${permissionPrefix}:remove")
     @Log(title = "${functionName}" , businessType = BusinessType.DELETE)
     @DeleteMapping("/{${pkColumn.javaField}s}")
-    public AjaxResult<Void> remove(@NotEmpty(message = "涓婚敭涓嶈兘涓虹┖")
+    public AjaxResult<Void> remove(@ApiParam("涓婚敭涓�")
+                                       @NotEmpty(message = "涓婚敭涓嶈兘涓虹┖")
                                        @PathVariable ${pkColumn.javaType}[] ${pkColumn.javaField}s) {
         return toAjax(i${ClassName}Service.deleteWithValidByIds(Arrays.asList(${pkColumn.javaField}s), true) ? 1 : 0);
     }
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 24494ad..7c530cb 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
@@ -108,7 +108,11 @@
 #elseif($column.list && $column.dictType && "" != $column.dictType)
       <el-table-column label="${comment}" align="center" prop="${javaField}">
         <template slot-scope="scope">
+#if($column.htmlType == "checkbox")
+          <dict-tag :options="dict.type.${column.dictType}" :value="scope.row.${javaField} ? scope.row.${javaField}.split(',') : []"/>
+#else
           <dict-tag :options="dict.type.${column.dictType}" :value="scope.row.${javaField}"/>
+#end
         </template>
       </el-table-column>
 #elseif($column.list && "" != $javaField)
@@ -296,8 +300,7 @@
       queryParams: {
 #foreach ($column in $columns)
 #if($column.query)
-        $column.javaField: null#if($velocityCount != $columns.size()),#end
-
+        $column.javaField: null#if($foreach.count != $columns.size()),#end
 #end
 #end
       },
@@ -315,8 +318,7 @@
 #end
         $column.javaField: [
           { required: true, message: "$comment涓嶈兘涓虹┖", trigger: #if($column.htmlType == "select")"change"#else"blur"#end }
-        ]#if($velocityCount != $columns.size()),#end
-
+        ]#if($foreach.count != $columns.size()),#end
 #end
 #end
       }
@@ -379,14 +381,12 @@
       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
+        $column.javaField: #if($column.javaType == "Integer" || $column.javaType == "Long")0#else"0"#end#if($foreach.count != $columns.size()),#end
 
 #elseif($column.htmlType == "checkbox")
-        $column.javaField: []#if($velocityCount != $columns.size()),#end
-
+        $column.javaField: []#if($foreach.count != $columns.size()),#end
 #else
-        $column.javaField: null#if($velocityCount != $columns.size()),#end
-
+        $column.javaField: null#if($foreach.count != $columns.size()),#end
 #end
 #end
       };
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 7e28c2e..c0a5bf7 100644
--- a/ruoyi-generator/src/main/resources/vm/vue/index.vue.vm
+++ b/ruoyi-generator/src/main/resources/vm/vue/index.vue.vm
@@ -108,7 +108,6 @@
           plain
           icon="el-icon-download"
           size="mini"
-          :loading="exportLoading"
           @click="handleExport"
           v-hasPermi="['${moduleName}:${businessName}:export']"
         >瀵煎嚭</el-button>
@@ -137,7 +136,11 @@
 #elseif($column.list && $column.dictType && "" != $column.dictType)
       <el-table-column label="${comment}" align="center" prop="${javaField}">
         <template slot-scope="scope">
+#if($column.htmlType == "checkbox")
+          <dict-tag :options="dict.type.${column.dictType}" :value="scope.row.${javaField} ? scope.row.${javaField}.split(',') : []"/>
+#else
           <dict-tag :options="dict.type.${column.dictType}" :value="scope.row.${javaField}"/>
+#end
         </template>
       </el-table-column>
 #elseif($column.list && "" != $javaField)
@@ -324,8 +327,6 @@
       buttonLoading: false,
       // 閬僵灞�
       loading: true,
-      // 瀵煎嚭閬僵灞�
-      exportLoading: false,
       // 閫変腑鏁扮粍
       ids: [],
 #if($table.sub)
@@ -363,8 +364,7 @@
         pageSize: 10,
 #foreach ($column in $columns)
 #if($column.query)
-        $column.javaField: undefined#if($velocityCount != $columns.size()),#end
-
+        $column.javaField: undefined#if($foreach.count != $columns.size()),#end
 #end
 #end
       },
@@ -382,8 +382,7 @@
 #end
         $column.javaField: [
           { required: true, message: "$comment涓嶈兘涓虹┖", trigger: #if($column.htmlType == "select")"change"#else"blur"#end }
-        ]#if($velocityCount != $columns.size()),#end
-
+        ]#if($foreach.count != $columns.size()),#end
 #end
 #end
       }
@@ -427,14 +426,11 @@
       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
-
+        $column.javaField: #if($column.javaType == "Integer" || $column.javaType == "Long")0#else"0"#end#if($foreach.count != $columns.size()),#end
 #elseif($column.htmlType == "checkbox")
-        $column.javaField: []#if($velocityCount != $columns.size()),#end
-
+        $column.javaField: []#if($foreach.count != $columns.size()),#end
 #else
-        $column.javaField: undefined#if($velocityCount != $columns.size()),#end
-
+        $column.javaField: undefined#if($foreach.count != $columns.size()),#end
 #end
 #end
       };
@@ -573,7 +569,9 @@
 #end
     /** 瀵煎嚭鎸夐挳鎿嶄綔 */
     handleExport() {
-        this.#[[$download]]#.excel('/${moduleName}/${businessName}/export', this.queryParams);
+      this.download('${moduleName}/${businessName}/export', {
+        ...this.queryParams
+      }, `${businessName}_#[[${new Date().getTime()}]]#.xlsx`)
     }
   }
 };
diff --git a/ruoyi-oss/src/main/java/com/ruoyi/oss/constant/CloudConstant.java b/ruoyi-oss/src/main/java/com/ruoyi/oss/constant/OssConstant.java
similarity index 73%
rename from ruoyi-oss/src/main/java/com/ruoyi/oss/constant/CloudConstant.java
rename to ruoyi-oss/src/main/java/com/ruoyi/oss/constant/OssConstant.java
index 7bba1f4..b5236bf 100644
--- a/ruoyi-oss/src/main/java/com/ruoyi/oss/constant/CloudConstant.java
+++ b/ruoyi-oss/src/main/java/com/ruoyi/oss/constant/OssConstant.java
@@ -8,7 +8,7 @@
  *
  * @author Lion Li
  */
-public class CloudConstant {
+public class OssConstant {
 
 	/**
 	 * OSS妯″潡KEY
@@ -18,12 +18,12 @@
 	/**
 	 * 瀵硅薄瀛樺偍閰嶇疆KEY
 	 */
-	public static final String CLOUD_STORAGE_CONFIG_KEY = "CloudStorageConfig";
+	public static final String OSS_CONFIG_KEY = "OssConfig";
 
 	/**
 	 * 缂撳瓨閰嶇疆KEY
 	 */
-	public static final String CACHE_CONFIG_KEY = SYS_OSS_KEY + CLOUD_STORAGE_CONFIG_KEY;
+	public static final String CACHE_CONFIG_KEY = SYS_OSS_KEY + OSS_CONFIG_KEY;
 
 	/**
 	 * 棰勮鍒楄〃璧勬簮寮�鍏矺ey
diff --git a/ruoyi-oss/src/main/java/com/ruoyi/oss/enumd/CloudServiceEnumd.java b/ruoyi-oss/src/main/java/com/ruoyi/oss/enumd/CloudServiceEnumd.java
deleted file mode 100644
index ac8ad81..0000000
--- a/ruoyi-oss/src/main/java/com/ruoyi/oss/enumd/CloudServiceEnumd.java
+++ /dev/null
@@ -1,63 +0,0 @@
-package com.ruoyi.oss.enumd;
-
-import com.ruoyi.common.utils.StringUtils;
-import com.ruoyi.oss.service.impl.AliyunCloudStorageStrategy;
-import com.ruoyi.oss.service.impl.MinioCloudStorageStrategy;
-import com.ruoyi.oss.service.impl.QcloudCloudStorageStrategy;
-import com.ruoyi.oss.service.impl.QiniuCloudStorageStrategy;
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-
-/**
- * 瀵硅薄瀛樺偍鏈嶅姟鍟嗘灇涓�
- *
- * @author Lion Li
- */
-@Getter
-@AllArgsConstructor
-public enum CloudServiceEnumd {
-
-	/**
-	 * 涓冪墰浜�
-	 */
-	QINIU("qiniu", QiniuCloudStorageStrategy.class),
-
-	/**
-	 * 闃块噷浜�
-	 */
-	ALIYUN("aliyun", AliyunCloudStorageStrategy.class),
-
-	/**
-	 * 鑵捐浜�
-	 */
-	QCLOUD("qcloud", QcloudCloudStorageStrategy.class),
-
-	/**
-	 * minio
-	 */
-	MINIO("minio", MinioCloudStorageStrategy.class);
-
-	private final String value;
-
-	private final Class<?> serviceClass;
-
-	public static Class<?> getServiceClass(String value) {
-		for (CloudServiceEnumd clazz : values()) {
-			if (clazz.getValue().equals(value)) {
-				return clazz.getServiceClass();
-			}
-		}
-		return null;
-	}
-
-	public static String getServiceName(String value) {
-		for (CloudServiceEnumd clazz : values()) {
-			if (clazz.getValue().equals(value)) {
-				return StringUtils.uncapitalize(clazz.getServiceClass().getSimpleName());
-			}
-		}
-		return null;
-	}
-
-
-}
diff --git a/ruoyi-oss/src/main/java/com/ruoyi/oss/enumd/OssEnumd.java b/ruoyi-oss/src/main/java/com/ruoyi/oss/enumd/OssEnumd.java
new file mode 100644
index 0000000..4defca4
--- /dev/null
+++ b/ruoyi-oss/src/main/java/com/ruoyi/oss/enumd/OssEnumd.java
@@ -0,0 +1,63 @@
+package com.ruoyi.oss.enumd;
+
+import com.ruoyi.common.utils.StringUtils;
+import com.ruoyi.oss.service.impl.AliyunOssStrategy;
+import com.ruoyi.oss.service.impl.MinioOssStrategy;
+import com.ruoyi.oss.service.impl.QcloudOssStrategy;
+import com.ruoyi.oss.service.impl.QiniuOssStrategy;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * 瀵硅薄瀛樺偍鏈嶅姟鍟嗘灇涓�
+ *
+ * @author Lion Li
+ */
+@Getter
+@AllArgsConstructor
+public enum OssEnumd {
+
+	/**
+	 * 涓冪墰浜�
+	 */
+	QINIU("qiniu", QiniuOssStrategy.class),
+
+	/**
+	 * 闃块噷浜�
+	 */
+	ALIYUN("aliyun", AliyunOssStrategy.class),
+
+	/**
+	 * 鑵捐浜�
+	 */
+	QCLOUD("qcloud", QcloudOssStrategy.class),
+
+	/**
+	 * minio
+	 */
+	MINIO("minio", MinioOssStrategy.class);
+
+	private final String value;
+
+	private final Class<?> serviceClass;
+
+	public static Class<?> getServiceClass(String value) {
+		for (OssEnumd clazz : values()) {
+			if (clazz.getValue().equals(value)) {
+				return clazz.getServiceClass();
+			}
+		}
+		return null;
+	}
+
+	public static String getServiceName(String value) {
+		for (OssEnumd clazz : values()) {
+			if (clazz.getValue().equals(value)) {
+				return StringUtils.uncapitalize(clazz.getServiceClass().getSimpleName());
+			}
+		}
+		return null;
+	}
+
+
+}
diff --git a/ruoyi-oss/src/main/java/com/ruoyi/oss/factory/OssFactory.java b/ruoyi-oss/src/main/java/com/ruoyi/oss/factory/OssFactory.java
index ecb269d..1691596 100644
--- a/ruoyi-oss/src/main/java/com/ruoyi/oss/factory/OssFactory.java
+++ b/ruoyi-oss/src/main/java/com/ruoyi/oss/factory/OssFactory.java
@@ -1,16 +1,15 @@
 package com.ruoyi.oss.factory;
 
-import cn.hutool.core.convert.Convert;
 import com.ruoyi.common.utils.JsonUtils;
 import com.ruoyi.common.utils.RedisUtils;
 import com.ruoyi.common.utils.StringUtils;
 import com.ruoyi.common.utils.reflect.ReflectUtils;
-import com.ruoyi.oss.constant.CloudConstant;
-import com.ruoyi.oss.enumd.CloudServiceEnumd;
+import com.ruoyi.oss.constant.OssConstant;
+import com.ruoyi.oss.enumd.OssEnumd;
 import com.ruoyi.oss.exception.OssException;
-import com.ruoyi.oss.properties.CloudStorageProperties;
-import com.ruoyi.oss.service.ICloudStorageStrategy;
-import com.ruoyi.oss.service.abstractd.AbstractCloudStorageStrategy;
+import com.ruoyi.oss.properties.OssProperties;
+import com.ruoyi.oss.service.IOssStrategy;
+import com.ruoyi.oss.service.abstractd.AbstractOssStrategy;
 import lombok.extern.slf4j.Slf4j;
 
 import java.util.Map;
@@ -24,24 +23,31 @@
 @Slf4j
 public class OssFactory {
 
-	static {
-		RedisUtils.subscribe(CloudConstant.CACHE_CONFIG_KEY, String.class, msg -> {
-			refreshService(msg);
-			log.info("璁㈤槄鍒锋柊OSS閰嶇疆 => " + msg);
-		});
-	}
-
 	/**
 	 * 鏈嶅姟瀹炰緥缂撳瓨
 	 */
-	private static final Map<String, ICloudStorageStrategy> SERVICES = new ConcurrentHashMap<>();
+	private static final Map<String, IOssStrategy> SERVICES = new ConcurrentHashMap<>();
+
+    /**
+     * 鍒濆鍖栧伐鍘�
+     */
+    public static void init() {
+        log.info("鍒濆鍖朞SS宸ュ巶");
+        RedisUtils.subscribe(OssConstant.CACHE_CONFIG_KEY, String.class, type -> {
+            // 娌℃湁鐨勫疄渚嬩笉澶勭悊
+            if (SERVICES.containsKey(type)) {
+                refreshService(type);
+                log.info("璁㈤槄鍒锋柊OSS閰嶇疆 => " + type);
+            }
+        });
+    }
 
 	/**
 	 * 鑾峰彇榛樿瀹炰緥
 	 */
-	public static ICloudStorageStrategy instance() {
+	public static IOssStrategy instance() {
 		// 鑾峰彇redis 榛樿绫诲瀷
-		String type = Convert.toStr(RedisUtils.getCacheObject(CloudConstant.CACHE_CONFIG_KEY));
+		String type = RedisUtils.getCacheObject(OssConstant.CACHE_CONFIG_KEY);
 		if (StringUtils.isEmpty(type)) {
 			throw new OssException("鏂囦欢瀛樺偍鏈嶅姟绫诲瀷鏃犳硶鎵惧埌!");
 		}
@@ -51,8 +57,8 @@
 	/**
 	 * 鏍规嵁绫诲瀷鑾峰彇瀹炰緥
 	 */
-	public static ICloudStorageStrategy instance(String type) {
-		ICloudStorageStrategy service = SERVICES.get(type);
+	public static IOssStrategy instance(String type) {
+        IOssStrategy service = SERVICES.get(type);
 		if (service == null) {
 			refreshService(type);
 			service = SERVICES.get(type);
@@ -61,14 +67,14 @@
 	}
 
 	private static void refreshService(String type) {
-		Object json = RedisUtils.getCacheObject(CloudConstant.SYS_OSS_KEY + type);
-		CloudStorageProperties properties = JsonUtils.parseObject(json.toString(), CloudStorageProperties.class);
+		Object json = RedisUtils.getCacheObject(OssConstant.SYS_OSS_KEY + type);
+        OssProperties properties = JsonUtils.parseObject(json.toString(), OssProperties.class);
 		if (properties == null) {
 			throw new OssException("绯荤粺寮傚父, '" + type + "'閰嶇疆淇℃伅涓嶅瓨鍦�!");
 		}
 		// 鑾峰彇redis閰嶇疆淇℃伅 鍒涘缓瀵硅薄 骞剁紦瀛�
-		ICloudStorageStrategy service = (ICloudStorageStrategy) ReflectUtils.newInstance(CloudServiceEnumd.getServiceClass(type));
-		((AbstractCloudStorageStrategy)service).init(properties);
+        IOssStrategy service = (IOssStrategy) ReflectUtils.newInstance(OssEnumd.getServiceClass(type));
+		((AbstractOssStrategy)service).init(properties);
 		SERVICES.put(type, service);
 	}
 
diff --git a/ruoyi-oss/src/main/java/com/ruoyi/oss/properties/CloudStorageProperties.java b/ruoyi-oss/src/main/java/com/ruoyi/oss/properties/OssProperties.java
similarity index 81%
rename from ruoyi-oss/src/main/java/com/ruoyi/oss/properties/CloudStorageProperties.java
rename to ruoyi-oss/src/main/java/com/ruoyi/oss/properties/OssProperties.java
index 9d3f15a..48a478b 100644
--- a/ruoyi-oss/src/main/java/com/ruoyi/oss/properties/CloudStorageProperties.java
+++ b/ruoyi-oss/src/main/java/com/ruoyi/oss/properties/OssProperties.java
@@ -2,15 +2,13 @@
 
 import lombok.Data;
 
-import java.util.Date;
-
 /**
  * OSS瀵硅薄瀛樺偍 閰嶇疆灞炴��
  *
  * @author Lion Li
  */
 @Data
-public class CloudStorageProperties {
+public class OssProperties {
 
 	/**
 	 * 鍩熷悕
@@ -46,10 +44,5 @@
 	 * 鏄惁https锛圷=鏄�,N=鍚︼級
 	 */
 	private String isHttps;
-
-	/**
-	 * 鏇存柊鏃堕棿
-	 */
-	private Date updateTime;
 
 }
diff --git a/ruoyi-oss/src/main/java/com/ruoyi/oss/service/ICloudStorageStrategy.java b/ruoyi-oss/src/main/java/com/ruoyi/oss/service/IOssStrategy.java
similarity index 83%
rename from ruoyi-oss/src/main/java/com/ruoyi/oss/service/ICloudStorageStrategy.java
rename to ruoyi-oss/src/main/java/com/ruoyi/oss/service/IOssStrategy.java
index 96ea539..34d25e4 100644
--- a/ruoyi-oss/src/main/java/com/ruoyi/oss/service/ICloudStorageStrategy.java
+++ b/ruoyi-oss/src/main/java/com/ruoyi/oss/service/IOssStrategy.java
@@ -9,7 +9,7 @@
  *
  * @author Lion Li
  */
-public interface ICloudStorageStrategy {
+public interface IOssStrategy {
 
 	void createBucket();
 
@@ -17,15 +17,6 @@
 	 * 鑾峰彇鏈嶅姟鍟嗙被鍨�
 	 */
 	String getServiceType();
-
-	/**
-	 * 鏂囦欢璺緞
-	 *
-	 * @param prefix 鍓嶇紑
-	 * @param suffix 鍚庣紑
-	 * @return 杩斿洖涓婁紶璺緞
-	 */
-	String getPath(String prefix, String suffix);
 
 	/**
 	 * 鏂囦欢涓婁紶
@@ -70,5 +61,4 @@
 	 */
 	UploadResult uploadSuffix(InputStream inputStream, String suffix, String contentType);
 
-	String getEndpointLink();
 }
diff --git a/ruoyi-oss/src/main/java/com/ruoyi/oss/service/abstractd/AbstractCloudStorageStrategy.java b/ruoyi-oss/src/main/java/com/ruoyi/oss/service/abstractd/AbstractOssStrategy.java
similarity index 80%
rename from ruoyi-oss/src/main/java/com/ruoyi/oss/service/abstractd/AbstractCloudStorageStrategy.java
rename to ruoyi-oss/src/main/java/com/ruoyi/oss/service/abstractd/AbstractOssStrategy.java
index 8f5e962..9fa52ac 100644
--- a/ruoyi-oss/src/main/java/com/ruoyi/oss/service/abstractd/AbstractCloudStorageStrategy.java
+++ b/ruoyi-oss/src/main/java/com/ruoyi/oss/service/abstractd/AbstractOssStrategy.java
@@ -5,8 +5,8 @@
 import com.ruoyi.common.utils.DateUtils;
 import com.ruoyi.common.utils.StringUtils;
 import com.ruoyi.oss.entity.UploadResult;
-import com.ruoyi.oss.properties.CloudStorageProperties;
-import com.ruoyi.oss.service.ICloudStorageStrategy;
+import com.ruoyi.oss.properties.OssProperties;
+import com.ruoyi.oss.service.IOssStrategy;
 
 import java.io.InputStream;
 
@@ -15,11 +15,11 @@
  *
  * @author Lion Li
  */
-public abstract class AbstractCloudStorageStrategy implements ICloudStorageStrategy {
+public abstract class AbstractOssStrategy implements IOssStrategy {
 
-	protected CloudStorageProperties properties;
+	protected OssProperties properties;
 
-	public abstract void init(CloudStorageProperties properties);
+	public abstract void init(OssProperties properties);
 
 	@Override
 	public abstract void createBucket();
@@ -27,7 +27,6 @@
 	@Override
 	public abstract String getServiceType();
 
-	@Override
 	public String getPath(String prefix, String suffix) {
 		// 鐢熸垚uuid
 		String uuid = IdUtil.fastSimpleUUID();
@@ -57,6 +56,5 @@
 	@Override
 	public abstract UploadResult uploadSuffix(InputStream inputStream, String suffix, String contentType);
 
-	@Override
 	public abstract String getEndpointLink();
 }
diff --git a/ruoyi-oss/src/main/java/com/ruoyi/oss/service/impl/AliyunCloudStorageStrategy.java b/ruoyi-oss/src/main/java/com/ruoyi/oss/service/impl/AliyunOssStrategy.java
similarity index 90%
rename from ruoyi-oss/src/main/java/com/ruoyi/oss/service/impl/AliyunCloudStorageStrategy.java
rename to ruoyi-oss/src/main/java/com/ruoyi/oss/service/impl/AliyunOssStrategy.java
index 04ee675..db9ad91 100644
--- a/ruoyi-oss/src/main/java/com/ruoyi/oss/service/impl/AliyunCloudStorageStrategy.java
+++ b/ruoyi-oss/src/main/java/com/ruoyi/oss/service/impl/AliyunOssStrategy.java
@@ -9,10 +9,10 @@
 import com.aliyun.oss.model.PutObjectRequest;
 import com.ruoyi.common.utils.StringUtils;
 import com.ruoyi.oss.entity.UploadResult;
-import com.ruoyi.oss.enumd.CloudServiceEnumd;
+import com.ruoyi.oss.enumd.OssEnumd;
 import com.ruoyi.oss.exception.OssException;
-import com.ruoyi.oss.properties.CloudStorageProperties;
-import com.ruoyi.oss.service.abstractd.AbstractCloudStorageStrategy;
+import com.ruoyi.oss.properties.OssProperties;
+import com.ruoyi.oss.service.abstractd.AbstractOssStrategy;
 
 import java.io.ByteArrayInputStream;
 import java.io.InputStream;
@@ -22,12 +22,12 @@
  *
  * @author Lion Li
  */
-public class AliyunCloudStorageStrategy extends AbstractCloudStorageStrategy {
+public class AliyunOssStrategy extends AbstractOssStrategy {
 
 	private OSSClient client;
 
 	@Override
-	public void init(CloudStorageProperties cloudStorageProperties) {
+	public void init(OssProperties cloudStorageProperties) {
 		properties = cloudStorageProperties;
 		try {
 			ClientConfiguration configuration = new ClientConfiguration();
@@ -57,7 +57,7 @@
 
 	@Override
 	public String getServiceType() {
-		return CloudServiceEnumd.ALIYUN.getValue();
+		return OssEnumd.ALIYUN.getValue();
 	}
 
 	@Override
diff --git a/ruoyi-oss/src/main/java/com/ruoyi/oss/service/impl/MinioCloudStorageStrategy.java b/ruoyi-oss/src/main/java/com/ruoyi/oss/service/impl/MinioOssStrategy.java
similarity index 94%
rename from ruoyi-oss/src/main/java/com/ruoyi/oss/service/impl/MinioCloudStorageStrategy.java
rename to ruoyi-oss/src/main/java/com/ruoyi/oss/service/impl/MinioOssStrategy.java
index 3bbf187..0423dcc 100644
--- a/ruoyi-oss/src/main/java/com/ruoyi/oss/service/impl/MinioCloudStorageStrategy.java
+++ b/ruoyi-oss/src/main/java/com/ruoyi/oss/service/impl/MinioOssStrategy.java
@@ -2,11 +2,11 @@
 
 import com.ruoyi.common.utils.StringUtils;
 import com.ruoyi.oss.entity.UploadResult;
-import com.ruoyi.oss.enumd.CloudServiceEnumd;
+import com.ruoyi.oss.enumd.OssEnumd;
 import com.ruoyi.oss.enumd.PolicyType;
 import com.ruoyi.oss.exception.OssException;
-import com.ruoyi.oss.properties.CloudStorageProperties;
-import com.ruoyi.oss.service.abstractd.AbstractCloudStorageStrategy;
+import com.ruoyi.oss.properties.OssProperties;
+import com.ruoyi.oss.service.abstractd.AbstractOssStrategy;
 import io.minio.*;
 import org.springframework.http.MediaType;
 
@@ -18,12 +18,12 @@
  *
  * @author Lion Li
  */
-public class MinioCloudStorageStrategy extends AbstractCloudStorageStrategy {
+public class MinioOssStrategy extends AbstractOssStrategy {
 
 	private MinioClient minioClient;
 
 	@Override
-	public void init(CloudStorageProperties cloudStorageProperties) {
+	public void init(OssProperties cloudStorageProperties) {
 		properties = cloudStorageProperties;
 		try {
 			minioClient = MinioClient.builder()
@@ -57,7 +57,7 @@
 
 	@Override
 	public String getServiceType() {
-		return CloudServiceEnumd.MINIO.getValue();
+		return OssEnumd.MINIO.getValue();
 	}
 
 	@Override
diff --git a/ruoyi-oss/src/main/java/com/ruoyi/oss/service/impl/QcloudCloudStorageStrategy.java b/ruoyi-oss/src/main/java/com/ruoyi/oss/service/impl/QcloudOssStrategy.java
similarity index 91%
rename from ruoyi-oss/src/main/java/com/ruoyi/oss/service/impl/QcloudCloudStorageStrategy.java
rename to ruoyi-oss/src/main/java/com/ruoyi/oss/service/impl/QcloudOssStrategy.java
index 9bd366e..156eb24 100644
--- a/ruoyi-oss/src/main/java/com/ruoyi/oss/service/impl/QcloudCloudStorageStrategy.java
+++ b/ruoyi-oss/src/main/java/com/ruoyi/oss/service/impl/QcloudOssStrategy.java
@@ -9,10 +9,10 @@
 import com.qcloud.cos.region.Region;
 import com.ruoyi.common.utils.StringUtils;
 import com.ruoyi.oss.entity.UploadResult;
-import com.ruoyi.oss.enumd.CloudServiceEnumd;
+import com.ruoyi.oss.enumd.OssEnumd;
 import com.ruoyi.oss.exception.OssException;
-import com.ruoyi.oss.properties.CloudStorageProperties;
-import com.ruoyi.oss.service.abstractd.AbstractCloudStorageStrategy;
+import com.ruoyi.oss.properties.OssProperties;
+import com.ruoyi.oss.service.abstractd.AbstractOssStrategy;
 
 import java.io.ByteArrayInputStream;
 import java.io.InputStream;
@@ -22,12 +22,12 @@
  *
  * @author Lion Li
  */
-public class QcloudCloudStorageStrategy extends AbstractCloudStorageStrategy {
+public class QcloudOssStrategy extends AbstractOssStrategy {
 
 	private COSClient client;
 
 	@Override
-	public void init(CloudStorageProperties cloudStorageProperties) {
+	public void init(OssProperties cloudStorageProperties) {
 		properties = cloudStorageProperties;
 		try {
 			COSCredentials credentials = new BasicCOSCredentials(
@@ -65,7 +65,7 @@
 
 	@Override
 	public String getServiceType() {
-		return CloudServiceEnumd.QCLOUD.getValue();
+		return OssEnumd.QCLOUD.getValue();
 	}
 
 	@Override
diff --git a/ruoyi-oss/src/main/java/com/ruoyi/oss/service/impl/QiniuCloudStorageStrategy.java b/ruoyi-oss/src/main/java/com/ruoyi/oss/service/impl/QiniuOssStrategy.java
similarity index 82%
rename from ruoyi-oss/src/main/java/com/ruoyi/oss/service/impl/QiniuCloudStorageStrategy.java
rename to ruoyi-oss/src/main/java/com/ruoyi/oss/service/impl/QiniuOssStrategy.java
index e9b8dc0..bf90aa8 100644
--- a/ruoyi-oss/src/main/java/com/ruoyi/oss/service/impl/QiniuCloudStorageStrategy.java
+++ b/ruoyi-oss/src/main/java/com/ruoyi/oss/service/impl/QiniuOssStrategy.java
@@ -8,10 +8,10 @@
 import com.qiniu.storage.UploadManager;
 import com.qiniu.util.Auth;
 import com.ruoyi.oss.entity.UploadResult;
-import com.ruoyi.oss.enumd.CloudServiceEnumd;
+import com.ruoyi.oss.enumd.OssEnumd;
 import com.ruoyi.oss.exception.OssException;
-import com.ruoyi.oss.properties.CloudStorageProperties;
-import com.ruoyi.oss.service.abstractd.AbstractCloudStorageStrategy;
+import com.ruoyi.oss.properties.OssProperties;
+import com.ruoyi.oss.service.abstractd.AbstractOssStrategy;
 
 import java.io.InputStream;
 
@@ -20,14 +20,14 @@
  *
  * @author Lion Li
  */
-public class QiniuCloudStorageStrategy extends AbstractCloudStorageStrategy {
+public class QiniuOssStrategy extends AbstractOssStrategy {
 
 	private UploadManager uploadManager;
 	private BucketManager bucketManager;
-	private String token;
+	private Auth auth;
 
 	@Override
-	public void init(CloudStorageProperties cloudStorageProperties) {
+	public void init(OssProperties cloudStorageProperties) {
 		properties = cloudStorageProperties;
 		try {
 			Configuration config = new Configuration(getRegion(properties.getRegion()));
@@ -35,9 +35,8 @@
 			config.useHttpsDomains = false;
 			config.useHttpsDomains = "Y".equals(properties.getIsHttps());
 			uploadManager = new UploadManager(config);
-			Auth auth = Auth.create(properties.getAccessKey(), properties.getSecretKey());
+			auth = Auth.create(properties.getAccessKey(), properties.getSecretKey());
 			String bucketName = properties.getBucketName();
-			token = auth.uploadToken(bucketName);
 			bucketManager = new BucketManager(auth, config);
 
 			if (!ArrayUtil.contains(bucketManager.buckets(), bucketName)) {
@@ -63,15 +62,16 @@
 
 	@Override
 	public String getServiceType() {
-		return CloudServiceEnumd.QINIU.getValue();
+		return OssEnumd.QINIU.getValue();
 	}
 
 	@Override
 	public UploadResult upload(byte[] data, String path, String contentType) {
 		try {
-			Response res = uploadManager.put(data, path, token, null, contentType, false);
+            String token = auth.uploadToken(properties.getBucketName());
+            Response res = uploadManager.put(data, path, token, null, contentType, false);
 			if (!res.isOK()) {
-				throw new RuntimeException("涓婁紶涓冪墰鍑洪敊锛�" + res.toString());
+				throw new RuntimeException("涓婁紶涓冪墰鍑洪敊锛�" + res.error);
 			}
 		} catch (Exception e) {
 			throw new OssException("涓婁紶鏂囦欢澶辫触锛岃鏍稿涓冪墰閰嶇疆淇℃伅:[" + e.getMessage() + "]");
@@ -85,7 +85,7 @@
 			path = path.replace(getEndpointLink() + "/", "");
 			Response res = bucketManager.delete(properties.getBucketName(), path);
 			if (!res.isOK()) {
-				throw new RuntimeException("鍒犻櫎涓冪墰鏂囦欢鍑洪敊锛�" + res.toString());
+				throw new RuntimeException("鍒犻櫎涓冪墰鏂囦欢鍑洪敊锛�" + res.error);
 			}
 		} catch (Exception e) {
 			throw new OssException(e.getMessage());
diff --git a/ruoyi-quartz/pom.xml b/ruoyi-quartz/pom.xml
deleted file mode 100644
index 1480b81..0000000
--- a/ruoyi-quartz/pom.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-    <parent>
-        <artifactId>ruoyi-vue-plus</artifactId>
-        <groupId>com.ruoyi</groupId>
-        <version>3.3.0</version>
-    </parent>
-    <modelVersion>4.0.0</modelVersion>
-
-    <artifactId>ruoyi-quartz</artifactId>
-
-    <description>
-        quartz瀹氭椂浠诲姟
-    </description>
-
-    <dependencies>
-
-        <!-- 瀹氭椂浠诲姟 -->
-        <dependency>
-            <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter-quartz</artifactId>
-            <exclusions>
-                <exclusion>
-                    <groupId>com.mchange</groupId>
-                    <artifactId>c3p0</artifactId>
-                </exclusion>
-            </exclusions>
-        </dependency>
-
-        <!-- 閫氱敤宸ュ叿-->
-        <dependency>
-            <groupId>com.ruoyi</groupId>
-            <artifactId>ruoyi-common</artifactId>
-        </dependency>
-
-    </dependencies>
-
-</project>
diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/config/ScheduleConfig.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/config/ScheduleConfig.java
deleted file mode 100644
index c5fa2ec..0000000
--- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/config/ScheduleConfig.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.ruoyi.quartz.config;
-
-import org.springframework.context.annotation.Configuration;
-
-/**
- * 瀹氭椂浠诲姟閰嶇疆
- *
- * @deprecated 3.4.0鍒犻櫎 杩佺Щ鑷硏xl-job
- * @author Lion Li
- */
-@Deprecated
-@Configuration
-public class ScheduleConfig {
-
-}
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
deleted file mode 100644
index 7a86393..0000000
--- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/controller/SysJobController.java
+++ /dev/null
@@ -1,158 +0,0 @@
-package com.ruoyi.quartz.controller;
-
-import cn.dev33.satoken.annotation.SaCheckPermission;
-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.StringUtils;
-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.web.bind.annotation.*;
-
-import javax.servlet.http.HttpServletResponse;
-import java.util.List;
-
-/**
- * 璋冨害浠诲姟淇℃伅鎿嶄綔澶勭悊
- *
- * @deprecated 3.4.0鍒犻櫎 杩佺Щ鑷硏xl-job
- * @author ruoyi
- */
-@RestController
-@RequestMapping("/monitor/job")
-public class SysJobController extends BaseController
-{
-    @Autowired
-    private ISysJobService jobService;
-
-    /**
-     * 鏌ヨ瀹氭椂浠诲姟鍒楄〃
-     */
-    @SaCheckPermission("monitor:job:list")
-    @GetMapping("/list")
-    public TableDataInfo list(SysJob sysJob)
-    {
-        return jobService.selectPageJobList(sysJob);
-    }
-
-    /**
-     * 瀵煎嚭瀹氭椂浠诲姟鍒楄〃
-     */
-    @SaCheckPermission("monitor:job:export")
-    @Log(title = "瀹氭椂浠诲姟", businessType = BusinessType.EXPORT)
-    @GetMapping("/export")
-    public void export(SysJob sysJob, HttpServletResponse response)
-    {
-        List<SysJob> list = jobService.selectJobList(sysJob);
-		ExcelUtil.exportExcel(list, "瀹氭椂浠诲姟", SysJob.class, response);
-    }
-
-    /**
-     * 鑾峰彇瀹氭椂浠诲姟璇︾粏淇℃伅
-     */
-    @SaCheckPermission("monitor:job:query")
-    @GetMapping(value = "/{jobId}")
-    public AjaxResult getInfo(@PathVariable("jobId") Long jobId)
-    {
-        return AjaxResult.success(jobService.selectJobById(jobId));
-    }
-
-    /**
-     * 鏂板瀹氭椂浠诲姟
-     */
-    @SaCheckPermission("monitor:job:add")
-    @Log(title = "瀹氭椂浠诲姟", businessType = BusinessType.INSERT)
-    @PostMapping
-    public AjaxResult add(@RequestBody SysJob job) throws SchedulerException, TaskException
-    {
-        if (!CronUtils.isValid(job.getCronExpression()))
-        {
-            return error("鏂板浠诲姟'" + job.getJobName() + "'澶辫触锛孋ron琛ㄨ揪寮忎笉姝g‘");
-        }
-        else if (StringUtils.containsIgnoreCase(job.getInvokeTarget(), Constants.LOOKUP_RMI))
-        {
-            return error("鏂板浠诲姟'" + job.getJobName() + "'澶辫触锛岀洰鏍囧瓧绗︿覆涓嶅厑璁�'rmi://'璋冪敤");
-        }
-        else if (StringUtils.containsIgnoreCase(job.getInvokeTarget(), Constants.LOOKUP_LDAP))
-        {
-            return error("鏂板浠诲姟'" + job.getJobName() + "'澶辫触锛岀洰鏍囧瓧绗︿覆涓嶅厑璁�'ldap://'璋冪敤");
-        }
-        else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), new String[] { Constants.HTTP, Constants.HTTPS }))
-        {
-            return error("鏂板浠诲姟'" + job.getJobName() + "'澶辫触锛岀洰鏍囧瓧绗︿覆涓嶅厑璁�'http(s)//'璋冪敤");
-        }
-        return toAjax(jobService.insertJob(job));
-    }
-
-    /**
-     * 淇敼瀹氭椂浠诲姟
-     */
-    @SaCheckPermission("monitor:job:edit")
-    @Log(title = "瀹氭椂浠诲姟", businessType = BusinessType.UPDATE)
-    @PutMapping
-    public AjaxResult edit(@RequestBody SysJob job) throws SchedulerException, TaskException
-    {
-        if (!CronUtils.isValid(job.getCronExpression()))
-        {
-            return error("淇敼浠诲姟'" + job.getJobName() + "'澶辫触锛孋ron琛ㄨ揪寮忎笉姝g‘");
-        }
-        else if (StringUtils.containsIgnoreCase(job.getInvokeTarget(), Constants.LOOKUP_RMI))
-        {
-            return error("淇敼浠诲姟'" + job.getJobName() + "'澶辫触锛岀洰鏍囧瓧绗︿覆涓嶅厑璁�'rmi://'璋冪敤");
-        }
-        else if (StringUtils.containsIgnoreCase(job.getInvokeTarget(), Constants.LOOKUP_LDAP))
-        {
-            return error("淇敼浠诲姟'" + job.getJobName() + "'澶辫触锛岀洰鏍囧瓧绗︿覆涓嶅厑璁�'ldap://'璋冪敤");
-        }
-        else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), new String[] { Constants.HTTP, Constants.HTTPS }))
-        {
-            return error("淇敼浠诲姟'" + job.getJobName() + "'澶辫触锛岀洰鏍囧瓧绗︿覆涓嶅厑璁�'http(s)//'璋冪敤");
-        }
-        return toAjax(jobService.updateJob(job));
-    }
-
-    /**
-     * 瀹氭椂浠诲姟鐘舵�佷慨鏀�
-     */
-    @SaCheckPermission("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));
-    }
-
-    /**
-     * 瀹氭椂浠诲姟绔嬪嵆鎵ц涓�娆�
-     */
-    @SaCheckPermission("monitor:job:changeStatus")
-    @Log(title = "瀹氭椂浠诲姟", businessType = BusinessType.UPDATE)
-    @PutMapping("/run")
-    public AjaxResult run(@RequestBody SysJob job) throws SchedulerException
-    {
-        jobService.run(job);
-        return AjaxResult.success();
-    }
-
-    /**
-     * 鍒犻櫎瀹氭椂浠诲姟
-     */
-    @SaCheckPermission("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/controller/SysJobLogController.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/controller/SysJobLogController.java
deleted file mode 100644
index 8ab3229..0000000
--- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/controller/SysJobLogController.java
+++ /dev/null
@@ -1,87 +0,0 @@
-package com.ruoyi.quartz.controller;
-
-import cn.dev33.satoken.annotation.SaCheckPermission;
-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.utils.poi.ExcelUtil;
-import com.ruoyi.quartz.domain.SysJobLog;
-import com.ruoyi.quartz.service.ISysJobLogService;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.*;
-
-import javax.servlet.http.HttpServletResponse;
-import java.util.List;
-
-/**
- * 璋冨害鏃ュ織鎿嶄綔澶勭悊
- *
- * @deprecated 3.4.0鍒犻櫎 杩佺Щ鑷硏xl-job
- * @author ruoyi
- */
-@RestController
-@RequestMapping("/monitor/jobLog")
-public class SysJobLogController extends BaseController
-{
-    @Autowired
-    private ISysJobLogService jobLogService;
-
-    /**
-     * 鏌ヨ瀹氭椂浠诲姟璋冨害鏃ュ織鍒楄〃
-     */
-
-    @SaCheckPermission("monitor:job:list")
-    @GetMapping("/list")
-    public TableDataInfo list(SysJobLog sysJobLog)
-    {
-        return jobLogService.selectPageJobLogList(sysJobLog);
-    }
-
-    /**
-     * 瀵煎嚭瀹氭椂浠诲姟璋冨害鏃ュ織鍒楄〃
-     */
-    @SaCheckPermission("monitor:job:export")
-    @Log(title = "浠诲姟璋冨害鏃ュ織", businessType = BusinessType.EXPORT)
-    @GetMapping("/export")
-    public void export(SysJobLog sysJobLog, HttpServletResponse response)
-    {
-        List<SysJobLog> list = jobLogService.selectJobLogList(sysJobLog);
-		ExcelUtil.exportExcel(list, "璋冨害鏃ュ織", SysJobLog.class, response);
-    }
-
-    /**
-     * 鏍规嵁璋冨害缂栧彿鑾峰彇璇︾粏淇℃伅
-     */
-    @SaCheckPermission("monitor:job:query")
-    @GetMapping(value = "/{configId}")
-    public AjaxResult getInfo(@PathVariable Long jobLogId)
-    {
-        return AjaxResult.success(jobLogService.selectJobLogById(jobLogId));
-    }
-
-
-    /**
-     * 鍒犻櫎瀹氭椂浠诲姟璋冨害鏃ュ織
-     */
-    @SaCheckPermission("monitor:job:remove")
-    @Log(title = "瀹氭椂浠诲姟璋冨害鏃ュ織", businessType = BusinessType.DELETE)
-    @DeleteMapping("/{jobLogIds}")
-    public AjaxResult remove(@PathVariable Long[] jobLogIds)
-    {
-        return toAjax(jobLogService.deleteJobLogByIds(jobLogIds));
-    }
-
-    /**
-     * 娓呯┖瀹氭椂浠诲姟璋冨害鏃ュ織
-     */
-    @SaCheckPermission("monitor:job:remove")
-    @Log(title = "璋冨害鏃ュ織", businessType = BusinessType.CLEAN)
-    @DeleteMapping("/clean")
-    public AjaxResult clean()
-    {
-        jobLogService.cleanJobLog();
-        return AjaxResult.success();
-    }
-}
diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/domain/SysJob.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/domain/SysJob.java
deleted file mode 100644
index ee15e55..0000000
--- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/domain/SysJob.java
+++ /dev/null
@@ -1,140 +0,0 @@
-package com.ruoyi.quartz.domain;
-
-import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
-import com.alibaba.excel.annotation.ExcelProperty;
-import com.baomidou.mybatisplus.annotation.*;
-import com.fasterxml.jackson.annotation.JsonFormat;
-import com.ruoyi.common.annotation.ExcelDictFormat;
-import com.ruoyi.common.constant.ScheduleConstants;
-import com.ruoyi.common.convert.ExcelDictConvert;
-import com.ruoyi.common.utils.StringUtils;
-import com.ruoyi.quartz.util.CronUtils;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-import lombok.experimental.Accessors;
-
-import javax.validation.constraints.NotBlank;
-import javax.validation.constraints.Size;
-import java.io.Serializable;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * 瀹氭椂浠诲姟璋冨害琛� sys_job
- *
- * @deprecated 3.4.0鍒犻櫎 杩佺Щ鑷硏xl-job
- * @author ruoyi
- */
-
-@Data
-@NoArgsConstructor
-@Accessors(chain = true)
-@TableName("sys_job")
-@ExcelIgnoreUnannotated
-public class SysJob implements Serializable {
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * 浠诲姟ID
-     */
-    @ExcelProperty(value = "浠诲姟搴忓彿")
-    @TableId(value = "job_id", type = IdType.AUTO)
-    private Long jobId;
-
-    /**
-     * 浠诲姟鍚嶇О
-     */
-    @NotBlank(message = "浠诲姟鍚嶇О涓嶈兘涓虹┖")
-    @Size(min = 0, max = 64, message = "浠诲姟鍚嶇О涓嶈兘瓒呰繃64涓瓧绗�")
-    @ExcelProperty(value = "浠诲姟鍚嶇О")
-    private String jobName;
-
-    /**
-     * 浠诲姟缁勫悕
-     */
-	@ExcelProperty(value = "浠诲姟缁勫悕", converter = ExcelDictConvert.class)
-	@ExcelDictFormat(dictType = "sys_job_group")
-    private String jobGroup;
-
-    /**
-     * 璋冪敤鐩爣瀛楃涓�
-     */
-    @NotBlank(message = "璋冪敤鐩爣瀛楃涓蹭笉鑳戒负绌�")
-    @Size(min = 0, max = 500, message = "璋冪敤鐩爣瀛楃涓查暱搴︿笉鑳借秴杩�500涓瓧绗�")
-    @ExcelProperty(value = "璋冪敤鐩爣瀛楃涓�")
-    private String invokeTarget;
-
-    /**
-     * cron鎵ц琛ㄨ揪寮�
-     */
-    @NotBlank(message = "Cron鎵ц琛ㄨ揪寮忎笉鑳戒负绌�")
-    @Size(min = 0, max = 255, message = "Cron鎵ц琛ㄨ揪寮忎笉鑳借秴杩�255涓瓧绗�")
-    @ExcelProperty(value = "鎵ц琛ㄨ揪寮�")
-    private String cronExpression;
-
-    /**
-     * cron璁″垝绛栫暐
-     */
-    @ExcelProperty(value = "璁″垝绛栫暐 ", converter = ExcelDictConvert.class)
-    @ExcelDictFormat(readConverterExp = "0=榛樿,1=绔嬪嵆瑙﹀彂鎵ц,2=瑙﹀彂涓�娆℃墽琛�,3=涓嶈Е鍙戠珛鍗虫墽琛�")
-	private String misfirePolicy = ScheduleConstants.MISFIRE_DEFAULT;
-
-    /**
-     * 鏄惁骞跺彂鎵ц锛�0鍏佽 1绂佹锛�
-     */
-    @ExcelProperty(value = "骞跺彂鎵ц", converter = ExcelDictConvert.class)
-	@ExcelDictFormat(readConverterExp = "0=鍏佽,1=绂佹")
-    private String concurrent;
-
-    /**
-     * 浠诲姟鐘舵�侊紙0姝e父 1鏆傚仠锛�
-     */
-    @ExcelProperty(value = "浠诲姟鐘舵��", converter = ExcelDictConvert.class)
-	@ExcelDictFormat(dictType = "sys_job_status")
-    private String status;
-
-    /**
-     * 鍒涘缓鑰�
-     */
-    @TableField(fill = FieldFill.INSERT)
-    private String createBy;
-
-    /**
-     * 鍒涘缓鏃堕棿
-     */
-    @TableField(fill = FieldFill.INSERT)
-    private Date createTime;
-
-    /**
-     * 鏇存柊鑰�
-     */
-    @TableField(fill = FieldFill.INSERT_UPDATE)
-    private String updateBy;
-
-    /**
-     * 鏇存柊鏃堕棿
-     */
-    @TableField(fill = FieldFill.INSERT_UPDATE)
-    private Date updateTime;
-
-    /**
-     * 澶囨敞
-     */
-    private String remark;
-
-    /**
-     * 璇锋眰鍙傛暟
-     */
-    @TableField(exist = false)
-    private Map<String, Object> params = new HashMap<>();
-
-    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
-    public Date getNextValidTime() {
-        if (StringUtils.isNotEmpty(cronExpression)) {
-            return CronUtils.getNextExecution(cronExpression);
-        }
-        return null;
-    }
-
-}
diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/domain/SysJobLog.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/domain/SysJobLog.java
deleted file mode 100644
index 2ea63df..0000000
--- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/domain/SysJobLog.java
+++ /dev/null
@@ -1,83 +0,0 @@
-package com.ruoyi.quartz.domain;
-
-import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
-import com.alibaba.excel.annotation.ExcelProperty;
-import com.baomidou.mybatisplus.annotation.*;
-import com.ruoyi.common.annotation.ExcelDictFormat;
-import com.ruoyi.common.convert.ExcelDictConvert;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-import lombok.experimental.Accessors;
-
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * 瀹氭椂浠诲姟璋冨害鏃ュ織琛� sys_job_log
- *
- * @deprecated 3.4.0鍒犻櫎 杩佺Щ鑷硏xl-job
- * @author ruoyi
- */
-
-@Data
-@NoArgsConstructor
-@Accessors(chain = true)
-@TableName("sys_job_log")
-@ExcelIgnoreUnannotated
-public class SysJobLog
-{
-    private static final long serialVersionUID = 1L;
-
-    /** ID */
-    @ExcelProperty(value = "鏃ュ織搴忓彿")
-    @TableId(value = "job_log_id", type = IdType.AUTO)
-    private Long jobLogId;
-
-    /** 浠诲姟鍚嶇О */
-    @ExcelProperty(value = "浠诲姟鍚嶇О")
-    private String jobName;
-
-    /** 浠诲姟缁勫悕 */
-    @ExcelProperty(value = "浠诲姟缁勫悕", converter = ExcelDictConvert.class)
-	@ExcelDictFormat(dictType = "sys_job_group")
-    private String jobGroup;
-
-    /** 璋冪敤鐩爣瀛楃涓� */
-    @ExcelProperty(value = "璋冪敤鐩爣瀛楃涓�")
-    private String invokeTarget;
-
-    /** 鏃ュ織淇℃伅 */
-    @ExcelProperty(value = "鏃ュ織淇℃伅")
-    private String jobMessage;
-
-    /** 鎵ц鐘舵�侊紙0姝e父 1澶辫触锛� */
-    @ExcelProperty(value = "鎵ц鐘舵��", converter = ExcelDictConvert.class)
-	@ExcelDictFormat(dictType = "sys_common_status")
-    private String status;
-
-    /** 寮傚父淇℃伅 */
-    @ExcelProperty(value = "寮傚父淇℃伅")
-    private String exceptionInfo;
-
-    /**
-     * 鍒涘缓鏃堕棿
-     */
-    @TableField(fill = FieldFill.INSERT)
-    private Date createTime;
-
-    /**
-     * 璇锋眰鍙傛暟
-     */
-    @TableField(exist = false)
-    private Map<String, Object> params = new HashMap<>();
-
-    /** 寮�濮嬫椂闂� */
-    @TableField(exist = false)
-    private Date startTime;
-
-    /** 鍋滄鏃堕棿 */
-    @TableField(exist = false)
-    private Date stopTime;
-
-}
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
deleted file mode 100644
index 0bffa11..0000000
--- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/mapper/SysJobLogMapper.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package com.ruoyi.quartz.mapper;
-
-import com.ruoyi.common.core.mybatisplus.core.BaseMapperPlus;
-import com.ruoyi.quartz.domain.SysJobLog;
-
-/**
- * 璋冨害浠诲姟鏃ュ織淇℃伅 鏁版嵁灞�
- *
- * @deprecated 3.4.0鍒犻櫎 杩佺Щ鑷硏xl-job
- * @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
deleted file mode 100644
index 13f2da7..0000000
--- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/mapper/SysJobMapper.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package com.ruoyi.quartz.mapper;
-
-import com.ruoyi.common.core.mybatisplus.core.BaseMapperPlus;
-import com.ruoyi.quartz.domain.SysJob;
-
-/**
- * 璋冨害浠诲姟淇℃伅 鏁版嵁灞�
- *
- * @deprecated 3.4.0鍒犻櫎 杩佺Щ鑷硏xl-job
- * @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
deleted file mode 100644
index ff8451a..0000000
--- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/ISysJobLogService.java
+++ /dev/null
@@ -1,63 +0,0 @@
-package com.ruoyi.quartz.service;
-
-import com.baomidou.mybatisplus.extension.service.IService;
-import com.ruoyi.common.core.page.TableDataInfo;
-import com.ruoyi.quartz.domain.SysJobLog;
-
-import java.util.List;
-
-/**
- * 瀹氭椂浠诲姟璋冨害鏃ュ織淇℃伅淇℃伅 鏈嶅姟灞�
- *
- * @deprecated 3.4.0鍒犻櫎 杩佺Щ鑷硏xl-job
- * @author ruoyi
- */
-public interface ISysJobLogService extends IService<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
deleted file mode 100644
index cbe4621..0000000
--- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/ISysJobService.java
+++ /dev/null
@@ -1,107 +0,0 @@
-package com.ruoyi.quartz.service;
-
-import com.baomidou.mybatisplus.extension.service.IService;
-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;
-
-/**
- * 瀹氭椂浠诲姟璋冨害淇℃伅淇℃伅 鏈嶅姟灞�
- *
- * @deprecated 3.4.0鍒犻櫎 杩佺Щ鑷硏xl-job
- * @author ruoyi
- */
-public interface ISysJobService extends IService<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
deleted file mode 100644
index 76edb49..0000000
--- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/impl/SysJobLogServiceImpl.java
+++ /dev/null
@@ -1,114 +0,0 @@
-package com.ruoyi.quartz.service.impl;
-
-import com.ruoyi.common.utils.StringUtils;
-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;
-
-/**
- * 瀹氭椂浠诲姟璋冨害鏃ュ織淇℃伅 鏈嶅姟灞�
- *
- * @deprecated 3.4.0鍒犻櫎 杩佺Щ鑷硏xl-job
- * @author ruoyi
- */
-@Service
-public class SysJobLogServiceImpl extends ServicePlusImpl<SysJobLogMapper, SysJobLog, SysJobLog> implements ISysJobLogService {
-
-    @Override
-    public TableDataInfo<SysJobLog> selectPageJobLogList(SysJobLog jobLog) {
-        Map<String, Object> params = jobLog.getParams();
-        LambdaQueryWrapper<SysJobLog> lqw = new LambdaQueryWrapper<SysJobLog>()
-                .like(StringUtils.isNotBlank(jobLog.getJobName()), SysJobLog::getJobName, jobLog.getJobName())
-                .eq(StringUtils.isNotBlank(jobLog.getJobGroup()), SysJobLog::getJobGroup, jobLog.getJobGroup())
-                .eq(StringUtils.isNotBlank(jobLog.getStatus()), SysJobLog::getStatus, jobLog.getStatus())
-                .like(StringUtils.isNotBlank(jobLog.getInvokeTarget()), SysJobLog::getInvokeTarget, jobLog.getInvokeTarget())
-                .apply(StringUtils.isNotEmpty(params.get("beginTime")),
-                        "date_format(create_time,'%y%m%d') >= date_format({0},'%y%m%d')",
-                        params.get("beginTime"))
-                .apply(StringUtils.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(StringUtils.isNotBlank(jobLog.getJobName()), SysJobLog::getJobName, jobLog.getJobName())
-                .eq(StringUtils.isNotBlank(jobLog.getJobGroup()), SysJobLog::getJobGroup, jobLog.getJobGroup())
-                .eq(StringUtils.isNotBlank(jobLog.getStatus()), SysJobLog::getStatus, jobLog.getStatus())
-                .like(StringUtils.isNotBlank(jobLog.getInvokeTarget()), SysJobLog::getInvokeTarget, jobLog.getInvokeTarget())
-                .apply(StringUtils.isNotEmpty(params.get("beginTime")),
-                        "date_format(create_time,'%y%m%d') >= date_format({0},'%y%m%d')",
-                        params.get("beginTime"))
-                .apply(StringUtils.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
deleted file mode 100644
index 6962cf1..0000000
--- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/impl/SysJobServiceImpl.java
+++ /dev/null
@@ -1,247 +0,0 @@
-package com.ruoyi.quartz.service.impl;
-
-import com.ruoyi.common.utils.StringUtils;
-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;
-
-/**
- * 瀹氭椂浠诲姟璋冨害淇℃伅 鏈嶅姟灞�
- *
- * @deprecated 3.4.0鍒犻櫎 杩佺Щ鑷硏xl-job
- * @author ruoyi
- */
-@Service
-public class SysJobServiceImpl extends ServicePlusImpl<SysJobMapper, SysJob, 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(StringUtils.isNotBlank(job.getJobName()), SysJob::getJobName, job.getJobName())
-                .eq(StringUtils.isNotBlank(job.getJobGroup()), SysJob::getJobGroup, job.getJobGroup())
-                .eq(StringUtils.isNotBlank(job.getStatus()), SysJob::getStatus, job.getStatus())
-                .like(StringUtils.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(StringUtils.isNotBlank(job.getJobName()), SysJob::getJobName, job.getJobName())
-                .eq(StringUtils.isNotBlank(job.getJobGroup()), SysJob::getJobGroup, job.getJobGroup())
-                .eq(StringUtils.isNotBlank(job.getStatus()), SysJob::getStatus, job.getStatus())
-                .like(StringUtils.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(rollbackFor = Exception.class)
-    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(rollbackFor = Exception.class)
-    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(rollbackFor = Exception.class)
-    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(rollbackFor = Exception.class)
-    public void deleteJobByIds(Long[] jobIds) throws SchedulerException {
-        for (Long jobId : jobIds) {
-            SysJob job = getById(jobId);
-            deleteJob(job);
-        }
-    }
-
-    /**
-     * 浠诲姟璋冨害鐘舵�佷慨鏀�
-     *
-     * @param job 璋冨害淇℃伅
-     */
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    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(rollbackFor = Exception.class)
-    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(rollbackFor = Exception.class)
-    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(rollbackFor = Exception.class)
-    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-quartz/src/main/java/com/ruoyi/quartz/task/RyTask.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/RyTask.java
deleted file mode 100644
index 7fd55c5..0000000
--- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/RyTask.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package com.ruoyi.quartz.task;
-
-import cn.hutool.core.lang.Console;
-import com.ruoyi.common.utils.StringUtils;
-import org.springframework.stereotype.Component;
-
-/**
- * 瀹氭椂浠诲姟璋冨害娴嬭瘯
- *
- * @deprecated 3.4.0鍒犻櫎 杩佺Щ鑷硏xl-job
- * @author ruoyi
- */
-@Component("ryTask")
-public class RyTask
-{
-    public void ryMultipleParams(String s, Boolean b, Long l, Double d, Integer i)
-    {
-        Console.log(StringUtils.format("鎵ц澶氬弬鏂规硶锛� 瀛楃涓茬被鍨媨}锛屽竷灏旂被鍨媨}锛岄暱鏁村瀷{}锛屾诞鐐瑰瀷{}锛屾暣褰}", s, b, l, d, i));
-    }
-
-    public void ryParams(String params)
-    {
-        Console.log("鎵ц鏈夊弬鏂规硶锛�" + params);
-    }
-
-    public void ryNoParams()
-    {
-        Console.log("鎵ц鏃犲弬鏂规硶");
-    }
-}
diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/AbstractQuartzJob.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/AbstractQuartzJob.java
deleted file mode 100644
index 1705433..0000000
--- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/AbstractQuartzJob.java
+++ /dev/null
@@ -1,109 +0,0 @@
-package com.ruoyi.quartz.util;
-
-import cn.hutool.core.bean.BeanUtil;
-import cn.hutool.core.exceptions.ExceptionUtil;
-import com.ruoyi.common.constant.Constants;
-import com.ruoyi.common.constant.ScheduleConstants;
-import com.ruoyi.common.utils.StringUtils;
-import com.ruoyi.common.utils.spring.SpringUtils;
-import com.ruoyi.quartz.domain.SysJob;
-import com.ruoyi.quartz.domain.SysJobLog;
-import com.ruoyi.quartz.service.ISysJobLogService;
-import org.quartz.Job;
-import org.quartz.JobExecutionContext;
-import org.quartz.JobExecutionException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.Date;
-
-/**
- * 鎶借薄quartz璋冪敤
- *
- * @deprecated 3.4.0鍒犻櫎 杩佺Щ鑷硏xl-job
- * @author ruoyi
- */
-public abstract class AbstractQuartzJob implements Job
-{
-    private static final Logger log = LoggerFactory.getLogger(AbstractQuartzJob.class);
-
-    /**
-     * 绾跨▼鏈湴鍙橀噺
-     */
-    private static ThreadLocal<Date> threadLocal = new ThreadLocal<>();
-
-    @Override
-    public void execute(JobExecutionContext context) throws JobExecutionException
-    {
-        SysJob sysJob = new SysJob();
-        BeanUtil.copyProperties(context.getMergedJobDataMap().get(ScheduleConstants.TASK_PROPERTIES),sysJob);
-        try
-        {
-            before(context, sysJob);
-            if (StringUtils.isNotNull(sysJob))
-            {
-                doExecute(context, sysJob);
-            }
-            after(context, sysJob, null);
-        }
-        catch (Exception e)
-        {
-            log.error("浠诲姟鎵ц寮傚父  - 锛�", e);
-            after(context, sysJob, e);
-        }
-    }
-
-    /**
-     * 鎵ц鍓�
-     *
-     * @param context 宸ヤ綔鎵ц涓婁笅鏂囧璞�
-     * @param sysJob 绯荤粺璁″垝浠诲姟
-     */
-    protected void before(JobExecutionContext context, SysJob sysJob)
-    {
-        threadLocal.set(new Date());
-    }
-
-    /**
-     * 鎵ц鍚�
-     *
-     * @param context 宸ヤ綔鎵ц涓婁笅鏂囧璞�
-     * @param sysJob 绯荤粺璁″垝浠诲姟
-     */
-    protected void after(JobExecutionContext context, SysJob sysJob, Exception e)
-    {
-        Date startTime = threadLocal.get();
-        threadLocal.remove();
-
-        final SysJobLog sysJobLog = new SysJobLog();
-        sysJobLog.setJobName(sysJob.getJobName());
-        sysJobLog.setJobGroup(sysJob.getJobGroup());
-        sysJobLog.setInvokeTarget(sysJob.getInvokeTarget());
-        sysJobLog.setStartTime(startTime);
-        sysJobLog.setStopTime(new Date());
-        long runMs = sysJobLog.getStopTime().getTime() - sysJobLog.getStartTime().getTime();
-        sysJobLog.setJobMessage(sysJobLog.getJobName() + " 鎬诲叡鑰楁椂锛�" + runMs + "姣");
-        if (e != null)
-        {
-            sysJobLog.setStatus(Constants.FAIL);
-            String errorMsg = StringUtils.substring(ExceptionUtil.stacktraceToString(e), 0, 2000);
-            sysJobLog.setExceptionInfo(errorMsg);
-        }
-        else
-        {
-            sysJobLog.setStatus(Constants.SUCCESS);
-        }
-
-        // 鍐欏叆鏁版嵁搴撳綋涓�
-        SpringUtils.getBean(ISysJobLogService.class).addJobLog(sysJobLog);
-    }
-
-    /**
-     * 鎵ц鏂规硶锛岀敱瀛愮被閲嶈浇
-     *
-     * @param context 宸ヤ綔鎵ц涓婁笅鏂囧璞�
-     * @param sysJob 绯荤粺璁″垝浠诲姟
-     * @throws Exception 鎵ц杩囩▼涓殑寮傚父
-     */
-    protected abstract void doExecute(JobExecutionContext context, SysJob sysJob) throws Exception;
-}
diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/CronUtils.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/CronUtils.java
deleted file mode 100644
index 2253af1..0000000
--- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/CronUtils.java
+++ /dev/null
@@ -1,65 +0,0 @@
-package com.ruoyi.quartz.util;
-
-import org.quartz.CronExpression;
-
-import java.text.ParseException;
-import java.util.Date;
-
-/**
- * cron琛ㄨ揪寮忓伐鍏风被
- *
- * @deprecated 3.4.0鍒犻櫎 杩佺Щ鑷硏xl-job
- * @author ruoyi
- *
- */
-public class CronUtils
-{
-    /**
-     * 杩斿洖涓�涓竷灏斿�间唬琛ㄤ竴涓粰瀹氱殑Cron琛ㄨ揪寮忕殑鏈夋晥鎬�
-     *
-     * @param cronExpression Cron琛ㄨ揪寮�
-     * @return boolean 琛ㄨ揪寮忔槸鍚︽湁鏁�
-     */
-    public static boolean isValid(String cronExpression)
-    {
-        return CronExpression.isValidExpression(cronExpression);
-    }
-
-    /**
-     * 杩斿洖涓�涓瓧绗︿覆鍊�,琛ㄧず璇ユ秷鎭棤鏁圕ron琛ㄨ揪寮忕粰鍑烘湁鏁堟��
-     *
-     * @param cronExpression Cron琛ㄨ揪寮�
-     * @return String 鏃犳晥鏃惰繑鍥炶〃杈惧紡閿欒鎻忚堪,濡傛灉鏈夋晥杩斿洖null
-     */
-    public static String getInvalidMessage(String cronExpression)
-    {
-        try
-        {
-            new CronExpression(cronExpression);
-            return null;
-        }
-        catch (ParseException pe)
-        {
-            return pe.getMessage();
-        }
-    }
-
-    /**
-     * 杩斿洖涓嬩竴涓墽琛屾椂闂存牴鎹粰瀹氱殑Cron琛ㄨ揪寮�
-     *
-     * @param cronExpression Cron琛ㄨ揪寮�
-     * @return Date 涓嬫Cron琛ㄨ揪寮忔墽琛屾椂闂�
-     */
-    public static Date getNextExecution(String cronExpression)
-    {
-        try
-        {
-            CronExpression cron = new CronExpression(cronExpression);
-            return cron.getNextValidTimeAfter(new Date(System.currentTimeMillis()));
-        }
-        catch (ParseException e)
-        {
-            throw new IllegalArgumentException(e.getMessage());
-        }
-    }
-}
diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/JobInvokeUtil.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/JobInvokeUtil.java
deleted file mode 100644
index ed15d1f..0000000
--- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/JobInvokeUtil.java
+++ /dev/null
@@ -1,183 +0,0 @@
-package com.ruoyi.quartz.util;
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.LinkedList;
-import java.util.List;
-import com.ruoyi.common.utils.StringUtils;
-import com.ruoyi.common.utils.spring.SpringUtils;
-import com.ruoyi.quartz.domain.SysJob;
-
-/**
- * 浠诲姟鎵ц宸ュ叿
- *
- * @deprecated 3.4.0鍒犻櫎 杩佺Щ鑷硏xl-job
- * @author ruoyi
- */
-public class JobInvokeUtil
-{
-    /**
-     * 鎵ц鏂规硶
-     *
-     * @param sysJob 绯荤粺浠诲姟
-     */
-    public static void invokeMethod(SysJob sysJob) throws Exception
-    {
-        String invokeTarget = sysJob.getInvokeTarget();
-        String beanName = getBeanName(invokeTarget);
-        String methodName = getMethodName(invokeTarget);
-        List<Object[]> methodParams = getMethodParams(invokeTarget);
-
-        if (!isValidClassName(beanName))
-        {
-            Object bean = SpringUtils.getBean(beanName);
-            invokeMethod(bean, methodName, methodParams);
-        }
-        else
-        {
-            Object bean = Class.forName(beanName).newInstance();
-            invokeMethod(bean, methodName, methodParams);
-        }
-    }
-
-    /**
-     * 璋冪敤浠诲姟鏂规硶
-     *
-     * @param bean 鐩爣瀵硅薄
-     * @param methodName 鏂规硶鍚嶇О
-     * @param methodParams 鏂规硶鍙傛暟
-     */
-    private static void invokeMethod(Object bean, String methodName, List<Object[]> methodParams)
-            throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException,
-            InvocationTargetException
-    {
-        if (StringUtils.isNotNull(methodParams) && methodParams.size() > 0)
-        {
-            Method method = bean.getClass().getDeclaredMethod(methodName, getMethodParamsType(methodParams));
-            method.invoke(bean, getMethodParamsValue(methodParams));
-        }
-        else
-        {
-            Method method = bean.getClass().getDeclaredMethod(methodName);
-            method.invoke(bean);
-        }
-    }
-
-    /**
-     * 鏍¢獙鏄惁涓轰负class鍖呭悕
-     * 
-     * @param str 鍚嶇О
-     * @return true鏄� false鍚�
-     */
-    public static boolean isValidClassName(String invokeTarget)
-    {
-        return StringUtils.countMatches(invokeTarget, ".") > 1;
-    }
-
-    /**
-     * 鑾峰彇bean鍚嶇О
-     * 
-     * @param invokeTarget 鐩爣瀛楃涓�
-     * @return bean鍚嶇О
-     */
-    public static String getBeanName(String invokeTarget)
-    {
-        String beanName = StringUtils.substringBefore(invokeTarget, "(");
-        return StringUtils.substringBeforeLast(beanName, ".");
-    }
-
-    /**
-     * 鑾峰彇bean鏂规硶
-     * 
-     * @param invokeTarget 鐩爣瀛楃涓�
-     * @return method鏂规硶
-     */
-    public static String getMethodName(String invokeTarget)
-    {
-        String methodName = StringUtils.substringBefore(invokeTarget, "(");
-        return StringUtils.substringAfterLast(methodName, ".");
-    }
-
-    /**
-     * 鑾峰彇method鏂规硶鍙傛暟鐩稿叧鍒楄〃
-     * 
-     * @param invokeTarget 鐩爣瀛楃涓�
-     * @return method鏂规硶鐩稿叧鍙傛暟鍒楄〃
-     */
-    public static List<Object[]> getMethodParams(String invokeTarget)
-    {
-        String methodStr = StringUtils.substringBetween(invokeTarget, "(", ")");
-        if (StringUtils.isEmpty(methodStr))
-        {
-            return null;
-        }
-        String[] methodParams = methodStr.split(",");
-        List<Object[]> classs = new LinkedList<>();
-        for (int i = 0; i < methodParams.length; i++)
-        {
-            String str = StringUtils.trimToEmpty(methodParams[i]);
-            // String瀛楃涓茬被鍨嬶紝鍖呭惈'
-            if (StringUtils.contains(str, "'"))
-            {
-                classs.add(new Object[] { StringUtils.replace(str, "'", ""), String.class });
-            }
-            // boolean甯冨皵绫诲瀷锛岀瓑浜巘rue鎴栬�協alse
-            else if (StringUtils.equals(str, "true") || StringUtils.equalsIgnoreCase(str, "false"))
-            {
-                classs.add(new Object[] { Boolean.valueOf(str), Boolean.class });
-            }
-            // long闀挎暣褰紝鍖呭惈L
-            else if (StringUtils.containsIgnoreCase(str, "L"))
-            {
-                classs.add(new Object[] { Long.valueOf(StringUtils.replaceIgnoreCase(str, "L", "")), Long.class });
-            }
-            // double娴偣绫诲瀷锛屽寘鍚獶
-            else if (StringUtils.containsIgnoreCase(str, "D"))
-            {
-                classs.add(new Object[] { Double.valueOf(StringUtils.replaceIgnoreCase(str, "D", "")), Double.class });
-            }
-            // 鍏朵粬绫诲瀷褰掔被涓烘暣褰�
-            else
-            {
-                classs.add(new Object[] { Integer.valueOf(str), Integer.class });
-            }
-        }
-        return classs;
-    }
-
-    /**
-     * 鑾峰彇鍙傛暟绫诲瀷
-     * 
-     * @param methodParams 鍙傛暟鐩稿叧鍒楄〃
-     * @return 鍙傛暟绫诲瀷鍒楄〃
-     */
-    public static Class<?>[] getMethodParamsType(List<Object[]> methodParams)
-    {
-        Class<?>[] classs = new Class<?>[methodParams.size()];
-        int index = 0;
-        for (Object[] os : methodParams)
-        {
-            classs[index] = (Class<?>) os[1];
-            index++;
-        }
-        return classs;
-    }
-
-    /**
-     * 鑾峰彇鍙傛暟鍊�
-     * 
-     * @param methodParams 鍙傛暟鐩稿叧鍒楄〃
-     * @return 鍙傛暟鍊煎垪琛�
-     */
-    public static Object[] getMethodParamsValue(List<Object[]> methodParams)
-    {
-        Object[] classs = new Object[methodParams.size()];
-        int index = 0;
-        for (Object[] os : methodParams)
-        {
-            classs[index] = (Object) os[0];
-            index++;
-        }
-        return classs;
-    }
-}
diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/QuartzDisallowConcurrentExecution.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/QuartzDisallowConcurrentExecution.java
deleted file mode 100644
index fc0ce7b..0000000
--- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/QuartzDisallowConcurrentExecution.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package com.ruoyi.quartz.util;
-
-import org.quartz.DisallowConcurrentExecution;
-import org.quartz.JobExecutionContext;
-import com.ruoyi.quartz.domain.SysJob;
-
-/**
- * 瀹氭椂浠诲姟澶勭悊锛堢姝㈠苟鍙戞墽琛岋級
- *
- * @deprecated 3.4.0鍒犻櫎 杩佺Щ鑷硏xl-job
- * @author ruoyi
- *
- */
-@DisallowConcurrentExecution
-public class QuartzDisallowConcurrentExecution extends AbstractQuartzJob
-{
-    @Override
-    protected void doExecute(JobExecutionContext context, SysJob sysJob) throws Exception
-    {
-        JobInvokeUtil.invokeMethod(sysJob);
-    }
-}
diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/QuartzJobExecution.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/QuartzJobExecution.java
deleted file mode 100644
index 404c266..0000000
--- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/QuartzJobExecution.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package com.ruoyi.quartz.util;
-
-import org.quartz.JobExecutionContext;
-import com.ruoyi.quartz.domain.SysJob;
-
-/**
- * 瀹氭椂浠诲姟澶勭悊锛堝厑璁稿苟鍙戞墽琛岋級
- *
- * @deprecated 3.4.0鍒犻櫎 杩佺Щ鑷硏xl-job
- * @author ruoyi
- *
- */
-public class QuartzJobExecution extends AbstractQuartzJob
-{
-    @Override
-    protected void doExecute(JobExecutionContext context, SysJob sysJob) throws Exception
-    {
-        JobInvokeUtil.invokeMethod(sysJob);
-    }
-}
diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/ScheduleUtils.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/ScheduleUtils.java
deleted file mode 100644
index 182d1d6..0000000
--- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/ScheduleUtils.java
+++ /dev/null
@@ -1,114 +0,0 @@
-package com.ruoyi.quartz.util;
-
-import org.quartz.CronScheduleBuilder;
-import org.quartz.CronTrigger;
-import org.quartz.Job;
-import org.quartz.JobBuilder;
-import org.quartz.JobDetail;
-import org.quartz.JobKey;
-import org.quartz.Scheduler;
-import org.quartz.SchedulerException;
-import org.quartz.TriggerBuilder;
-import org.quartz.TriggerKey;
-import com.ruoyi.common.constant.ScheduleConstants;
-import com.ruoyi.common.exception.job.TaskException;
-import com.ruoyi.common.exception.job.TaskException.Code;
-import com.ruoyi.quartz.domain.SysJob;
-
-/**
- * 瀹氭椂浠诲姟宸ュ叿绫�
- *
- * @deprecated 3.4.0鍒犻櫎 杩佺Щ鑷硏xl-job
- * @author ruoyi
- *
- */
-public class ScheduleUtils
-{
-    /**
-     * 寰楀埌quartz浠诲姟绫�
-     *
-     * @param sysJob 鎵ц璁″垝
-     * @return 鍏蜂綋鎵ц浠诲姟绫�
-     */
-    private static Class<? extends Job> getQuartzJobClass(SysJob sysJob)
-    {
-        boolean isConcurrent = "0".equals(sysJob.getConcurrent());
-        return isConcurrent ? QuartzJobExecution.class : QuartzDisallowConcurrentExecution.class;
-    }
-
-    /**
-     * 鏋勫缓浠诲姟瑙﹀彂瀵硅薄
-     */
-    public static TriggerKey getTriggerKey(Long jobId, String jobGroup)
-    {
-        return TriggerKey.triggerKey(ScheduleConstants.TASK_CLASS_NAME + jobId, jobGroup);
-    }
-
-    /**
-     * 鏋勫缓浠诲姟閿璞�
-     */
-    public static JobKey getJobKey(Long jobId, String jobGroup)
-    {
-        return JobKey.jobKey(ScheduleConstants.TASK_CLASS_NAME + jobId, jobGroup);
-    }
-
-    /**
-     * 鍒涘缓瀹氭椂浠诲姟
-     */
-    public static void createScheduleJob(Scheduler scheduler, SysJob job) throws SchedulerException, TaskException
-    {
-        Class<? extends Job> jobClass = getQuartzJobClass(job);
-        // 鏋勫缓job淇℃伅
-        Long jobId = job.getJobId();
-        String jobGroup = job.getJobGroup();
-        JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(getJobKey(jobId, jobGroup)).build();
-
-        // 琛ㄨ揪寮忚皟搴︽瀯寤哄櫒
-        CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());
-        cronScheduleBuilder = handleCronScheduleMisfirePolicy(job, cronScheduleBuilder);
-
-        // 鎸夋柊鐨刢ronExpression琛ㄨ揪寮忔瀯寤轰竴涓柊鐨則rigger
-        CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(getTriggerKey(jobId, jobGroup))
-                .withSchedule(cronScheduleBuilder).build();
-
-        // 鏀惧叆鍙傛暟锛岃繍琛屾椂鐨勬柟娉曞彲浠ヨ幏鍙�
-        jobDetail.getJobDataMap().put(ScheduleConstants.TASK_PROPERTIES, job);
-
-        // 鍒ゆ柇鏄惁瀛樺湪
-        if (scheduler.checkExists(getJobKey(jobId, jobGroup)))
-        {
-            // 闃叉鍒涘缓鏃跺瓨鍦ㄦ暟鎹棶棰� 鍏堢Щ闄わ紝鐒跺悗鍦ㄦ墽琛屽垱寤烘搷浣�
-            scheduler.deleteJob(getJobKey(jobId, jobGroup));
-        }
-
-        scheduler.scheduleJob(jobDetail, trigger);
-
-        // 鏆傚仠浠诲姟
-        if (job.getStatus().equals(ScheduleConstants.Status.PAUSE.getValue()))
-        {
-            scheduler.pauseJob(ScheduleUtils.getJobKey(jobId, jobGroup));
-        }
-    }
-
-    /**
-     * 璁剧疆瀹氭椂浠诲姟绛栫暐
-     */
-    public static CronScheduleBuilder handleCronScheduleMisfirePolicy(SysJob job, CronScheduleBuilder cb)
-            throws TaskException
-    {
-        switch (job.getMisfirePolicy())
-        {
-            case ScheduleConstants.MISFIRE_DEFAULT:
-                return cb;
-            case ScheduleConstants.MISFIRE_IGNORE_MISFIRES:
-                return cb.withMisfireHandlingInstructionIgnoreMisfires();
-            case ScheduleConstants.MISFIRE_FIRE_AND_PROCEED:
-                return cb.withMisfireHandlingInstructionFireAndProceed();
-            case ScheduleConstants.MISFIRE_DO_NOTHING:
-                return cb.withMisfireHandlingInstructionDoNothing();
-            default:
-                throw new TaskException("The task misfire policy '" + job.getMisfirePolicy()
-                        + "' cannot be used in cron schedule tasks", Code.CONFIG_ERROR);
-        }
-    }
-}
diff --git a/ruoyi-quartz/src/main/resources/mapper/quartz/SysJobLogMapper.xml b/ruoyi-quartz/src/main/resources/mapper/quartz/SysJobLogMapper.xml
deleted file mode 100644
index 736a699..0000000
--- a/ruoyi-quartz/src/main/resources/mapper/quartz/SysJobLogMapper.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<!DOCTYPE mapper
-PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
-"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-<mapper namespace="com.ruoyi.quartz.mapper.SysJobLogMapper">
-
-	<resultMap type="SysJobLog" id="SysJobLogResult">
-		<id     property="jobLogId"       column="job_log_id"      />
-		<result property="jobName"        column="job_name"        />
-		<result property="jobGroup"       column="job_group"       />
-		<result property="invokeTarget"   column="invoke_target"   />
-		<result property="jobMessage"     column="job_message"     />
-		<result property="status"         column="status"          />
-		<result property="exceptionInfo"  column="exception_info"  />
-		<result property="createTime"     column="create_time"     />
-	</resultMap>
-
-</mapper> 
\ No newline at end of file
diff --git a/ruoyi-quartz/src/main/resources/mapper/quartz/SysJobMapper.xml b/ruoyi-quartz/src/main/resources/mapper/quartz/SysJobMapper.xml
deleted file mode 100644
index 0a6342b..0000000
--- a/ruoyi-quartz/src/main/resources/mapper/quartz/SysJobMapper.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<!DOCTYPE mapper
-PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
-"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-<mapper namespace="com.ruoyi.quartz.mapper.SysJobMapper">
-
-	<resultMap type="SysJob" id="SysJobResult">
-		<id     property="jobId"          column="job_id"          />
-		<result property="jobName"        column="job_name"        />
-		<result property="jobGroup"       column="job_group"       />
-		<result property="invokeTarget"   column="invoke_target"   />
-		<result property="cronExpression" column="cron_expression" />
-		<result property="misfirePolicy"  column="misfire_policy"  />
-		<result property="concurrent"     column="concurrent"      />
-		<result property="status"         column="status"          />
-		<result property="createBy"       column="create_by"       />
-		<result property="createTime"     column="create_time"     />
-		<result property="updateBy"       column="update_by"       />
-		<result property="updateTime"     column="update_time"     />
-		<result property="remark"         column="remark"          />
-	</resultMap>
-
-</mapper> 
\ No newline at end of file
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysUserImportVo.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysUserImportVo.java
index 16932ad..d461332 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysUserImportVo.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysUserImportVo.java
@@ -67,7 +67,7 @@
      * 甯愬彿鐘舵�侊紙0姝e父 1鍋滅敤锛�
      */
     @ExcelProperty(value = "甯愬彿鐘舵��", converter = ExcelDictConvert.class)
-    @ExcelDictFormat(dictType = "sys_common_status")
+    @ExcelDictFormat(dictType = "sys_normal_disable")
     private String status;
 
 }
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/listener/SysUserImportListener.java b/ruoyi-system/src/main/java/com/ruoyi/system/listener/SysUserImportListener.java
new file mode 100644
index 0000000..d0fd7d0
--- /dev/null
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/listener/SysUserImportListener.java
@@ -0,0 +1,109 @@
+package com.ruoyi.system.listener;
+
+import cn.hutool.core.bean.BeanUtil;
+import com.alibaba.excel.context.AnalysisContext;
+import com.alibaba.excel.event.AnalysisEventListener;
+import com.ruoyi.common.core.domain.entity.SysUser;
+import com.ruoyi.common.excel.ExcelListener;
+import com.ruoyi.common.excel.ExcelResult;
+import com.ruoyi.common.exception.ServiceException;
+import com.ruoyi.common.utils.SecurityUtils;
+import com.ruoyi.common.utils.StringUtils;
+import com.ruoyi.common.utils.spring.SpringUtils;
+import com.ruoyi.system.domain.vo.SysUserImportVo;
+import com.ruoyi.system.service.ISysConfigService;
+import com.ruoyi.system.service.ISysUserService;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.List;
+
+/**
+ * 绯荤粺鐢ㄦ埛鑷畾涔夊鍏�
+ *
+ * @author Lion Li
+ */
+@Slf4j
+public class SysUserImportListener extends AnalysisEventListener<SysUserImportVo> implements ExcelListener<SysUserImportVo> {
+
+    private final ISysUserService userService;
+
+    private final String password;
+
+    private final Boolean isUpdateSupport;
+
+    private final String operName;
+
+    private int successNum = 0;
+    private int failureNum = 0;
+    private final StringBuilder successMsg = new StringBuilder();
+    private final StringBuilder failureMsg = new StringBuilder();
+
+    public SysUserImportListener(Boolean isUpdateSupport) {
+        this.userService = SpringUtils.getBean(ISysUserService.class);
+        this.password = SpringUtils.getBean(ISysConfigService.class)
+            .selectConfigByKey("sys.user.initPassword");
+        this.isUpdateSupport = isUpdateSupport;
+        this.operName = SecurityUtils.getUsername();
+    }
+
+    @Override
+    public void invoke(SysUserImportVo userVo, AnalysisContext context) {
+        SysUser user = this.userService.selectUserByUserName(userVo.getUserName());
+        try {
+            // 楠岃瘉鏄惁瀛樺湪杩欎釜鐢ㄦ埛
+            if (StringUtils.isNull(user)) {
+                user = BeanUtil.toBean(userVo, SysUser.class);
+                user.setPassword(SecurityUtils.encryptPassword(password));
+                user.setCreateBy(operName);
+                userService.insertUser(user);
+                successNum++;
+                successMsg.append("<br/>").append(successNum).append("銆佽处鍙� ").append(user.getUserName()).append(" 瀵煎叆鎴愬姛");
+            } else if (isUpdateSupport) {
+                user.setUpdateBy(operName);
+                userService.updateUser(user);
+                successNum++;
+                successMsg.append("<br/>").append(successNum).append("銆佽处鍙� ").append(user.getUserName()).append(" 鏇存柊鎴愬姛");
+            } else {
+                failureNum++;
+                failureMsg.append("<br/>").append(failureNum).append("銆佽处鍙� ").append(user.getUserName()).append(" 宸插瓨鍦�");
+            }
+        } catch (Exception e) {
+            failureNum++;
+            String msg = "<br/>" + failureNum + "銆佽处鍙� " + user.getUserName() + " 瀵煎叆澶辫触锛�";
+            failureMsg.append(msg).append(e.getMessage());
+            log.error(msg, e);
+        }
+    }
+
+    @Override
+    public void doAfterAllAnalysed(AnalysisContext context) {
+
+    }
+
+    @Override
+    public ExcelResult<SysUserImportVo> getExcelResult() {
+        return new ExcelResult<SysUserImportVo>() {
+
+            @Override
+            public String getAnalysis() {
+                if (failureNum > 0) {
+                    failureMsg.insert(0, "寰堟姳姝夛紝瀵煎叆澶辫触锛佸叡 " + failureNum + " 鏉℃暟鎹牸寮忎笉姝g‘锛岄敊璇涓嬶細");
+                    throw new ServiceException(failureMsg.toString());
+                } else {
+                    successMsg.insert(0, "鎭枩鎮紝鏁版嵁宸插叏閮ㄥ鍏ユ垚鍔燂紒鍏� " + successNum + " 鏉★紝鏁版嵁濡備笅锛�");
+                }
+                return successMsg.toString();
+            }
+
+            @Override
+            public List<SysUserImportVo> getList() {
+                return null;
+            }
+
+            @Override
+            public List<String> getErrorList() {
+                return null;
+            }
+        };
+    }
+}
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 8b5dcd6..f1a018f 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
@@ -58,6 +58,6 @@
      * @param menuCheckStrictly 鑿滃崟鏍戦�夋嫨椤规槸鍚﹀叧鑱旀樉绀�
      * @return 閫変腑鑿滃崟鍒楄〃
      */
-    List<Integer> selectMenuListByRoleId(@Param("roleId") Long roleId, @Param("menuCheckStrictly") boolean menuCheckStrictly);
+    List<Long> selectMenuListByRoleId(@Param("roleId") Long roleId, @Param("menuCheckStrictly") boolean menuCheckStrictly);
 
 }
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/runner/SystemApplicationRunner.java b/ruoyi-system/src/main/java/com/ruoyi/system/runner/SystemApplicationRunner.java
new file mode 100644
index 0000000..4080a1a
--- /dev/null
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/runner/SystemApplicationRunner.java
@@ -0,0 +1,42 @@
+package com.ruoyi.system.runner;
+
+import com.ruoyi.common.config.RuoYiConfig;
+import com.ruoyi.system.service.ISysConfigService;
+import com.ruoyi.system.service.ISysDictTypeService;
+import com.ruoyi.system.service.ISysOssConfigService;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.ApplicationArguments;
+import org.springframework.boot.ApplicationRunner;
+import org.springframework.stereotype.Component;
+
+/**
+ * 鍒濆鍖� system 妯″潡瀵瑰簲涓氬姟鏁版嵁
+ *
+ * @author Lion Li
+ */
+@Slf4j
+@RequiredArgsConstructor(onConstructor_ = @Autowired)
+@Component
+public class SystemApplicationRunner implements ApplicationRunner {
+
+    private final RuoYiConfig ruoyiConfig;
+    private final ISysConfigService configService;
+    private final ISysDictTypeService dictTypeService;
+    private final ISysOssConfigService ossConfigService;
+
+    @Override
+    public void run(ApplicationArguments args) throws Exception {
+        ossConfigService.init();
+        log.info("鍒濆鍖朞SS閰嶇疆鎴愬姛");
+        if (ruoyiConfig.isCacheLazy()){
+            return;
+        }
+        configService.loadingConfigCache();
+        log.info("鍔犺浇鍙傛暟缂撳瓨鏁版嵁鎴愬姛");
+        dictTypeService.loadingDictCache();
+        log.info("鍔犺浇瀛楀吀缂撳瓨鏁版嵁鎴愬姛");
+    }
+
+}
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 ea6afa2..bd8c5ff 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
@@ -1,7 +1,7 @@
 package com.ruoyi.system.service;
 
+import cn.hutool.core.lang.tree.Tree;
 import com.baomidou.mybatisplus.extension.service.IService;
-import com.ruoyi.common.core.domain.TreeSelect;
 import com.ruoyi.common.core.domain.entity.SysDept;
 
 import java.util.List;
@@ -21,20 +21,12 @@
     List<SysDept> selectDeptList(SysDept dept);
 
     /**
-     * 鏋勫缓鍓嶇鎵�闇�瑕佹爲缁撴瀯
-     *
-     * @param depts 閮ㄩ棬鍒楄〃
-     * @return 鏍戠粨鏋勫垪琛�
-     */
-    List<SysDept> buildDeptTree(List<SysDept> depts);
-
-    /**
      * 鏋勫缓鍓嶇鎵�闇�瑕佷笅鎷夋爲缁撴瀯
      *
      * @param depts 閮ㄩ棬鍒楄〃
      * @return 涓嬫媺鏍戠粨鏋勫垪琛�
      */
-    List<TreeSelect> buildDeptTreeSelect(List<SysDept> depts);
+    List<Tree<Long>> buildDeptTreeSelect(List<SysDept> depts);
 
     /**
      * 鏍规嵁瑙掕壊ID鏌ヨ閮ㄩ棬鏍戜俊鎭�
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 eea882e..9424052 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
@@ -1,7 +1,7 @@
 package com.ruoyi.system.service;
 
+import cn.hutool.core.lang.tree.Tree;
 import com.baomidou.mybatisplus.extension.service.IService;
-import com.ruoyi.common.core.domain.TreeSelect;
 import com.ruoyi.common.core.domain.entity.SysMenu;
 import com.ruoyi.system.domain.vo.RouterVo;
 
@@ -54,7 +54,7 @@
      * @param roleId 瑙掕壊ID
      * @return 閫変腑鑿滃崟鍒楄〃
      */
-    List<Integer> selectMenuListByRoleId(Long roleId);
+    List<Long> selectMenuListByRoleId(Long roleId);
 
     /**
      * 鏋勫缓鍓嶇璺敱鎵�闇�瑕佺殑鑿滃崟
@@ -65,20 +65,12 @@
     List<RouterVo> buildMenus(List<SysMenu> menus);
 
     /**
-     * 鏋勫缓鍓嶇鎵�闇�瑕佹爲缁撴瀯
-     *
-     * @param menus 鑿滃崟鍒楄〃
-     * @return 鏍戠粨鏋勫垪琛�
-     */
-    List<SysMenu> buildMenuTree(List<SysMenu> menus);
-
-    /**
      * 鏋勫缓鍓嶇鎵�闇�瑕佷笅鎷夋爲缁撴瀯
      *
      * @param menus 鑿滃崟鍒楄〃
      * @return 涓嬫媺鏍戠粨鏋勫垪琛�
      */
-    List<TreeSelect> buildMenuTreeSelect(List<SysMenu> menus);
+    List<Tree<Long>> buildMenuTreeSelect(List<SysMenu> menus);
 
     /**
      * 鏍规嵁鑿滃崟ID鏌ヨ淇℃伅
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysOssConfigService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysOssConfigService.java
index 759ec5b..9d9fd53 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysOssConfigService.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysOssConfigService.java
@@ -18,6 +18,11 @@
 public interface ISysOssConfigService extends IServicePlus<SysOssConfig, SysOssConfigVo> {
 
     /**
+     * 鍒濆鍖朞SS閰嶇疆
+     */
+    void init();
+
+    /**
      * 鏌ヨ鍗曚釜
      */
     SysOssConfigVo queryById(Integer ossConfigId);
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 a01bcd1..bbd09a1 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
@@ -7,6 +7,7 @@
 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.service.ConfigService;
 import com.ruoyi.common.enums.DataSourceType;
 import com.ruoyi.common.exception.ServiceException;
 import com.ruoyi.common.utils.PageUtils;
@@ -17,7 +18,6 @@
 import com.ruoyi.system.service.ISysConfigService;
 import org.springframework.stereotype.Service;
 
-import javax.annotation.PostConstruct;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.List;
@@ -29,29 +29,17 @@
  * @author Lion Li
  */
 @Service
-public class SysConfigServiceImpl extends ServicePlusImpl<SysConfigMapper, SysConfig, SysConfig> implements ISysConfigService {
-
-    /**
-     * 椤圭洰鍚姩鏃讹紝鍒濆鍖栧弬鏁板埌缂撳瓨
-     */
-    @PostConstruct
-    public void init() {
-        loadingConfigCache();
-    }
+public class SysConfigServiceImpl extends ServicePlusImpl<SysConfigMapper, SysConfig, SysConfig> implements ISysConfigService, ConfigService {
 
     @Override
     public TableDataInfo<SysConfig> selectPageConfigList(SysConfig config) {
         Map<String, Object> params = config.getParams();
         LambdaQueryWrapper<SysConfig> lqw = new LambdaQueryWrapper<SysConfig>()
-                .like(StringUtils.isNotBlank(config.getConfigName()), SysConfig::getConfigName, config.getConfigName())
-                .eq(StringUtils.isNotBlank(config.getConfigType()), SysConfig::getConfigType, config.getConfigType())
-                .like(StringUtils.isNotBlank(config.getConfigKey()), SysConfig::getConfigKey, config.getConfigKey())
-                .apply(StringUtils.isNotEmpty(params.get("beginTime")),
-                        "date_format(create_time,'%y%m%d') >= date_format({0},'%y%m%d')",
-                        params.get("beginTime"))
-                .apply(StringUtils.isNotEmpty(params.get("endTime")),
-                        "date_format(create_time,'%y%m%d') <= date_format({0},'%y%m%d')",
-                        params.get("endTime"));
+            .like(StringUtils.isNotBlank(config.getConfigName()), SysConfig::getConfigName, config.getConfigName())
+            .eq(StringUtils.isNotBlank(config.getConfigType()), SysConfig::getConfigType, config.getConfigType())
+            .like(StringUtils.isNotBlank(config.getConfigKey()), SysConfig::getConfigKey, config.getConfigKey())
+            .between(params.get("beginTime") != null && params.get("endTime") != null,
+                SysConfig::getCreateTime, params.get("beginTime"), params.get("endTime"));
         return PageUtils.buildDataInfo(page(PageUtils.buildPage(), lqw));
     }
 
@@ -75,12 +63,12 @@
      */
     @Override
     public String selectConfigByKey(String configKey) {
-        String configValue = Convert.toStr(RedisUtils.getCacheObject(getCacheKey(configKey)));
+        String configValue = RedisUtils.getCacheObject(getCacheKey(configKey));
         if (StringUtils.isNotEmpty(configValue)) {
             return configValue;
         }
         SysConfig retConfig = baseMapper.selectOne(new LambdaQueryWrapper<SysConfig>()
-                .eq(SysConfig::getConfigKey, configKey));
+            .eq(SysConfig::getConfigKey, configKey));
         if (StringUtils.isNotNull(retConfig)) {
             RedisUtils.setCacheObject(getCacheKey(configKey), retConfig.getConfigValue());
             return retConfig.getConfigValue();
@@ -112,15 +100,11 @@
     public List<SysConfig> selectConfigList(SysConfig config) {
         Map<String, Object> params = config.getParams();
         LambdaQueryWrapper<SysConfig> lqw = new LambdaQueryWrapper<SysConfig>()
-                .like(StringUtils.isNotBlank(config.getConfigName()), SysConfig::getConfigName, config.getConfigName())
-                .eq(StringUtils.isNotBlank(config.getConfigType()), SysConfig::getConfigType, config.getConfigType())
-                .like(StringUtils.isNotBlank(config.getConfigKey()), SysConfig::getConfigKey, config.getConfigKey())
-                .apply(StringUtils.isNotEmpty(params.get("beginTime")),
-                        "date_format(create_time,'%y%m%d') >= date_format({0},'%y%m%d')",
-                        params.get("beginTime"))
-                .apply(StringUtils.isNotEmpty(params.get("endTime")),
-                        "date_format(create_time,'%y%m%d') <= date_format({0},'%y%m%d')",
-                        params.get("endTime"));
+            .like(StringUtils.isNotBlank(config.getConfigName()), SysConfig::getConfigName, config.getConfigName())
+            .eq(StringUtils.isNotBlank(config.getConfigType()), SysConfig::getConfigType, config.getConfigType())
+            .like(StringUtils.isNotBlank(config.getConfigKey()), SysConfig::getConfigKey, config.getConfigKey())
+            .between(params.get("beginTime") != null && params.get("endTime") != null,
+                SysConfig::getCreateTime, params.get("beginTime"), params.get("endTime"));
         return baseMapper.selectList(lqw);
     }
 
@@ -218,6 +202,17 @@
     }
 
     /**
+     * 鏍规嵁鍙傛暟 key 鑾峰彇鍙傛暟鍊�
+     *
+     * @param configKey 鍙傛暟 key
+     * @return 鍙傛暟鍊�
+     */
+    @Override
+    public String getConfigValue(String configKey) {
+        return selectConfigByKey(configKey);
+    }
+
+    /**
      * 璁剧疆cache key
      *
      * @param configKey 鍙傛暟閿�
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 45c6fae..995bd2d 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,11 +1,11 @@
 package com.ruoyi.system.service.impl;
 
 import cn.hutool.core.convert.Convert;
+import cn.hutool.core.lang.tree.Tree;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 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;
@@ -13,6 +13,7 @@
 import com.ruoyi.common.exception.ServiceException;
 import com.ruoyi.common.utils.SecurityUtils;
 import com.ruoyi.common.utils.StringUtils;
+import com.ruoyi.common.utils.TreeBuildUtils;
 import com.ruoyi.common.utils.spring.SpringUtils;
 import com.ruoyi.system.mapper.SysDeptMapper;
 import com.ruoyi.system.mapper.SysRoleMapper;
@@ -21,10 +22,8 @@
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
-import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
-import java.util.stream.Collectors;
 
 /**
  * 閮ㄩ棬绠$悊 鏈嶅姟瀹炵幇
@@ -53,41 +52,18 @@
     }
 
     /**
-     * 鏋勫缓鍓嶇鎵�闇�瑕佹爲缁撴瀯
-     *
-     * @param depts 閮ㄩ棬鍒楄〃
-     * @return 鏍戠粨鏋勫垪琛�
-     */
-    @Override
-    public List<SysDept> buildDeptTree(List<SysDept> depts) {
-        List<SysDept> returnList = new ArrayList<SysDept>();
-        List<Long> tempList = new ArrayList<Long>();
-        for (SysDept dept : depts) {
-            tempList.add(dept.getDeptId());
-        }
-        for (SysDept dept : depts) {
-            // 濡傛灉鏄《绾ц妭鐐�, 閬嶅巻璇ョ埗鑺傜偣鐨勬墍鏈夊瓙鑺傜偣
-            if (!tempList.contains(dept.getParentId())) {
-                recursionFn(depts, dept);
-                returnList.add(dept);
-            }
-        }
-        if (returnList.isEmpty()) {
-            returnList = depts;
-        }
-        return returnList;
-    }
-
-    /**
      * 鏋勫缓鍓嶇鎵�闇�瑕佷笅鎷夋爲缁撴瀯
      *
      * @param depts 閮ㄩ棬鍒楄〃
      * @return 涓嬫媺鏍戠粨鏋勫垪琛�
      */
     @Override
-    public List<TreeSelect> buildDeptTreeSelect(List<SysDept> depts) {
-        List<SysDept> deptTrees = buildDeptTree(depts);
-        return deptTrees.stream().map(TreeSelect::new).collect(Collectors.toList());
+    public List<Tree<Long>> buildDeptTreeSelect(List<SysDept> depts) {
+        return TreeBuildUtils.build(depts, (dept, tree) ->
+            tree.setId(dept.getDeptId())
+                .setParentId(dept.getParentId())
+                .setName(dept.getDeptName())
+                .setWeight(dept.getOrderNum()));
     }
 
     /**
@@ -122,8 +98,8 @@
     @Override
     public long selectNormalChildrenDeptById(Long deptId) {
         return count(new LambdaQueryWrapper<SysDept>()
-                .eq(SysDept::getStatus, 0)
-                .apply("find_in_set({0}, ancestors)", deptId));
+            .eq(SysDept::getStatus, 0)
+            .apply("find_in_set({0}, ancestors)", deptId));
     }
 
     /**
@@ -135,8 +111,7 @@
     @Override
     public boolean hasChildByDeptId(Long deptId) {
         long result = count(new LambdaQueryWrapper<SysDept>()
-                .eq(SysDept::getParentId, deptId)
-                .last("limit 1"));
+            .eq(SysDept::getParentId, deptId));
         return result > 0;
     }
 
@@ -149,7 +124,7 @@
     @Override
     public boolean checkDeptExistUser(Long deptId) {
         long result = userMapper.selectCount(new LambdaQueryWrapper<SysUser>()
-                .eq(SysUser::getDeptId, deptId));
+            .eq(SysUser::getDeptId, deptId));
         return result > 0;
     }
 
@@ -162,11 +137,11 @@
     @Override
     public String checkDeptNameUnique(SysDept dept) {
         Long deptId = StringUtils.isNull(dept.getDeptId()) ? -1L : dept.getDeptId();
-        SysDept info = getOne(new LambdaQueryWrapper<SysDept>()
-                .eq(SysDept::getDeptName, dept.getDeptName())
-                .eq(SysDept::getParentId, dept.getParentId())
-                .last("limit 1"));
-        if (StringUtils.isNotNull(info) && info.getDeptId().longValue() != deptId.longValue()) {
+        long count = count(new LambdaQueryWrapper<SysDept>()
+            .eq(SysDept::getDeptName, dept.getDeptName())
+            .eq(SysDept::getParentId, dept.getParentId())
+            .ne(SysDept::getDeptId, deptId));
+        if (count > 0) {
             return UserConstants.NOT_UNIQUE;
         }
         return UserConstants.UNIQUE;
@@ -224,7 +199,7 @@
         }
         int result = baseMapper.updateById(dept);
         if (UserConstants.DEPT_NORMAL.equals(dept.getStatus()) && StringUtils.isNotEmpty(dept.getAncestors())
-                && !StringUtils.equals("0", dept.getAncestors())) {
+            && !StringUtils.equals("0", dept.getAncestors())) {
             // 濡傛灉璇ラ儴闂ㄦ槸鍚敤鐘舵�侊紝鍒欏惎鐢ㄨ閮ㄩ棬鐨勬墍鏈変笂绾ч儴闂�
             updateParentDeptStatusNormal(dept);
         }
@@ -240,8 +215,8 @@
         String ancestors = dept.getAncestors();
         Long[] deptIds = Convert.toLongArray(ancestors);
         update(null, new LambdaUpdateWrapper<SysDept>()
-                .set(SysDept::getStatus, "0")
-                .in(SysDept::getDeptId, Arrays.asList(deptIds)));
+            .set(SysDept::getStatus, "0")
+            .in(SysDept::getDeptId, Arrays.asList(deptIds)));
     }
 
     /**
@@ -253,7 +228,7 @@
      */
     public void updateDeptChildren(Long deptId, String newAncestors, String oldAncestors) {
         List<SysDept> children = list(new LambdaQueryWrapper<SysDept>()
-                .apply("find_in_set({0},ancestors)", deptId));
+            .apply("find_in_set({0},ancestors)", deptId));
         for (SysDept child : children) {
             child.setAncestors(child.getAncestors().replaceFirst(oldAncestors, newAncestors));
         }
@@ -273,37 +248,4 @@
         return baseMapper.deleteById(deptId);
     }
 
-    /**
-     * 閫掑綊鍒楄〃
-     */
-    private void recursionFn(List<SysDept> list, SysDept t) {
-        // 寰楀埌瀛愯妭鐐瑰垪琛�
-        List<SysDept> childList = getChildList(list, t);
-        t.setChildren(childList);
-        for (SysDept tChild : childList) {
-            if (hasChild(list, tChild)) {
-                recursionFn(list, tChild);
-            }
-        }
-    }
-
-    /**
-     * 寰楀埌瀛愯妭鐐瑰垪琛�
-     */
-    private List<SysDept> getChildList(List<SysDept> list, SysDept t) {
-        List<SysDept> tlist = new ArrayList<SysDept>();
-        for (SysDept n : list) {
-            if (StringUtils.isNotNull(n.getParentId()) && n.getParentId().longValue() == t.getDeptId().longValue()) {
-                tlist.add(n);
-            }
-        }
-        return tlist;
-    }
-
-    /**
-     * 鍒ゆ柇鏄惁鏈夊瓙鑺傜偣
-     */
-    private boolean hasChild(List<SysDept> list, SysDept t) {
-        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 35908e3..d2ac2a0 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
@@ -1,11 +1,12 @@
 package com.ruoyi.system.service.impl;
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.ruoyi.common.constant.Constants;
 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;
+import com.ruoyi.common.utils.RedisUtils;
 import com.ruoyi.common.utils.StringUtils;
 import com.ruoyi.system.mapper.SysDictDataMapper;
 import com.ruoyi.system.service.ISysDictDataService;
@@ -85,7 +86,7 @@
             SysDictData data = selectDictDataById(dictCode);
             removeById(dictCode);
             List<SysDictData> dictDatas = baseMapper.selectDictDataByType(data.getDictType());
-            DictUtils.setDictCache(data.getDictType(), dictDatas);
+            RedisUtils.setCacheObject(getCacheKey(data.getDictType()), dictDatas);
         }
     }
 
@@ -100,7 +101,7 @@
         int row = baseMapper.insert(data);
         if (row > 0) {
             List<SysDictData> dictDatas = baseMapper.selectDictDataByType(data.getDictType());
-            DictUtils.setDictCache(data.getDictType(), dictDatas);
+            RedisUtils.setCacheObject(getCacheKey(data.getDictType()), dictDatas);
         }
         return row;
     }
@@ -116,8 +117,18 @@
         int row = baseMapper.updateById(data);
         if (row > 0) {
             List<SysDictData> dictDatas = baseMapper.selectDictDataByType(data.getDictType());
-            DictUtils.setDictCache(data.getDictType(), dictDatas);
+            RedisUtils.setCacheObject(getCacheKey(data.getDictType()), dictDatas);
         }
         return row;
     }
+
+    /**
+     * 璁剧疆cache key
+     *
+     * @param configKey 鍙傛暟閿�
+     * @return 缂撳瓨閿甼ey
+     */
+    String getCacheKey(String configKey) {
+        return Constants.SYS_DICT_KEY + configKey;
+    }
 }
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 bb940c2..b520d41 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
@@ -3,14 +3,16 @@
 import cn.hutool.core.collection.CollUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.ruoyi.common.constant.Constants;
 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.core.service.DictService;
 import com.ruoyi.common.exception.ServiceException;
-import com.ruoyi.common.utils.DictUtils;
 import com.ruoyi.common.utils.PageUtils;
+import com.ruoyi.common.utils.RedisUtils;
 import com.ruoyi.common.utils.StringUtils;
 import com.ruoyi.system.mapper.SysDictDataMapper;
 import com.ruoyi.system.mapper.SysDictTypeMapper;
@@ -19,8 +21,8 @@
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
-import javax.annotation.PostConstruct;
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 
@@ -30,32 +32,20 @@
  * @author Lion Li
  */
 @Service
-public class SysDictTypeServiceImpl extends ServicePlusImpl<SysDictTypeMapper, SysDictType, SysDictType> implements ISysDictTypeService {
+public class SysDictTypeServiceImpl extends ServicePlusImpl<SysDictTypeMapper, SysDictType, SysDictType> implements ISysDictTypeService, DictService {
 
     @Autowired
     private SysDictDataMapper dictDataMapper;
-
-    /**
-     * 椤圭洰鍚姩鏃讹紝鍒濆鍖栧瓧鍏稿埌缂撳瓨
-     */
-    @PostConstruct
-    public void init() {
-        loadingDictCache();
-    }
 
     @Override
     public TableDataInfo<SysDictType> selectPageDictTypeList(SysDictType dictType) {
         Map<String, Object> params = dictType.getParams();
         LambdaQueryWrapper<SysDictType> lqw = new LambdaQueryWrapper<SysDictType>()
-                .like(StringUtils.isNotBlank(dictType.getDictName()), SysDictType::getDictName, dictType.getDictName())
-                .eq(StringUtils.isNotBlank(dictType.getStatus()), SysDictType::getStatus, dictType.getStatus())
-                .like(StringUtils.isNotBlank(dictType.getDictType()), SysDictType::getDictType, dictType.getDictType())
-                .apply(StringUtils.isNotEmpty(params.get("beginTime")),
-                        "date_format(create_time,'%y%m%d') >= date_format({0},'%y%m%d')",
-                        params.get("beginTime"))
-                .apply(StringUtils.isNotEmpty(params.get("endTime")),
-                        "date_format(create_time,'%y%m%d') <= date_format({0},'%y%m%d')",
-                        params.get("endTime"));
+            .like(StringUtils.isNotBlank(dictType.getDictName()), SysDictType::getDictName, dictType.getDictName())
+            .eq(StringUtils.isNotBlank(dictType.getStatus()), SysDictType::getStatus, dictType.getStatus())
+            .like(StringUtils.isNotBlank(dictType.getDictType()), SysDictType::getDictType, dictType.getDictType())
+            .between(params.get("beginTime") != null && params.get("endTime") != null,
+                SysDictType::getCreateTime, params.get("beginTime"), params.get("endTime"));
         return PageUtils.buildDataInfo(page(PageUtils.buildPage(), lqw));
     }
 
@@ -69,15 +59,11 @@
     public List<SysDictType> selectDictTypeList(SysDictType dictType) {
         Map<String, Object> params = dictType.getParams();
         return list(new LambdaQueryWrapper<SysDictType>()
-                .like(StringUtils.isNotBlank(dictType.getDictName()), SysDictType::getDictName, dictType.getDictName())
-                .eq(StringUtils.isNotBlank(dictType.getStatus()), SysDictType::getStatus, dictType.getStatus())
-                .like(StringUtils.isNotBlank(dictType.getDictType()), SysDictType::getDictType, dictType.getDictType())
-                .apply(StringUtils.isNotEmpty(params.get("beginTime")),
-                        "date_format(create_time,'%y%m%d') >= date_format({0},'%y%m%d')",
-                        params.get("beginTime"))
-                .apply(StringUtils.isNotEmpty(params.get("endTime")),
-                        "date_format(create_time,'%y%m%d') <= date_format({0},'%y%m%d')",
-                        params.get("endTime")));
+            .like(StringUtils.isNotBlank(dictType.getDictName()), SysDictType::getDictName, dictType.getDictName())
+            .eq(StringUtils.isNotBlank(dictType.getStatus()), SysDictType::getStatus, dictType.getStatus())
+            .like(StringUtils.isNotBlank(dictType.getDictType()), SysDictType::getDictType, dictType.getDictType())
+            .between(params.get("beginTime") != null && params.get("endTime") != null,
+                SysDictType::getCreateTime, params.get("beginTime"), params.get("endTime")));
     }
 
     /**
@@ -98,13 +84,13 @@
      */
     @Override
     public List<SysDictData> selectDictDataByType(String dictType) {
-        List<SysDictData> dictDatas = DictUtils.getDictCache(dictType);
-        if (CollUtil.isNotEmpty(dictDatas)) {
+        List<SysDictData> dictDatas = RedisUtils.getCacheObject(getCacheKey(dictType));
+        if (StringUtils.isNotEmpty(dictDatas)) {
             return dictDatas;
         }
         dictDatas = dictDataMapper.selectDictDataByType(dictType);
         if (CollUtil.isNotEmpty(dictDatas)) {
-            DictUtils.setDictCache(dictType, dictDatas);
+            RedisUtils.setCacheObject(getCacheKey(dictType), dictDatas);
             return dictDatas;
         }
         return null;
@@ -143,10 +129,10 @@
         for (Long dictId : dictIds) {
             SysDictType dictType = selectDictTypeById(dictId);
             if (dictDataMapper.selectCount(new LambdaQueryWrapper<SysDictData>()
-                    .eq(SysDictData::getDictType, dictType.getDictType())) > 0) {
+                .eq(SysDictData::getDictType, dictType.getDictType())) > 0) {
                 throw new ServiceException(String.format("%1$s宸插垎閰�,涓嶈兘鍒犻櫎", dictType.getDictName()));
             }
-            DictUtils.removeDictCache(dictType.getDictType());
+            RedisUtils.deleteObject(getCacheKey(dictType.getDictType()));
         }
         baseMapper.deleteBatchIds(Arrays.asList(dictIds));
     }
@@ -159,7 +145,7 @@
         List<SysDictType> dictTypeList = list();
         for (SysDictType dictType : dictTypeList) {
             List<SysDictData> dictDatas = dictDataMapper.selectDictDataByType(dictType.getDictType());
-            DictUtils.setDictCache(dictType.getDictType(), dictDatas);
+            RedisUtils.setCacheObject(getCacheKey(dictType.getDictType()), dictDatas);
         }
     }
 
@@ -168,7 +154,8 @@
      */
     @Override
     public void clearDictCache() {
-        DictUtils.clearDictCache();
+        Collection<String> keys = RedisUtils.keys(Constants.SYS_DICT_KEY + "*");
+        RedisUtils.deleteObject(keys);
     }
 
     /**
@@ -190,7 +177,7 @@
     public int insertDictType(SysDictType dict) {
         int row = baseMapper.insert(dict);
         if (row > 0) {
-            DictUtils.setDictCache(dict.getDictType(), null);
+            RedisUtils.setCacheObject(getCacheKey(dict.getDictType()), null);
         }
         return row;
     }
@@ -206,12 +193,12 @@
     public int updateDictType(SysDictType dict) {
         SysDictType oldDict = getById(dict.getDictId());
         dictDataMapper.update(null, new LambdaUpdateWrapper<SysDictData>()
-                .set(SysDictData::getDictType, dict.getDictType())
-                .eq(SysDictData::getDictType, oldDict.getDictType()));
+            .set(SysDictData::getDictType, dict.getDictType())
+            .eq(SysDictData::getDictType, oldDict.getDictType()));
         int row = baseMapper.updateById(dict);
         if (row > 0) {
             List<SysDictData> dictDatas = dictDataMapper.selectDictDataByType(dict.getDictType());
-            DictUtils.setDictCache(dict.getDictType(), dictDatas);
+            RedisUtils.setCacheObject(getCacheKey(dict.getDictType()), dictDatas);
         }
         return row;
     }
@@ -225,12 +212,86 @@
     @Override
     public String checkDictTypeUnique(SysDictType dict) {
         Long dictId = StringUtils.isNull(dict.getDictId()) ? -1L : dict.getDictId();
-        SysDictType dictType = getOne(new LambdaQueryWrapper<SysDictType>()
-                .eq(SysDictType::getDictType, dict.getDictType())
-                .last("limit 1"));
-        if (StringUtils.isNotNull(dictType) && dictType.getDictId().longValue() != dictId.longValue()) {
+        long count = count(new LambdaQueryWrapper<SysDictType>()
+            .eq(SysDictType::getDictType, dict.getDictType())
+            .ne(SysDictType::getDictId, dictId));
+        if (count > 0) {
             return UserConstants.NOT_UNIQUE;
         }
         return UserConstants.UNIQUE;
     }
+
+    /**
+     * 鏍规嵁瀛楀吀绫诲瀷鍜屽瓧鍏稿�艰幏鍙栧瓧鍏告爣绛�
+     *
+     * @param dictType  瀛楀吀绫诲瀷
+     * @param dictValue 瀛楀吀鍊�
+     * @param separator 鍒嗛殧绗�
+     * @return 瀛楀吀鏍囩
+     */
+    @Override
+    public String getDictLabel(String dictType, String dictValue, String separator) {
+        StringBuilder propertyString = new StringBuilder();
+        List<SysDictData> datas = selectDictDataByType(dictType);
+
+        if (StringUtils.containsAny(dictValue, separator) && CollUtil.isNotEmpty(datas)) {
+            for (SysDictData dict : datas) {
+                for (String value : dictValue.split(separator)) {
+                    if (value.equals(dict.getDictValue())) {
+                        propertyString.append(dict.getDictLabel() + separator);
+                        break;
+                    }
+                }
+            }
+        } else {
+            for (SysDictData dict : datas) {
+                if (dictValue.equals(dict.getDictValue())) {
+                    return dict.getDictLabel();
+                }
+            }
+        }
+        return StringUtils.stripEnd(propertyString.toString(), separator);
+    }
+
+    /**
+     * 鏍规嵁瀛楀吀绫诲瀷鍜屽瓧鍏告爣绛捐幏鍙栧瓧鍏稿��
+     *
+     * @param dictType  瀛楀吀绫诲瀷
+     * @param dictLabel 瀛楀吀鏍囩
+     * @param separator 鍒嗛殧绗�
+     * @return 瀛楀吀鍊�
+     */
+    @Override
+    public String getDictValue(String dictType, String dictLabel, String separator) {
+        StringBuilder propertyString = new StringBuilder();
+        List<SysDictData> datas = selectDictDataByType(dictType);
+
+        if (StringUtils.containsAny(dictLabel, separator) && CollUtil.isNotEmpty(datas)) {
+            for (SysDictData dict : datas) {
+                for (String label : dictLabel.split(separator)) {
+                    if (label.equals(dict.getDictLabel())) {
+                        propertyString.append(dict.getDictValue() + separator);
+                        break;
+                    }
+                }
+            }
+        } else {
+            for (SysDictData dict : datas) {
+                if (dictLabel.equals(dict.getDictLabel())) {
+                    return dict.getDictValue();
+                }
+            }
+        }
+        return StringUtils.stripEnd(propertyString.toString(), separator);
+    }
+
+    /**
+     * 璁剧疆cache key
+     *
+     * @param configKey 鍙傛暟閿�
+     * @return 缂撳瓨閿甼ey
+     */
+    String getCacheKey(String configKey) {
+        return Constants.SYS_DICT_KEY + configKey;
+    }
 }
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 dda5b5d..0ce33be 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
@@ -90,16 +90,12 @@
     public TableDataInfo<SysLogininfor> selectPageLogininforList(SysLogininfor logininfor) {
         Map<String, Object> params = logininfor.getParams();
         LambdaQueryWrapper<SysLogininfor> lqw = new LambdaQueryWrapper<SysLogininfor>()
-                .like(StringUtils.isNotBlank(logininfor.getIpaddr()), SysLogininfor::getIpaddr, logininfor.getIpaddr())
-                .eq(StringUtils.isNotBlank(logininfor.getStatus()), SysLogininfor::getStatus, logininfor.getStatus())
-                .like(StringUtils.isNotBlank(logininfor.getUserName()), SysLogininfor::getUserName, logininfor.getUserName())
-                .apply(StringUtils.isNotEmpty(params.get("beginTime")),
-                        "date_format(login_time,'%y%m%d') >= date_format({0},'%y%m%d')",
-                        params.get("beginTime"))
-                .apply(StringUtils.isNotEmpty(params.get("endTime")),
-                        "date_format(login_time,'%y%m%d') <= date_format({0},'%y%m%d')",
-                        params.get("endTime"));
-        return PageUtils.buildDataInfo(page(PageUtils.buildPage("info_id","desc"), lqw));
+            .like(StringUtils.isNotBlank(logininfor.getIpaddr()), SysLogininfor::getIpaddr, logininfor.getIpaddr())
+            .eq(StringUtils.isNotBlank(logininfor.getStatus()), SysLogininfor::getStatus, logininfor.getStatus())
+            .like(StringUtils.isNotBlank(logininfor.getUserName()), SysLogininfor::getUserName, logininfor.getUserName())
+            .between(params.get("beginTime") != null && params.get("endTime") != null,
+                SysLogininfor::getLoginTime, params.get("beginTime"), params.get("endTime"));
+        return PageUtils.buildDataInfo(page(PageUtils.buildPage("info_id", "desc"), lqw));
     }
 
     /**
@@ -123,16 +119,12 @@
     public List<SysLogininfor> selectLogininforList(SysLogininfor logininfor) {
         Map<String, Object> params = logininfor.getParams();
         return list(new LambdaQueryWrapper<SysLogininfor>()
-                .like(StringUtils.isNotBlank(logininfor.getIpaddr()),SysLogininfor::getIpaddr,logininfor.getIpaddr())
-                .eq(StringUtils.isNotBlank(logininfor.getStatus()),SysLogininfor::getStatus,logininfor.getStatus())
-                .like(StringUtils.isNotBlank(logininfor.getUserName()),SysLogininfor::getUserName,logininfor.getUserName())
-                .apply(StringUtils.isNotEmpty(params.get("beginTime")),
-                        "date_format(login_time,'%y%m%d') >= date_format({0},'%y%m%d')",
-                        params.get("beginTime"))
-                .apply(StringUtils.isNotEmpty(params.get("endTime")),
-                        "date_format(login_time,'%y%m%d') <= date_format({0},'%y%m%d')",
-                        params.get("endTime"))
-                .orderByDesc(SysLogininfor::getInfoId));
+            .like(StringUtils.isNotBlank(logininfor.getIpaddr()), SysLogininfor::getIpaddr, logininfor.getIpaddr())
+            .eq(StringUtils.isNotBlank(logininfor.getStatus()), SysLogininfor::getStatus, logininfor.getStatus())
+            .like(StringUtils.isNotBlank(logininfor.getUserName()), SysLogininfor::getUserName, logininfor.getUserName())
+            .between(params.get("beginTime") != null && params.get("endTime") != null,
+                SysLogininfor::getLoginTime, params.get("beginTime"), params.get("endTime"))
+            .orderByDesc(SysLogininfor::getInfoId));
     }
 
     /**
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 643d304..9c3bfeb 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
@@ -1,15 +1,16 @@
 package com.ruoyi.system.service.impl;
 
+import cn.hutool.core.lang.tree.Tree;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.ruoyi.common.constant.Constants;
 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.common.utils.StringUtils;
+import com.ruoyi.common.utils.TreeBuildUtils;
 import com.ruoyi.system.domain.SysRoleMenu;
 import com.ruoyi.system.domain.vo.MetaVo;
 import com.ruoyi.system.domain.vo.RouterVo;
@@ -21,7 +22,6 @@
 import org.springframework.stereotype.Service;
 
 import java.util.*;
-import java.util.stream.Collectors;
 
 /**
  * 鑿滃崟 涓氬姟灞傚鐞�
@@ -60,11 +60,11 @@
         // 绠$悊鍛樻樉绀烘墍鏈夎彍鍗曚俊鎭�
         if (SysUser.isAdmin(userId)) {
             menuList = list(new LambdaQueryWrapper<SysMenu>()
-                    .like(StringUtils.isNotBlank(menu.getMenuName()), SysMenu::getMenuName, menu.getMenuName())
-                    .eq(StringUtils.isNotBlank(menu.getVisible()), SysMenu::getVisible, menu.getVisible())
-                    .eq(StringUtils.isNotBlank(menu.getStatus()), SysMenu::getStatus, menu.getStatus())
-                    .orderByAsc(SysMenu::getParentId)
-                    .orderByAsc(SysMenu::getOrderNum));
+                .like(StringUtils.isNotBlank(menu.getMenuName()), SysMenu::getMenuName, menu.getMenuName())
+                .eq(StringUtils.isNotBlank(menu.getVisible()), SysMenu::getVisible, menu.getVisible())
+                .eq(StringUtils.isNotBlank(menu.getStatus()), SysMenu::getStatus, menu.getStatus())
+                .orderByAsc(SysMenu::getParentId)
+                .orderByAsc(SysMenu::getOrderNum));
         } else {
             menu.getParams().put("userId", userId);
             menuList = baseMapper.selectMenuListByUserId(menu);
@@ -114,7 +114,7 @@
      * @return 閫変腑鑿滃崟鍒楄〃
      */
     @Override
-    public List<Integer> selectMenuListByRoleId(Long roleId) {
+    public List<Long> selectMenuListByRoleId(Long roleId) {
         SysRole role = roleMapper.selectById(roleId);
         return baseMapper.selectMenuListByRoleId(roleId, role.isMenuCheckStrictly());
     }
@@ -171,41 +171,18 @@
     }
 
     /**
-     * 鏋勫缓鍓嶇鎵�闇�瑕佹爲缁撴瀯
-     *
-     * @param menus 鑿滃崟鍒楄〃
-     * @return 鏍戠粨鏋勫垪琛�
-     */
-    @Override
-    public List<SysMenu> buildMenuTree(List<SysMenu> menus) {
-        List<SysMenu> returnList = new ArrayList<SysMenu>();
-        List<Long> tempList = new ArrayList<Long>();
-        for (SysMenu dept : menus) {
-            tempList.add(dept.getMenuId());
-        }
-        for (SysMenu menu : menus) {
-            // 濡傛灉鏄《绾ц妭鐐�, 閬嶅巻璇ョ埗鑺傜偣鐨勬墍鏈夊瓙鑺傜偣
-            if (!tempList.contains(menu.getParentId())) {
-                recursionFn(menus, menu);
-                returnList.add(menu);
-            }
-        }
-        if (returnList.isEmpty()) {
-            returnList = menus;
-        }
-        return returnList;
-    }
-
-    /**
      * 鏋勫缓鍓嶇鎵�闇�瑕佷笅鎷夋爲缁撴瀯
      *
      * @param menus 鑿滃崟鍒楄〃
      * @return 涓嬫媺鏍戠粨鏋勫垪琛�
      */
     @Override
-    public List<TreeSelect> buildMenuTreeSelect(List<SysMenu> menus) {
-        List<SysMenu> menuTrees = buildMenuTree(menus);
-        return menuTrees.stream().map(TreeSelect::new).collect(Collectors.toList());
+    public List<Tree<Long>> buildMenuTreeSelect(List<SysMenu> menus) {
+        return TreeBuildUtils.build(menus, (menu, tree) ->
+            tree.setId(menu.getMenuId())
+                .setParentId(menu.getParentId())
+                .setName(menu.getMenuName())
+                .setWeight(menu.getOrderNum()));
     }
 
     /**
@@ -285,11 +262,11 @@
     @Override
     public String checkMenuNameUnique(SysMenu menu) {
         Long menuId = StringUtils.isNull(menu.getMenuId()) ? -1L : menu.getMenuId();
-        SysMenu info = getOne(new LambdaQueryWrapper<SysMenu>()
-                .eq(SysMenu::getMenuName, menu.getMenuName())
-                .eq(SysMenu::getParentId, menu.getParentId())
-                .last("limit 1"));
-        if (StringUtils.isNotNull(info) && info.getMenuId().longValue() != menuId.longValue()) {
+        long count = count(new LambdaQueryWrapper<SysMenu>()
+            .eq(SysMenu::getMenuName, menu.getMenuName())
+            .eq(SysMenu::getParentId, menu.getParentId())
+            .ne(SysMenu::getMenuId, menuId));
+        if (count > 0) {
             return UserConstants.NOT_UNIQUE;
         }
         return UserConstants.UNIQUE;
@@ -324,7 +301,7 @@
         }
         // 闈炲閾惧苟涓旀槸涓�绾х洰褰曪紙绫诲瀷涓虹洰褰曪級
         if (0 == menu.getParentId().intValue() && UserConstants.TYPE_DIR.equals(menu.getMenuType())
-                && UserConstants.NO_FRAME.equals(menu.getIsFrame())) {
+            && UserConstants.NO_FRAME.equals(menu.getIsFrame())) {
             routerPath = "/" + menu.getPath();
         }
         // 闈炲閾惧苟涓旀槸涓�绾х洰褰曪紙绫诲瀷涓鸿彍鍗曪級
@@ -360,7 +337,7 @@
      */
     public boolean isMenuFrame(SysMenu menu) {
         return menu.getParentId().intValue() == 0 && UserConstants.TYPE_MENU.equals(menu.getMenuType())
-                && menu.getIsFrame().equals(UserConstants.NO_FRAME);
+            && menu.getIsFrame().equals(UserConstants.NO_FRAME);
     }
 
     /**
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 c39ced0..c08b634 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
@@ -47,23 +47,19 @@
     public TableDataInfo<SysOperLog> selectPageOperLogList(SysOperLog operLog) {
         Map<String, Object> params = operLog.getParams();
         LambdaQueryWrapper<SysOperLog> lqw = new LambdaQueryWrapper<SysOperLog>()
-                .like(StringUtils.isNotBlank(operLog.getTitle()), SysOperLog::getTitle, operLog.getTitle())
-                .eq(operLog.getBusinessType() != null && operLog.getBusinessType() > 0,
-                        SysOperLog::getBusinessType, operLog.getBusinessType())
-                .func(f -> {
-                    if (ArrayUtil.isNotEmpty(operLog.getBusinessTypes())) {
-                        f.in(SysOperLog::getBusinessType, Arrays.asList(operLog.getBusinessTypes()));
-                    }
-                })
-                .eq(operLog.getStatus() != null,
-                        SysOperLog::getStatus, operLog.getStatus())
-                .like(StringUtils.isNotBlank(operLog.getOperName()), SysOperLog::getOperName, operLog.getOperName())
-                .apply(StringUtils.isNotEmpty(params.get("beginTime")),
-                        "date_format(oper_time,'%y%m%d') >= date_format({0},'%y%m%d')",
-                        params.get("beginTime"))
-                .apply(StringUtils.isNotEmpty(params.get("endTime")),
-                        "date_format(oper_time,'%y%m%d') <= date_format({0},'%y%m%d')",
-                        params.get("endTime"));
+            .like(StringUtils.isNotBlank(operLog.getTitle()), SysOperLog::getTitle, operLog.getTitle())
+            .eq(operLog.getBusinessType() != null && operLog.getBusinessType() > 0,
+                SysOperLog::getBusinessType, operLog.getBusinessType())
+            .func(f -> {
+                if (ArrayUtil.isNotEmpty(operLog.getBusinessTypes())) {
+                    f.in(SysOperLog::getBusinessType, Arrays.asList(operLog.getBusinessTypes()));
+                }
+            })
+            .eq(operLog.getStatus() != null,
+                SysOperLog::getStatus, operLog.getStatus())
+            .like(StringUtils.isNotBlank(operLog.getOperName()), SysOperLog::getOperName, operLog.getOperName())
+            .between(params.get("beginTime") != null && params.get("endTime") != null,
+                SysOperLog::getOperTime, params.get("beginTime"), params.get("endTime"));
         return PageUtils.buildDataInfo(page(PageUtils.buildPage("oper_id", "desc"), lqw));
     }
 
@@ -88,24 +84,20 @@
     public List<SysOperLog> selectOperLogList(SysOperLog operLog) {
         Map<String, Object> params = operLog.getParams();
         return list(new LambdaQueryWrapper<SysOperLog>()
-                .like(StringUtils.isNotBlank(operLog.getTitle()), SysOperLog::getTitle, operLog.getTitle())
-                .eq(operLog.getBusinessType() != null && operLog.getBusinessType() > 0,
-                        SysOperLog::getBusinessType, operLog.getBusinessType())
-                .func(f -> {
-                    if (ArrayUtil.isNotEmpty(operLog.getBusinessTypes())) {
-                        f.in(SysOperLog::getBusinessType, Arrays.asList(operLog.getBusinessTypes()));
-                    }
-                })
-                .eq(operLog.getStatus() != null && operLog.getStatus() > 0,
-                        SysOperLog::getStatus, operLog.getStatus())
-                .like(StringUtils.isNotBlank(operLog.getOperName()), SysOperLog::getOperName, operLog.getOperName())
-                .apply(StringUtils.isNotEmpty(params.get("beginTime")),
-                        "date_format(oper_time,'%y%m%d') >= date_format({0},'%y%m%d')",
-                        params.get("beginTime"))
-                .apply(StringUtils.isNotEmpty(params.get("endTime")),
-                        "date_format(oper_time,'%y%m%d') <= date_format({0},'%y%m%d')",
-                        params.get("endTime"))
-                .orderByDesc(SysOperLog::getOperId));
+            .like(StringUtils.isNotBlank(operLog.getTitle()), SysOperLog::getTitle, operLog.getTitle())
+            .eq(operLog.getBusinessType() != null && operLog.getBusinessType() > 0,
+                SysOperLog::getBusinessType, operLog.getBusinessType())
+            .func(f -> {
+                if (ArrayUtil.isNotEmpty(operLog.getBusinessTypes())) {
+                    f.in(SysOperLog::getBusinessType, Arrays.asList(operLog.getBusinessTypes()));
+                }
+            })
+            .eq(operLog.getStatus() != null && operLog.getStatus() > 0,
+                SysOperLog::getStatus, operLog.getStatus())
+            .like(StringUtils.isNotBlank(operLog.getOperName()), SysOperLog::getOperName, operLog.getOperName())
+            .between(params.get("beginTime") != null && params.get("endTime") != null,
+                SysOperLog::getOperTime, params.get("beginTime"), params.get("endTime"))
+            .orderByDesc(SysOperLog::getOperId));
     }
 
     /**
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysOssConfigServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysOssConfigServiceImpl.java
index df3f6d1..9940bea 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysOssConfigServiceImpl.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysOssConfigServiceImpl.java
@@ -15,7 +15,8 @@
 import com.ruoyi.common.utils.PageUtils;
 import com.ruoyi.common.utils.RedisUtils;
 import com.ruoyi.common.utils.StringUtils;
-import com.ruoyi.oss.constant.CloudConstant;
+import com.ruoyi.oss.constant.OssConstant;
+import com.ruoyi.oss.factory.OssFactory;
 import com.ruoyi.system.domain.SysOssConfig;
 import com.ruoyi.system.domain.bo.SysOssConfigBo;
 import com.ruoyi.system.domain.vo.SysOssConfigVo;
@@ -27,7 +28,6 @@
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
-import javax.annotation.PostConstruct;
 import java.util.Collection;
 import java.util.List;
 
@@ -46,16 +46,19 @@
     /**
      * 椤圭洰鍚姩鏃讹紝鍒濆鍖栧弬鏁板埌缂撳瓨锛屽姞杞介厤缃被
      */
-    @PostConstruct
+    @Override
     public void init() {
         List<SysOssConfig> list = list();
+        // 鍔犺浇OSS鍒濆鍖栭厤缃�
         for (SysOssConfig config : list) {
             String configKey = config.getConfigKey();
             if ("0".equals(config.getStatus())) {
-                RedisUtils.setCacheObject(CloudConstant.CACHE_CONFIG_KEY, configKey);
+                RedisUtils.setCacheObject(OssConstant.CACHE_CONFIG_KEY, configKey);
             }
             setConfigCache(true, config);
         }
+        // 鍒濆鍖朞SS宸ュ巶
+        OssFactory.init();
     }
 
     @Override
@@ -110,7 +113,7 @@
     @Override
     public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
         if (isValid) {
-            if (CollUtil.containsAny(ids, CloudConstant.SYSTEM_DATA_IDS)) {
+            if (CollUtil.containsAny(ids, OssConstant.SYSTEM_DATA_IDS)) {
                 throw new ServiceException("绯荤粺鍐呯疆, 涓嶅彲鍒犻櫎!");
             }
         }
@@ -153,7 +156,7 @@
                 .set(SysOssConfig::getStatus, "1"));
         row += baseMapper.updateById(sysOssConfig);
         if (row > 0) {
-            RedisUtils.setCacheObject(CloudConstant.CACHE_CONFIG_KEY, sysOssConfig.getConfigKey());
+            RedisUtils.setCacheObject(OssConstant.CACHE_CONFIG_KEY, sysOssConfig.getConfigKey());
         }
         return row;
     }
@@ -165,7 +168,7 @@
      * @return 缂撳瓨閿甼ey
      */
     private String getCacheKey(String configKey) {
-        return CloudConstant.SYS_OSS_KEY + configKey;
+        return OssConstant.SYS_OSS_KEY + configKey;
     }
 
     /**
@@ -180,7 +183,7 @@
             RedisUtils.setCacheObject(
                     getCacheKey(config.getConfigKey()),
                     JsonUtils.toJsonString(config));
-            RedisUtils.publish(CloudConstant.CACHE_CONFIG_KEY, config.getConfigKey(), msg -> {
+            RedisUtils.publish(OssConstant.CACHE_CONFIG_KEY, config.getConfigKey(), msg -> {
                 log.info("鍙戝竷鍒锋柊OSS閰嶇疆 => " + msg);
             });
         }
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysOssServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysOssServiceImpl.java
index b703ff6..c20cc4b 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysOssServiceImpl.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysOssServiceImpl.java
@@ -10,7 +10,7 @@
 import com.ruoyi.common.utils.StringUtils;
 import com.ruoyi.oss.entity.UploadResult;
 import com.ruoyi.oss.factory.OssFactory;
-import com.ruoyi.oss.service.ICloudStorageStrategy;
+import com.ruoyi.oss.service.IOssStrategy;
 import com.ruoyi.system.domain.SysOss;
 import com.ruoyi.system.domain.bo.SysOssBo;
 import com.ruoyi.system.domain.vo.SysOssVo;
@@ -56,7 +56,7 @@
     public SysOss upload(MultipartFile file) {
         String originalfileName = file.getOriginalFilename();
         String suffix = StringUtils.substring(originalfileName, originalfileName.lastIndexOf("."), originalfileName.length());
-        ICloudStorageStrategy storage = OssFactory.instance();
+        IOssStrategy storage = OssFactory.instance();
         UploadResult uploadResult;
         try {
             uploadResult = storage.uploadSuffix(file.getBytes(), suffix, file.getContentType());
@@ -81,7 +81,7 @@
         }
         List<SysOss> list = listByIds(ids);
         for (SysOss sysOss : list) {
-            ICloudStorageStrategy storage = OssFactory.instance(sysOss.getService());
+            IOssStrategy storage = OssFactory.instance(sysOss.getService());
             storage.delete(sysOss.getUrl());
         }
         return removeByIds(ids);
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 9681b3d..4e04f3a 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
@@ -93,9 +93,10 @@
     @Override
     public String checkPostNameUnique(SysPost post) {
         Long postId = StringUtils.isNull(post.getPostId()) ? -1L : post.getPostId();
-        SysPost info = getOne(new LambdaQueryWrapper<SysPost>()
-                .eq(SysPost::getPostName, post.getPostName()).last("limit 1"));
-        if (StringUtils.isNotNull(info) && info.getPostId().longValue() != postId.longValue()) {
+        long count = count(new LambdaQueryWrapper<SysPost>()
+                .eq(SysPost::getPostName, post.getPostName())
+                .ne(SysPost::getPostId, postId));
+        if (count > 0) {
             return UserConstants.NOT_UNIQUE;
         }
         return UserConstants.UNIQUE;
@@ -110,9 +111,10 @@
     @Override
     public String checkPostCodeUnique(SysPost post) {
         Long postId = StringUtils.isNull(post.getPostId()) ? -1L : post.getPostId();
-        SysPost info = getOne(new LambdaQueryWrapper<SysPost>()
-                .eq(SysPost::getPostCode, post.getPostCode()).last("limit 1"));
-        if (StringUtils.isNotNull(info) && info.getPostId().longValue() != postId.longValue()) {
+        long count = count(new LambdaQueryWrapper<SysPost>()
+                .eq(SysPost::getPostCode, post.getPostCode())
+                .ne(SysPost::getPostId, postId));
+        if (count > 0) {
             return UserConstants.NOT_UNIQUE;
         }
         return UserConstants.UNIQUE;
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 7dd14af..7bad297 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
@@ -141,9 +141,10 @@
     @Override
     public String checkRoleNameUnique(SysRole role) {
         Long roleId = StringUtils.isNull(role.getRoleId()) ? -1L : role.getRoleId();
-        SysRole info = getOne(new LambdaQueryWrapper<SysRole>()
-                .eq(SysRole::getRoleName, role.getRoleName()).last("limit 1"));
-        if (StringUtils.isNotNull(info) && info.getRoleId().longValue() != roleId.longValue()) {
+        long count = count(new LambdaQueryWrapper<SysRole>()
+                .eq(SysRole::getRoleName, role.getRoleName())
+                .ne(SysRole::getRoleId, roleId));
+        if (count > 0) {
             return UserConstants.NOT_UNIQUE;
         }
         return UserConstants.UNIQUE;
@@ -158,9 +159,10 @@
     @Override
     public String checkRoleKeyUnique(SysRole role) {
         Long roleId = StringUtils.isNull(role.getRoleId()) ? -1L : role.getRoleId();
-        SysRole info = getOne(new LambdaQueryWrapper<SysRole>()
-                .eq(SysRole::getRoleKey, role.getRoleKey()).last("limit 1"));
-        if (StringUtils.isNotNull(info) && info.getRoleId().longValue() != roleId.longValue()) {
+        long count = count(new LambdaQueryWrapper<SysRole>()
+                .eq(SysRole::getRoleKey, role.getRoleKey())
+                .ne(SysRole::getRoleId, roleId));
+        if (count > 0) {
             return UserConstants.NOT_UNIQUE;
         }
         return UserConstants.UNIQUE;
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 788992a..62d497d 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
@@ -8,6 +8,7 @@
 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.core.service.UserService;
 import com.ruoyi.common.exception.ServiceException;
 import com.ruoyi.common.utils.PageUtils;
 import com.ruoyi.common.utils.SecurityUtils;
@@ -35,7 +36,7 @@
  */
 @Slf4j
 @Service
-public class SysUserServiceImpl extends ServicePlusImpl<SysUserMapper, SysUser, SysUser> implements ISysUserService {
+public class SysUserServiceImpl extends ServicePlusImpl<SysUserMapper, SysUser, SysUser> implements ISysUserService, UserService {
 
     @Autowired
     private SysRoleMapper roleMapper;
@@ -162,7 +163,7 @@
      */
     @Override
     public String checkUserNameUnique(String userName) {
-        long count = count(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUserName, userName).last("limit 1"));
+        long count = count(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUserName, userName));
         if (count > 0) {
             return UserConstants.NOT_UNIQUE;
         }
@@ -178,10 +179,11 @@
     @Override
     public String checkPhoneUnique(SysUser user) {
         Long userId = StringUtils.isNull(user.getUserId()) ? -1L : user.getUserId();
-        SysUser info = getOne(new LambdaQueryWrapper<SysUser>()
+        long count = count(new LambdaQueryWrapper<SysUser>()
                 .select(SysUser::getUserId, SysUser::getPhonenumber)
-                .eq(SysUser::getPhonenumber, user.getPhonenumber()).last("limit 1"));
-        if (StringUtils.isNotNull(info) && info.getUserId().longValue() != userId.longValue()) {
+                .eq(SysUser::getPhonenumber, user.getPhonenumber())
+                .ne(SysUser::getUserId, userId));
+        if (count > 0) {
             return UserConstants.NOT_UNIQUE;
         }
         return UserConstants.UNIQUE;
@@ -196,10 +198,11 @@
     @Override
     public String checkEmailUnique(SysUser user) {
         Long userId = StringUtils.isNull(user.getUserId()) ? -1L : user.getUserId();
-        SysUser info = getOne(new LambdaQueryWrapper<SysUser>()
+        long count = count(new LambdaQueryWrapper<SysUser>()
                 .select(SysUser::getUserId, SysUser::getEmail)
-                .eq(SysUser::getEmail, user.getEmail()).last("limit 1"));
-        if (StringUtils.isNotNull(info) && info.getUserId().longValue() != userId.longValue()) {
+                .eq(SysUser::getEmail, user.getEmail())
+                .ne(SysUser::getUserId, userId));
+        if (count > 0) {
             return UserConstants.NOT_UNIQUE;
         }
         return UserConstants.UNIQUE;
diff --git a/ruoyi-system/src/main/resources/mapper/package-info.md b/ruoyi-system/src/main/resources/mapper/package-info.md
new file mode 100644
index 0000000..c938b1e
--- /dev/null
+++ b/ruoyi-system/src/main/resources/mapper/package-info.md
@@ -0,0 +1,3 @@
+java鍖呬娇鐢� `.` 鍒嗗壊 resource 鐩綍浣跨敤 `/` 鍒嗗壊
+<br>
+姝ゆ枃浠剁洰鐨� 闃叉鏂囦欢澶圭矘杩炴壘涓嶅埌 `xml` 鏂囦欢
\ No newline at end of file
diff --git a/ruoyi-system/src/main/resources/mapper/system/SysMenuMapper.xml b/ruoyi-system/src/main/resources/mapper/system/SysMenuMapper.xml
index 756eb53..bfb5436 100644
--- a/ruoyi-system/src/main/resources/mapper/system/SysMenuMapper.xml
+++ b/ruoyi-system/src/main/resources/mapper/system/SysMenuMapper.xml
@@ -117,7 +117,7 @@
         order by m.parent_id, m.order_num
     </select>
 
-    <select id="selectMenuListByRoleId" resultType="Integer">
+    <select id="selectMenuListByRoleId" resultType="Long">
         select m.menu_id
         from sys_menu m
         left join sys_role_menu rm on m.menu_id = rm.menu_id
@@ -147,4 +147,4 @@
           and ur.user_id = #{userId}
     </select>
 
-</mapper> 
\ No newline at end of file
+</mapper>
diff --git a/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml b/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml
index 04788f7..5d9a185 100644
--- a/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml
+++ b/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml
@@ -189,12 +189,12 @@
 
     <select id="selectUserByUserName" parameterType="String" resultMap="SysUserResult">
         <include refid="selectUserVo"/>
-        where u.user_name = #{userName}
+        where u.del_flag = '0' and u.user_name = #{userName}
     </select>
 
     <select id="selectUserById" parameterType="Long" resultMap="SysUserResult">
         <include refid="selectUserVo"/>
-        where u.user_id = #{userId}
+        where u.del_flag = '0' and u.user_id = #{userId}
     </select>
 
 
diff --git a/ruoyi-ui/.env.development b/ruoyi-ui/.env.development
index 3b003aa..232d907 100644
--- a/ruoyi-ui/.env.development
+++ b/ruoyi-ui/.env.development
@@ -7,6 +7,9 @@
 # 鑻ヤ緷绠$悊绯荤粺/寮�鍙戠幆澧�
 VUE_APP_BASE_API = '/dev-api'
 
+# 搴旂敤璁块棶璺緞 渚嬪浣跨敤鍓嶇紑 /admin/
+VUE_APP_CONTEXT_PATH = '/'
+
 # 鐩戞帶鍦板潃
 VUE_APP_MONITRO_ADMIN = 'http://localhost:9090/admin/login'
 
diff --git a/ruoyi-ui/.env.production b/ruoyi-ui/.env.production
index 2d0bb61..928000b 100644
--- a/ruoyi-ui/.env.production
+++ b/ruoyi-ui/.env.production
@@ -4,6 +4,9 @@
 # 鐢熶骇鐜閰嶇疆
 ENV = 'production'
 
+# 搴旂敤璁块棶璺緞 渚嬪浣跨敤鍓嶇紑 /admin/
+VUE_APP_CONTEXT_PATH = '/'
+
 # 鐩戞帶鍦板潃
 VUE_APP_MONITRO_ADMIN = '/admin/login'
 
diff --git a/ruoyi-ui/.env.staging b/ruoyi-ui/.env.staging
index 49ce55c..903abe6 100644
--- a/ruoyi-ui/.env.staging
+++ b/ruoyi-ui/.env.staging
@@ -6,6 +6,9 @@
 # 娴嬭瘯鐜閰嶇疆
 ENV = 'staging'
 
+# 搴旂敤璁块棶璺緞 渚嬪浣跨敤鍓嶇紑 /admin/
+VUE_APP_CONTEXT_PATH = '/'
+
 # 鐩戞帶鍦板潃
 VUE_APP_MONITRO_ADMIN = '/admin/login'
 
diff --git a/ruoyi-ui/package.json b/ruoyi-ui/package.json
index 89d591b..bad8e77 100644
--- a/ruoyi-ui/package.json
+++ b/ruoyi-ui/package.json
@@ -37,17 +37,17 @@
   },
   "dependencies": {
     "@riophae/vue-treeselect": "0.4.0",
-    "axios": "0.21.0",
+    "axios": "0.24.0",
     "clipboard": "2.0.6",
-    "core-js": "3.8.1",
+    "core-js": "3.19.1",
     "echarts": "4.9.0",
     "element-ui": "2.15.6",
     "file-saver": "2.0.5",
     "fuse.js": "6.4.3",
     "highlight.js": "9.18.5",
     "js-beautify": "1.13.0",
-    "js-cookie": "2.2.1",
-    "jsencrypt": "3.0.0-rc.1",
+    "js-cookie": "3.0.1",
+    "jsencrypt": "3.2.1",
     "nprogress": "0.2.0",
     "quill": "1.3.7",
     "screenfull": "5.0.2",
@@ -55,7 +55,7 @@
     "vue": "2.6.12",
     "vue-count-to": "1.0.13",
     "vue-cropper": "0.5.5",
-    "vue-meta": "^2.4.0",
+    "vue-meta": "2.4.0",
     "vue-router": "3.4.9",
     "vuedraggable": "2.24.3",
     "vuex": "3.6.0"
diff --git a/ruoyi-ui/src/api/login.js b/ruoyi-ui/src/api/login.js
index abd49c7..0327e6f 100644
--- a/ruoyi-ui/src/api/login.js
+++ b/ruoyi-ui/src/api/login.js
@@ -10,6 +10,9 @@
   }
   return request({
     url: '/login',
+    headers: {
+      isToken: false
+    },
     method: 'post',
     data: data
   })
@@ -47,7 +50,10 @@
 export function getCodeImg() {
   return request({
     url: '/captchaImage',
+    headers: {
+      isToken: false
+    },
     method: 'get',
     timeout: 20000
   })
-}
\ No newline at end of file
+}
diff --git a/ruoyi-ui/src/api/monitor/job.js b/ruoyi-ui/src/api/monitor/job.js
deleted file mode 100644
index 58c4343..0000000
--- a/ruoyi-ui/src/api/monitor/job.js
+++ /dev/null
@@ -1,80 +0,0 @@
-import request from '@/utils/request'
-
-// 鏌ヨ瀹氭椂浠诲姟璋冨害鍒楄〃
-export function listJob(query) {
-  return request({
-    url: '/monitor/job/list',
-    method: 'get',
-    params: query
-  })
-}
-
-// 鏌ヨ瀹氭椂浠诲姟璋冨害璇︾粏
-export function getJob(jobId) {
-  return request({
-    url: '/monitor/job/' + jobId,
-    method: 'get'
-  })
-}
-
-// 鏂板瀹氭椂浠诲姟璋冨害
-export function addJob(data) {
-  return request({
-    url: '/monitor/job',
-    method: 'post',
-    data: data
-  })
-}
-
-// 淇敼瀹氭椂浠诲姟璋冨害
-export function updateJob(data) {
-  return request({
-    url: '/monitor/job',
-    method: 'put',
-    data: data
-  })
-}
-
-// 鍒犻櫎瀹氭椂浠诲姟璋冨害
-export function delJob(jobId) {
-  return request({
-    url: '/monitor/job/' + jobId,
-    method: 'delete'
-  })
-}
-
-// 瀵煎嚭瀹氭椂浠诲姟璋冨害
-export function exportJob(query) {
-  return request({
-    url: '/monitor/job/export',
-    method: 'get',
-    params: query
-  })
-}
-
-// 浠诲姟鐘舵�佷慨鏀�
-export function changeJobStatus(jobId, status) {
-  const data = {
-    jobId,
-    status
-  }
-  return request({
-    url: '/monitor/job/changeStatus',
-    method: 'put',
-    data: data
-  })
-}
-
-
-// 瀹氭椂浠诲姟绔嬪嵆鎵ц涓�娆�
-export function runJob(jobId, jobGroup) {
-  const data = {
-    jobId,
-    jobGroup
-  }
-  return request({
-    url: '/monitor/job/run',
-    method: 'put',
-    data: data
-  })
-}
\ No newline at end of file
diff --git a/ruoyi-ui/src/api/monitor/jobLog.js b/ruoyi-ui/src/api/monitor/jobLog.js
deleted file mode 100644
index 6e0be61..0000000
--- a/ruoyi-ui/src/api/monitor/jobLog.js
+++ /dev/null
@@ -1,26 +0,0 @@
-import request from '@/utils/request'
-
-// 鏌ヨ璋冨害鏃ュ織鍒楄〃
-export function listJobLog(query) {
-  return request({
-    url: '/monitor/jobLog/list',
-    method: 'get',
-    params: query
-  })
-}
-
-// 鍒犻櫎璋冨害鏃ュ織
-export function delJobLog(jobLogId) {
-  return request({
-    url: '/monitor/jobLog/' + jobLogId,
-    method: 'delete'
-  })
-}
-
-// 娓呯┖璋冨害鏃ュ織
-export function cleanJobLog() {
-  return request({
-    url: '/monitor/jobLog/clean',
-    method: 'delete'
-  })
-}
diff --git a/ruoyi-ui/src/api/monitor/server.js b/ruoyi-ui/src/api/monitor/server.js
deleted file mode 100644
index feed783..0000000
--- a/ruoyi-ui/src/api/monitor/server.js
+++ /dev/null
@@ -1,9 +0,0 @@
-import request from '@/utils/request'
-
-// 鏌ヨ鏈嶅姟鍣ㄨ缁�
-export function getServer() {
-  return request({
-    url: '/monitor/server',
-    method: 'get'
-  })
-}
\ No newline at end of file
diff --git a/ruoyi-ui/src/api/system/post.js b/ruoyi-ui/src/api/system/post.js
index 434cd35..1a8e9ca 100644
--- a/ruoyi-ui/src/api/system/post.js
+++ b/ruoyi-ui/src/api/system/post.js
@@ -42,12 +42,3 @@
     method: 'delete'
   })
 }
-
-// 瀵煎嚭宀椾綅
-export function exportPost(query) {
-  return request({
-    url: '/system/post/export',
-    method: 'get',
-    params: query
-  })
-}
\ No newline at end of file
diff --git a/ruoyi-ui/src/components/Breadcrumb/index.vue b/ruoyi-ui/src/components/Breadcrumb/index.vue
index 1fbae5f..1696f54 100644
--- a/ruoyi-ui/src/components/Breadcrumb/index.vue
+++ b/ruoyi-ui/src/components/Breadcrumb/index.vue
@@ -2,7 +2,7 @@
   <el-breadcrumb class="app-breadcrumb" separator="/">
     <transition-group name="breadcrumb">
       <el-breadcrumb-item v-for="(item,index) in levelList" :key="item.path">
-        <span v-if="item.redirect==='noRedirect'||index==levelList.length-1" class="no-redirect">{{ item.meta.title }}</span>
+        <span v-if="item.redirect === 'noRedirect' || index == levelList.length - 1" class="no-redirect">{{ item.meta.title }}</span>
         <a v-else @click.prevent="handleLink(item)">{{ item.meta.title }}</a>
       </el-breadcrumb-item>
     </transition-group>
diff --git a/ruoyi-ui/src/components/RightToolbar/index.vue b/ruoyi-ui/src/components/RightToolbar/index.vue
index c7ab139..976974e 100644
--- a/ruoyi-ui/src/components/RightToolbar/index.vue
+++ b/ruoyi-ui/src/components/RightToolbar/index.vue
@@ -62,7 +62,7 @@
     },
     // 鍙充晶鍒楄〃鍏冪礌鍙樺寲
     dataChange(data) {
-      for (var item in this.columns) {
+      for (let item in this.columns) {
         const key = this.columns[item].key;
         this.columns[item].visible = !data.includes(key);
       }
diff --git a/ruoyi-ui/src/components/RuoYi/Doc/index.vue b/ruoyi-ui/src/components/RuoYi/Doc/index.vue
index e267f90..a60fd21 100644
--- a/ruoyi-ui/src/components/RuoYi/Doc/index.vue
+++ b/ruoyi-ui/src/components/RuoYi/Doc/index.vue
@@ -1,6 +1,6 @@
 <template>
   <div>
-    <svg-icon icon-class="question" @click="goto"/>
+    <svg-icon icon-class="question" @click="goto" />
   </div>
 </template>
 
diff --git a/ruoyi-ui/src/components/RuoYi/Git/index.vue b/ruoyi-ui/src/components/RuoYi/Git/index.vue
index 4d580e4..faecbc1 100644
--- a/ruoyi-ui/src/components/RuoYi/Git/index.vue
+++ b/ruoyi-ui/src/components/RuoYi/Git/index.vue
@@ -1,6 +1,6 @@
 <template>
   <div>
-    <svg-icon icon-class="github" @click="goto"/>
+    <svg-icon icon-class="github" @click="goto" />
   </div>
 </template>
 
diff --git a/ruoyi-ui/src/components/SizeSelect/index.vue b/ruoyi-ui/src/components/SizeSelect/index.vue
index e88065b..069b5de 100644
--- a/ruoyi-ui/src/components/SizeSelect/index.vue
+++ b/ruoyi-ui/src/components/SizeSelect/index.vue
@@ -5,8 +5,7 @@
     </div>
     <el-dropdown-menu slot="dropdown">
       <el-dropdown-item v-for="item of sizeOptions" :key="item.value" :disabled="size===item.value" :command="item.value">
-        {{
-          item.label }}
+        {{ item.label }}
       </el-dropdown-item>
     </el-dropdown-menu>
   </el-dropdown>
diff --git a/ruoyi-ui/src/layout/components/Navbar.vue b/ruoyi-ui/src/layout/components/Navbar.vue
index e6721b7..9de102c 100644
--- a/ruoyi-ui/src/layout/components/Navbar.vue
+++ b/ruoyi-ui/src/layout/components/Navbar.vue
@@ -102,7 +102,7 @@
         type: 'warning'
       }).then(() => {
         this.$store.dispatch('LogOut').then(() => {
-          location.href = this.$router.options.base + '/index';
+          location.href = process.env.VUE_APP_CONTEXT_PATH + "index";
         })
       }).catch(() => {});
     }
diff --git a/ruoyi-ui/src/layout/components/Sidebar/Logo.vue b/ruoyi-ui/src/layout/components/Sidebar/Logo.vue
index 4169687..b8d9d6b 100644
--- a/ruoyi-ui/src/layout/components/Sidebar/Logo.vue
+++ b/ruoyi-ui/src/layout/components/Sidebar/Logo.vue
@@ -29,7 +29,7 @@
     variables() {
       return variables;
     },
-	sideTheme() {
+    sideTheme() {
       return this.$store.state.settings.sideTheme
     }
   },
diff --git a/ruoyi-ui/src/layout/components/TagsView/index.vue b/ruoyi-ui/src/layout/components/TagsView/index.vue
index 99bb289..20c4b55 100644
--- a/ruoyi-ui/src/layout/components/TagsView/index.vue
+++ b/ruoyi-ui/src/layout/components/TagsView/index.vue
@@ -152,31 +152,24 @@
       })
     },
     refreshSelectedTag(view) {
-      this.$store.dispatch('tagsView/delCachedView', view).then(() => {
-        const { fullPath } = view
-        this.$nextTick(() => {
-          this.$router.replace({
-            path: '/redirect' + fullPath
-          })
-        })
-      })
+      this.$tab.refreshPage(view);
     },
     closeSelectedTag(view) {
-      this.$store.dispatch('tagsView/delView', view).then(({ visitedViews }) => {
+      this.$tab.closePage(view).then(({ visitedViews }) => {
         if (this.isActive(view)) {
           this.toLastView(visitedViews, view)
         }
       })
     },
     closeRightTags() {
-      this.$store.dispatch('tagsView/delRightTags', this.selectedTag).then(visitedViews => {
+      this.$tab.closeRightPage(this.selectedTag).then(visitedViews => {
         if (!visitedViews.find(i => i.fullPath === this.$route.fullPath)) {
           this.toLastView(visitedViews)
         }
       })
     },
     closeLeftTags() {
-      this.$store.dispatch('tagsView/delLeftTags', this.selectedTag).then(visitedViews => {
+      this.$tab.closeLeftPage(this.selectedTag).then(visitedViews => {
         if (!visitedViews.find(i => i.fullPath === this.$route.fullPath)) {
           this.toLastView(visitedViews)
         }
@@ -184,12 +177,12 @@
     },
     closeOthersTags() {
       this.$router.push(this.selectedTag).catch(()=>{});
-      this.$store.dispatch('tagsView/delOthersViews', this.selectedTag).then(() => {
+      this.$tab.closeOtherPage(this.selectedTag).then(() => {
         this.moveToCurrentTag()
       })
     },
     closeAllTags(view) {
-      this.$store.dispatch('tagsView/delAllViews').then(({ visitedViews }) => {
+      this.$tab.closeAllPage().then(({ visitedViews }) => {
         if (this.affixTags.some(tag => tag.path === this.$route.path)) {
           return
         }
diff --git a/ruoyi-ui/src/layout/index.vue b/ruoyi-ui/src/layout/index.vue
index 214d86f..8be4184 100644
--- a/ruoyi-ui/src/layout/index.vue
+++ b/ruoyi-ui/src/layout/index.vue
@@ -98,7 +98,7 @@
   }
 
   .hideSidebar .fixed-header {
-    width: calc(100% - 54px)
+    width: calc(100% - 54px);
   }
 
   .mobile .fixed-header {
diff --git a/ruoyi-ui/src/main.js b/ruoyi-ui/src/main.js
index c6306a6..29c4022 100644
--- a/ruoyi-ui/src/main.js
+++ b/ruoyi-ui/src/main.js
@@ -10,8 +10,9 @@
 import App from './App'
 import store from './store'
 import router from './router'
-import directive from './directive' //directive
+import directive from './directive' // directive
 import plugins from './plugins' // plugins
+import { download } from '@/utils/request'
 
 import './assets/icons' // icon
 import './permission' // permission control
@@ -43,6 +44,7 @@
 Vue.prototype.addDateRange = addDateRange
 Vue.prototype.selectDictLabel = selectDictLabel
 Vue.prototype.selectDictLabels = selectDictLabels
+Vue.prototype.download = download
 Vue.prototype.handleTree = handleTree
 
 // 鍏ㄥ眬缁勪欢鎸傝浇
diff --git a/ruoyi-ui/src/plugins/download.js b/ruoyi-ui/src/plugins/download.js
index ec7bdd4..ac50dad 100644
--- a/ruoyi-ui/src/plugins/download.js
+++ b/ruoyi-ui/src/plugins/download.js
@@ -1,51 +1,12 @@
-import { saveAs } from 'file-saver'
 import axios from 'axios'
-import { getToken } from '@/utils/auth'
 import { Message } from 'element-ui'
+import { saveAs } from 'file-saver'
+import { getToken } from '@/utils/auth'
+import { blobValidate } from "@/utils/ruoyi";
 
 const baseURL = process.env.VUE_APP_BASE_API
 
 export default {
-  excel(url, params) {
-    // get璇锋眰鏄犲皠params鍙傛暟
-    if (params) {
-      let urlparams = url + '?';
-      for (const propName of Object.keys(params)) {
-        const value = params[propName];
-        var part = encodeURIComponent(propName) + "=";
-        if (value !== null && typeof(value) !== "undefined") {
-          if (typeof value === 'object') {
-            for (const key of Object.keys(value)) {
-              if (value[key] !== null && typeof (value[key]) !== 'undefined') {
-                let params = propName + '[' + key + ']';
-                let subPart = encodeURIComponent(params) + '=';
-                urlparams += subPart + encodeURIComponent(value[key]) + '&';
-              }
-            }
-          } else {
-            urlparams += part + encodeURIComponent(value) + "&";
-          }
-        }
-      }
-      urlparams = urlparams.slice(0, -1);
-      url = urlparams;
-    }
-    url = baseURL + url
-    axios({
-      method: 'get',
-      url: url,
-      responseType: 'blob',
-      headers: { 'Authorization': 'Bearer ' + getToken() }
-    }).then(async (res) => {
-      const isLogin = await this.blobValidate(res.data);
-      if (isLogin) {
-        const blob = new Blob([res.data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' })
-        this.saveAs(blob, decodeURI(res.headers['download-filename']))
-      } else {
-          Message.error('鏃犳晥鐨勪細璇濓紝鎴栬�呬細璇濆凡杩囨湡锛岃閲嶆柊鐧诲綍銆�');
-      }
-    })
-  },
   oss(ossId) {
     var url = baseURL + '/system/oss/download/' + ossId
     axios({
@@ -54,7 +15,7 @@
       responseType: 'blob',
       headers: { 'Authorization': 'Bearer ' + getToken() }
     }).then(async (res) => {
-      const isLogin = await this.blobValidate(res.data);
+      const isLogin = await blobValidate(res.data);
       if (isLogin) {
         const blob = new Blob([res.data], { type: 'application/octet-stream' })
         this.saveAs(blob, decodeURI(res.headers['download-filename']))
@@ -71,7 +32,7 @@
       responseType: 'blob',
       headers: { 'Authorization': 'Bearer ' + getToken() }
     }).then(async (res) => {
-      const isLogin = await this.blobValidate(res.data);
+      const isLogin = await blobValidate(res.data);
       if (isLogin) {
         const blob = new Blob([res.data], { type: 'application/zip' })
         this.saveAs(blob, name)
@@ -82,15 +43,6 @@
   },
   saveAs(text, name, opts) {
     saveAs(text, name, opts);
-  },
-  async blobValidate(data) {
-    try {
-      const text = await data.text();
-      JSON.parse(text);
-      return false;
-    } catch (error) {
-      return true;
-    }
-  },
+  }
 }
 
diff --git a/ruoyi-ui/src/plugins/index.js b/ruoyi-ui/src/plugins/index.js
index 7cc83a4..9bc6eac 100644
--- a/ruoyi-ui/src/plugins/index.js
+++ b/ruoyi-ui/src/plugins/index.js
@@ -1,3 +1,4 @@
+import tab from './tab'
 import auth from './auth'
 import cache from './cache'
 import modal from './modal'
@@ -5,6 +6,8 @@
 
 export default {
   install(Vue) {
+    // 椤电鎿嶄綔
+    Vue.prototype.$tab = tab
     // 璁よ瘉瀵硅薄
     Vue.prototype.$auth = auth
     // 缂撳瓨瀵硅薄
diff --git a/ruoyi-ui/src/plugins/tab.js b/ruoyi-ui/src/plugins/tab.js
new file mode 100644
index 0000000..95a3848
--- /dev/null
+++ b/ruoyi-ui/src/plugins/tab.js
@@ -0,0 +1,66 @@
+import store from '@/store'
+import router from '@/router';
+
+export default {
+  // 鍒锋柊褰撳墠tab椤电
+  refreshPage(obj) {
+    const { path, matched } = router.currentRoute;
+    if (obj === undefined) {
+      matched.forEach((m) => {
+        if (m.components && m.components.default && m.components.default.name) {
+          if (!['Layout', 'ParentView'].includes(m.components.default.name)) {
+            obj = { name: m.components.default.name, path: path };
+          }
+        }
+      });
+    }
+    return store.dispatch('tagsView/delCachedView', obj).then(() => {
+      const { path } = obj
+      router.replace({
+        path: '/redirect' + path
+      })
+    })
+  },
+  // 鍏抽棴褰撳墠tab椤电锛屾墦寮�鏂伴〉绛�
+  closeOpenPage(obj) {
+    store.dispatch("tagsView/delView", router.currentRoute);
+    if (obj !== undefined) {
+      return router.push(obj);
+    }
+  },
+  // 鍏抽棴鎸囧畾tab椤电
+  closePage(obj) {
+    if (obj === undefined) {
+      return store.dispatch('tagsView/delView', router.currentRoute).then(({ lastPath }) => {
+        return router.push(lastPath || '/');
+      });
+    }
+    return store.dispatch('tagsView/delView', obj);
+  },
+  // 鍏抽棴鎵�鏈塼ab椤电
+  closeAllPage() {
+    return store.dispatch('tagsView/delAllViews');
+  },
+  // 鍏抽棴宸︿晶tab椤电
+  closeLeftPage(obj) {
+    return store.dispatch('tagsView/delLeftTags', obj || router.currentRoute);
+  },
+  // 鍏抽棴鍙充晶tab椤电
+  closeRightPage(obj) {
+    return store.dispatch('tagsView/delRightTags', obj || router.currentRoute);
+  },
+  // 鍏抽棴鍏朵粬tab椤电
+  closeOtherPage(obj) {
+    return store.dispatch('tagsView/delOthersViews', obj || router.currentRoute);
+  },
+  // 娣诲姞tab椤电
+  openPage(title, url) {
+    var obj = { path: url, meta: { title: title } }
+    store.dispatch('tagsView/addView', obj);
+    return router.push(url);
+  },
+  // 淇敼tab椤电
+  updatePage(obj) {
+    return store.dispatch('tagsView/updateVisitedView', obj);
+  }
+}
diff --git a/ruoyi-ui/src/router/index.js b/ruoyi-ui/src/router/index.js
index cedf0b3..cda6d4c 100644
--- a/ruoyi-ui/src/router/index.js
+++ b/ruoyi-ui/src/router/index.js
@@ -95,7 +95,7 @@
         path: 'role/:userId(\\d+)',
         component: (resolve) => require(['@/views/system/user/authRole'], resolve),
         name: 'AuthRole',
-        meta: { title: '鍒嗛厤瑙掕壊', activeMenu: '/system/user'}
+        meta: { title: '鍒嗛厤瑙掕壊', activeMenu: '/system/user' }
       }
     ]
   },
@@ -108,7 +108,7 @@
         path: 'user/:roleId(\\d+)',
         component: (resolve) => require(['@/views/system/role/authUser'], resolve),
         name: 'AuthUser',
-        meta: { title: '鍒嗛厤鐢ㄦ埛', activeMenu: '/system/role'}
+        meta: { title: '鍒嗛厤鐢ㄦ埛', activeMenu: '/system/role' }
       }
     ]
   },
@@ -121,7 +121,7 @@
         path: 'index/:dictId(\\d+)',
         component: (resolve) => require(['@/views/system/dict/data'], resolve),
         name: 'Data',
-        meta: { title: '瀛楀吀鏁版嵁', activeMenu: '/system/dict'}
+        meta: { title: '瀛楀吀鏁版嵁', activeMenu: '/system/dict' }
       }
     ]
   },
@@ -139,19 +139,6 @@
     ]
   },
   {
-    path: '/monitor/job-log',
-    component: Layout,
-    hidden: true,
-    children: [
-      {
-        path: 'index',
-        component: (resolve) => require(['@/views/monitor/job/log'], resolve),
-        name: 'JobLog',
-        meta: { title: '璋冨害鏃ュ織', activeMenu: '/monitor/job'}
-      }
-    ]
-  },
-  {
     path: '/tool/gen-edit',
     component: Layout,
     hidden: true,
@@ -160,14 +147,13 @@
         path: 'index',
         component: (resolve) => require(['@/views/tool/gen/editTable'], resolve),
         name: 'GenEdit',
-        meta: { title: '淇敼鐢熸垚閰嶇疆', activeMenu: '/tool/gen'}
+        meta: { title: '淇敼鐢熸垚閰嶇疆', activeMenu: '/tool/gen' }
       }
     ]
   }
 ]
 
 export default new Router({
-  base: "", // 椤圭洰鍓嶇紑 涓� publicPath 鍚屾 渚嬪 /api
   mode: 'history', // 鍘绘帀url涓殑#
   scrollBehavior: () => ({ y: 0 }),
   routes: constantRoutes
diff --git a/ruoyi-ui/src/store/modules/permission.js b/ruoyi-ui/src/store/modules/permission.js
index dba9252..8d84fff 100644
--- a/ruoyi-ui/src/store/modules/permission.js
+++ b/ruoyi-ui/src/store/modules/permission.js
@@ -1,7 +1,7 @@
 import { constantRoutes } from '@/router'
 import { getRouters } from '@/api/menu'
 import Layout from '@/layout/index'
-import ParentView from '@/components/ParentView';
+import ParentView from '@/components/ParentView'
 import InnerLink from '@/layout/components/InnerLink'
 
 const permission = {
@@ -24,7 +24,7 @@
       // 椤堕儴瀵艰埅鑿滃崟榛樿娣诲姞缁熻鎶ヨ〃鏍忔寚鍚戦椤�
       const index = [{
         path: 'index',
-        meta: { title: '缁熻鎶ヨ〃', icon: 'dashboard'}
+        meta: { title: '缁熻鎶ヨ〃', icon: 'dashboard' }
       }]
       state.topbarRouters = routes.concat(index);
     },
diff --git a/ruoyi-ui/src/store/modules/settings.js b/ruoyi-ui/src/store/modules/settings.js
index 5f36d8e..2455a1e 100644
--- a/ruoyi-ui/src/store/modules/settings.js
+++ b/ruoyi-ui/src/store/modules/settings.js
@@ -8,7 +8,7 @@
   theme: storageSetting.theme || '#409EFF',
   sideTheme: storageSetting.sideTheme || sideTheme,
   showSettings: showSettings,
-  topNav:  storageSetting.topNav === undefined ? topNav : storageSetting.topNav,
+  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,
diff --git a/ruoyi-ui/src/store/modules/tagsView.js b/ruoyi-ui/src/store/modules/tagsView.js
index ef2fe4c..002c1d0 100644
--- a/ruoyi-ui/src/store/modules/tagsView.js
+++ b/ruoyi-ui/src/store/modules/tagsView.js
@@ -14,7 +14,7 @@
   },
   ADD_CACHED_VIEW: (state, view) => {
     if (state.cachedViews.includes(view.name)) return
-    if (!view.meta.noCache) {
+    if (view.meta && !view.meta.noCache) {
       state.cachedViews.push(view.name)
     }
   },
@@ -63,7 +63,7 @@
       }
     }
   },
-  
+
   DEL_RIGHT_VIEWS: (state, view) => {
     const index = state.visitedViews.findIndex(v => v.path === view.path)
     if (index === -1) {
diff --git a/ruoyi-ui/src/utils/dict/index.js b/ruoyi-ui/src/utils/dict/index.js
index 66ddfef..d6fdb80 100644
--- a/ruoyi-ui/src/utils/dict/index.js
+++ b/ruoyi-ui/src/utils/dict/index.js
@@ -5,7 +5,7 @@
   mergeOptions(options)
   Vue.mixin({
     data() {
-      if (this.$options.dicts === undefined || this.$options.dicts === null) {
+      if (this.$options === undefined || this.$options.dicts === undefined || this.$options.dicts === null) {
         return {}
       }
       const dict = new Dict()
diff --git a/ruoyi-ui/src/utils/index.js b/ruoyi-ui/src/utils/index.js
index 918580f..df5db12 100644
--- a/ruoyi-ui/src/utils/index.js
+++ b/ruoyi-ui/src/utils/index.js
@@ -5,12 +5,12 @@
  */
 export function formatDate(cellValue) {
   if (cellValue == null || cellValue == "") return "";
-  var date = new Date(cellValue) 
+  var date = new Date(cellValue)
   var year = date.getFullYear()
   var month = date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1
-  var day = date.getDate() < 10 ? '0' + date.getDate() : date.getDate() 
-  var hours = date.getHours() < 10 ? '0' + date.getHours() : date.getHours() 
-  var minutes = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes() 
+  var day = date.getDate() < 10 ? '0' + date.getDate() : date.getDate()
+  var hours = date.getHours() < 10 ? '0' + date.getHours() : date.getHours()
+  var minutes = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()
   var seconds = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds()
   return year + '-' + month + '-' + day + ' ' + hours + ':' + minutes + ':' + seconds
 }
@@ -330,7 +330,7 @@
     ? val => map[val.toLowerCase()]
     : val => map[val]
 }
- 
+
 export const exportDefault = 'export default '
 
 export const beautifierConf = {
@@ -381,10 +381,10 @@
 
 // 涓嬪垝杞┘宄�
 export function camelCase(str) {
-  return str.replace(/-[a-z]/g, str1 => str1.substr(-1).toUpperCase())
+  return str.replace(/_[a-z]/g, str1 => str1.substr(-1).toUpperCase())
 }
 
 export function isNumberStr(str) {
   return /^[+-]?(0|([1-9]\d*))(\.\d+)?$/g.test(str)
 }
- 
+
diff --git a/ruoyi-ui/src/utils/request.js b/ruoyi-ui/src/utils/request.js
index e8b3b5f..d376a76 100644
--- a/ruoyi-ui/src/utils/request.js
+++ b/ruoyi-ui/src/utils/request.js
@@ -1,8 +1,12 @@
 import axios from 'axios'
-import { Notification, MessageBox, Message } from 'element-ui'
+import { Notification, MessageBox, Message, Loading } from 'element-ui'
 import store from '@/store'
 import { getToken } from '@/utils/auth'
 import errorCode from '@/utils/errorCode'
+import { tansParams, blobValidate } from "@/utils/ruoyi";
+import { saveAs } from 'file-saver'
+
+let downloadLoadingInstance;
 
 axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
 // 瀵瑰簲鍥介檯鍖栬祫婧愭枃浠跺悗缂�
@@ -14,6 +18,7 @@
   // 瓒呮椂
   timeout: 10000
 })
+
 // request鎷︽埅鍣�
 service.interceptors.request.use(config => {
   // 鏄惁闇�瑕佽缃� token
@@ -23,24 +28,7 @@
   }
   // get璇锋眰鏄犲皠params鍙傛暟
   if (config.method === 'get' && config.params) {
-    let url = config.url + '?';
-    for (const propName of Object.keys(config.params)) {
-      const value = config.params[propName];
-      var part = encodeURIComponent(propName) + "=";
-      if (value !== null && typeof(value) !== "undefined") {
-        if (typeof value === 'object') {
-          for (const key of Object.keys(value)) {
-            if (value[key] !== null && typeof (value[key]) !== 'undefined') {
-              let params = propName + '[' + key + ']';
-              let subPart = encodeURIComponent(params) + '=';
-              url += subPart + encodeURIComponent(value[key]) + '&';
-            }
-          }
-        } else {
-          url += part + encodeURIComponent(value) + "&";
-        }
-      }
-    }
+    let url = config.url + '?' + tansParams(config.params);
     url = url.slice(0, -1);
     config.params = {};
     config.url = url;
@@ -57,6 +45,10 @@
     const code = res.data.code || 200;
     // 鑾峰彇閿欒淇℃伅
     const msg = errorCode[code] || res.data.msg || errorCode['default']
+    // 浜岃繘鍒舵暟鎹垯鐩存帴杩斿洖
+    if(res.request.responseType ===  'blob' || res.request.responseType ===  'arraybuffer'){
+      return res.data
+    }
     if (code === 401) {
       MessageBox.confirm('鐧诲綍鐘舵�佸凡杩囨湡锛屾偍鍙互缁х画鐣欏湪璇ラ〉闈紝鎴栬�呴噸鏂扮櫥褰�', '绯荤粺鎻愮ず', {
           confirmButtonText: '閲嶆柊鐧诲綍',
@@ -65,7 +57,7 @@
         }
       ).then(() => {
         store.dispatch('LogOut').then(() => {
-          location.href = this.$router.options.base + '/index';
+          location.href = process.env.VUE_APP_CONTEXT_PATH + "index";
         })
       }).catch(() => {});
       return Promise.reject('鏃犳晥鐨勪細璇濓紝鎴栬�呬細璇濆凡杩囨湡锛岃閲嶆柊鐧诲綍銆�')
@@ -105,4 +97,27 @@
   }
 )
 
+// 閫氱敤涓嬭浇鏂规硶
+export function download(url, params, filename) {
+  downloadLoadingInstance = Loading.service({ text: "姝e湪涓嬭浇鏁版嵁锛岃绋嶅��", spinner: "el-icon-loading", background: "rgba(0, 0, 0, 0.7)", })
+  return service.post(url, params, {
+    transformRequest: [(params) => { return tansParams(params) }],
+    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
+    responseType: 'blob'
+  }).then(async (data) => {
+    const isLogin = await blobValidate(data);
+    if (isLogin) {
+      const blob = new Blob([data])
+      saveAs(blob, filename)
+    } else {
+      Message.error('鏃犳晥鐨勪細璇濓紝鎴栬�呬細璇濆凡杩囨湡锛岃閲嶆柊鐧诲綍銆�');
+    }
+    downloadLoadingInstance.close();
+  }).catch((r) => {
+    console.error(r)
+    Message.error('涓嬭浇鏂囦欢鍑虹幇閿欒锛岃鑱旂郴绠$悊鍛橈紒')
+    downloadLoadingInstance.close();
+  })
+}
+
 export default service
diff --git a/ruoyi-ui/src/utils/ruoyi.js b/ruoyi-ui/src/utils/ruoyi.js
index 63bd379..4cc5e24 100644
--- a/ruoyi-ui/src/utils/ruoyi.js
+++ b/ruoyi-ui/src/utils/ruoyi.js
@@ -85,8 +85,8 @@
 	var temp = value.split(currentSeparator);
 	Object.keys(value.split(currentSeparator)).some((val) => {
 		Object.keys(datas).some((key) => {
-			if (datas[key].dictValue == ('' + temp[val])) {
-				actions.push(datas[key].dictLabel + currentSeparator);
+			if (datas[key].value == ('' + temp[val])) {
+				actions.push(datas[key].label + currentSeparator);
 			}
 		})
 	})
@@ -181,3 +181,40 @@
 	}
 	return tree;
 }
+
+/**
+* 鍙傛暟澶勭悊
+* @param {*} params  鍙傛暟
+*/
+export function tansParams(params) {
+	let result = ''
+	for (const propName of Object.keys(params)) {
+		const value = params[propName];
+		var part = encodeURIComponent(propName) + "=";
+		if (value !== null && typeof (value) !== "undefined") {
+			if (typeof value === 'object') {
+				for (const key of Object.keys(value)) {
+					if (value[key] !== null && typeof (value[key]) !== 'undefined') {
+						let params = propName + '[' + key + ']';
+						var subPart = encodeURIComponent(params) + "=";
+						result += subPart + encodeURIComponent(value[key]) + "&";
+					}
+				}
+			} else {
+				result += part + encodeURIComponent(value) + "&";
+			}
+		}
+	}
+	return result
+}
+
+// 楠岃瘉鏄惁涓篵lob鏍煎紡
+export async function blobValidate(data) {
+    try {
+      const text = await data.text();
+      JSON.parse(text);
+      return false;
+    } catch (error) {
+      return true;
+    }
+}
diff --git a/ruoyi-ui/src/views/demo/demo/index.vue b/ruoyi-ui/src/views/demo/demo/index.vue
index 678ae21..65387c9 100644
--- a/ruoyi-ui/src/views/demo/demo/index.vue
+++ b/ruoyi-ui/src/views/demo/demo/index.vue
@@ -73,11 +73,20 @@
       </el-col>
       <el-col :span="1.5">
         <el-button
+          type="info"
+          plain
+          icon="el-icon-upload2"
+          size="mini"
+          @click="handleImport"
+          v-hasPermi="['demo:demo:import']"
+        >瀵煎叆(鏍¢獙)</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
           type="warning"
           plain
           icon="el-icon-download"
           size="mini"
-          :loading="exportLoading"
           @click="handleExport"
           v-hasPermi="['demo:demo:export']"
         >瀵煎嚭</el-button>
@@ -165,11 +174,34 @@
         <el-button @click="cancel">鍙� 娑�</el-button>
       </div>
     </el-dialog>
+    <!-- 鐢ㄦ埛瀵煎叆瀵硅瘽妗� -->
+    <el-dialog :title="upload.title" :visible.sync="upload.open" width="400px" append-to-body>
+      <el-upload
+        ref="upload"
+        :limit="1"
+        accept=".xlsx, .xls"
+        :headers="upload.headers"
+        :action="upload.url + '?updateSupport=' + upload.updateSupport"
+        :disabled="upload.isUploading"
+        :on-progress="handleFileUploadProgress"
+        :on-success="handleFileSuccess"
+        :auto-upload="false"
+        drag
+      >
+        <i class="el-icon-upload"></i>
+        <div class="el-upload__text">灏嗘枃浠舵嫋鍒版澶勶紝鎴�<em>鐐瑰嚮涓婁紶</em></div>
+      </el-upload>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="submitFileForm">纭� 瀹�</el-button>
+        <el-button @click="upload.open = false">鍙� 娑�</el-button>
+      </div>
+    </el-dialog>
   </div>
 </template>
 
 <script>
 import { listDemo, pageDemo, getDemo, delDemo, addDemo, updateDemo } from "@/api/demo/demo";
+import {getToken} from "@/utils/auth";
 
 export default {
   name: "Demo",
@@ -181,8 +213,6 @@
       buttonLoading: false,
       // 閬僵灞�
       loading: true,
-      // 瀵煎嚭閬僵灞�
-      exportLoading: false,
       // 閫変腑鏁扮粍
       ids: [],
       // 闈炲崟涓鐢�
@@ -201,6 +231,19 @@
       open: false,
       // 鍒涘缓鏃堕棿鏃堕棿鑼冨洿
       daterangeCreateTime: [],
+      // 鐢ㄦ埛瀵煎叆鍙傛暟
+      upload: {
+        // 鏄惁鏄剧ず寮瑰嚭灞傦紙鐢ㄦ埛瀵煎叆锛�
+        open: false,
+        // 寮瑰嚭灞傛爣棰橈紙鐢ㄦ埛瀵煎叆锛�
+        title: "",
+        // 鏄惁绂佺敤涓婁紶
+        isUploading: false,
+        // 璁剧疆涓婁紶鐨勮姹傚ご閮�
+        headers: { Authorization: "Bearer " + getToken() },
+        // 涓婁紶鐨勫湴鍧�
+        url: process.env.VUE_APP_BASE_API + "/demo/demo/importData"
+      },
       // 鏌ヨ鍙傛暟
       queryParams: {
         pageNum: 1,
@@ -356,9 +399,32 @@
         this.loading = false;
       });
     },
+    /** 瀵煎叆鎸夐挳鎿嶄綔 */
+    handleImport() {
+      this.upload.title = "鐢ㄦ埛瀵煎叆";
+      this.upload.open = true;
+    },
     /** 瀵煎嚭鎸夐挳鎿嶄綔 */
     handleExport() {
-      this.$download.excel('/demo/demo/export', this.queryParams);
+      this.download('demo/demo/export', {
+        ...this.queryParams
+      }, `demo_${new Date().getTime()}.xlsx`)
+    },
+    // 鏂囦欢涓婁紶涓鐞�
+    handleFileUploadProgress(event, file, fileList) {
+      this.upload.isUploading = true;
+    },
+    // 鏂囦欢涓婁紶鎴愬姛澶勭悊
+    handleFileSuccess(response, file, fileList) {
+      this.upload.open = false;
+      this.upload.isUploading = false;
+      this.$refs.upload.clearFiles();
+      this.$alert(response.msg, "瀵煎叆缁撴灉", { dangerouslyUseHTMLString: true });
+      this.getList();
+    },
+    // 鎻愪氦涓婁紶鏂囦欢
+    submitFileForm() {
+      this.$refs.upload.submit();
     }
   }
 };
diff --git a/ruoyi-ui/src/views/index.vue b/ruoyi-ui/src/views/index.vue
index 9767127..37e6ff4 100644
--- a/ruoyi-ui/src/views/index.vue
+++ b/ruoyi-ui/src/views/index.vue
@@ -4,26 +4,34 @@
       <el-col :sm="24" :lg="12" style="padding-left: 20px">
         <h2>RuoYi-Vue-Plus鍚庡彴绠$悊妗嗘灦</h2>
         <p>
-          鍩轰簬 RuoYi-Vue 闆嗘垚 Mybatis-Plus Lombok Hutool 绛変究鎹峰紑鍙戝伐鍏� 閫傞厤閲嶅啓鐩稿叧涓氬姟 渚夸簬寮�鍙� 瀹氭湡涓� RuoYi-Vue 鍚屾
+          RuoYi-Vue-Plus 鏄熀浜� RuoYi-Vue 閽堝 鍒嗗竷寮忛泦缇� 鍦烘櫙鍗囩骇(涓嶅吋瀹瑰師妗嗘灦)
           <br/>
           * 鍓嶇寮�鍙戞鏋� Vue銆丒lement UI<br/>
-          * 鍚庣寮�鍙戞鏋� Spring Boot銆丷edis<br/>
+          * 鍚庣寮�鍙戞鏋� Spring Boot<br/>
           * 瀹瑰櫒妗嗘灦 Undertow 鍩轰簬 Netty 鐨勯珮鎬ц兘瀹瑰櫒<br/>
-          * 鏉冮檺璁よ瘉妗嗘灦 Spring Security銆丣wt锛屾敮鎸佸缁堢璁よ瘉绯荤粺<br/>
-          * 鍏崇郴鏁版嵁搴� MySQL 閫傞厤 8.X<br/>
-          * 缂撳瓨鏁版嵁搴� Redis 閫傞厤 6.X<br/>
-          * 鏁版嵁搴撳紑鍙戞鏋� Mybatis-Plus 蹇�� CRUD 澧炲姞寮�鍙戞晥鐜� 鎻掍欢鍖栨敮鎸佸悇绫婚渶姹�<br/>
-          * 缃戠粶妗嗘灦 Feign銆丱kHttp3 鎺ュ彛鍖栫鐞� HTTP 璇锋眰<br/>
-          * 宸ュ叿绫绘鏋� Hutool銆丩ombok 鍑忓皯浠g爜鍐椾綑 澧炲姞瀹夊叏鎬�<br/>
-          * 鐩戞帶妗嗘灦 spring-boot-admin 鍏ㄦ柟浣嶆湇鍔$洃鎺�<br/>
-          * 鏍¢獙妗嗘灦 validation 澧炲己鎺ュ彛瀹夊叏鎬� 涓ヨ皑鎬�<br/>
-          * 鏂囨。妗嗘灦 knife4j 缇庡寲鎺ュ彛鏂囨。<br/>
-          * 浠g爜鐢熸垚鍣� 涓�閿敓鎴愬墠鍚庣浠g爜<br/>
+          * 鏉冮檺璁よ瘉妗嗘灦 Spring Security銆丣wt 鏀寔澶氱粓绔璇佺郴缁�<br/>
+          * 鍏崇郴鏁版嵁搴� MySQL 閫傞厤 8.X 鏈�浣� 5.7<br/>
+          * 缂撳瓨鏁版嵁搴� Redis 閫傞厤 6.X 鏈�浣� 4.X<br/>
+          * 鏁版嵁搴撴鏋� Mybatis-Plus 蹇�� CRUD 澧炲姞寮�鍙戞晥鐜�<br/>
+          * 鏁版嵁搴撴鏋� p6spy 鏇村己鍔茬殑 SQL 鍒嗘瀽<br/>
           * 澶氭暟鎹簮妗嗘灦 dynamic-datasource 鏀寔涓讳粠涓庡绉嶇被鏁版嵁搴撳紓鏋�<br/>
-          * Redis瀹㈡埛绔� 閲囩敤 Redisson 鎬ц兘鏇村己<br/>
+          * 搴忓垪鍖栨鏋� Jackson 缁熶竴浣跨敤 jackson 楂樻晥鍙潬<br/>
+          * Redis瀹㈡埛绔� Redisson 鎬ц兘寮哄姴銆丄PI涓板瘜<br/>
+          * 鍒嗗竷寮忛檺娴� Redisson 鍏ㄥ眬銆佽姹侷P銆侀泦缇D 澶氱闄愭祦<br/>
           * 鍒嗗竷寮忛攣 Lock4j 娉ㄨВ閿併�佸伐鍏烽攣 澶氱澶氭牱<br/>
+          * 鍒嗗竷寮忓箓绛� Lock4j 鍩轰簬鍒嗗竷寮忛攣瀹炵幇<br/>
+          * 鍒嗗竷寮忔棩蹇� TLog 鏀寔璺熻釜閾捐矾鏃ュ織璁板綍銆佹�ц兘鍒嗘瀽銆侀摼璺帓鏌�<br/>
+          * 鍒嗗竷寮忎换鍔¤皟搴� Xxl-Job 楂樻�ц兘 楂樺彲闈� 鏄撴墿灞�<br/>
+          * 鏂囦欢瀛樺偍 Minio 鏈湴瀛樺偍<br/>
+          * 鏂囦欢瀛樺偍 涓冪墰銆侀樋閲屻�佽吘璁�	浜戝瓨鍌�<br/>
+          * 鐩戞帶妗嗘灦 SpringBoot-Admin 鍏ㄦ柟浣嶆湇鍔$洃鎺�<br/>
+          * 鏍¢獙妗嗘灦 Validation 澧炲己鎺ュ彛瀹夊叏鎬� 涓ヨ皑鎬�<br/>
+          * Excel妗嗘灦 Alibaba EasyExcel 鎬ц兘浼樺紓 鎵╁睍鎬у己<br/>
+          * 鏂囨。妗嗘灦 knife4j 缇庡寲鎺ュ彛鏂囨。<br/>
+          * 宸ュ叿绫绘鏋� Hutool銆丩ombok 鍑忓皯浠g爜鍐椾綑 澧炲姞瀹夊叏鎬�<br/>
+          * 浠g爜鐢熸垚鍣� 閫傞厤MP銆並nife4j瑙勮寖鍖栦唬鐮� 涓�閿敓鎴愬墠鍚庣浠g爜<br/>
           * 閮ㄧ讲鏂瑰紡 Docker 瀹瑰櫒缂栨帓 涓�閿儴缃蹭笟鍔¢泦缇�<br/>
-          * 鏂囦欢瀛樺偍 OSS 瀵硅薄瀛樺偍妯″潡 鏀寔(Minio銆佷竷鐗涖�侀樋閲屻�佽吘璁�)<br/>
+          * 鍥介檯鍖� SpringMessage Spring鏍囧噯鍥介檯鍖栨柟妗�<br/>
         </p>
         <p>
           <b>褰撳墠鐗堟湰:</b> <span>v{{ version }}</span>
diff --git a/ruoyi-ui/src/views/login.vue b/ruoyi-ui/src/views/login.vue
index 6c35bd8..4df8936 100644
--- a/ruoyi-ui/src/views/login.vue
+++ b/ruoyi-ui/src/views/login.vue
@@ -3,7 +3,12 @@
     <el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form">
       <h3 class="title">RuoYi-Vue-Plus鍚庡彴绠$悊绯荤粺</h3>
       <el-form-item prop="username">
-        <el-input v-model="loginForm.username" type="text" auto-complete="off" placeholder="璐﹀彿">
+        <el-input
+          v-model="loginForm.username"
+          type="text"
+          auto-complete="off"
+          placeholder="璐﹀彿"
+        >
           <svg-icon slot="prefix" icon-class="user" class="el-input__icon input-icon" />
         </el-input>
       </el-form-item>
@@ -66,7 +71,6 @@
   data() {
     return {
       codeUrl: "",
-      cookiePassword: "",
       loginForm: {
         username: "admin",
         password: "admin123",
diff --git a/ruoyi-ui/src/views/monitor/job/index.vue b/ruoyi-ui/src/views/monitor/job/index.vue
deleted file mode 100644
index a97477b..0000000
--- a/ruoyi-ui/src/views/monitor/job/index.vue
+++ /dev/null
@@ -1,517 +0,0 @@
-<template>
-  <div class="app-container">
-    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
-      <el-form-item label="浠诲姟鍚嶇О" prop="jobName">
-        <el-input
-          v-model="queryParams.jobName"
-          placeholder="璇疯緭鍏ヤ换鍔″悕绉�"
-          clearable
-          size="small"
-          @keyup.enter.native="handleQuery"
-        />
-      </el-form-item>
-      <el-form-item label="浠诲姟缁勫悕" prop="jobGroup">
-        <el-select v-model="queryParams.jobGroup" placeholder="璇烽�夋嫨浠诲姟缁勫悕" clearable size="small">
-          <el-option
-            v-for="dict in dict.type.sys_job_group"
-            :key="dict.value"
-            :label="dict.label"
-            :value="dict.value"
-          />
-        </el-select>
-      </el-form-item>
-      <el-form-item label="浠诲姟鐘舵��" prop="status">
-        <el-select v-model="queryParams.status" placeholder="璇烽�夋嫨浠诲姟鐘舵��" clearable size="small">
-          <el-option
-            v-for="dict in dict.type.sys_job_status"
-            :key="dict.value"
-            :label="dict.label"
-            :value="dict.value"
-          />
-        </el-select>
-      </el-form-item>
-      <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="['monitor:job:add']"
-        >鏂板</el-button>
-      </el-col>
-      <el-col :span="1.5">
-        <el-button
-          type="success"
-          plain
-          icon="el-icon-edit"
-          size="mini"
-          :disabled="single"
-          @click="handleUpdate"
-          v-hasPermi="['monitor:job:edit']"
-        >淇敼</el-button>
-      </el-col>
-      <el-col :span="1.5">
-        <el-button
-          type="danger"
-          plain
-          icon="el-icon-delete"
-          size="mini"
-          :disabled="multiple"
-          @click="handleDelete"
-          v-hasPermi="['monitor:job:remove']"
-        >鍒犻櫎</el-button>
-      </el-col>
-      <el-col :span="1.5">
-        <el-button
-          type="warning"
-          plain
-          icon="el-icon-download"
-          size="mini"
-          :loading="exportLoading"
-          @click="handleExport"
-          v-hasPermi="['monitor:job:export']"
-        >瀵煎嚭</el-button>
-      </el-col>
-      <el-col :span="1.5">
-        <el-button
-          type="info"
-          plain
-          icon="el-icon-s-operation"
-          size="mini"
-          @click="handleJobLog"
-          v-hasPermi="['monitor:job:query']"
-        >鏃ュ織</el-button>
-      </el-col>
-      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
-    </el-row>
-
-    <el-table v-loading="loading" :data="jobList" @selection-change="handleSelectionChange">
-      <el-table-column type="selection" width="55" align="center" />
-      <el-table-column label="浠诲姟缂栧彿" width="100" align="center" prop="jobId" />
-      <el-table-column label="浠诲姟鍚嶇О" align="center" prop="jobName" :show-overflow-tooltip="true" />
-      <el-table-column label="浠诲姟缁勫悕" align="center" prop="jobGroup">
-        <template slot-scope="scope">
-          <dict-tag :options="dict.type.sys_job_group" :value="scope.row.jobGroup"/>
-        </template>
-      </el-table-column>
-      <el-table-column label="璋冪敤鐩爣瀛楃涓�" align="center" prop="invokeTarget" :show-overflow-tooltip="true" />
-      <el-table-column label="cron鎵ц琛ㄨ揪寮�" align="center" prop="cronExpression" :show-overflow-tooltip="true" />
-      <el-table-column label="鐘舵��" align="center">
-        <template slot-scope="scope">
-          <el-switch
-            v-model="scope.row.status"
-            active-value="0"
-            inactive-value="1"
-            @change="handleStatusChange(scope.row)"
-          ></el-switch>
-        </template>
-      </el-table-column>
-      <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="['monitor:job:edit']"
-          >淇敼</el-button>
-          <el-button
-            size="mini"
-            type="text"
-            icon="el-icon-delete"
-            @click="handleDelete(scope.row)"
-            v-hasPermi="['monitor:job:remove']"
-          >鍒犻櫎</el-button>
-          <el-dropdown size="mini" @command="(command) => handleCommand(command, scope.row)" v-hasPermi="['monitor:job:changeStatus', 'monitor:job:query']">
-            <span class="el-dropdown-link">
-              <i class="el-icon-d-arrow-right el-icon--right"></i>鏇村
-            </span>
-            <el-dropdown-menu slot="dropdown">
-              <el-dropdown-item command="handleRun" icon="el-icon-caret-right"
-                v-hasPermi="['monitor:job:changeStatus']">鎵ц涓�娆�</el-dropdown-item>
-              <el-dropdown-item command="handleView" icon="el-icon-view"
-                v-hasPermi="['monitor:job:query']">浠诲姟璇︾粏</el-dropdown-item>
-              <el-dropdown-item command="handleJobLog" icon="el-icon-s-operation"
-                v-hasPermi="['monitor:job:query']">璋冨害鏃ュ織</el-dropdown-item>
-            </el-dropdown-menu>
-          </el-dropdown>
-        </template>
-      </el-table-column>
-    </el-table>
-
-    <pagination
-      v-show="total>0"
-      :total="total"
-      :page.sync="queryParams.pageNum"
-      :limit.sync="queryParams.pageSize"
-      @pagination="getList"
-    />
-
-    <!-- 娣诲姞鎴栦慨鏀瑰畾鏃朵换鍔″璇濇 -->
-    <el-dialog :title="title" :visible.sync="open" width="800px" append-to-body>
-      <el-form ref="form" :model="form" :rules="rules" label-width="120px">
-        <el-row>
-          <el-col :span="12">
-            <el-form-item label="浠诲姟鍚嶇О" prop="jobName">
-              <el-input v-model="form.jobName" placeholder="璇疯緭鍏ヤ换鍔″悕绉�" />
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="浠诲姟鍒嗙粍" prop="jobGroup">
-              <el-select v-model="form.jobGroup" placeholder="璇烽�夋嫨">
-                <el-option
-                  v-for="dict in dict.type.sys_job_group"
-                  :key="dict.value"
-                  :label="dict.label"
-                  :value="dict.value"
-                ></el-option>
-              </el-select>
-            </el-form-item>
-          </el-col>
-          <el-col :span="24">
-            <el-form-item prop="invokeTarget">
-              <span slot="label">
-                璋冪敤鏂规硶
-                <el-tooltip placement="top">
-                  <div slot="content">
-                    Bean璋冪敤绀轰緥锛歳yTask.ryParams('ry')
-                    <br />Class绫昏皟鐢ㄧず渚嬶細com.ruoyi.quartz.task.RyTask.ryParams('ry')
-                    <br />鍙傛暟璇存槑锛氭敮鎸佸瓧绗︿覆锛屽竷灏旂被鍨嬶紝闀挎暣鍨嬶紝娴偣鍨嬶紝鏁村瀷
-                  </div>
-                  <i class="el-icon-question"></i>
-                </el-tooltip>
-              </span>
-              <el-input v-model="form.invokeTarget" placeholder="璇疯緭鍏ヨ皟鐢ㄧ洰鏍囧瓧绗︿覆" />
-            </el-form-item>
-          </el-col>
-          <el-col :span="24">
-            <el-form-item label="cron琛ㄨ揪寮�" prop="cronExpression">
-              <el-input v-model="form.cronExpression" placeholder="璇疯緭鍏ron鎵ц琛ㄨ揪寮�">
-                <template slot="append">
-                  <el-button type="primary" @click="handleShowCron">
-                    鐢熸垚琛ㄨ揪寮�
-                    <i class="el-icon-time el-icon--right"></i>
-                  </el-button>
-                </template>
-              </el-input>
-            </el-form-item>
-          </el-col>
-          <el-col :span="24">
-            <el-form-item label="閿欒绛栫暐" prop="misfirePolicy">
-              <el-radio-group v-model="form.misfirePolicy" size="small">
-                <el-radio-button label="1">绔嬪嵆鎵ц</el-radio-button>
-                <el-radio-button label="2">鎵ц涓�娆�</el-radio-button>
-                <el-radio-button label="3">鏀惧純鎵ц</el-radio-button>
-              </el-radio-group>
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="鏄惁骞跺彂" prop="concurrent">
-              <el-radio-group v-model="form.concurrent" size="small">
-                <el-radio-button label="0">鍏佽</el-radio-button>
-                <el-radio-button label="1">绂佹</el-radio-button>
-              </el-radio-group>
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="鐘舵��">
-              <el-radio-group v-model="form.status">
-                <el-radio
-                  v-for="dict in dict.type.sys_job_status"
-                  :key="dict.value"
-                  :label="dict.value"
-                >{{dict.label}}</el-radio>
-              </el-radio-group>
-            </el-form-item>
-          </el-col>
-        </el-row>
-      </el-form>
-      <div slot="footer" class="dialog-footer">
-        <el-button type="primary" @click="submitForm">纭� 瀹�</el-button>
-        <el-button @click="cancel">鍙� 娑�</el-button>
-      </div>
-    </el-dialog>
-
-    <el-dialog title="Cron琛ㄨ揪寮忕敓鎴愬櫒" :visible.sync="openCron" append-to-body destroy-on-close class="scrollbar">
-      <crontab @hide="openCron=false" @fill="crontabFill" :expression="expression"></crontab>
-    </el-dialog>
-
-    <!-- 浠诲姟鏃ュ織璇︾粏 -->
-    <el-dialog title="浠诲姟璇︾粏" :visible.sync="openView" width="700px" append-to-body>
-      <el-form ref="form" :model="form" label-width="120px" size="mini">
-        <el-row>
-          <el-col :span="12">
-            <el-form-item label="浠诲姟缂栧彿锛�">{{ form.jobId }}</el-form-item>
-            <el-form-item label="浠诲姟鍚嶇О锛�">{{ form.jobName }}</el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="浠诲姟鍒嗙粍锛�">{{ jobGroupFormat(form) }}</el-form-item>
-            <el-form-item label="鍒涘缓鏃堕棿锛�">{{ form.createTime }}</el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="cron琛ㄨ揪寮忥細">{{ form.cronExpression }}</el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="涓嬫鎵ц鏃堕棿锛�">{{ parseTime(form.nextValidTime) }}</el-form-item>
-          </el-col>
-          <el-col :span="24">
-            <el-form-item label="璋冪敤鐩爣鏂规硶锛�">{{ form.invokeTarget }}</el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="浠诲姟鐘舵�侊細">
-              <div v-if="form.status == 0">姝e父</div>
-              <div v-else-if="form.status == 1">澶辫触</div>
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="鏄惁骞跺彂锛�">
-              <div v-if="form.concurrent == 0">鍏佽</div>
-              <div v-else-if="form.concurrent == 1">绂佹</div>
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="鎵ц绛栫暐锛�">
-              <div v-if="form.misfirePolicy == 0">榛樿绛栫暐</div>
-              <div v-else-if="form.misfirePolicy == 1">绔嬪嵆鎵ц</div>
-              <div v-else-if="form.misfirePolicy == 2">鎵ц涓�娆�</div>
-              <div v-else-if="form.misfirePolicy == 3">鏀惧純鎵ц</div>
-            </el-form-item>
-          </el-col>
-        </el-row>
-      </el-form>
-      <div slot="footer" class="dialog-footer">
-        <el-button @click="openView = false">鍏� 闂�</el-button>
-      </div>
-    </el-dialog>
-  </div>
-</template>
-
-<script>
-import { listJob, getJob, delJob, addJob, updateJob, runJob, changeJobStatus } from "@/api/monitor/job";
-import Crontab from '@/components/Crontab'
-
-export default {
-  components: { Crontab },
-  name: "Job",
-  dicts: ['sys_job_group', 'sys_job_status'],
-  data() {
-    return {
-      // 閬僵灞�
-      loading: true,
-      // 瀵煎嚭閬僵灞�
-      exportLoading: false,
-      // 閫変腑鏁扮粍
-      ids: [],
-      // 闈炲崟涓鐢�
-      single: true,
-      // 闈炲涓鐢�
-      multiple: true,
-      // 鏄剧ず鎼滅储鏉′欢
-      showSearch: true,
-      // 鎬绘潯鏁�
-      total: 0,
-      // 瀹氭椂浠诲姟琛ㄦ牸鏁版嵁
-      jobList: [],
-      // 寮瑰嚭灞傛爣棰�
-      title: "",
-      // 鏄惁鏄剧ず寮瑰嚭灞�
-      open: false,
-      // 鏄惁鏄剧ず璇︾粏寮瑰嚭灞�
-      openView: false,
-      // 鏄惁鏄剧ずCron琛ㄨ揪寮忓脊鍑哄眰
-      openCron: false,
-      // 浼犲叆鐨勮〃杈惧紡
-      expression: "",
-      // 鏌ヨ鍙傛暟
-      queryParams: {
-        pageNum: 1,
-        pageSize: 10,
-        jobName: undefined,
-        jobGroup: undefined,
-        status: undefined
-      },
-      // 琛ㄥ崟鍙傛暟
-      form: {},
-      // 琛ㄥ崟鏍¢獙
-      rules: {
-        jobName: [
-          { required: true, message: "浠诲姟鍚嶇О涓嶈兘涓虹┖", trigger: "blur" }
-        ],
-        invokeTarget: [
-          { required: true, message: "璋冪敤鐩爣瀛楃涓蹭笉鑳戒负绌�", trigger: "blur" }
-        ],
-        cronExpression: [
-          { required: true, message: "cron鎵ц琛ㄨ揪寮忎笉鑳戒负绌�", trigger: "blur" }
-        ]
-      }
-    };
-  },
-  created() {
-    this.getList();
-  },
-  methods: {
-    /** 鏌ヨ瀹氭椂浠诲姟鍒楄〃 */
-    getList() {
-      this.loading = true;
-      listJob(this.queryParams).then(response => {
-        this.jobList = response.rows;
-        this.total = response.total;
-        this.loading = false;
-      });
-    },
-    // 浠诲姟缁勫悕瀛楀吀缈昏瘧
-    jobGroupFormat(row, column) {
-      return this.selectDictLabel(this.dict.type.sys_job_group, row.jobGroup);
-    },
-    // 鍙栨秷鎸夐挳
-    cancel() {
-      this.open = false;
-      this.reset();
-    },
-    // 琛ㄥ崟閲嶇疆
-    reset() {
-      this.form = {
-        jobId: undefined,
-        jobName: undefined,
-        jobGroup: undefined,
-        invokeTarget: undefined,
-        cronExpression: undefined,
-        misfirePolicy: 1,
-        concurrent: 1,
-        status: "0"
-      };
-      this.resetForm("form");
-    },
-    /** 鎼滅储鎸夐挳鎿嶄綔 */
-    handleQuery() {
-      this.queryParams.pageNum = 1;
-      this.getList();
-    },
-    /** 閲嶇疆鎸夐挳鎿嶄綔 */
-    resetQuery() {
-      this.resetForm("queryForm");
-      this.handleQuery();
-    },
-    // 澶氶�夋閫変腑鏁版嵁
-    handleSelectionChange(selection) {
-      this.ids = selection.map(item => item.jobId);
-      this.single = selection.length != 1;
-      this.multiple = !selection.length;
-    },
-    // 鏇村鎿嶄綔瑙﹀彂
-    handleCommand(command, row) {
-      switch (command) {
-        case "handleRun":
-          this.handleRun(row);
-          break;
-        case "handleView":
-          this.handleView(row);
-          break;
-        case "handleJobLog":
-          this.handleJobLog(row);
-          break;
-        default:
-          break;
-      }
-    },
-    // 浠诲姟鐘舵�佷慨鏀�
-    handleStatusChange(row) {
-      let text = row.status === "0" ? "鍚敤" : "鍋滅敤";
-      this.$modal.confirm('纭瑕�"' + text + '""' + row.jobName + '"浠诲姟鍚楋紵').then(function() {
-        return changeJobStatus(row.jobId, row.status);
-      }).then(() => {
-        this.$modal.msgSuccess(text + "鎴愬姛");
-      }).catch(function() {
-        row.status = row.status === "0" ? "1" : "0";
-      });
-    },
-    /* 绔嬪嵆鎵ц涓�娆� */
-    handleRun(row) {
-      this.$modal.confirm('纭瑕佺珛鍗虫墽琛屼竴娆�"' + row.jobName + '"浠诲姟鍚楋紵').then(function() {
-        return runJob(row.jobId, row.jobGroup);
-      }).then(() => {
-        this.$modal.msgSuccess("鎵ц鎴愬姛");
-      }).catch(() => {});
-    },
-    /** 浠诲姟璇︾粏淇℃伅 */
-    handleView(row) {
-      getJob(row.jobId).then(response => {
-        this.form = response.data;
-        this.openView = true;
-      });
-    },
-    /** cron琛ㄨ揪寮忔寜閽搷浣� */
-    handleShowCron() {
-      this.expression = this.form.cronExpression;
-      this.openCron = true;
-    },
-    /** 纭畾鍚庡洖浼犲�� */
-    crontabFill(value) {
-      this.form.cronExpression = value;
-    },
-    /** 浠诲姟鏃ュ織鍒楄〃鏌ヨ */
-    handleJobLog(row) {
-      const jobId = row.jobId || 0;
-      this.$router.push({ path: '/monitor/job-log/index', query: { jobId: jobId } })
-    },
-    /** 鏂板鎸夐挳鎿嶄綔 */
-    handleAdd() {
-      this.reset();
-      this.open = true;
-      this.title = "娣诲姞浠诲姟";
-    },
-    /** 淇敼鎸夐挳鎿嶄綔 */
-    handleUpdate(row) {
-      this.reset();
-      const jobId = row.jobId || this.ids;
-      getJob(jobId).then(response => {
-        this.form = response.data;
-        this.open = true;
-        this.title = "淇敼浠诲姟";
-      });
-    },
-    /** 鎻愪氦鎸夐挳 */
-    submitForm: function() {
-      this.$refs["form"].validate(valid => {
-        if (valid) {
-          if (this.form.jobId != undefined) {
-            updateJob(this.form).then(response => {
-              this.$modal.msgSuccess("淇敼鎴愬姛");
-              this.open = false;
-              this.getList();
-            });
-          } else {
-            addJob(this.form).then(response => {
-              this.$modal.msgSuccess("鏂板鎴愬姛");
-              this.open = false;
-              this.getList();
-            });
-          }
-        }
-      });
-    },
-    /** 鍒犻櫎鎸夐挳鎿嶄綔 */
-    handleDelete(row) {
-      const jobIds = row.jobId || this.ids;
-      this.$modal.confirm('鏄惁纭鍒犻櫎瀹氭椂浠诲姟缂栧彿涓�"' + jobIds + '"鐨勬暟鎹」锛�').then(function() {
-        return delJob(jobIds);
-      }).then(() => {
-        this.getList();
-        this.$modal.msgSuccess("鍒犻櫎鎴愬姛");
-      }).catch(() => {});
-    },
-    /** 瀵煎嚭鎸夐挳鎿嶄綔 */
-    handleExport() {
-      this.$download.excel('/monitor/job/export', this.queryParams);
-    }
-  }
-};
-</script>
diff --git a/ruoyi-ui/src/views/monitor/job/log.vue b/ruoyi-ui/src/views/monitor/job/log.vue
deleted file mode 100644
index fca1af4..0000000
--- a/ruoyi-ui/src/views/monitor/job/log.vue
+++ /dev/null
@@ -1,300 +0,0 @@
-<template>
-  <div class="app-container">
-    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
-      <el-form-item label="浠诲姟鍚嶇О" prop="jobName">
-        <el-input
-          v-model="queryParams.jobName"
-          placeholder="璇疯緭鍏ヤ换鍔″悕绉�"
-          clearable
-          size="small"
-          style="width: 240px"
-          @keyup.enter.native="handleQuery"
-        />
-      </el-form-item>
-      <el-form-item label="浠诲姟缁勫悕" prop="jobGroup">
-        <el-select
-          v-model="queryParams.jobGroup"
-          placeholder="璇蜂换鍔$粍鍚�"
-          clearable
-          size="small"
-          style="width: 240px"
-        >
-          <el-option
-            v-for="dict in dict.type.sys_job_group"
-            :key="dict.value"
-            :label="dict.label"
-            :value="dict.value"
-          />
-        </el-select>
-      </el-form-item>
-      <el-form-item label="鎵ц鐘舵��" prop="status">
-        <el-select
-          v-model="queryParams.status"
-          placeholder="璇烽�夋嫨鎵ц鐘舵��"
-          clearable
-          size="small"
-          style="width: 240px"
-        >
-          <el-option
-            v-for="dict in dict.type.sys_common_status"
-            :key="dict.value"
-            :label="dict.label"
-            :value="dict.value"
-          />
-        </el-select>
-      </el-form-item>
-      <el-form-item label="鎵ц鏃堕棿">
-        <el-date-picker
-          v-model="dateRange"
-          size="small"
-          style="width: 240px"
-          value-format="yyyy-MM-dd"
-          type="daterange"
-          range-separator="-"
-          start-placeholder="寮�濮嬫棩鏈�"
-          end-placeholder="缁撴潫鏃ユ湡"
-        ></el-date-picker>
-      </el-form-item>
-      <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="danger"
-          plain
-          icon="el-icon-delete"
-          size="mini"
-          :disabled="multiple"
-          @click="handleDelete"
-          v-hasPermi="['monitor:job:remove']"
-        >鍒犻櫎</el-button>
-      </el-col>
-      <el-col :span="1.5">
-        <el-button
-          type="danger"
-          plain
-          icon="el-icon-delete"
-          size="mini"
-          @click="handleClean"
-          v-hasPermi="['monitor:job:remove']"
-        >娓呯┖</el-button>
-      </el-col>
-      <el-col :span="1.5">
-        <el-button
-          type="warning"
-          plain
-          icon="el-icon-download"
-          size="mini"
-          :loading="exportLoading"
-          @click="handleExport"
-          v-hasPermi="['monitor:job:export']"
-        >瀵煎嚭</el-button>
-      </el-col>
-      <el-col :span="1.5">
-        <el-button
-          type="warning"
-          plain
-          icon="el-icon-close"
-          size="mini"
-          @click="handleClose"
-        >鍏抽棴</el-button>
-      </el-col>
-      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
-    </el-row>
-
-    <el-table v-loading="loading" :data="jobLogList" @selection-change="handleSelectionChange">
-      <el-table-column type="selection" width="55" align="center" />
-      <el-table-column label="鏃ュ織缂栧彿" width="80" align="center" prop="jobLogId" />
-      <el-table-column label="浠诲姟鍚嶇О" align="center" prop="jobName" :show-overflow-tooltip="true" />
-      <el-table-column label="浠诲姟缁勫悕" align="center" prop="jobGroup" :show-overflow-tooltip="true">
-        <template slot-scope="scope">
-          <dict-tag :options="dict.type.sys_job_group" :value="scope.row.jobGroup"/>
-        </template>
-      </el-table-column>
-      <el-table-column label="璋冪敤鐩爣瀛楃涓�" align="center" prop="invokeTarget" :show-overflow-tooltip="true" />
-      <el-table-column label="鏃ュ織淇℃伅" align="center" prop="jobMessage" :show-overflow-tooltip="true" />
-      <el-table-column label="鎵ц鐘舵��" align="center" prop="status">
-        <template slot-scope="scope">
-          <dict-tag :options="dict.type.sys_common_status" :value="scope.row.status"/>
-        </template>
-      </el-table-column>
-      <el-table-column label="鎵ц鏃堕棿" align="center" prop="createTime" width="180">
-        <template slot-scope="scope">
-          <span>{{ parseTime(scope.row.createTime) }}</span>
-        </template>
-      </el-table-column>
-      <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-view"
-            @click="handleView(scope.row)"
-            v-hasPermi="['monitor:job:query']"
-          >璇︾粏</el-button>
-        </template>
-      </el-table-column>
-    </el-table>
-
-    <pagination
-      v-show="total>0"
-      :total="total"
-      :page.sync="queryParams.pageNum"
-      :limit.sync="queryParams.pageSize"
-      @pagination="getList"
-    />
-
-    <!-- 璋冨害鏃ュ織璇︾粏 -->
-    <el-dialog title="璋冨害鏃ュ織璇︾粏" :visible.sync="open" width="700px" append-to-body>
-      <el-form ref="form" :model="form" label-width="100px" size="mini">
-        <el-row>
-          <el-col :span="12">
-            <el-form-item label="鏃ュ織搴忓彿锛�">{{ form.jobLogId }}</el-form-item>
-            <el-form-item label="浠诲姟鍚嶇О锛�">{{ form.jobName }}</el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="浠诲姟鍒嗙粍锛�">{{ form.jobGroup }}</el-form-item>
-            <el-form-item label="鎵ц鏃堕棿锛�">{{ form.createTime }}</el-form-item>
-          </el-col>
-          <el-col :span="24">
-            <el-form-item label="璋冪敤鏂规硶锛�">{{ form.invokeTarget }}</el-form-item>
-          </el-col>
-          <el-col :span="24">
-            <el-form-item label="鏃ュ織淇℃伅锛�">{{ form.jobMessage }}</el-form-item>
-          </el-col>
-          <el-col :span="24">
-            <el-form-item label="鎵ц鐘舵�侊細">
-              <div v-if="form.status == 0">姝e父</div>
-              <div v-else-if="form.status == 1">澶辫触</div>
-            </el-form-item>
-          </el-col>
-          <el-col :span="24">
-            <el-form-item label="寮傚父淇℃伅锛�" v-if="form.status == 1">{{ form.exceptionInfo }}</el-form-item>
-          </el-col>
-        </el-row>
-      </el-form>
-      <div slot="footer" class="dialog-footer">
-        <el-button @click="open = false">鍏� 闂�</el-button>
-      </div>
-    </el-dialog>
-  </div>
-</template>
-
-<script>
-import { getJob } from "@/api/monitor/job";
-import { listJobLog, delJobLog, cleanJobLog } from "@/api/monitor/jobLog";
-
-export default {
-  name: "JobLog",
-  dicts: ['sys_common_status', 'sys_job_group'],
-  data() {
-    return {
-      // 閬僵灞�
-      loading: true,
-      // 瀵煎嚭閬僵灞�
-      exportLoading: false,
-      // 閫変腑鏁扮粍
-      ids: [],
-      // 闈炲涓鐢�
-      multiple: true,
-      // 鏄剧ず鎼滅储鏉′欢
-      showSearch: true,
-      // 鎬绘潯鏁�
-      total: 0,
-      // 璋冨害鏃ュ織琛ㄦ牸鏁版嵁
-      jobLogList: [],
-      // 鏄惁鏄剧ず寮瑰嚭灞�
-      open: false,
-      // 鏃ユ湡鑼冨洿
-      dateRange: [],
-      // 琛ㄥ崟鍙傛暟
-      form: {},
-      // 鏌ヨ鍙傛暟
-      queryParams: {
-        pageNum: 1,
-        pageSize: 10,
-        jobName: undefined,
-        jobGroup: undefined,
-        status: undefined
-      }
-    };
-  },
-  created() {
-    const jobId = this.$route.query.jobId;
-    if (jobId !== undefined && jobId != 0) {
-      getJob(jobId).then(response => {
-        this.queryParams.jobName = response.data.jobName;
-        this.queryParams.jobGroup = response.data.jobGroup;
-        this.getList();
-      });
-    } else {
-      this.getList();
-    }
-  },
-  methods: {
-    /** 鏌ヨ璋冨害鏃ュ織鍒楄〃 */
-    getList() {
-      this.loading = true;
-      listJobLog(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
-          this.jobLogList = response.rows;
-          this.total = response.total;
-          this.loading = false;
-        }
-      );
-    },
-    // 杩斿洖鎸夐挳
-    handleClose() {
-      this.$store.dispatch("tagsView/delView", this.$route);
-      this.$router.push({ path: "/monitor/job" });
-    },
-    /** 鎼滅储鎸夐挳鎿嶄綔 */
-    handleQuery() {
-      this.queryParams.pageNum = 1;
-      this.getList();
-    },
-    /** 閲嶇疆鎸夐挳鎿嶄綔 */
-    resetQuery() {
-      this.dateRange = [];
-      this.resetForm("queryForm");
-      this.handleQuery();
-    },
-    // 澶氶�夋閫変腑鏁版嵁
-    handleSelectionChange(selection) {
-      this.ids = selection.map(item => item.jobLogId);
-      this.multiple = !selection.length;
-    },
-    /** 璇︾粏鎸夐挳鎿嶄綔 */
-    handleView(row) {
-      this.open = true;
-      this.form = row;
-    },
-    /** 鍒犻櫎鎸夐挳鎿嶄綔 */
-    handleDelete(row) {
-      const jobLogIds = this.ids;
-      this.$modal.confirm('鏄惁纭鍒犻櫎璋冨害鏃ュ織缂栧彿涓�"' + jobLogIds + '"鐨勬暟鎹」锛�').then(function() {
-        return delJobLog(jobLogIds);
-      }).then(() => {
-        this.getList();
-        this.$modal.msgSuccess("鍒犻櫎鎴愬姛");
-      }).catch(() => {});
-    },
-    /** 娓呯┖鎸夐挳鎿嶄綔 */
-    handleClean() {
-      this.$modal.confirm('鏄惁纭娓呯┖鎵�鏈夎皟搴︽棩蹇楁暟鎹」锛�').then(function() {
-        return cleanJobLog();
-      }).then(() => {
-        this.getList();
-        this.$modal.msgSuccess("娓呯┖鎴愬姛");
-      }).catch(() => {});
-    },
-    /** 瀵煎嚭鎸夐挳鎿嶄綔 */
-    handleExport() {
-      this.$download.excel('/monitor/jobLog/export', this.queryParams);
-    }
-  }
-};
-</script>
diff --git a/ruoyi-ui/src/views/monitor/logininfor/index.vue b/ruoyi-ui/src/views/monitor/logininfor/index.vue
index 5b11301..98bd743 100644
--- a/ruoyi-ui/src/views/monitor/logininfor/index.vue
+++ b/ruoyi-ui/src/views/monitor/logininfor/index.vue
@@ -6,8 +6,8 @@
           v-model="queryParams.ipaddr"
           placeholder="璇疯緭鍏ョ櫥褰曞湴鍧�"
           clearable
+		  size="small"
           style="width: 240px;"
-          size="small"
           @keyup.enter.native="handleQuery"
         />
       </el-form-item>
@@ -16,8 +16,8 @@
           v-model="queryParams.userName"
           placeholder="璇疯緭鍏ョ敤鎴峰悕绉�"
           clearable
+		  size="small"
           style="width: 240px;"
-          size="small"
           @keyup.enter.native="handleQuery"
         />
       </el-form-item>
@@ -83,7 +83,6 @@
           plain
           icon="el-icon-download"
           size="mini"
-          :loading="exportLoading"
           @click="handleExport"
           v-hasPermi="['monitor:logininfor:export']"
         >瀵煎嚭</el-button>
@@ -132,8 +131,6 @@
     return {
       // 閬僵灞�
       loading: true,
-      // 瀵煎嚭閬僵灞�
-      exportLoading: false,
       // 閫変腑鏁扮粍
       ids: [],
       // 闈炲涓鐢�
@@ -216,7 +213,9 @@
     },
     /** 瀵煎嚭鎸夐挳鎿嶄綔 */
     handleExport() {
-      this.$download.excel('/monitor/logininfor/export', this.queryParams);
+      this.download('monitor/logininfor/export', {
+        ...this.queryParams
+      }, `logininfor_${new Date().getTime()}.xlsx`)
     }
   }
 };
diff --git a/ruoyi-ui/src/views/monitor/operlog/index.vue b/ruoyi-ui/src/views/monitor/operlog/index.vue
index 35fd2b8..9b8b785 100644
--- a/ruoyi-ui/src/views/monitor/operlog/index.vue
+++ b/ruoyi-ui/src/views/monitor/operlog/index.vue
@@ -6,8 +6,8 @@
           v-model="queryParams.title"
           placeholder="璇疯緭鍏ョ郴缁熸ā鍧�"
           clearable
-          style="width: 240px;"
           size="small"
+          style="width: 240px;"
           @keyup.enter.native="handleQuery"
         />
       </el-form-item>
@@ -16,8 +16,8 @@
           v-model="queryParams.operName"
           placeholder="璇疯緭鍏ユ搷浣滀汉鍛�"
           clearable
-          style="width: 240px;"
           size="small"
+          style="width: 240px;"
           @keyup.enter.native="handleQuery"
         />
       </el-form-item>
@@ -99,7 +99,6 @@
           plain
           icon="el-icon-download"
           size="mini"
-          :loading="exportLoading"
           @click="handleExport"
           v-hasPermi="['monitor:operlog:export']"
         >瀵煎嚭</el-button>
@@ -205,8 +204,6 @@
     return {
       // 閬僵灞�
       loading: true,
-      // 瀵煎嚭閬僵灞�
-      exportLoading: false,
       // 閫変腑鏁扮粍
       ids: [],
       // 闈炲涓鐢�
@@ -303,7 +300,9 @@
     },
     /** 瀵煎嚭鎸夐挳鎿嶄綔 */
     handleExport() {
-      this.$download.excel('/monitor/operlog/export', this.queryParams);
+      this.download('monitor/operlog/export', {
+        ...this.queryParams
+      }, `operlog_${new Date().getTime()}.xlsx`)
     }
   }
 };
diff --git a/ruoyi-ui/src/views/register.vue b/ruoyi-ui/src/views/register.vue
index 393f100..7599314 100644
--- a/ruoyi-ui/src/views/register.vue
+++ b/ruoyi-ui/src/views/register.vue
@@ -127,7 +127,8 @@
           register(this.registerForm).then(res => {
             const username = this.registerForm.username;
             this.$alert("<font color='red'>鎭枩浣狅紝鎮ㄧ殑璐﹀彿 " + username + " 娉ㄥ唽鎴愬姛锛�</font>", '绯荤粺鎻愮ず', {
-              dangerouslyUseHTMLString: true
+              dangerouslyUseHTMLString: true,
+              type: 'success'
             }).then(() => {
               this.$router.push("/login");
             }).catch(() => {});
diff --git a/ruoyi-ui/src/views/system/config/index.vue b/ruoyi-ui/src/views/system/config/index.vue
index b037917..9fde370 100644
--- a/ruoyi-ui/src/views/system/config/index.vue
+++ b/ruoyi-ui/src/views/system/config/index.vue
@@ -88,7 +88,6 @@
           plain
           icon="el-icon-download"
           size="mini"
-          :loading="exportLoading"
           @click="handleExport"
           v-hasPermi="['system:config:export']"
         >瀵煎嚭</el-button>
@@ -194,8 +193,6 @@
     return {
       // 閬僵灞�
       loading: true,
-      // 瀵煎嚭閬僵灞�
-      exportLoading: false,
       // 閫変腑鏁扮粍
       ids: [],
       // 闈炲崟涓鐢�
@@ -334,7 +331,9 @@
     },
     /** 瀵煎嚭鎸夐挳鎿嶄綔 */
     handleExport() {
-      this.$download.excel('/system/config/export', this.queryParams);
+      this.download('system/config/export', {
+        ...this.queryParams
+      }, `config_${new Date().getTime()}.xlsx`)
     },
     /** 鍒锋柊缂撳瓨鎸夐挳鎿嶄綔 */
     handleRefreshCache() {
diff --git a/ruoyi-ui/src/views/system/dept/index.vue b/ruoyi-ui/src/views/system/dept/index.vue
index f9c7741..e215b1c 100644
--- a/ruoyi-ui/src/views/system/dept/index.vue
+++ b/ruoyi-ui/src/views/system/dept/index.vue
@@ -179,8 +179,6 @@
       isExpandAll: true,
       // 閲嶆柊娓叉煋琛ㄦ牸鐘舵��
       refreshTable: true,
-      // 鏄惁灞曞紑
-      expand: false,
       // 鏌ヨ鍙傛暟
       queryParams: {
         deptName: undefined,
@@ -276,7 +274,7 @@
       this.open = true;
       this.title = "娣诲姞閮ㄩ棬";
       listDept().then(response => {
-	        this.deptOptions = this.handleTree(response.data, "deptId");
+        this.deptOptions = this.handleTree(response.data, "deptId");
       });
     },
     /** 灞曞紑/鎶樺彔鎿嶄綔 */
@@ -296,7 +294,7 @@
         this.title = "淇敼閮ㄩ棬";
       });
       listDeptExcludeChild(row.deptId).then(response => {
-	        this.deptOptions = this.handleTree(response.data, "deptId");
+        this.deptOptions = this.handleTree(response.data, "deptId");
       });
     },
     /** 鎻愪氦鎸夐挳 */
diff --git a/ruoyi-ui/src/views/system/dict/data.vue b/ruoyi-ui/src/views/system/dict/data.vue
index c7a9006..bf538ad 100644
--- a/ruoyi-ui/src/views/system/dict/data.vue
+++ b/ruoyi-ui/src/views/system/dict/data.vue
@@ -75,10 +75,18 @@
           plain
           icon="el-icon-download"
           size="mini"
-          :loading="exportLoading"
           @click="handleExport"
           v-hasPermi="['system:dict:export']"
         >瀵煎嚭</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="warning"
+          plain
+          icon="el-icon-close"
+          size="mini"
+          @click="handleClose"
+        >鍏抽棴</el-button>
       </el-col>
       <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
     </el-row>
@@ -193,8 +201,6 @@
     return {
       // 閬僵灞�
       loading: true,
-      // 瀵煎嚭閬僵灞�
-      exportLoading: false,
       // 閫変腑鏁扮粍
       ids: [],
       // 闈炲崟涓鐢�
@@ -319,6 +325,11 @@
       this.queryParams.pageNum = 1;
       this.getList();
     },
+    /** 杩斿洖鎸夐挳鎿嶄綔 */
+    handleClose() {
+      const obj = { path: "/system/dict" };
+      this.$tab.closeOpenPage(obj);
+    },
     /** 閲嶇疆鎸夐挳鎿嶄綔 */
     resetQuery() {
       this.resetForm("queryForm");
@@ -380,8 +391,10 @@
     },
     /** 瀵煎嚭鎸夐挳鎿嶄綔 */
     handleExport() {
-      this.$download.excel('/system/dict/data/export', this.queryParams);
+      this.download('system/dict/data/export', {
+        ...this.queryParams
+      }, `data_${new Date().getTime()}.xlsx`)
     }
   }
 };
-</script>
\ No newline at end of file
+</script>
diff --git a/ruoyi-ui/src/views/system/dict/index.vue b/ruoyi-ui/src/views/system/dict/index.vue
index 6daa867..92b78c9 100644
--- a/ruoyi-ui/src/views/system/dict/index.vue
+++ b/ruoyi-ui/src/views/system/dict/index.vue
@@ -94,7 +94,6 @@
           plain
           icon="el-icon-download"
           size="mini"
-          :loading="exportLoading"
           @click="handleExport"
           v-hasPermi="['system:dict:export']"
         >瀵煎嚭</el-button>
@@ -202,8 +201,6 @@
     return {
       // 閬僵灞�
       loading: true,
-      // 瀵煎嚭閬僵灞�
-      exportLoading: false,
       // 閫変腑鏁扮粍
       ids: [],
       // 闈炲崟涓鐢�
@@ -338,7 +335,9 @@
     },
     /** 瀵煎嚭鎸夐挳鎿嶄綔 */
     handleExport() {
-      this.$download.excel('/system/dict/type/export', this.queryParams);
+      this.download('system/dict/type/export', {
+        ...this.queryParams
+      }, `type_${new Date().getTime()}.xlsx`)
     },
     /** 鍒锋柊缂撳瓨鎸夐挳鎿嶄綔 */
     handleRefreshCache() {
@@ -348,4 +347,4 @@
     }
   }
 };
-</script>
\ No newline at end of file
+</script>
diff --git a/ruoyi-ui/src/views/system/menu/index.vue b/ruoyi-ui/src/views/system/menu/index.vue
index a89e1ee..d65773a 100644
--- a/ruoyi-ui/src/views/system/menu/index.vue
+++ b/ruoyi-ui/src/views/system/menu/index.vue
@@ -78,7 +78,8 @@
       </el-table-column>
       <el-table-column label="鎿嶄綔" align="center" class-name="small-padding fixed-width">
         <template slot-scope="scope">
-          <el-button size="mini"
+          <el-button 
+            size="mini"
             type="text"
             icon="el-icon-edit"
             @click="handleUpdate(scope.row)"
@@ -126,8 +127,8 @@
               </el-radio-group>
             </el-form-item>
           </el-col>
-          <el-col :span="24">
-            <el-form-item v-if="form.menuType != 'F'" label="鑿滃崟鍥炬爣">
+          <el-col :span="24" v-if="form.menuType != 'F'">
+            <el-form-item label="鑿滃崟鍥炬爣">
               <el-popover
                 placement="bottom-start"
                 width="460"
@@ -158,8 +159,8 @@
               <el-input-number v-model="form.orderNum" controls-position="right" :min="0" />
             </el-form-item>
           </el-col>
-          <el-col :span="12">
-            <el-form-item v-if="form.menuType != 'F'">
+          <el-col :span="12" v-if="form.menuType != 'F'">
+            <el-form-item>
               <span slot="label">
                 <el-tooltip content="閫夋嫨鏄閾惧垯璺敱鍦板潃闇�瑕佷互`http(s)://`寮�澶�" placement="top">
                 <i class="el-icon-question"></i>
@@ -172,8 +173,8 @@
               </el-radio-group>
             </el-form-item>
           </el-col>
-          <el-col :span="12">
-            <el-form-item v-if="form.menuType != 'F'" prop="path">
+          <el-col :span="12" v-if="form.menuType != 'F'">
+            <el-form-item prop="path">
               <span slot="label">
                 <el-tooltip content="璁块棶鐨勮矾鐢卞湴鍧�锛屽锛歚user`锛屽澶栫綉鍦板潃闇�鍐呴摼璁块棶鍒欎互`http(s)://`寮�澶�" placement="top">
                 <i class="el-icon-question"></i>
@@ -194,8 +195,8 @@
               <el-input v-model="form.component" placeholder="璇疯緭鍏ョ粍浠惰矾寰�" />
             </el-form-item>
           </el-col>
-          <el-col :span="12">
-            <el-form-item v-if="form.menuType != 'M'">
+          <el-col :span="12" v-if="form.menuType != 'M'">
+            <el-form-item>
               <el-input v-model="form.perms" placeholder="璇疯緭鍏ユ潈闄愭爣璇�" maxlength="100" />
               <span slot="label">
                 <el-tooltip content="鎺у埗鍣ㄤ腑瀹氫箟鐨勬潈闄愬瓧绗︼紝濡傦細@PreAuthorize(`@ss.hasPermi('system:user:list')`)" placement="top">
@@ -205,8 +206,8 @@
               </span>
             </el-form-item>
           </el-col>
-          <el-col :span="12">
-            <el-form-item v-if="form.menuType == 'C'">
+          <el-col :span="12" v-if="form.menuType == 'C'">
+            <el-form-item>
               <el-input v-model="form.query" placeholder="璇疯緭鍏ヨ矾鐢卞弬鏁�" maxlength="255" />
               <span slot="label">
                 <el-tooltip content='璁块棶璺敱鐨勯粯璁や紶閫掑弬鏁帮紝濡傦細`{"id": 1, "name": "ry"}`' placement="top">
@@ -216,8 +217,8 @@
               </span>
             </el-form-item>
           </el-col>
-          <el-col :span="12">
-            <el-form-item v-if="form.menuType == 'C'">
+          <el-col :span="12" v-if="form.menuType == 'C'">
+            <el-form-item>
               <span slot="label">
                 <el-tooltip content="閫夋嫨鏄垯浼氳`keep-alive`缂撳瓨锛岄渶瑕佸尮閰嶇粍浠剁殑`name`鍜屽湴鍧�淇濇寔涓�鑷�" placement="top">
                 <i class="el-icon-question"></i>
@@ -230,8 +231,8 @@
               </el-radio-group>
             </el-form-item>
           </el-col>
-          <el-col :span="12">
-            <el-form-item v-if="form.menuType != 'F'">
+          <el-col :span="12" v-if="form.menuType != 'F'">
+            <el-form-item>
               <span slot="label">
                 <el-tooltip content="閫夋嫨闅愯棌鍒欒矾鐢卞皢涓嶄細鍑虹幇鍦ㄤ晶杈规爮锛屼絾浠嶇劧鍙互璁块棶" placement="top">
                 <i class="el-icon-question"></i>
@@ -247,8 +248,8 @@
               </el-radio-group>
             </el-form-item>
           </el-col>
-          <el-col :span="12">
-            <el-form-item v-if="form.menuType != 'F'">
+          <el-col :span="12" v-if="form.menuType != 'F'">
+            <el-form-item>
               <span slot="label">
                 <el-tooltip content="閫夋嫨鍋滅敤鍒欒矾鐢卞皢涓嶄細鍑虹幇鍦ㄤ晶杈规爮锛屼篃涓嶈兘琚闂�" placement="top">
                 <i class="el-icon-question"></i>
diff --git a/ruoyi-ui/src/views/system/post/index.vue b/ruoyi-ui/src/views/system/post/index.vue
index 8f823f3..02698da 100644
--- a/ruoyi-ui/src/views/system/post/index.vue
+++ b/ruoyi-ui/src/views/system/post/index.vue
@@ -74,7 +74,6 @@
           plain
           icon="el-icon-download"
           size="mini"
-          :loading="exportLoading"
           @click="handleExport"
           v-hasPermi="['system:post:export']"
         >瀵煎嚭</el-button>
@@ -169,8 +168,6 @@
     return {
       // 閬僵灞�
       loading: true,
-      // 瀵煎嚭閬僵灞�
-      exportLoading: false,
       // 閫変腑鏁扮粍
       ids: [],
       // 闈炲崟涓鐢�
@@ -305,7 +302,9 @@
     },
     /** 瀵煎嚭鎸夐挳鎿嶄綔 */
     handleExport() {
-      this.$download.excel('/system/post/export', this.queryParams);
+      this.download('system/post/export', {
+        ...this.queryParams
+      }, `post_${new Date().getTime()}.xlsx`)
     }
   }
 };
diff --git a/ruoyi-ui/src/views/system/role/authUser.vue b/ruoyi-ui/src/views/system/role/authUser.vue
index e18ea8b..dd18812 100644
--- a/ruoyi-ui/src/views/system/role/authUser.vue
+++ b/ruoyi-ui/src/views/system/role/authUser.vue
@@ -153,8 +153,8 @@
     },
     // 杩斿洖鎸夐挳
     handleClose() {
-      this.$store.dispatch("tagsView/delView", this.$route);
-      this.$router.push({ path: "/system/role" });
+      const obj = { path: "/system/role" };
+      this.$tab.closeOpenPage(obj);
     },
     /** 鎼滅储鎸夐挳鎿嶄綔 */
     handleQuery() {
diff --git a/ruoyi-ui/src/views/system/role/index.vue b/ruoyi-ui/src/views/system/role/index.vue
index 9ca11c0..779f556 100644
--- a/ruoyi-ui/src/views/system/role/index.vue
+++ b/ruoyi-ui/src/views/system/role/index.vue
@@ -94,7 +94,6 @@
           plain
           icon="el-icon-download"
           size="mini"
-          :loading="exportLoading"
           @click="handleExport"
           v-hasPermi="['system:role:export']"
         >瀵煎嚭</el-button>
@@ -270,8 +269,6 @@
     return {
       // 閬僵灞�
       loading: true,
-      // 瀵煎嚭閬僵灞�
-      exportLoading: false,
       // 閫変腑鏁扮粍
       ids: [],
       // 闈炲崟涓鐢�
@@ -358,8 +355,7 @@
     /** 鏌ヨ瑙掕壊鍒楄〃 */
     getList() {
       this.loading = true;
-      listRole(this.addDateRange(this.queryParams, this.dateRange)).then(
-        response => {
+      listRole(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
           this.roleList = response.rows;
           this.total = response.total;
           this.loading = false;
@@ -613,8 +609,10 @@
     },
     /** 瀵煎嚭鎸夐挳鎿嶄綔 */
     handleExport() {
-      this.$download.excel('/system/role/export', this.queryParams);
+      this.download('system/role/export', {
+        ...this.queryParams
+      }, `role_${new Date().getTime()}.xlsx`)
     }
   }
 };
-</script>
\ No newline at end of file
+</script>
diff --git a/ruoyi-ui/src/views/system/role/selectUser.vue b/ruoyi-ui/src/views/system/role/selectUser.vue
index a9e2ce0..02610d8 100644
--- a/ruoyi-ui/src/views/system/role/selectUser.vue
+++ b/ruoyi-ui/src/views/system/role/selectUser.vue
@@ -123,6 +123,10 @@
     handleSelectUser() {
       const roleId = this.queryParams.roleId;
       const userIds = this.userIds.join(",");
+      if (userIds == "") {
+        this.$modal.msgError("璇烽�夋嫨瑕佸垎閰嶇殑鐢ㄦ埛");
+        return;
+      }
       authUserSelectAll({ roleId: roleId, userIds: userIds }).then(res => {
         this.$modal.msgSuccess(res.msg);
         if (res.code === 200) {
diff --git a/ruoyi-ui/src/views/system/user/authRole.vue b/ruoyi-ui/src/views/system/user/authRole.vue
index dabdc27..52a7923 100644
--- a/ruoyi-ui/src/views/system/user/authRole.vue
+++ b/ruoyi-ui/src/views/system/user/authRole.vue
@@ -33,7 +33,7 @@
         </template>
       </el-table-column>
     </el-table>
-    
+
     <pagination v-show="total>0" :total="total" :page.sync="pageNum" :limit.sync="pageSize" />
 
     <el-form label-width="100px">
@@ -109,9 +109,9 @@
     },
     /** 鍏抽棴鎸夐挳 */
     close() {
-      this.$store.dispatch("tagsView/delView", this.$route);
-      this.$router.push({ path: "/system/user" });
+      const obj = { path: "/system/user" };
+      this.$tab.closeOpenPage(obj);
     },
   },
 };
-</script>
\ No newline at end of file
+</script>
diff --git a/ruoyi-ui/src/views/system/user/index.vue b/ruoyi-ui/src/views/system/user/index.vue
index 4faa250..1ff9b90 100644
--- a/ruoyi-ui/src/views/system/user/index.vue
+++ b/ruoyi-ui/src/views/system/user/index.vue
@@ -131,7 +131,6 @@
               plain
               icon="el-icon-download"
               size="mini"
-              :loading="exportLoading"
               @click="handleExport"
               v-hasPermi="['system:user:export']"
             >瀵煎嚭</el-button>
@@ -207,7 +206,7 @@
       </el-col>
     </el-row>
 
-    <!-- 娣诲姞鎴栦慨鏀瑰弬鏁伴厤缃璇濇 -->
+    <!-- 娣诲姞鎴栦慨鏀圭敤鎴烽厤缃璇濇 -->
     <el-dialog :title="title" :visible.sync="open" width="600px" append-to-body>
       <el-form ref="form" :model="form" :rules="rules" label-width="80px">
         <el-row>
@@ -360,8 +359,6 @@
     return {
       // 閬僵灞�
       loading: true,
-      // 瀵煎嚭閬僵灞�
-      exportLoading: false,
       // 閫変腑鏁扮粍
       ids: [],
       // 闈炲崟涓鐢�
@@ -643,7 +640,9 @@
     },
     /** 瀵煎嚭鎸夐挳鎿嶄綔 */
     handleExport() {
-      this.$download.excel('/system/user/export', this.queryParams);
+      this.download('system/user/export', {
+        ...this.queryParams
+      }, `user_${new Date().getTime()}.xlsx`)
     },
     /** 瀵煎叆鎸夐挳鎿嶄綔 */
     handleImport() {
@@ -652,7 +651,8 @@
     },
     /** 涓嬭浇妯℃澘鎿嶄綔 */
     importTemplate() {
-      this.$download.excel('/system/user/importTemplate');
+      this.download('system/user/importTemplate', {
+      }, `user_template_${new Date().getTime()}.xlsx`)
     },
     // 鏂囦欢涓婁紶涓鐞�
     handleFileUploadProgress(event, file, fileList) {
@@ -672,4 +672,4 @@
     }
   }
 };
-</script>
\ No newline at end of file
+</script>
diff --git a/ruoyi-ui/src/views/system/user/profile/resetPwd.vue b/ruoyi-ui/src/views/system/user/profile/resetPwd.vue
index 119f103..0a8d216 100644
--- a/ruoyi-ui/src/views/system/user/profile/resetPwd.vue
+++ b/ruoyi-ui/src/views/system/user/profile/resetPwd.vue
@@ -29,7 +29,6 @@
       }
     };
     return {
-      test: "1test",
       user: {
         oldPassword: undefined,
         newPassword: undefined,
@@ -55,17 +54,14 @@
     submit() {
       this.$refs["form"].validate(valid => {
         if (valid) {
-          updateUserPwd(this.user.oldPassword, this.user.newPassword).then(
-            response => {
-              this.$modal.msgSuccess("淇敼鎴愬姛");
-            }
-          );
+          updateUserPwd(this.user.oldPassword, this.user.newPassword).then(response => {
+            this.$modal.msgSuccess("淇敼鎴愬姛");
+          });
         }
       });
     },
     close() {
-      this.$store.dispatch("tagsView/delView", this.$route);
-      this.$router.push({ path: "/index" });
+      this.$tab.closePage();
     }
   }
 };
diff --git a/ruoyi-ui/src/views/system/user/profile/userAvatar.vue b/ruoyi-ui/src/views/system/user/profile/userAvatar.vue
index 08652c2..d094602 100644
--- a/ruoyi-ui/src/views/system/user/profile/userAvatar.vue
+++ b/ruoyi-ui/src/views/system/user/profile/userAvatar.vue
@@ -1,7 +1,7 @@
 <template>
   <div>
     <div class="user-info-head" @click="editCropper()"><img v-bind:src="options.img" title="鐐瑰嚮涓婁紶澶村儚" class="img-circle img-lg" /></div>
-    <el-dialog :title="title" :visible.sync="open" width="800px" append-to-body @opened="modalOpened"  @close="closeDialog()">
+    <el-dialog :title="title" :visible.sync="open" width="800px" append-to-body @opened="modalOpened"  @close="closeDialog">
       <el-row>
         <el-col :xs="24" :md="12" :style="{height: '350px'}">
           <vue-cropper
@@ -143,7 +143,7 @@
     // 鍏抽棴绐楀彛
     closeDialog() {
       this.options.img = store.getters.avatar
-	  this.visible = false;
+      this.visible = false;
     }
   }
 };
@@ -172,4 +172,4 @@
   line-height: 110px;
   border-radius: 50%;
 }
-</style>
\ No newline at end of file
+</style>
diff --git a/ruoyi-ui/src/views/system/user/profile/userInfo.vue b/ruoyi-ui/src/views/system/user/profile/userInfo.vue
index 854b819..b422c51 100644
--- a/ruoyi-ui/src/views/system/user/profile/userInfo.vue
+++ b/ruoyi-ui/src/views/system/user/profile/userInfo.vue
@@ -2,7 +2,7 @@
   <el-form ref="form" :model="user" :rules="rules" label-width="80px">
     <el-form-item label="鐢ㄦ埛鏄电О" prop="nickName">
       <el-input v-model="user.nickName" maxlength="30" />
-    </el-form-item> 
+    </el-form-item>
     <el-form-item label="鎵嬫満鍙风爜" prop="phonenumber">
       <el-input v-model="user.phonenumber" maxlength="11" />
     </el-form-item>
@@ -68,8 +68,7 @@
       });
     },
     close() {
-      this.$store.dispatch("tagsView/delView", this.$route);
-      this.$router.push({ path: "/index" });
+      this.$tab.closePage();
     }
   }
 };
diff --git a/ruoyi-ui/src/views/tool/gen/editTable.vue b/ruoyi-ui/src/views/tool/gen/editTable.vue
index 95b12cf..6ba7f5d 100644
--- a/ruoyi-ui/src/views/tool/gen/editTable.vue
+++ b/ruoyi-ui/src/views/tool/gen/editTable.vue
@@ -211,8 +211,8 @@
     },
     /** 鍏抽棴鎸夐挳 */
     close() {
-      this.$store.dispatch("tagsView/delView", this.$route);
-      this.$router.push({ path: "/tool/gen", query: { t: Date.now(), pageNum: this.$route.query.pageNum } })
+      const obj = { path: "/tool/gen", query: { t: Date.now(), pageNum: this.$route.query.pageNum } };
+      this.$tab.closeOpenPage(obj);
     }
   },
   mounted() {
diff --git a/ruoyi-ui/vue.config.js b/ruoyi-ui/vue.config.js
index 4d6967b..73c2177 100644
--- a/ruoyi-ui/vue.config.js
+++ b/ruoyi-ui/vue.config.js
@@ -16,8 +16,7 @@
   // 閮ㄧ讲鐢熶骇鐜鍜屽紑鍙戠幆澧冧笅鐨刄RL銆�
   // 榛樿鎯呭喌涓嬶紝Vue CLI 浼氬亣璁句綘鐨勫簲鐢ㄦ槸琚儴缃插湪涓�涓煙鍚嶇殑鏍硅矾寰勪笂
   // 渚嬪 https://www.ruoyi.vip/銆傚鏋滃簲鐢ㄨ閮ㄧ讲鍦ㄤ竴涓瓙璺緞涓婏紝浣犲氨闇�瑕佺敤杩欎釜閫夐」鎸囧畾杩欎釜瀛愯矾寰勩�備緥濡傦紝濡傛灉浣犵殑搴旂敤琚儴缃插湪 https://www.ruoyi.vip/admin/锛屽垯璁剧疆 baseUrl 涓� /admin/銆�
-  // 璁剧疆鍩鸿矾寰勫弬鑰冩枃妗�: http://doc.ruoyi.vip/ruoyi-vue/document/qdsc.html#搴旂敤璺緞
-  publicPath: process.env.NODE_ENV === "production" ? "/" : "/",
+  publicPath: process.env.VUE_APP_CONTEXT_PATH,
   // 鍦╪pm run build 鎴� yarn build 鏃� 锛岀敓鎴愭枃浠剁殑鐩綍鍚嶇О锛堣鍜宐aseUrl鐨勭敓浜х幆澧冭矾寰勪竴鑷达級锛堥粯璁ist锛�
   outputDir: 'dist',
   // 鐢ㄤ簬鏀剧疆鐢熸垚鐨勯潤鎬佽祫婧� (js銆乧ss銆乮mg銆乫onts) 鐨勶紱锛堥」鐩墦鍖呬箣鍚庯紝闈欐�佽祫婧愪細鏀惧湪杩欎釜鏂囦欢澶逛笅锛�
diff --git a/script/bin/ry.bat b/script/bin/ry.bat
index fd33a72..ae24940 100644
--- a/script/bin/ry.bat
+++ b/script/bin/ry.bat
@@ -1,21 +1,21 @@
 @echo off
 
-rem jar平锟斤拷目录
+rem jar平级目录
 set AppName=ruoyi-admin.jar
 
-rem JVM锟斤拷锟斤拷
+rem JVM参数
 set JVM_OPTS="-Dname=%AppName%  -Duser.timezone=Asia/Shanghai -Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -XX:+PrintGCDateStamps  -XX:+PrintGCDetails -XX:NewRatio=1 -XX:SurvivorRatio=30 -XX:+UseParallelGC -XX:+UseParallelOldGC"
 
 
 ECHO.
-	ECHO.  [1] 锟斤拷锟斤拷%AppName%
-	ECHO.  [2] 锟截憋拷%AppName%
-	ECHO.  [3] 锟斤拷锟斤拷%AppName%
-	ECHO.  [4] 锟斤拷锟斤拷状态 %AppName%
-	ECHO.  [5] 锟斤拷 锟斤拷
+	ECHO.  [1] 启动%AppName%
+	ECHO.  [2] 关闭%AppName%
+	ECHO.  [3] 重启%AppName%
+	ECHO.  [4] 启动状态 %AppName%
+	ECHO.  [5] 退 出
 ECHO.
 
-ECHO.锟斤拷锟斤拷锟斤拷选锟斤拷锟斤拷目锟斤拷锟斤拷锟�:
+ECHO.请输入选择项目的序号:
 set /p ID=
 	IF "%id%"=="1" GOTO start
 	IF "%id%"=="2" GOTO stop
@@ -35,11 +35,11 @@
 
 start javaw %JAVA_OPTS% -jar %AppName%
 
-echo  starting锟斤拷锟斤拷
+echo  starting……
 echo  Start %AppName% success...
 goto:eof
 
-rem 锟斤拷锟斤拷stop通锟斤拷jps锟斤拷锟斤拷锟斤拷锟絧id锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷
+rem 函数stop通过jps命令查找pid并结束进程
 :stop
 	for /f "usebackq tokens=1-2" %%a in (`jps -l ^| findstr %AppName%`) do (
 		set pid=%%a
@@ -48,7 +48,7 @@
 	if not defined pid (echo process %AppName% does not exists) else (
 		echo prepare to kill %image_name%
 		echo start kill %pid% ...
-		rem 锟斤拷锟捷斤拷锟斤拷ID锟斤拷kill锟斤拷锟斤拷
+		rem 根据进程ID,kill进程
 		taskkill /f /pid %pid%
 	)
 goto:eof
diff --git a/script/docker/docker-compose.yml b/script/docker/docker-compose.yml
index c73a93c..3782823 100644
--- a/script/docker/docker-compose.yml
+++ b/script/docker/docker-compose.yml
@@ -2,7 +2,7 @@
 
 services:
   mysql:
-    image: mysql:8.0.24
+    image: mysql:8.0.27
     container_name: mysql
     environment:
       # 鏃跺尯涓婃捣
@@ -32,8 +32,7 @@
         ipv4_address: 172.30.0.36
 
   nginx-web:
-    # 濡傛灉闇�瑕佹寚瀹氱増鏈� 灏辨妸 latest 鎹㈡垚鐗堟湰鍙�
-    image: nginx:latest
+    image: nginx:1.21.3
     container_name: nginx-web
     environment:
       # 鏃跺尯涓婃捣
@@ -56,7 +55,7 @@
       - ruoyi_net
 
   redis:
-    image: redis:6.2.1
+    image: redis:6.2.6
     container_name: redis
     ports:
       - 6379:6379
@@ -67,8 +66,8 @@
       # 閰嶇疆鏂囦欢
       - /docker/redis/conf:/redis/config:rw
       # 鏁版嵁鏂囦欢
-      - /docker/redis/data:/redis/data:rw
-    command: "redis-server /redis/config/redis.conf --appendonly yes"
+      - /docker/redis/data/:/redis/data/:rw
+    command: "redis-server /redis/config/redis.conf"
     privileged: true
     restart: always
     networks:
@@ -76,7 +75,7 @@
         ipv4_address: 172.30.0.48
 
   minio:
-    image: minio/minio:RELEASE.2021-07-08T01-15-01Z
+    image: minio/minio:RELEASE.2021-10-27T16-29-42Z
     container_name: minio
     ports:
       # api 绔彛
diff --git a/script/docker/redis/redis.conf b/script/docker/redis/redis.conf
index 213e9ba..7d550e1 100644
--- a/script/docker/redis/redis.conf
+++ b/script/docker/redis/redis.conf
@@ -1,2 +1,25 @@
 # redis 瀵嗙爜
-# requirepass 123456
\ No newline at end of file
+# requirepass ruoyi123
+
+# 閰嶇疆鎸佷箙鍖栨枃浠跺瓨鍌ㄨ矾寰�
+dir /redis/data
+# 閰嶇疆rdb
+# 15鍒嗛挓鍐呮湁鑷冲皯1涓猭ey琚洿鏀瑰垯杩涜蹇収
+save 900 1
+# 5鍒嗛挓鍐呮湁鑷冲皯10涓猭ey琚洿鏀瑰垯杩涜蹇収
+save 300 10
+# 1鍒嗛挓鍐呮湁鑷冲皯10000涓猭ey琚洿鏀瑰垯杩涜蹇収
+save 60 10000
+# 寮�鍚帇缂�
+rdbcompression yes
+# rdb鏂囦欢鍚� 鐢ㄩ粯璁ょ殑鍗冲彲
+dbfilename dump.rdb
+
+# 寮�鍚痑of
+appendonly yes
+# 鏂囦欢鍚�
+appendfilename "appendonly.aof"
+# 鎸佷箙鍖栫瓥鐣�,no:涓嶅悓姝�,everysec:姣忕涓�娆�,always:鎬绘槸鍚屾,閫熷害姣旇緝鎱�
+# appendfsync always
+appendfsync everysec
+# appendfsync no
diff --git a/script/sql/quartz.sql b/script/sql/quartz.sql
deleted file mode 100644
index cee613b..0000000
--- a/script/sql/quartz.sql
+++ /dev/null
@@ -1,174 +0,0 @@
-DROP TABLE IF EXISTS QRTZ_FIRED_TRIGGERS;
-DROP TABLE IF EXISTS QRTZ_PAUSED_TRIGGER_GRPS;
-DROP TABLE IF EXISTS QRTZ_SCHEDULER_STATE;
-DROP TABLE IF EXISTS QRTZ_LOCKS;
-DROP TABLE IF EXISTS QRTZ_SIMPLE_TRIGGERS;
-DROP TABLE IF EXISTS QRTZ_SIMPROP_TRIGGERS;
-DROP TABLE IF EXISTS QRTZ_CRON_TRIGGERS;
-DROP TABLE IF EXISTS QRTZ_BLOB_TRIGGERS;
-DROP TABLE IF EXISTS QRTZ_TRIGGERS;
-DROP TABLE IF EXISTS QRTZ_JOB_DETAILS;
-DROP TABLE IF EXISTS QRTZ_CALENDARS;
-
--- ----------------------------
--- 1銆佸瓨鍌ㄦ瘡涓�涓凡閰嶇疆鐨� jobDetail 鐨勮缁嗕俊鎭�
--- ----------------------------
-create table QRTZ_JOB_DETAILS (
-    sched_name           varchar(120)    not null            comment '璋冨害鍚嶇О',
-    job_name             varchar(200)    not null            comment '浠诲姟鍚嶇О',
-    job_group            varchar(200)    not null            comment '浠诲姟缁勫悕',
-    description          varchar(250)    null                comment '鐩稿叧浠嬬粛',
-    job_class_name       varchar(250)    not null            comment '鎵ц浠诲姟绫诲悕绉�',
-    is_durable           varchar(1)      not null            comment '鏄惁鎸佷箙鍖�',
-    is_nonconcurrent     varchar(1)      not null            comment '鏄惁骞跺彂',
-    is_update_data       varchar(1)      not null            comment '鏄惁鏇存柊鏁版嵁',
-    requests_recovery    varchar(1)      not null            comment '鏄惁鎺ュ彈鎭㈠鎵ц',
-    job_data             blob            null                comment '瀛樻斁鎸佷箙鍖杍ob瀵硅薄',
-    primary key (sched_name, job_name, job_group)
-) engine=innodb comment = '浠诲姟璇︾粏淇℃伅琛�';
-
--- ----------------------------
--- 2銆� 瀛樺偍宸查厤缃殑 Trigger 鐨勪俊鎭�
--- ----------------------------
-create table QRTZ_TRIGGERS (
-    sched_name           varchar(120)    not null            comment '璋冨害鍚嶇О',
-    trigger_name         varchar(200)    not null            comment '瑙﹀彂鍣ㄧ殑鍚嶅瓧',
-    trigger_group        varchar(200)    not null            comment '瑙﹀彂鍣ㄦ墍灞炵粍鐨勫悕瀛�',
-    job_name             varchar(200)    not null            comment 'qrtz_job_details琛╦ob_name鐨勫閿�',
-    job_group            varchar(200)    not null            comment 'qrtz_job_details琛╦ob_group鐨勫閿�',
-    description          varchar(250)    null                comment '鐩稿叧浠嬬粛',
-    next_fire_time       bigint(13)      null                comment '涓婁竴娆¤Е鍙戞椂闂达紙姣锛�',
-    prev_fire_time       bigint(13)      null                comment '涓嬩竴娆¤Е鍙戞椂闂达紙榛樿涓�-1琛ㄧず涓嶈Е鍙戯級',
-    priority             integer         null                comment '浼樺厛绾�',
-    trigger_state        varchar(16)     not null            comment '瑙﹀彂鍣ㄧ姸鎬�',
-    trigger_type         varchar(8)      not null            comment '瑙﹀彂鍣ㄧ殑绫诲瀷',
-    start_time           bigint(13)      not null            comment '寮�濮嬫椂闂�',
-    end_time             bigint(13)      null                comment '缁撴潫鏃堕棿',
-    calendar_name        varchar(200)    null                comment '鏃ョ▼琛ㄥ悕绉�',
-    misfire_instr        smallint(2)     null                comment '琛ュ伩鎵ц鐨勭瓥鐣�',
-    job_data             blob            null                comment '瀛樻斁鎸佷箙鍖杍ob瀵硅薄',
-    primary key (sched_name, trigger_name, trigger_group),
-    foreign key (sched_name, job_name, job_group) references QRTZ_JOB_DETAILS(sched_name, job_name, job_group)
-) engine=innodb comment = '瑙﹀彂鍣ㄨ缁嗕俊鎭〃';
-
--- ----------------------------
--- 3銆� 瀛樺偍绠�鍗曠殑 Trigger锛屽寘鎷噸澶嶆鏁帮紝闂撮殧锛屼互鍙婂凡瑙﹀彂鐨勬鏁�
--- ----------------------------
-create table QRTZ_SIMPLE_TRIGGERS (
-    sched_name           varchar(120)    not null            comment '璋冨害鍚嶇О',
-    trigger_name         varchar(200)    not null            comment 'qrtz_triggers琛╰rigger_name鐨勫閿�',
-    trigger_group        varchar(200)    not null            comment 'qrtz_triggers琛╰rigger_group鐨勫閿�',
-    repeat_count         bigint(7)       not null            comment '閲嶅鐨勬鏁扮粺璁�',
-    repeat_interval      bigint(12)      not null            comment '閲嶅鐨勯棿闅旀椂闂�',
-    times_triggered      bigint(10)      not null            comment '宸茬粡瑙﹀彂鐨勬鏁�',
-    primary key (sched_name, trigger_name, trigger_group),
-    foreign key (sched_name, trigger_name, trigger_group) references QRTZ_TRIGGERS(sched_name, trigger_name, trigger_group)
-) engine=innodb comment = '绠�鍗曡Е鍙戝櫒鐨勪俊鎭〃';
-
--- ----------------------------
--- 4銆� 瀛樺偍 Cron Trigger锛屽寘鎷� Cron 琛ㄨ揪寮忓拰鏃跺尯淇℃伅
--- ---------------------------- 
-create table QRTZ_CRON_TRIGGERS (
-    sched_name           varchar(120)    not null            comment '璋冨害鍚嶇О',
-    trigger_name         varchar(200)    not null            comment 'qrtz_triggers琛╰rigger_name鐨勫閿�',
-    trigger_group        varchar(200)    not null            comment 'qrtz_triggers琛╰rigger_group鐨勫閿�',
-    cron_expression      varchar(200)    not null            comment 'cron琛ㄨ揪寮�',
-    time_zone_id         varchar(80)                         comment '鏃跺尯',
-    primary key (sched_name, trigger_name, trigger_group),
-    foreign key (sched_name, trigger_name, trigger_group) references QRTZ_TRIGGERS(sched_name, trigger_name, trigger_group)
-) engine=innodb comment = 'Cron绫诲瀷鐨勮Е鍙戝櫒琛�';
-
--- ----------------------------
--- 5銆� Trigger 浣滀负 Blob 绫诲瀷瀛樺偍(鐢ㄤ簬 Quartz 鐢ㄦ埛鐢� JDBC 鍒涘缓浠栦滑鑷繁瀹氬埗鐨� Trigger 绫诲瀷锛孞obStore 骞朵笉鐭ラ亾濡備綍瀛樺偍瀹炰緥鐨勬椂鍊�)
--- ---------------------------- 
-create table QRTZ_BLOB_TRIGGERS (
-    sched_name           varchar(120)    not null            comment '璋冨害鍚嶇О',
-    trigger_name         varchar(200)    not null            comment 'qrtz_triggers琛╰rigger_name鐨勫閿�',
-    trigger_group        varchar(200)    not null            comment 'qrtz_triggers琛╰rigger_group鐨勫閿�',
-    blob_data            blob            null                comment '瀛樻斁鎸佷箙鍖朤rigger瀵硅薄',
-    primary key (sched_name, trigger_name, trigger_group),
-    foreign key (sched_name, trigger_name, trigger_group) references QRTZ_TRIGGERS(sched_name, trigger_name, trigger_group)
-) engine=innodb comment = 'Blob绫诲瀷鐨勮Е鍙戝櫒琛�';
-
--- ----------------------------
--- 6銆� 浠� Blob 绫诲瀷瀛樺偍瀛樻斁鏃ュ巻淇℃伅锛� quartz鍙厤缃竴涓棩鍘嗘潵鎸囧畾涓�涓椂闂磋寖鍥�
--- ---------------------------- 
-create table QRTZ_CALENDARS (
-    sched_name           varchar(120)    not null            comment '璋冨害鍚嶇О',
-    calendar_name        varchar(200)    not null            comment '鏃ュ巻鍚嶇О',
-    calendar             blob            not null            comment '瀛樻斁鎸佷箙鍖朿alendar瀵硅薄',
-    primary key (sched_name, calendar_name)
-) engine=innodb comment = '鏃ュ巻淇℃伅琛�';
-
--- ----------------------------
--- 7銆� 瀛樺偍宸叉殏鍋滅殑 Trigger 缁勭殑淇℃伅
--- ---------------------------- 
-create table QRTZ_PAUSED_TRIGGER_GRPS (
-    sched_name           varchar(120)    not null            comment '璋冨害鍚嶇О',
-    trigger_group        varchar(200)    not null            comment 'qrtz_triggers琛╰rigger_group鐨勫閿�',
-    primary key (sched_name, trigger_group)
-) engine=innodb comment = '鏆傚仠鐨勮Е鍙戝櫒琛�';
-
--- ----------------------------
--- 8銆� 瀛樺偍涓庡凡瑙﹀彂鐨� Trigger 鐩稿叧鐨勭姸鎬佷俊鎭紝浠ュ強鐩歌仈 Job 鐨勬墽琛屼俊鎭�
--- ---------------------------- 
-create table QRTZ_FIRED_TRIGGERS (
-    sched_name           varchar(120)    not null            comment '璋冨害鍚嶇О',
-    entry_id             varchar(95)     not null            comment '璋冨害鍣ㄥ疄渚媔d',
-    trigger_name         varchar(200)    not null            comment 'qrtz_triggers琛╰rigger_name鐨勫閿�',
-    trigger_group        varchar(200)    not null            comment 'qrtz_triggers琛╰rigger_group鐨勫閿�',
-    instance_name        varchar(200)    not null            comment '璋冨害鍣ㄥ疄渚嬪悕',
-    fired_time           bigint(13)      not null            comment '瑙﹀彂鐨勬椂闂�',
-    sched_time           bigint(13)      not null            comment '瀹氭椂鍣ㄥ埗瀹氱殑鏃堕棿',
-    priority             integer         not null            comment '浼樺厛绾�',
-    state                varchar(16)     not null            comment '鐘舵��',
-    job_name             varchar(200)    null                comment '浠诲姟鍚嶇О',
-    job_group            varchar(200)    null                comment '浠诲姟缁勫悕',
-    is_nonconcurrent     varchar(1)      null                comment '鏄惁骞跺彂',
-    requests_recovery    varchar(1)      null                comment '鏄惁鎺ュ彈鎭㈠鎵ц',
-    primary key (sched_name, entry_id)
-) engine=innodb comment = '宸茶Е鍙戠殑瑙﹀彂鍣ㄨ〃';
-
--- ----------------------------
--- 9銆� 瀛樺偍灏戦噺鐨勬湁鍏� Scheduler 鐨勭姸鎬佷俊鎭紝鍋囧鏄敤浜庨泦缇や腑锛屽彲浠ョ湅鍒板叾浠栫殑 Scheduler 瀹炰緥
--- ---------------------------- 
-create table QRTZ_SCHEDULER_STATE (
-    sched_name           varchar(120)    not null            comment '璋冨害鍚嶇О',
-    instance_name        varchar(200)    not null            comment '瀹炰緥鍚嶇О',
-    last_checkin_time    bigint(13)      not null            comment '涓婃妫�鏌ユ椂闂�',
-    checkin_interval     bigint(13)      not null            comment '妫�鏌ラ棿闅旀椂闂�',
-    primary key (sched_name, instance_name)
-) engine=innodb comment = '璋冨害鍣ㄧ姸鎬佽〃';
-
--- ----------------------------
--- 10銆� 瀛樺偍绋嬪簭鐨勬偛瑙傞攣鐨勪俊鎭�(鍋囧浣跨敤浜嗘偛瑙傞攣)
--- ---------------------------- 
-create table QRTZ_LOCKS (
-    sched_name           varchar(120)    not null            comment '璋冨害鍚嶇О',
-    lock_name            varchar(40)     not null            comment '鎮茶閿佸悕绉�',
-    primary key (sched_name, lock_name)
-) engine=innodb comment = '瀛樺偍鐨勬偛瑙傞攣淇℃伅琛�';
-
--- ----------------------------
--- 11銆� Quartz闆嗙兢瀹炵幇鍚屾鏈哄埗鐨勮閿佽〃
--- ---------------------------- 
-create table QRTZ_SIMPROP_TRIGGERS (
-    sched_name           varchar(120)    not null            comment '璋冨害鍚嶇О',
-    trigger_name         varchar(200)    not null            comment 'qrtz_triggers琛╰rigger_name鐨勫閿�',
-    trigger_group        varchar(200)    not null            comment 'qrtz_triggers琛╰rigger_group鐨勫閿�',
-    str_prop_1           varchar(512)    null                comment 'String绫诲瀷鐨則rigger鐨勭涓�涓弬鏁�',
-    str_prop_2           varchar(512)    null                comment 'String绫诲瀷鐨則rigger鐨勭浜屼釜鍙傛暟',
-    str_prop_3           varchar(512)    null                comment 'String绫诲瀷鐨則rigger鐨勭涓変釜鍙傛暟',
-    int_prop_1           int             null                comment 'int绫诲瀷鐨則rigger鐨勭涓�涓弬鏁�',
-    int_prop_2           int             null                comment 'int绫诲瀷鐨則rigger鐨勭浜屼釜鍙傛暟',
-    long_prop_1          bigint          null                comment 'long绫诲瀷鐨則rigger鐨勭涓�涓弬鏁�',
-    long_prop_2          bigint          null                comment 'long绫诲瀷鐨則rigger鐨勭浜屼釜鍙傛暟',
-    dec_prop_1           numeric(13,4)   null                comment 'decimal绫诲瀷鐨則rigger鐨勭涓�涓弬鏁�',
-    dec_prop_2           numeric(13,4)   null                comment 'decimal绫诲瀷鐨則rigger鐨勭浜屼釜鍙傛暟',
-    bool_prop_1          varchar(1)      null                comment 'Boolean绫诲瀷鐨則rigger鐨勭涓�涓弬鏁�',
-    bool_prop_2          varchar(1)      null                comment 'Boolean绫诲瀷鐨則rigger鐨勭浜屼釜鍙傛暟',
-    primary key (sched_name, trigger_name, trigger_group),
-    foreign key (sched_name, trigger_name, trigger_group) references QRTZ_TRIGGERS(sched_name, trigger_name, trigger_group)
-) engine=innodb comment = '鍚屾鏈哄埗鐨勮閿佽〃';
-
-commit;
\ No newline at end of file
diff --git a/script/sql/ry_20210908.sql b/script/sql/ry_20210908.sql
index ec61edf..4df76f6 100644
--- a/script/sql/ry_20210908.sql
+++ b/script/sql/ry_20210908.sql
@@ -172,9 +172,7 @@
 insert into sys_menu values('107',  '閫氱煡鍏憡', '1',   '8', 'notice',     'system/notice/index',      '', 1, 0, 'C', '0', '0', 'system:notice:list',      'message',       'admin', sysdate(), '', null, '閫氱煡鍏憡鑿滃崟');
 insert into sys_menu values('108',  '鏃ュ織绠$悊', '1',   '9', 'log',        '',                         '', 1, 0, 'M', '0', '0', '',                        'log',           'admin', sysdate(), '', null, '鏃ュ織绠$悊鑿滃崟');
 insert into sys_menu values('109',  '鍦ㄧ嚎鐢ㄦ埛', '2',   '1', 'online',     'monitor/online/index',     '', 1, 0, 'C', '0', '0', 'monitor:online:list',     'online',        'admin', sysdate(), '', null, '鍦ㄧ嚎鐢ㄦ埛鑿滃崟');
-# insert into sys_menu values('110',  '瀹氭椂浠诲姟', '2',   '2', 'job',        'monitor/job/index',        '', 1, 0, 'C', '0', '0', 'monitor:job:list',        'job',           'admin', sysdate(), '', null, '瀹氭椂浠诲姟鑿滃崟');
 insert into sys_menu values('111',  '鏁版嵁鐩戞帶', '2',   '3', 'druid',      'monitor/druid/index',      '', 1, 0, 'C', '0', '0', 'monitor:druid:list',      'druid',         'admin', sysdate(), '', null, '鏁版嵁鐩戞帶鑿滃崟');
-# insert into sys_menu values('112',  '鏈嶅姟鐩戞帶', '2',   '4', 'server',     'monitor/server/index',     '', 1, 0, 'C', '0', '0', 'monitor:server:list',     'server',        'admin', sysdate(), '', null, '鏈嶅姟鐩戞帶鑿滃崟');
 insert into sys_menu values('113',  '缂撳瓨鐩戞帶', '2',   '5', 'cache',      'monitor/cache/index',      '', 1, 0, 'C', '0', '0', 'monitor:cache:list',      'redis',         'admin', sysdate(), '', null, '缂撳瓨鐩戞帶鑿滃崟');
 insert into sys_menu values('114',  '琛ㄥ崟鏋勫缓', '3',   '1', 'build',      'tool/build/index',         '', 1, 0, 'C', '0', '0', 'tool:build:list',         'build',         'admin', sysdate(), '', null, '琛ㄥ崟鏋勫缓鑿滃崟');
 insert into sys_menu values('115',  '浠g爜鐢熸垚', '3',   '2', 'gen',        'tool/gen/index',           '', 1, 0, 'C', '0', '0', 'tool:gen:list',           'code',          'admin', sysdate(), '', null, '浠g爜鐢熸垚鑿滃崟');
@@ -248,13 +246,6 @@
 insert into sys_menu values('1046', '鍦ㄧ嚎鏌ヨ', '109', '1', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:online:query',       '#', 'admin', sysdate(), '', null, '');
 insert into sys_menu values('1047', '鎵归噺寮洪��', '109', '2', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:online:batchLogout', '#', 'admin', sysdate(), '', null, '');
 insert into sys_menu values('1048', '鍗曟潯寮洪��', '109', '3', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:online:forceLogout', '#', 'admin', sysdate(), '', null, '');
--- 瀹氭椂浠诲姟鎸夐挳
-# insert into sys_menu values('1049', '浠诲姟鏌ヨ', '110', '1', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:job:query',          '#', 'admin', sysdate(), '', null, '');
-# insert into sys_menu values('1050', '浠诲姟鏂板', '110', '2', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:job:add',            '#', 'admin', sysdate(), '', null, '');
-# insert into sys_menu values('1051', '浠诲姟淇敼', '110', '3', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:job:edit',           '#', 'admin', sysdate(), '', null, '');
-# insert into sys_menu values('1052', '浠诲姟鍒犻櫎', '110', '4', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:job:remove',         '#', 'admin', sysdate(), '', null, '');
-# insert into sys_menu values('1053', '鐘舵�佷慨鏀�', '110', '5', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:job:changeStatus',   '#', 'admin', sysdate(), '', null, '');
-# insert into sys_menu values('1054', '浠诲姟瀵煎嚭', '110', '7', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:job:export',         '#', 'admin', sysdate(), '', null, '');
 -- 浠g爜鐢熸垚鎸夐挳
 insert into sys_menu values('1055', '鐢熸垚鏌ヨ', '115', '1', '#', '', '', 1, 0, 'F', '0', '0', 'tool:gen:query',             '#', 'admin', sysdate(), '', null, '');
 insert into sys_menu values('1056', '鐢熸垚淇敼', '115', '2', '#', '', '', 1, 0, 'F', '0', '0', 'tool:gen:edit',              '#', 'admin', sysdate(), '', null, '');
@@ -373,12 +364,6 @@
 insert into sys_role_menu values ('2', '1046');
 insert into sys_role_menu values ('2', '1047');
 insert into sys_role_menu values ('2', '1048');
-insert into sys_role_menu values ('2', '1049');
-insert into sys_role_menu values ('2', '1050');
-insert into sys_role_menu values ('2', '1051');
-insert into sys_role_menu values ('2', '1052');
-insert into sys_role_menu values ('2', '1053');
-insert into sys_role_menu values ('2', '1054');
 insert into sys_role_menu values ('2', '1055');
 insert into sys_role_menu values ('2', '1056');
 insert into sys_role_menu values ('2', '1057');
@@ -469,8 +454,6 @@
 insert into sys_dict_type values(1,  '鐢ㄦ埛鎬у埆', 'sys_user_sex',        '0', 'admin', sysdate(), '', null, '鐢ㄦ埛鎬у埆鍒楄〃');
 insert into sys_dict_type values(2,  '鑿滃崟鐘舵��', 'sys_show_hide',       '0', 'admin', sysdate(), '', null, '鑿滃崟鐘舵�佸垪琛�');
 insert into sys_dict_type values(3,  '绯荤粺寮�鍏�', 'sys_normal_disable',  '0', 'admin', sysdate(), '', null, '绯荤粺寮�鍏冲垪琛�');
-insert into sys_dict_type values(4,  '浠诲姟鐘舵��', 'sys_job_status',      '0', 'admin', sysdate(), '', null, '浠诲姟鐘舵�佸垪琛�');
-insert into sys_dict_type values(5,  '浠诲姟鍒嗙粍', 'sys_job_group',       '0', 'admin', sysdate(), '', null, '浠诲姟鍒嗙粍鍒楄〃');
 insert into sys_dict_type values(6,  '绯荤粺鏄惁', 'sys_yes_no',          '0', 'admin', sysdate(), '', null, '绯荤粺鏄惁鍒楄〃');
 insert into sys_dict_type values(7,  '閫氱煡绫诲瀷', 'sys_notice_type',     '0', 'admin', sysdate(), '', null, '閫氱煡绫诲瀷鍒楄〃');
 insert into sys_dict_type values(8,  '閫氱煡鐘舵��', 'sys_notice_status',   '0', 'admin', sysdate(), '', null, '閫氱煡鐘舵�佸垪琛�');
@@ -508,10 +491,6 @@
 insert into sys_dict_data values(5,  2,  '闅愯棌',     '1',       'sys_show_hide',       '',   'danger',  'N', '0', 'admin', sysdate(), '', null, '闅愯棌鑿滃崟');
 insert into sys_dict_data values(6,  1,  '姝e父',     '0',       'sys_normal_disable',  '',   'primary', 'Y', '0', 'admin', sysdate(), '', null, '姝e父鐘舵��');
 insert into sys_dict_data values(7,  2,  '鍋滅敤',     '1',       'sys_normal_disable',  '',   'danger',  'N', '0', 'admin', sysdate(), '', null, '鍋滅敤鐘舵��');
-insert into sys_dict_data values(8,  1,  '姝e父',     '0',       'sys_job_status',      '',   'primary', 'Y', '0', 'admin', sysdate(), '', null, '姝e父鐘舵��');
-insert into sys_dict_data values(9,  2,  '鏆傚仠',     '1',       'sys_job_status',      '',   'danger',  'N', '0', 'admin', sysdate(), '', null, '鍋滅敤鐘舵��');
-insert into sys_dict_data values(10, 1,  '榛樿',     'DEFAULT', 'sys_job_group',       '',   '',        'Y', '0', 'admin', sysdate(), '', null, '榛樿鍒嗙粍');
-insert into sys_dict_data values(11, 2,  '绯荤粺',     'SYSTEM',  'sys_job_group',       '',   '',        'N', '0', 'admin', sysdate(), '', null, '绯荤粺鍒嗙粍');
 insert into sys_dict_data values(12, 1,  '鏄�',       'Y',       'sys_yes_no',          '',   'primary', 'Y', '0', 'admin', sysdate(), '', null, '绯荤粺榛樿鏄�');
 insert into sys_dict_data values(13, 2,  '鍚�',       'N',       'sys_yes_no',          '',   'danger',  'N', '0', 'admin', sysdate(), '', null, '绯荤粺榛樿鍚�');
 insert into sys_dict_data values(14, 1,  '閫氱煡',     '1',       'sys_notice_type',     '',   'warning', 'Y', '0', 'admin', sysdate(), '', null, '閫氱煡');
@@ -576,49 +555,6 @@
 
 
 -- ----------------------------
--- 15銆佸畾鏃朵换鍔¤皟搴﹁〃
--- ----------------------------
-drop table if exists sys_job;
-create table sys_job (
-  job_id              bigint(20)    not null auto_increment    comment '浠诲姟ID',
-  job_name            varchar(64)   default ''                 comment '浠诲姟鍚嶇О',
-  job_group           varchar(64)   default 'DEFAULT'          comment '浠诲姟缁勫悕',
-  invoke_target       varchar(500)  not null                   comment '璋冪敤鐩爣瀛楃涓�',
-  cron_expression     varchar(255)  default ''                 comment 'cron鎵ц琛ㄨ揪寮�',
-  misfire_policy      varchar(20)   default '3'                comment '璁″垝鎵ц閿欒绛栫暐锛�1绔嬪嵆鎵ц 2鎵ц涓�娆� 3鏀惧純鎵ц锛�',
-  concurrent          char(1)       default '1'                comment '鏄惁骞跺彂鎵ц锛�0鍏佽 1绂佹锛�',
-  status              char(1)       default '0'                comment '鐘舵�侊紙0姝e父 1鏆傚仠锛�',
-  create_by           varchar(64)   default ''                 comment '鍒涘缓鑰�',
-  create_time         datetime                                 comment '鍒涘缓鏃堕棿',
-  update_by           varchar(64)   default ''                 comment '鏇存柊鑰�',
-  update_time         datetime                                 comment '鏇存柊鏃堕棿',
-  remark              varchar(500)  default ''                 comment '澶囨敞淇℃伅',
-  primary key (job_id, job_name, job_group)
-) engine=innodb auto_increment=100 comment = '瀹氭椂浠诲姟璋冨害琛�';
-
-insert into sys_job values(1, '绯荤粺榛樿锛堟棤鍙傦級', 'DEFAULT', 'ryTask.ryNoParams',        '0/10 * * * * ?', '3', '1', '1', 'admin', sysdate(), '', null, '');
-insert into sys_job values(2, '绯荤粺榛樿锛堟湁鍙傦級', 'DEFAULT', 'ryTask.ryParams(\'ry\')',  '0/15 * * * * ?', '3', '1', '1', 'admin', sysdate(), '', null, '');
-insert into sys_job values(3, '绯荤粺榛樿锛堝鍙傦級', 'DEFAULT', 'ryTask.ryMultipleParams(\'ry\', true, 2000L, 316.50D, 100)',  '0/20 * * * * ?', '3', '1', '1', 'admin', sysdate(), '', null, '');
-
-
--- ----------------------------
--- 16銆佸畾鏃朵换鍔¤皟搴︽棩蹇楄〃
--- ----------------------------
-drop table if exists sys_job_log;
-create table sys_job_log (
-  job_log_id          bigint(20)     not null auto_increment    comment '浠诲姟鏃ュ織ID',
-  job_name            varchar(64)    not null                   comment '浠诲姟鍚嶇О',
-  job_group           varchar(64)    not null                   comment '浠诲姟缁勫悕',
-  invoke_target       varchar(500)   not null                   comment '璋冪敤鐩爣瀛楃涓�',
-  job_message         varchar(500)                              comment '鏃ュ織淇℃伅',
-  status              char(1)        default '0'                comment '鎵ц鐘舵�侊紙0姝e父 1澶辫触锛�',
-  exception_info      varchar(2000)  default ''                 comment '寮傚父淇℃伅',
-  create_time         datetime                                  comment '鍒涘缓鏃堕棿',
-  primary key (job_log_id)
-) engine=innodb comment = '瀹氭椂浠诲姟璋冨害鏃ュ織琛�';
-
-
--- ----------------------------
 -- 17銆侀�氱煡鍏憡琛�
 -- ----------------------------
 drop table if exists sys_notice;
@@ -639,8 +575,8 @@
 -- ----------------------------
 -- 鍒濆鍖�-鍏憡淇℃伅琛ㄦ暟鎹�
 -- ----------------------------
-insert into sys_notice values('1', '娓╅Θ鎻愰啋锛�2018-07-01 鑻ヤ緷鏂扮増鏈彂甯冨暒', '2', '鏂扮増鏈唴瀹�', '0', 'admin', sysdate(), '', null, '绠$悊鍛�');
-insert into sys_notice values('2', '缁存姢閫氱煡锛�2018-07-01 鑻ヤ緷绯荤粺鍑屾櫒缁存姢', '1', '缁存姢鍐呭',   '0', 'admin', sysdate(), '', null, '绠$悊鍛�');
+insert into sys_notice values('1', '娓╅Θ鎻愰啋锛�2018-07-01 鏂扮増鏈彂甯冨暒', '2', '鏂扮増鏈唴瀹�', '0', 'admin', sysdate(), '', null, '绠$悊鍛�');
+insert into sys_notice values('2', '缁存姢閫氱煡锛�2018-07-01 绯荤粺鍑屾櫒缁存姢', '1', '缁存姢鍐呭',   '0', 'admin', sysdate(), '', null, '绠$悊鍛�');
 
 
 -- ----------------------------

--
Gitblit v1.9.3